Skip to content
This repository has been archived by the owner on Feb 7, 2024. It is now read-only.

Add optional AccessMode to StorageResourceMappingItem #438

Merged
merged 2 commits into from Nov 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion go.sum
Expand Up @@ -895,7 +895,6 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
github.com/prometheus/client_golang v1.2.1 h1:JnMpQc6ppsNgw9QPAGF6Dod479itz7lvlsMzzNayLOI=
github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U=
github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/v2v/v1beta1/resourcemapping_types.go
Expand Up @@ -93,6 +93,8 @@ type StorageResourceMappingItem struct {

// +optional
VolumeMode *corev1.PersistentVolumeMode `json:"volumeMode,omitempty"`
// +optional
AccessMode *corev1.PersistentVolumeAccessMode `json:"accessMode,omitempty"`
}

// ResourceMappingStatus defines the observed state of ResourceMapping
Expand Down
5 changes: 5 additions & 0 deletions pkg/apis/v2v/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pkg/jobs/jobs.go
Expand Up @@ -3,6 +3,7 @@ package jobs
import (
"context"
"fmt"

"github.com/kubevirt/vm-import-operator/pkg/utils"
batchv1 "k8s.io/api/batch/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down
24 changes: 24 additions & 0 deletions pkg/operator/resources/operator/operator.go
Expand Up @@ -2220,6 +2220,9 @@ func CreateVMImport() *extv1.CustomResourceDefinition {
"volumeMode": {
Type: "string",
},
"accessMode": {
Type: "string",
},
},
Required: []string{"source"},
},
Expand Down Expand Up @@ -2266,6 +2269,9 @@ func CreateVMImport() *extv1.CustomResourceDefinition {
"volumeMode": {
Type: "string",
},
"accessMode": {
Type: "string",
},
},
Required: []string{"source"},
},
Expand Down Expand Up @@ -2394,6 +2400,9 @@ NetworkMappings.Source.ID represents the macAddress field of the network adapter
"volumeMode": {
Type: "string",
},
"accessMode": {
Type: "string",
},
},
Required: []string{"source"},
},
Expand Down Expand Up @@ -2440,6 +2449,9 @@ DiskMappings.Source.ID represents the DiskObjectId or vDiskID of the VirtualDisk
"volumeMode": {
Type: "string",
},
"accessMode": {
Type: "string",
},
},
Required: []string{"source"},
},
Expand Down Expand Up @@ -2867,6 +2879,9 @@ func CreateResourceMapping() *extv1.CustomResourceDefinition {
"volumeMode": {
Type: "string",
},
"accessMode": {
Type: "string",
},
},
Required: []string{"source", "target"},
},
Expand Down Expand Up @@ -2913,6 +2928,9 @@ func CreateResourceMapping() *extv1.CustomResourceDefinition {
"volumeMode": {
Type: "string",
},
"accessMode": {
Type: "string",
},
},
Required: []string{"source", "target"},
},
Expand Down Expand Up @@ -3006,6 +3024,9 @@ NetworkMappings.Source.ID represents the macAddress field of the network adapter
"volumeMode": {
Type: "string",
},
"accessMode": {
Type: "string",
},
},
Required: []string{"source", "target"},
},
Expand Down Expand Up @@ -3052,6 +3073,9 @@ DiskMappings.Source.ID represents the DiskObjectId or vDiskID of the VirtualDisk
"volumeMode": {
Type: "string",
},
"accessMode": {
Type: "string",
},
},
Required: []string{"source", "target"},
},
Expand Down
11 changes: 7 additions & 4 deletions pkg/providers/ovirt/mapper/mapper.go
Expand Up @@ -231,9 +231,12 @@ func (o *OvirtMapper) mapDiskInterface(iface ovirtsdk.DiskInterface) string {
return string(iface)
}

