feat(platform): add gpu.vgpu, the root tenant's vGPU entitlement

Every tenant's vGPU entitlement needs its parent's, so the chain needs
a start the hoster controls. gpu.vgpu is it: the platform passes it to
cozystack-basics as _cluster.gpu-vgpu, which renders the root tenant.
The key is written only when on, since _cluster reaches every
tenant's values and an always-present key would upgrade every release.
The flag feeds only the entitlement, never the KubeVirt or GPU
Operator packages.

Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
This commit is contained in:
Aleksei Sviridkin committed 2026-11-03 05:24:30 +03:00
1 parent 8f69efe9a9
commit d812916896
4 files changed
+105

No files matched your search

@@ -253,6 +253,12 @@ stringData:
null/omitted in custom values. Missing key -> the true default,
matching the chart values.yaml. */}}
monitoring-enabled: {{ dig "rootEnabled" true (.Values.monitoring | default dict) | quote }}
{{- /* The root tenant's vGPU entitlement, read by cozystack-basics.
Only written when on: every release in every tenant reads this
Secret, and a key appearing would upgrade all of them. */}}
{{- if eq (printf "%v" ((.Values.gpu).vgpu | default false)) "true" }}
gpu-vgpu: "true"
{{- end }}
{{- /* The rate each shared-central tracing tenant's collector holds it
to. Only written when set: every release in every tenant reads
this Secret, and a key appearing would upgrade all of them. */}}
@@ -0,0 +1,42 @@
suite: apps.yaml gpu.vgpu → _cluster wiring
templates:
- templates/apps.yaml
release:
name: cozy-platform
namespace: cozy-system
# gpu.vgpu entitles the root tenant to vGPU, and every child's entitlement
# needs its parent's. cozystack-basics renders the root tenant from
# _cluster.gpu-vgpu. The key is written only when on: _cluster is copied into
# every tenant's cozystack-values, so a key that is always present would
# upgrade every release in every tenant.
tests:
- it: writes gpu-vgpu when gpu.vgpu is on
set:
gpu.vgpu: true
asserts:
- matchRegex:
path: stringData["values.yaml"]
pattern: '(?m)^_cluster:\n( .*\n)* gpu-vgpu: "true"$'
- it: leaves gpu-vgpu out by default
asserts:
- notMatchRegex:
path: stringData["values.yaml"]
pattern: gpu-vgpu
- it: leaves gpu-vgpu out for a quoted "false"
set:
gpu.vgpu: "false"
asserts:
- notMatchRegex:
path: stringData["values.yaml"]
pattern: gpu-vgpu
- it: does not fail on a null gpu block
set:
gpu: null
asserts:
- notMatchRegex:
path: stringData["values.yaml"]
pattern: gpu-vgpu
@@ -949,3 +949,56 @@ tests:
- contains:
path: spec.components.kubevirt.values.mediatedDevicesConfiguration.mediatedDeviceTypes
content: nvidia-473
# gpu.vgpu feeds the tenant entitlement, not KubeVirt or the GPU Operator.
- it: keeps gpu.vgpu out of the kubevirt component
set:
bundles:
system:
enabled: true
variant: isp-full
iaas:
enabled: true
enabledPackages:
- cozystack.gpu-operator
gpu:
vgpu: true
documentSelector:
path: metadata.name
value: cozystack.kubevirt
asserts:
- equal:
path: spec.components.kubevirt.values.extraFeatureGates
value:
- HostDevices
- contains:
path: spec.components.kubevirt.values.permittedHostDevices.pciHostDevices
content:
pciVendorSelector: "10DE:2335"
resourceName: nvidia.com/GH100_H200_SXM_141GB
externalResourceProvider: true
- notExists:
path: spec.components.kubevirt.values.vgpu
- it: keeps gpu.vgpu out of the gpu-operator Package under vgpu
set:
bundles:
system:
enabled: true
variant: isp-full
iaas:
enabled: true
gpuOperatorVariant: vgpu
enabledPackages:
- cozystack.gpu-operator
gpu:
vgpu: true
documentSelector:
path: metadata.name
value: cozystack.gpu-operator
asserts:
- equal:
path: spec.variant
value: vgpu
- notExists:
path: spec.components
+4
View File
@@ -917,6 +917,10 @@ gpu:
# missing entries).
vgpuDeviceManager:
enabled: false
# Entitle the root tenant to vGPU classes. Every other tenant is entitled
# only when its own Tenant sets gpu.vgpu and its parent is entitled, so
# vGPU reaches no tenant until this is on.
vgpu: false
# VM import from external virtualization platforms (opt-in; see the iaas bundle).
vmImport: