Add support for linked clones (#478)

This commit is contained in:
Lukas Kirylak
2025-05-09 15:36:00 +02:00
committed by GitHub
parent ec71aa4bdf
commit 679ebc101d
6 changed files with 38 additions and 7 deletions

View File

@@ -204,6 +204,8 @@ type TemplateSource struct {
}
// VirtualMachineCloneSpec is information used to clone a virtual machine.
// +kubebuilder:validation:XValidation:rule="self.full || !has(self.format)",message="Must set full=true when specifying format"
// +kubebuilder:validation:XValidation:rule="self.full || !has(self.storage)",message="Must set full=true when specifying storage"
type VirtualMachineCloneSpec struct {
TemplateSource `json:",inline"`
@@ -213,7 +215,6 @@ type VirtualMachineCloneSpec struct {
// Format for file storage. Only valid for full clone.
// +kubebuilder:validation:Enum=raw;qcow2;vmdk
// +kubebuilder:default=raw
// +optional
Format *TargetFileStorageFormat `json:"format,omitempty"`
@@ -578,7 +579,6 @@ type ProxmoxMachine struct {
// +kubebuilder:validation:XValidation:rule="[has(self.sourceNode), has(self.templateSelector)].exists_one(c, c)",message="must define either SourceNode with TemplateID, OR TemplateSelector"
// +kubebuilder:validation:XValidation:rule="[has(self.templateID), has(self.templateSelector)].exists_one(c, c)",message="must define either SourceNode with TemplateID, OR TemplateSelector."
// +kubebuilder:validation:XValidation:rule="self.full && self.format != ''",message="Must set full=true when specifying format"
Spec ProxmoxMachineSpec `json:"spec,omitempty"`
Status ProxmoxMachineStatus `json:"status,omitempty"`
}

View File

@@ -62,11 +62,29 @@ var _ = Describe("ProxmoxMachine Test", func() {
Context("VirtualMachineCloneSpec", func() {
It("Should not allow specifying format if full clone is disabled", func() {
dm := defaultMachine()
dm.Spec.Format = ptr.To(TargetStorageFormatRaw)
dm.Spec.Full = ptr.To(false)
Expect(k8sClient.Create(context.Background(), dm)).Should(MatchError(ContainSubstring("Must set full=true when specifying format")))
})
It("Should not allow specifying storage if full clone is disabled", func() {
dm := defaultMachine()
dm.Spec.Storage = ptr.To("local")
dm.Spec.Full = ptr.To(false)
Expect(k8sClient.Create(context.Background(), dm)).Should(MatchError(ContainSubstring("Must set full=true when specifying storage")))
})
It("Should allow disabling full clone in absence of format and storage", func() {
dm := defaultMachine()
dm.Spec.Format = nil
dm.Spec.Storage = nil
dm.Spec.Full = ptr.To(false)
Expect(k8sClient.Create(context.Background(), dm)).Should(Succeed())
})
It("Should disallow absence of SourceNode, TemplateID and TemplateSelector", func() {
dm := defaultMachine()
dm.Spec.TemplateSource.SourceNode = ""

View File

@@ -135,7 +135,6 @@ spec:
rule: self == oldSelf
type: object
format:
default: raw
description: Format for file storage. Only valid for full
clone.
enum:
@@ -700,6 +699,11 @@ spec:
- message: end should be greater than or equal to start
rule: self.end >= self.start
type: object
x-kubernetes-validations:
- message: Must set full=true when specifying format
rule: self.full || !has(self.format)
- message: Must set full=true when specifying storage
rule: self.full || !has(self.storage)
type: object
x-kubernetes-validations:
- message: Cowardly refusing to deploy cluster without control

View File

@@ -159,7 +159,6 @@ spec:
rule: self == oldSelf
type: object
format:
default: raw
description: Format for file storage. Only valid
for full clone.
enum:
@@ -742,6 +741,11 @@ spec:
start
rule: self.end >= self.start
type: object
x-kubernetes-validations:
- message: Must set full=true when specifying format
rule: self.full || !has(self.format)
- message: Must set full=true when specifying storage
rule: self.full || !has(self.storage)
type: object
x-kubernetes-validations:
- message: Cowardly refusing to deploy cluster without

View File

@@ -127,7 +127,6 @@ spec:
rule: self == oldSelf
type: object
format:
default: raw
description: Format for file storage. Only valid for full clone.
enum:
- raw
@@ -664,7 +663,9 @@ spec:
rule: '[has(self.templateID), has(self.templateSelector)].exists_one(c,
c)'
- message: Must set full=true when specifying format
rule: self.full && self.format != ''
rule: self.full || !has(self.format)
- message: Must set full=true when specifying storage
rule: self.full || !has(self.storage)
status:
description: ProxmoxMachineStatus defines the observed state of a ProxmoxMachine.
properties:

View File

@@ -139,7 +139,6 @@ spec:
rule: self == oldSelf
type: object
format:
default: raw
description: Format for file storage. Only valid for full
clone.
enum:
@@ -697,6 +696,11 @@ spec:
- message: end should be greater than or equal to start
rule: self.end >= self.start
type: object
x-kubernetes-validations:
- message: Must set full=true when specifying format
rule: self.full || !has(self.format)
- message: Must set full=true when specifying storage
rule: self.full || !has(self.storage)
required:
- spec
type: object