Skip to content

Commit ec4d26d

Browse files
authored
fix(kubernetes): accept a golden worker image that exists only as a PVC (#4578)
## What this PR does A worker pool on `osImage.builtin` refused a golden image that exists in `cozy-public` as a PVC without its DataVolume, and the whole KubernetesNodes release failed to render. CDI clones the PVC, not the DataVolume, so that golden is a valid source, and vm-disk already accepts it. This can happen once CDI garbage-collects DataVolumes (`dataVolumeTTLSeconds`) or when someone restores a golden PVC on its own. Now the render fails only when neither the DataVolume nor the PVC exists. The StorageClass and size checks already fall back to the PVC, so a PVC-only golden is still checked against the pool, and the new test suite pins that too. Closes #4565 ### Screenshots ### Downstream repositories - [x] No downstream repository is affected by this change - [ ] [cozystack/website](https://github.com/cozystack/website) - follow-up: - [ ] [cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack) - follow-up: - [ ] [cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack) - follow-up: - [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up: - [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up: - [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) - follow-up: - [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) - follow-up: - [ ] [cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server) - follow-up: - [ ] [cozystack/external-apps-example](https://github.com/cozystack/external-apps-example) - follow-up: - [ ] [cozystack/examples](https://github.com/cozystack/examples) - follow-up: - [ ] [cozystack/community](https://github.com/cozystack/community) - follow-up: ### Release note ```release-note fix(kubernetes): a worker pool on osImage.builtin now accepts a golden image that exists in cozy-public only as a PVC, matching vm-disk; it is refused only when neither the DataVolume nor the PVC exists. ``` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Built-in golden images can now be used when available as either a DataVolume or a PVC. * **Bug Fixes** * Missing golden images now produce an error that identifies the missing image and suggests ways to resolve the issue. The error is suppressed when the pool already has a successful clone. * PVC-based golden images are checked against the pool’s storage class and minimum disk size requirements. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2 parents f9f7562 + 52aaffb commit ec4d26d

4 files changed

Lines changed: 124 additions & 4 deletions

File tree

‎packages/apps/kubernetes-nodes/templates/nodegroup.yaml‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,10 +335,14 @@ spec:
335335
{{- $cloneWorkerSC = $cloneDefaultSC }}
336336
{{- $cloneWorkerSCFromDefault = true }}
337337
{{- end }}
338+
{{- /* CDI clones the golden's PVC, so a golden whose DataVolume is gone
339+
(CDI garbage collection, a PVC restored on its own) is still a
340+
source, and only the absence of both is refused. With no DataVolume
341+
the guards below read an empty spec and fall through to that PVC. */}}
338342
{{- $goldenDV := lookup "cdi.kubevirt.io/v1beta1" "DataVolume" "cozy-public" $goldenName }}
339-
{{- if not $goldenDV }}
343+
{{- if and (not $goldenDV) (not (lookup "v1" "PersistentVolumeClaim" "cozy-public" $goldenName)) }}
340344
{{- if not $poolCloned }}
341-
{{- fail (printf "nodeGroup %q: osImage.builtin requested golden DataVolume %q not found in cozy-public — enable the cozystack.kubernetes-worker-image catalog via bundles.enabledPackages with a matching (schematicID, version) entry, or switch this pool to osImage.factory." .groupName $goldenName) }}
345+
{{- fail (printf "nodeGroup %q: osImage.builtin requested golden image %q not found in cozy-public, neither as a DataVolume nor as a PVC — enable the cozystack.kubernetes-worker-image catalog via bundles.enabledPackages with a matching (schematicID, version) entry, or switch this pool to osImage.factory." .groupName $goldenName) }}
342346
{{- end }}
343347
{{- else }}
344348
{{- /* Fail only on the golden's terminal failure phase, not on "not yet
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
suite: osImage.builtin accepts a golden that exists only as a PVC
2+
3+
# CDI clones the golden's PVC, not its DataVolume, so a golden whose DataVolume
4+
# is gone -- garbage-collected under dataVolumeTTLSeconds, or a PVC restored on
5+
# its own -- is still a valid clone source. vm-disk accepts it; a worker pool
6+
# has to as well. The StorageClass and size guards read the PVC in that case,
7+
# so a PVC-only golden is not a way around them.
8+
9+
templates:
10+
- templates/nodegroup.yaml
11+
12+
release:
13+
name: kubernetes-nodes-myk8s-md0
14+
namespace: tenant-test
15+
16+
set:
17+
cluster: myk8s
18+
_cluster:
19+
cluster-domain: cozy.local
20+
version: "v1.35"
21+
minReplicas: 1
22+
maxReplicas: 3
23+
instanceType: u1.medium
24+
diskSize: 20Gi
25+
storageClass: replicated
26+
roles: [ingress-nginx]
27+
28+
kubernetesProvider:
29+
scheme:
30+
"instancetype.kubevirt.io/v1beta1/VirtualMachineClusterInstancetype":
31+
gvr: {group: instancetype.kubevirt.io, version: v1beta1, resource: virtualmachineclusterinstancetypes}
32+
namespaced: false
33+
"cluster.x-k8s.io/v1beta1/MachineSet":
34+
gvr: {group: cluster.x-k8s.io, version: v1beta1, resource: machinesets}
35+
namespaced: true
36+
"infrastructure.cluster.x-k8s.io/v1alpha1/KubevirtMachineTemplate":
37+
gvr: {group: infrastructure.cluster.x-k8s.io, version: v1alpha1, resource: kubevirtmachinetemplates}
38+
namespaced: true
39+
"cdi.kubevirt.io/v1beta1/DataVolume":
40+
gvr: {group: cdi.kubevirt.io, version: v1beta1, resource: datavolumes}
41+
namespaced: true
42+
"storage.k8s.io/v1/StorageClass":
43+
gvr: {group: storage.k8s.io, version: v1, resource: storageclasses}
44+
namespaced: false
45+
"v1/PersistentVolumeClaim":
46+
gvr: {group: "", version: v1, resource: persistentvolumeclaims}
47+
namespaced: true
48+
objects:
49+
- kind: VirtualMachineClusterInstancetype
50+
apiVersion: instancetype.kubevirt.io/v1beta1
51+
metadata: {name: u1.medium}
52+
- kind: MachineSet
53+
apiVersion: cluster.x-k8s.io/v1beta1
54+
metadata: {name: ignored-ms, namespace: tenant-test}
55+
spec: {template: {spec: {infrastructureRef: {kind: Other, name: ignored}}}}
56+
- kind: KubevirtMachineTemplate
57+
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
58+
metadata: {name: ignored-kmt, namespace: tenant-test}
59+
- kind: StorageClass
60+
apiVersion: storage.k8s.io/v1
61+
metadata: {name: replicated}
62+
# Registers the DataVolume LIST kind; no golden DataVolume exists in this file.
63+
- kind: DataVolume
64+
apiVersion: cdi.kubevirt.io/v1beta1
65+
metadata: {name: unrelated, namespace: tenant-test}
66+
- kind: PersistentVolumeClaim
67+
apiVersion: v1
68+
metadata: {name: talos-worker-pvconly-v1.13.6, namespace: cozy-public}
69+
spec:
70+
storageClassName: replicated
71+
resources: {requests: {storage: 6Gi}}
72+
73+
tests:
74+
- it: clones a golden that has a PVC and no DataVolume
75+
set:
76+
osImage:
77+
builtin:
78+
schematicID: pvconly
79+
version: v1.13.6
80+
asserts:
81+
- equal:
82+
path: spec.template.spec.virtualMachineTemplate.spec.dataVolumeTemplates[0].spec.source.pvc.name
83+
value: talos-worker-pvconly-v1.13.6
84+
documentSelector: {path: kind, value: KubevirtMachineTemplate}
85+
86+
- it: still refuses a golden that has neither a DataVolume nor a PVC
87+
set:
88+
osImage:
89+
builtin:
90+
schematicID: missing
91+
version: v1.13.6
92+
asserts:
93+
- failedTemplate:
94+
errorPattern: 'golden image "talos-worker-missing-v1\.13\.6" not found in cozy-public'
95+
96+
- it: compares the pool storageClass against the PVC-only golden's
97+
set:
98+
storageClass: local
99+
osImage:
100+
builtin:
101+
schematicID: pvconly
102+
version: v1.13.6
103+
asserts:
104+
- failedTemplate:
105+
errorPattern: 'storageClass "local" differs from golden image "talos-worker-pvconly-v1\.13\.6" storageClass "replicated"'
106+
107+
- it: compares the pool diskSize against the PVC-only golden's size
108+
set:
109+
diskSize: 4Gi
110+
osImage:
111+
builtin:
112+
schematicID: pvconly
113+
version: v1.13.6
114+
asserts:
115+
- failedTemplate:
116+
errorPattern: 'diskSize 4Gi is smaller than golden image "talos-worker-pvconly-v1\.13\.6" storage 6Gi'

‎packages/apps/kubernetes-nodes/tests/worker_image_source_test.yaml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ tests:
223223
version: v9.9.9
224224
asserts:
225225
- failedTemplate:
226-
errorPattern: 'osImage\.builtin requested golden DataVolume "talos-worker-doesnotexist-v9\.9\.9" not found in cozy-public'
226+
errorPattern: 'osImage\.builtin requested golden image "talos-worker-doesnotexist-v9\.9\.9" not found in cozy-public'
227227

228228
- it: setting both osImage.builtin and osImage.factory fails the render
229229
set:

‎packages/apps/kubernetes-nodes/tests/worker_image_two_default_classes_test.yaml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,4 @@ tests:
113113
version: v1.0.0
114114
asserts:
115115
- failedTemplate:
116-
errorPattern: 'requested golden DataVolume "talos-worker-elsewhere-v1\.0\.0" not found'
116+
errorPattern: 'requested golden image "talos-worker-elsewhere-v1\.0\.0" not found'

0 commit comments

Comments
 (0)