Skip to content

Commit fd8ed76

Browse files
authored
Refactor kubervirt provider storage (#1872)
* refactor kubervirt provider storage * refactor kubervirt provider storage * fix failing tests
1 parent 22c1174 commit fd8ed76

16 files changed

+113
-61
lines changed

pkg/cloudprovider/provider/kubevirt/provider.go

Lines changed: 80 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ type StorageTarget string
124124

125125
const (
126126
Storage StorageTarget = "storage"
127+
PVC StorageTarget = "pvc"
127128
)
128129

129130
type AffinityType string
@@ -308,30 +309,14 @@ func (p *provider) getConfig(provSpec clusterv1alpha1.ProviderSpec) (*Config, *p
308309
if rawConfig.VirtualMachine.DNSConfig != nil {
309310
config.DNSConfig = rawConfig.VirtualMachine.DNSConfig
310311
}
311-
config.SecondaryDisks = make([]SecondaryDisks, 0, len(rawConfig.VirtualMachine.Template.SecondaryDisks))
312-
for i, sd := range rawConfig.VirtualMachine.Template.SecondaryDisks {
313-
sdSizeString, err := p.configVarResolver.GetConfigVarStringValue(sd.Size)
314-
if err != nil {
315-
return nil, nil, fmt.Errorf(`failed to parse "secondaryDisks.size" field: %w`, err)
316-
}
317-
pvc, err := resource.ParseQuantity(sdSizeString)
318-
if err != nil {
319-
return nil, nil, fmt.Errorf(`failed to parse value of "secondaryDisks.size" field: %w`, err)
320-
}
321-
322-
scString, err := p.configVarResolver.GetConfigVarStringValue(sd.StorageClassName)
323-
if err != nil {
324-
return nil, nil, fmt.Errorf(`failed to parse value of "secondaryDisks.storageClass" field: %w`, err)
325-
}
326-
config.SecondaryDisks = append(config.SecondaryDisks, SecondaryDisks{
327-
Name: fmt.Sprintf("secondarydisk%d", i),
328-
Size: pvc,
329-
StorageClassName: scString,
330-
StorageAccessType: p.getStorageAccessType(sd.StorageAccessType),
331-
})
312+
infraClient, err := client.New(config.RestConfig, client.Options{})
313+
if err != nil {
314+
return nil, nil, fmt.Errorf("failed to get kubevirt client: %w", err)
315+
}
316+
config.StorageAccessType, config.SecondaryDisks, err = p.configureStorage(infraClient, rawConfig.VirtualMachine.Template)
317+
if err != nil {
318+
return nil, nil, fmt.Errorf(`failed to configure storage: %w`, err)
332319
}
333-
config.StorageAccessType = p.getStorageAccessType(rawConfig.VirtualMachine.Template.PrimaryDisk.StorageAccessType)
334-
335320
config.NodeAffinityPreset, err = p.parseNodeAffinityPreset(rawConfig.Affinity.NodeAffinityPreset)
336321
if err != nil {
337322
return nil, nil, fmt.Errorf(`failed to parse "nodeAffinityPreset" field: %w`, err)
@@ -356,12 +341,29 @@ func (p *provider) getConfig(provSpec clusterv1alpha1.ProviderSpec) (*Config, *p
356341
return &config, pconfig, nil
357342
}
358343

359-
func (p *provider) getStorageAccessType(accessType providerconfigtypes.ConfigVarString) corev1.PersistentVolumeAccessMode {
344+
func (p *provider) getStorageAccessType(ctx context.Context, accessType providerconfigtypes.ConfigVarString,
345+
infraClient client.Client, storageClassName string) (corev1.PersistentVolumeAccessMode, error) {
360346
at, _ := p.configVarResolver.GetConfigVarStringValue(accessType)
361347
if at == "" {
362-
return corev1.ReadWriteOnce
348+
sp := &cdiv1beta1.StorageProfile{}
349+
if err := infraClient.Get(ctx, types.NamespacedName{Name: storageClassName}, sp); err != nil {
350+
return "", fmt.Errorf(`failed to get cdi storageprofile: %w`, err)
351+
}
352+
353+
// choose RWO as a default access mode and if RWX is supported then choose it instead.
354+
accessMode := corev1.ReadWriteOnce
355+
for _, claimProperty := range sp.Status.ClaimPropertySets {
356+
for _, am := range claimProperty.AccessModes {
357+
if am == corev1.ReadWriteMany {
358+
accessMode = corev1.ReadWriteMany
359+
}
360+
}
361+
}
362+
363+
return accessMode, nil
363364
}
364-
return corev1.PersistentVolumeAccessMode(at)
365+
366+
return corev1.PersistentVolumeAccessMode(at), nil
365367
}
366368

367369
func (p *provider) parseNodeAffinityPreset(nodeAffinityPreset kubevirttypes.NodeAffinityPreset) (NodeAffinityPreset, error) {
@@ -712,7 +714,13 @@ func (p *provider) newVirtualMachine(c *Config, pc *providerconfigtypes.Config,
712714
}
713715

714716
defaultBridgeNetwork := defaultBridgeNetwork()
715-
runStrategyOnce := kubevirtv1.RunStrategyOnce
717+
runStrategy := kubevirtv1.RunStrategyOnce
718+
// currently we only support KubeOvn as a ProviderNetwork and KubeOvn has the ability to pin the IP of the VM(static ip)
719+
// even if the VMi was stopped or deleted thus we can have the VM always running and in the events of VM restarts the
720+
// ip address of the VMI will not change.
721+
if c.SubnetName != "" {
722+
runStrategy = kubevirtv1.RunStrategyAlways
723+
}
716724

717725
virtualMachine := &kubevirtv1.VirtualMachine{
718726
ObjectMeta: metav1.ObjectMeta{
@@ -721,7 +729,7 @@ func (p *provider) newVirtualMachine(c *Config, pc *providerconfigtypes.Config,
721729
Labels: labels,
722730
},
723731
Spec: kubevirtv1.VirtualMachineSpec{
724-
RunStrategy: &runStrategyOnce,
732+
RunStrategy: &runStrategy,
725733
Instancetype: c.Instancetype,
726734
Preference: c.Preference,
727735
Template: &kubevirtv1.VirtualMachineInstanceTemplateSpec{
@@ -885,8 +893,8 @@ func getDataVolumeTemplates(config *Config, dataVolumeName string, annotations m
885893
}
886894

887895
switch config.StorageTarget {
888-
case Storage:
889-
dataVolumeTemplates[0].Spec.Storage = &cdiv1beta1.StorageSpec{
896+
case PVC:
897+
dataVolumeTemplates[0].Spec.PVC = &corev1.PersistentVolumeClaimSpec{
890898
StorageClassName: ptr.To(config.StorageClassName),
891899
AccessModes: []corev1.PersistentVolumeAccessMode{
892900
config.StorageAccessType,
@@ -896,7 +904,7 @@ func getDataVolumeTemplates(config *Config, dataVolumeName string, annotations m
896904
},
897905
}
898906
default:
899-
dataVolumeTemplates[0].Spec.PVC = &corev1.PersistentVolumeClaimSpec{
907+
dataVolumeTemplates[0].Spec.Storage = &cdiv1beta1.StorageSpec{
900908
StorageClassName: ptr.To(config.StorageClassName),
901909
AccessModes: []corev1.PersistentVolumeAccessMode{
902910
config.StorageAccessType,
@@ -1064,3 +1072,44 @@ func setOVNAnnotations(c *Config, annotations map[string]string) error {
10641072

10651073
return nil
10661074
}
1075+
1076+
func (p *provider) configureStorage(infraClient client.Client, template kubevirttypes.Template) (corev1.PersistentVolumeAccessMode, []SecondaryDisks, error) {
1077+
secondaryDisks := make([]SecondaryDisks, 0, len(template.SecondaryDisks))
1078+
for i, sd := range template.SecondaryDisks {
1079+
sdSizeString, err := p.configVarResolver.GetConfigVarStringValue(sd.Size)
1080+
if err != nil {
1081+
return "", nil, fmt.Errorf(`failed to parse "secondaryDisks.size" field: %w`, err)
1082+
}
1083+
pvc, err := resource.ParseQuantity(sdSizeString)
1084+
if err != nil {
1085+
return "", nil, fmt.Errorf(`failed to parse value of "secondaryDisks.size" field: %w`, err)
1086+
}
1087+
1088+
scString, err := p.configVarResolver.GetConfigVarStringValue(sd.StorageClassName)
1089+
if err != nil {
1090+
return "", nil, fmt.Errorf(`failed to parse value of "secondaryDisks.storageClass" field: %w`, err)
1091+
}
1092+
storageAccessMode, err := p.getStorageAccessType(context.TODO(), sd.StorageAccessType, infraClient, scString)
1093+
if err != nil {
1094+
return "", nil, fmt.Errorf(`failed to get value of storageAccessMode: %w`, err)
1095+
}
1096+
secondaryDisks = append(secondaryDisks, SecondaryDisks{
1097+
Name: fmt.Sprintf("secondarydisk%d", i),
1098+
Size: pvc,
1099+
StorageClassName: scString,
1100+
StorageAccessType: storageAccessMode,
1101+
})
1102+
}
1103+
scString, err := p.configVarResolver.GetConfigVarStringValue(template.PrimaryDisk.StorageClassName)
1104+
if err != nil {
1105+
return "", nil, fmt.Errorf(`failed to parse value of "primaryDisk.storageClass" field: %w`, err)
1106+
}
1107+
1108+
primaryDisk, err := p.getStorageAccessType(context.TODO(), template.PrimaryDisk.StorageAccessType,
1109+
infraClient, scString)
1110+
if err != nil {
1111+
return "", nil, fmt.Errorf(`failed to get value of primaryDiskstorageAccessType: %w`, err)
1112+
}
1113+
1114+
return primaryDisk, secondaryDisks, nil
1115+
}

pkg/cloudprovider/provider/kubevirt/provider_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,14 @@ func (k kubevirtProviderSpecConf) rawProviderSpec(t *testing.T) []byte {
132132
{{- if .SecondaryDisks }}
133133
"secondaryDisks": [{
134134
"size": "20Gi",
135+
"storageAccessType": "ReadWriteMany",
135136
"storageClassName": "longhorn2"},{
136137
"size": "30Gi",
138+
"storageAccessType": "ReadWriteMany",
137139
"storageClassName": "longhorn3"}],
138140
{{- end }}
139141
"primaryDisk": {
142+
"storageAccessType": "ReadWriteMany",
140143
{{- if .StorageTarget }}
141144
"storageTarget": "{{ .StorageTarget }}",
142145
{{- end }}

pkg/cloudprovider/provider/kubevirt/testdata/affinity-no-values.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ spec:
1515
creationTimestamp: null
1616
name: affinity-no-values
1717
spec:
18-
pvc:
18+
storage:
1919
accessModes:
20-
- ReadWriteOnce
20+
- ReadWriteMany
2121
resources:
2222
requests:
2323
storage: 10Gi

pkg/cloudprovider/provider/kubevirt/testdata/affinity.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ spec:
1515
creationTimestamp: null
1616
name: affinity
1717
spec:
18-
pvc:
18+
storage:
1919
accessModes:
20-
- ReadWriteOnce
20+
- ReadWriteMany
2121
resources:
2222
requests:
2323
storage: 10Gi

pkg/cloudprovider/provider/kubevirt/testdata/custom-local-disk.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ spec:
1414
- metadata:
1515
name: custom-local-disk
1616
spec:
17-
pvc:
17+
storage:
1818
accessModes:
19-
- ReadWriteOnce
19+
- ReadWriteMany
2020
resources:
2121
requests:
2222
storage: 10Gi

pkg/cloudprovider/provider/kubevirt/testdata/http-image-source.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ spec:
1414
- metadata:
1515
name: http-image-source
1616
spec:
17-
pvc:
17+
storage:
1818
accessModes:
19-
- ReadWriteOnce
19+
- ReadWriteMany
2020
resources:
2121
requests:
2222
storage: 10Gi

pkg/cloudprovider/provider/kubevirt/testdata/instancetype-preference-custom.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ spec:
1515
creationTimestamp: null
1616
name: instancetype-preference-custom
1717
spec:
18-
pvc:
18+
storage:
1919
accessModes:
20-
- ReadWriteOnce
20+
- ReadWriteMany
2121
resources:
2222
requests:
2323
storage: 10Gi

pkg/cloudprovider/provider/kubevirt/testdata/instancetype-preference-standard.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ spec:
1414
- metadata:
1515
name: instancetype-preference-standard
1616
spec:
17-
pvc:
17+
storage:
1818
accessModes:
19-
- ReadWriteOnce
19+
- ReadWriteMany
2020
resources:
2121
requests:
2222
storage: 10Gi

pkg/cloudprovider/provider/kubevirt/testdata/kubeovn-provider-network.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@ spec:
1414
- metadata:
1515
name: kubeovn-provider-network
1616
spec:
17-
pvc:
17+
storage:
1818
accessModes:
19-
- ReadWriteOnce
19+
- ReadWriteMany
2020
resources:
2121
requests:
2222
storage: 10Gi
2323
storageClassName: longhorn
2424
source:
2525
http:
2626
url: http://x.y.z.t/ubuntu.img
27-
runStrategy: Once
27+
runStrategy: Always
2828
template:
2929
metadata:
3030
creationTimestamp: null

pkg/cloudprovider/provider/kubevirt/testdata/nominal-case.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ spec:
1414
- metadata:
1515
name: nominal-case
1616
spec:
17-
pvc:
17+
storage:
1818
accessModes:
19-
- ReadWriteOnce
19+
- ReadWriteMany
2020
resources:
2121
requests:
2222
storage: 10Gi

pkg/cloudprovider/provider/kubevirt/testdata/pvc-image-source.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ spec:
1414
- metadata:
1515
name: pvc-image-source
1616
spec:
17-
pvc:
17+
storage:
1818
accessModes:
19-
- ReadWriteOnce
19+
- ReadWriteMany
2020
resources:
2121
requests:
2222
storage: 10Gi

pkg/cloudprovider/provider/kubevirt/testdata/registry-image-source-pod.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ spec:
1414
- metadata:
1515
name: registry-image-source-pod
1616
spec:
17-
pvc:
17+
storage:
1818
accessModes:
19-
- ReadWriteOnce
19+
- ReadWriteMany
2020
resources:
2121
requests:
2222
storage: 10Gi

pkg/cloudprovider/provider/kubevirt/testdata/registry-image-source.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ spec:
1414
- metadata:
1515
name: registry-image-source
1616
spec:
17-
pvc:
17+
storage:
1818
accessModes:
19-
- ReadWriteOnce
19+
- ReadWriteMany
2020
resources:
2121
requests:
2222
storage: 10Gi

pkg/cloudprovider/provider/kubevirt/testdata/secondary-disks.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ spec:
1414
- metadata:
1515
name: secondary-disks
1616
spec:
17-
pvc:
17+
storage:
1818
accessModes:
19-
- ReadWriteOnce
19+
- ReadWriteMany
2020
resources:
2121
requests:
2222
storage: 10Gi
@@ -29,7 +29,7 @@ spec:
2929
spec:
3030
pvc:
3131
accessModes:
32-
- ReadWriteOnce
32+
- ReadWriteMany
3333
resources:
3434
requests:
3535
storage: 20Gi
@@ -42,7 +42,7 @@ spec:
4242
spec:
4343
pvc:
4444
accessModes:
45-
- ReadWriteOnce
45+
- ReadWriteMany
4646
resources:
4747
requests:
4848
storage: 30Gi

pkg/cloudprovider/provider/kubevirt/testdata/topologyspreadconstraints.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ spec:
1414
- metadata:
1515
name: topologyspreadconstraints
1616
spec:
17-
pvc:
17+
storage:
1818
accessModes:
19-
- ReadWriteOnce
19+
- ReadWriteMany
2020
resources:
2121
requests:
2222
storage: 10Gi

pkg/cloudprovider/provider/kubevirt/testdata/use-storage-as-storage-target.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ spec:
2020
url: "http://x.y.z.t/ubuntu.img"
2121
storage:
2222
accessModes:
23-
- ReadWriteOnce
23+
- ReadWriteMany
2424
resources:
2525
requests:
2626
storage: 10Gi

0 commit comments

Comments
 (0)