// Set the access mode of the PVC based on the VM's disk read only attribute
// and based on the affinity settings of the VM.
func (o *OvirtMapper) getAccessMode(diskAttachment *ovirtsdk.DiskAttachment) corev1.PersistentVolumeAccessMode {
// If the mapping specifies the access mode return that, otherwise determine the access mode
// of the PVC based on the VM's disk read only attribute and based on the affinity settings of the VM.
func (o *OvirtMapper) getAccessMode(diskAttachment *ovirtsdk.DiskAttachment, mapping *v2vv1.StorageResourceMappingItem) corev1.PersistentVolumeAccessMode {
if mapping != nil && mapping.AccessMode != nil {
return *mapping.AccessMode
}
accessMode := corev1.ReadWriteOnce
if readOnly, ok := diskAttachment.ReadOnly(); ok && readOnly {
accessMode = corev1.ReadOnlyMany
Expand Down Expand Up @@ -265,9 +268,9 @@ func (o *OvirtMapper) MapDataVolumes(targetVMName *string) (map[string]cdiv1.Dat
return dvs, err
}
quantity, _ := resource.ParseQuantity(diskSizeConverted)
accessMode := o.getAccessMode(diskAttachment)

mapping := o.getMapping(disk, o.mappings)
accessMode := o.getAccessMode(diskAttachment, mapping)
sdClass := o.getStorageClassForDisk(mapping)
volumeMode := o.getVolumeMode(mapping)

Expand Down
63 changes: 43 additions & 20 deletions pkg/providers/vmware/mapper/mapper.go
Expand Up @@ -46,6 +46,11 @@ const (
q35 = "q35"
)

var (
defaultVolumeMode = corev1.PersistentVolumeFilesystem
defaultAccessMode = corev1.ReadWriteOnce
)

var biosTypeMapping = map[string]*kubevirtv1.Bootloader{
"efi": {EFI: &kubevirtv1.EFI{}},
"bios": {BIOS: &kubevirtv1.BIOS{}},
Expand Down Expand Up @@ -222,49 +227,67 @@ func (r *VmwareMapper) buildDisks() error {
return nil
}

func (r *VmwareMapper) getStorageClassForDisk(disk *disk) *string {
func (r *VmwareMapper) getMappingForDisk(disk disk) *v1beta1.StorageResourceMappingItem {
if r.mappings.DiskMappings != nil {
for _, mapping := range *r.mappings.DiskMappings {
targetName := mapping.Target.Name
if mapping.Source.ID != nil {
if disk.id == *mapping.Source.ID {
if targetName != defaultStorageClassTargetName {
return &targetName
}
return &mapping
}
}
if mapping.Source.Name != nil {
if disk.name == *mapping.Source.Name {
if targetName != defaultStorageClassTargetName {
return &targetName
}
return &mapping
}
}
}
}

if r.mappings.StorageMappings != nil {
for _, mapping := range *r.mappings.StorageMappings {
targetName := mapping.Target.Name
if mapping.Source.ID != nil {
if disk.datastoreMoRef == *mapping.Source.ID {
if targetName != defaultStorageClassTargetName {
return &targetName
}
return &mapping
}
}
if mapping.Source.Name != nil {
if disk.datastoreName == *mapping.Source.Name {
if targetName != defaultStorageClassTargetName {
return &targetName
}
return &mapping
}
}
}
}
return nil
}

func (r *VmwareMapper) getStorageClassForDisk(mapping *v1beta1.StorageResourceMappingItem) *string {
if mapping != nil {
targetName := mapping.Target.Name
if targetName != defaultStorageClassTargetName {
return &targetName
}
}

// Use default storage class:
return nil
}

func (r *VmwareMapper) getAccessModeForDisk(mapping *v1beta1.StorageResourceMappingItem) corev1.PersistentVolumeAccessMode {
if mapping != nil && mapping.AccessMode != nil {
return *mapping.AccessMode
}

return defaultAccessMode
}

func (r *VmwareMapper) getVolumeModeForDisk(mapping *v1beta1.StorageResourceMappingItem) *corev1.PersistentVolumeMode {
if mapping != nil && mapping.VolumeMode != nil {
return mapping.VolumeMode
}

return &defaultVolumeMode
}

// MapDataVolumes maps the VMware disks to CDI DataVolumes
func (r *VmwareMapper) MapDataVolumes(targetVMName *string) (map[string]cdiv1.DataVolume, error) {
err := r.buildDisks()
Expand All @@ -277,6 +300,8 @@ func (r *VmwareMapper) MapDataVolumes(targetVMName *string) (map[string]cdiv1.Da
for _, disk := range *r.disks {
dvName := buildDataVolumeName(*targetVMName, disk.name)

mapping := r.getMappingForDisk(disk)

dvs[dvName] = cdiv1.DataVolume{
TypeMeta: metav1.TypeMeta{
APIVersion: cdiAPIVersion,
Expand All @@ -298,20 +323,18 @@ func (r *VmwareMapper) MapDataVolumes(targetVMName *string) (map[string]cdiv1.Da
},
PVC: &corev1.PersistentVolumeClaimSpec{
AccessModes: []corev1.PersistentVolumeAccessMode{
corev1.ReadWriteOnce,
r.getAccessModeForDisk(mapping),
},
VolumeMode: r.getVolumeModeForDisk(mapping),
Resources: corev1.ResourceRequirements{
Requests: corev1.ResourceList{
corev1.ResourceStorage: disk.capacity,
},
},
StorageClassName: r.getStorageClassForDisk(mapping),
},
},
}
sdClass := r.getStorageClassForDisk(&disk)
if sdClass != nil {
dvs[dvName].Spec.PVC.StorageClassName = sdClass
}
}
return dvs, nil
}
Expand Down
38 changes: 37 additions & 1 deletion pkg/providers/vmware/mapper/mapper_test.go
Expand Up @@ -3,6 +3,8 @@ package mapper_test
import (
"context"

v1 "k8s.io/api/core/v1"

"github.com/kubevirt/vm-import-operator/pkg/apis/v2v/v1beta1"
"github.com/kubevirt/vm-import-operator/pkg/providers/vmware/mapper"
"github.com/kubevirt/vm-import-operator/pkg/providers/vmware/os"
Expand Down Expand Up @@ -39,8 +41,15 @@ var (

// disks
expectedNumDisks = 2
diskId1 = "disk-202-0"
diskId2 = "disk-202-1"
expectedDiskName1 = "basic-vm-disk-202-0"
expectedDiskName2 = "basic-vm-disk-202-1"

volumeModeBlock = v1.PersistentVolumeBlock
volumeModeFilesystem = v1.PersistentVolumeFilesystem
accessModeRWO = v1.ReadWriteOnce
accessModeRWM = v1.ReadWriteMany
)

type mockOsFinder struct{}
Expand Down Expand Up @@ -250,13 +259,40 @@ var _ = Describe("Test mapping disks", func() {
credentials = prepareCredentials(server)
})

It("should map disks", func() {
It("should map datavolumes", func() {
storageClass := "mystorageclass"
mappings := createMinimalMapping()
mappings.DiskMappings = &[]v1beta1.StorageResourceMappingItem{
{
Source: v1beta1.Source{
Name: &diskId1,
},
Target: v1beta1.ObjectIdentifier{
Name: storageClass,
},
VolumeMode: &volumeModeBlock,
AccessMode: &accessModeRWM,
},
{
// using defaults
Source: v1beta1.Source{
Name: &diskId2,
},
},
}
mapper := mapper.NewVmwareMapper(vm, vmProperties, hostProperties, credentials, mappings, "", osFinder)
dvs, _ := mapper.MapDataVolumes(&targetVMName)
Expect(dvs).To(HaveLen(expectedNumDisks))
Expect(dvs).To(HaveKey(expectedDiskName1))
Expect(dvs).To(HaveKey(expectedDiskName2))
// check that mapped options are set correctly
Expect(dvs[expectedDiskName1].Spec.PVC.VolumeMode).To(Equal(&volumeModeBlock))
Expect(dvs[expectedDiskName1].Spec.PVC.AccessModes[0]).To(Equal(accessModeRWM))
Expect(dvs[expectedDiskName1].Spec.PVC.StorageClassName).To(Equal(&storageClass))
// check that defaults are set correctly
Expect(dvs[expectedDiskName2].Spec.PVC.VolumeMode).To(Equal(&volumeModeFilesystem))
Expect(dvs[expectedDiskName2].Spec.PVC.AccessModes[0]).To(Equal(accessModeRWO))
Expect(dvs[expectedDiskName2].Spec.PVC.StorageClassName).To(BeNil())
})
})

Expand Down
1 change: 1 addition & 0 deletions pkg/providers/vmware/provider_test.go
Expand Up @@ -3,6 +3,7 @@ package vmware
import (
"context"
"encoding/json"

"github.com/onsi/ginkgo/extensions/table"

"github.com/ghodss/yaml"
Expand Down
3 changes: 2 additions & 1 deletion pkg/providers/vmware/templates/template-finder.go
Expand Up @@ -2,11 +2,12 @@ package templates

import (
"fmt"
"sort"

"github.com/kubevirt/vm-import-operator/pkg/providers/vmware/os"
"github.com/kubevirt/vm-import-operator/pkg/templates"
templatev1 "github.com/openshift/api/template/v1"
"github.com/vmware/govmomi/vim25/mo"
"sort"
)

const (
Expand Down