From 0cdebf9123edd55fa88992ae7d61681b2eadb507 Mon Sep 17 00:00:00 2001 From: gitlawr Date: Thu, 5 Aug 2021 14:29:45 +0800 Subject: [PATCH] Change VMSpec to VMSpec + metadata in templates --- pkg/api/vm/handler.go | 15 +- pkg/apis/harvesterhci.io/v1beta1/template.go | 10 +- .../template/template_controller_test.go | 7 +- pkg/data/template.go | 370 ++++++++++-------- .../integration/api/vm_template_apis_test.go | 5 +- 5 files changed, 221 insertions(+), 186 deletions(-) diff --git a/pkg/api/vm/handler.go b/pkg/api/vm/handler.go index e56778f0fc..fa75d2328f 100644 --- a/pkg/api/vm/handler.go +++ b/pkg/api/vm/handler.go @@ -406,7 +406,7 @@ func (h *vmActionHandler) createTemplate(namespace, name string, input CreateTem Spec: harvesterv1.VirtualMachineTemplateVersionSpec{ TemplateID: vmID, Description: fmt.Sprintf("Template drived from virtual machine [%s]", vmID), - VM: removeMacAddresses(vm.Spec), + VM: removeMacAddresses(vm), KeyPairIDs: keyPairIDs, }, }) @@ -415,12 +415,15 @@ func (h *vmActionHandler) createTemplate(namespace, name string, input CreateTem // removeMacAddresses replaces the mac address of each device interface with an empty string. // This is because macAddresses are unique, and should not reuse the original's. -func removeMacAddresses(vmSpec kv1.VirtualMachineSpec) kv1.VirtualMachineSpec { - censoredSpec := vmSpec - for index := range censoredSpec.Template.Spec.Domain.Devices.Interfaces { - censoredSpec.Template.Spec.Domain.Devices.Interfaces[index].MacAddress = "" +func removeMacAddresses(vm *kv1.VirtualMachine) harvesterv1.VirtualMachineSourceSpec { + sanitizedVm := vm.DeepCopy() + for index := range sanitizedVm.Spec.Template.Spec.Domain.Devices.Interfaces { + sanitizedVm.Spec.Template.Spec.Domain.Devices.Interfaces[index].MacAddress = "" + } + return harvesterv1.VirtualMachineSourceSpec{ + ObjectMeta: sanitizedVm.ObjectMeta, + Spec: sanitizedVm.Spec, } - return censoredSpec } // getSSHKeysFromVMITemplateSpec first checks the given VirtualMachineInstanceTemplateSpec diff --git a/pkg/apis/harvesterhci.io/v1beta1/template.go b/pkg/apis/harvesterhci.io/v1beta1/template.go index 69a7c0622b..665a85a067 100644 --- a/pkg/apis/harvesterhci.io/v1beta1/template.go +++ b/pkg/apis/harvesterhci.io/v1beta1/template.go @@ -74,7 +74,15 @@ type VirtualMachineTemplateVersionSpec struct { KeyPairIDs []string `json:"keyPairIds,omitempty"` // +optional - VM kv1.VirtualMachineSpec `json:"vm,omitempty"` + VM VirtualMachineSourceSpec `json:"vm,omitempty"` +} + +type VirtualMachineSourceSpec struct { + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + ObjectMeta metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec kv1.VirtualMachineSpec `json:"spec,omitempty"` } type VirtualMachineTemplateVersionStatus struct { diff --git a/pkg/controller/master/template/template_controller_test.go b/pkg/controller/master/template/template_controller_test.go index 6a1f699313..b0dced5a00 100644 --- a/pkg/controller/master/template/template_controller_test.go +++ b/pkg/controller/master/template/template_controller_test.go @@ -12,7 +12,6 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/watch" - kv1 "kubevirt.io/client-go/api/v1" harvesterv1 "github.com/harvester/harvester/pkg/apis/harvesterhci.io/v1beta1" "github.com/harvester/harvester/pkg/generated/clientset/versioned/fake" @@ -119,7 +118,7 @@ func TestTemplateHandler_OnChanged(t *testing.T) { Description: "fake_description", TemplateID: "default/test", ImageID: "fake_image_id", - VM: kv1.VirtualMachineSpec{}, + VM: harvesterv1.VirtualMachineSourceSpec{}, }, Status: harvesterv1.VirtualMachineTemplateVersionStatus{ Version: 1, @@ -162,7 +161,7 @@ func TestTemplateHandler_OnChanged(t *testing.T) { Description: "fake_description", TemplateID: "fake_template_id", ImageID: "fake_image_id", - VM: kv1.VirtualMachineSpec{}, + VM: harvesterv1.VirtualMachineSourceSpec{}, }, Status: harvesterv1.VirtualMachineTemplateVersionStatus{ Version: 1, @@ -217,7 +216,7 @@ func TestTemplateHandler_OnChanged(t *testing.T) { Description: "fake_description", TemplateID: "default/test", ImageID: "fake_image_id", - VM: kv1.VirtualMachineSpec{}, + VM: harvesterv1.VirtualMachineSourceSpec{}, }, Status: harvesterv1.VirtualMachineTemplateVersionStatus{ Version: 2, diff --git a/pkg/data/template.go b/pkg/data/template.go index ba33cc5f01..0fdbe212c6 100644 --- a/pkg/data/template.go +++ b/pkg/data/template.go @@ -116,67 +116,75 @@ metadata: spec: templateId: {{ .Namespace }}/iso-image-base-template vm: - running: true - template: - spec: - evictionStrategy: LiveMigrate - domain: - cpu: - cores: 1 - devices: - disks: - - cdrom: - bus: sata - readonly: true - name: cdrom-disk - bootOrder: 2 - - disk: - bus: virtio - name: rootdisk - bootOrder: 1 - interfaces: - - name: default - masquerade: {} - resources: - requests: - memory: 2048Mi - networks: - - name: default - pod: {} - volumes: - - dataVolume: - name: datavolume-cdrom-disk - name: cdrom-disk - - dataVolume: - name: datavolume-rootdisk - name: rootdisk - dataVolumeTemplates: - - metadata: - annotations: - harvesterhci.io/imageId: $occupancy_url - name: datavolume-cdrom-disk - spec: - pvc: - accessModes: - - ReadWriteMany - volumeMode: Block - resources: - requests: - storage: 10Gi - source: - blank: {} - - metadata: - name: datavolume-rootdisk - spec: - pvc: - accessModes: - - ReadWriteMany - volumeMode: Block - resources: - requests: - storage: 10Gi - source: - blank: {} + metadata: + annotations: + harvesterhci.io/volumeClaimTemplates: |- + [{ + "metadata": { + "name": "pvc-cdrom-disk", + "annotations": { + "harvesterhci.io/imageId": "" + } + }, + "spec":{ + "accessModes": ["ReadWriteMany"], + "resources":{ + "requests":{ + "storage": "10Gi" + } + }, + "volumeMode": "Block" + } + }, + { + "metadata": { + "name": "pvc-rootdisk" + }, + "spec":{ + "accessModes": ["ReadWriteMany"], + "resources":{ + "requests":{ + "storage": "10Gi" + } + }, + "volumeMode": "Block" + } + }] + spec: + running: true + template: + spec: + evictionStrategy: LiveMigrate + domain: + cpu: + cores: 1 + devices: + disks: + - cdrom: + bus: sata + readonly: true + name: cdrom-disk + bootOrder: 2 + - disk: + bus: virtio + name: rootdisk + bootOrder: 1 + interfaces: + - name: default + masquerade: {} + resources: + requests: + memory: 2048Mi + networks: + - name: default + pod: {} + volumes: + - persistentVolumeClaim: + claimName: pvc-cdrom-disk + name: cdrom-disk + - persistentVolumeClaim: + claimName: pvc-rootdisk + name: rootdisk --- apiVersion: harvesterhci.io/v1beta1 kind: VirtualMachineTemplateVersion @@ -186,47 +194,53 @@ metadata: spec: templateId: {{ .Namespace }}/raw-image-base-template vm: - running: true - template: - spec: - evictionStrategy: LiveMigrate - domain: - cpu: - cores: 1 - devices: - disks: - - disk: - bus: virtio - name: rootdisk - bootOrder: 1 - interfaces: - - name: default - masquerade: {} - resources: - requests: - memory: 2048Mi - networks: - - name: default - pod: {} - volumes: - - dataVolume: - name: datavolume-rootdisk - name: rootdisk - dataVolumeTemplates: - - metadata: - annotations: - harvesterhci.io/imageId: $occupancy_url - name: datavolume-rootdisk - spec: - pvc: - accessModes: - - ReadWriteMany - volumeMode: Block - resources: - requests: - storage: 10Gi - source: - blank: {} + metadata: + annotations: + harvesterhci.io/volumeClaimTemplates: |- + [{ + "metadata": { + "name": "pvc-rootdisk", + "annotations": { + "harvesterhci.io/imageId": "" + } + }, + "spec":{ + "accessModes": ["ReadWriteMany"], + "resources":{ + "requests":{ + "storage": "10Gi" + } + }, + "volumeMode": "Block" + } + }] + spec: + running: true + template: + spec: + evictionStrategy: LiveMigrate + domain: + cpu: + cores: 1 + devices: + disks: + - disk: + bus: virtio + name: rootdisk + bootOrder: 1 + interfaces: + - name: default + masquerade: {} + resources: + requests: + memory: 2048Mi + networks: + - name: default + pod: {} + volumes: + - persistentVolumeClaim: + claimName: pvc-rootdisk + name: rootdisk --- apiVersion: harvesterhci.io/v1beta1 kind: VirtualMachineTemplateVersion @@ -236,77 +250,85 @@ metadata: spec: templateId: {{ .Namespace }}/windows-iso-image-base-template vm: - running: true - template: - spec: - evictionStrategy: LiveMigrate - domain: - cpu: - cores: 1 - devices: - disks: - - cdrom: - bus: sata - name: cdrom-disk - bootOrder: 1 - - disk: - bus: virtio - name: rootdisk - bootOrder: 2 - - cdrom: - bus: sata - name: virtio-container-disk - interfaces: - - name: default - model: e1000 - masquerade: {} - inputs: - - bus: usb - name: tablet - type: tablet - resources: - requests: - memory: 2048Mi - networks: - - name: default - pod: {} - volumes: - - dataVolume: - name: datavolume-cdrom-disk - name: cdrom-disk - - dataVolume: - name: datavolume-rootdisk - name: rootdisk - - containerDisk: - image: kubevirt/virtio-container-disk - imagePullPolicy: IfNotPresent - name: virtio-container-disk - dataVolumeTemplates: - - metadata: - annotations: - harvesterhci.io/imageId: $occupancy_url - name: datavolume-cdrom-disk - spec: - pvc: - accessModes: - - ReadWriteMany - volumeMode: Block - resources: - requests: - storage: 20Gi - source: - blank: {} - - metadata: - name: datavolume-rootdisk - spec: - pvc: - accessModes: - - ReadWriteMany - volumeMode: Block - resources: - requests: - storage: 32Gi - source: - blank: {} + metadata: + annotations: + harvesterhci.io/volumeClaimTemplates: |- + [{ + "metadata": { + "name": "pvc-cdrom-disk", + "annotations": { + "harvesterhci.io/imageId": "" + } + }, + "spec":{ + "accessModes": ["ReadWriteMany"], + "resources":{ + "requests":{ + "storage": "20Gi" + } + }, + "volumeMode": "Block" + } + }, + { + "metadata": { + "name": "pvc-rootdisk" + }, + "spec":{ + "accessModes": ["ReadWriteMany"], + "resources":{ + "requests":{ + "storage": "32Gi" + } + }, + "volumeMode": "Block" + } + }] + spec: + running: true + template: + spec: + evictionStrategy: LiveMigrate + domain: + cpu: + cores: 1 + devices: + disks: + - cdrom: + bus: sata + name: cdrom-disk + bootOrder: 1 + - disk: + bus: virtio + name: rootdisk + bootOrder: 2 + - cdrom: + bus: sata + name: virtio-container-disk + interfaces: + - name: default + model: e1000 + masquerade: {} + inputs: + - bus: usb + name: tablet + type: tablet + resources: + requests: + memory: 2048Mi + networks: + - name: default + pod: {} + volumes: + - persistentVolumeClaim: + claimName: pvc-cdrom-disk + name: cdrom-disk + - persistentVolumeClaim: + claimName: pvc-rootdisk + name: rootdisk + - containerDisk: + image: kubevirt/virtio-container-disk + imagePullPolicy: IfNotPresent + name: virtio-container-disk ` ) diff --git a/tests/integration/api/vm_template_apis_test.go b/tests/integration/api/vm_template_apis_test.go index 73095c14a3..11e5ba72b0 100644 --- a/tests/integration/api/vm_template_apis_test.go +++ b/tests/integration/api/vm_template_apis_test.go @@ -142,7 +142,10 @@ var _ = Describe("verify vm template APIs", func() { templateVersion.Spec.TemplateID = templateID vm, err := NewDefaultTestVMBuilder(testResourceLabels).VM() MustNotError(err) - templateVersion.Spec.VM = vm.Spec + templateVersion.Spec.VM = harvesterv1.VirtualMachineSourceSpec{ + ObjectMeta: vm.ObjectMeta, + Spec: vm.Spec, + } respCode, respBody, err := helper.PostObjectByYAML(templateVersionAPI, templateVersion) MustRespCodeIs(http.StatusCreated, "create template version", err, respCode, respBody)