Repository navigation
feat(gpu): compute GPUClass status and copy vGPU licenses - #5013
Open
Aleksei Sviridkin (lexfrei) wants to merge 5 commits into
Open
Aleksei Sviridkin (lexfrei) wants to merge 5 commits into
Aleksei Sviridkin (lexfrei) wants to merge 5 commits into
Conversation
Contributor
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the
|
12 tasks
Aleksei Sviridkin (lexfrei)
force-pushed
the
feat/gpudevice-quotas-pr
branch
from
October 23, 2026 01:08
f2f1d59 to
a883541
Compare
Aleksei Sviridkin (lexfrei)
requested review from
Andrey Kolkov (androndo),
Matthieu ROBIN (matthieu-robin),
scooby87 and
Timur Tukaev (tym83)
as code owners
October 23, 2026 01:08
Aleksei Sviridkin (lexfrei)
force-pushed
the
feat/gpudevice-controller-pr
branch
from
October 26, 2026 08:46
ccaef2f to
ebca80f
Compare
12 tasks
1 of 12 tasks
A tenant's GPU budget is declared per class as <class>.gpuclass.cozystack.io/devices and over every class as gpuclass.cozystack.io/devices. These keys are not pod resources, so no ResourceQuota enforces them. The proposal hands the check to the pool-wide admission gate that counts declared sizes; until that gate is on, the Cozystack API server does it for GPU keys only, with the inputs and the pool arithmetic that gate reads, so the switch changes no verdict. On a VMInstance or KubernetesNodes create or update, every class entry reserves its count, times maxReplicas for a worker pool, read from the chart-defaulted values. The tenant pool arithmetic is applied to the declared resourceQuotas and these entries. Only growth is checked on an update, so shrinking and unchanged entries pass even in a pool that is already over budget. Like the gate it stands in for, this is a read-check-write without a transaction. The tenant declaration gate already treats GPU keys like any other; it now reads their pool usage from the class entries, since the ResourceQuota it reads for other keys never carries them. It also refuses a key in the GPU budget domain that is not a budget key: the tenant chart keeps such a key out of the ResourceQuota, so nothing would enforce it. Assisted-by: LLM Signed-off-by: Aleksei Sviridkin <[email protected]>
Aleksei Sviridkin (lexfrei)
force-pushed
the
feat/gpudevice-quotas-pr
branch
from
November 3, 2026 03:19
a883541 to
02d1264
Compare
A tenant picking a GPU class needs to know whether a VM of it is likely to start, and a hoster needs to see a class that can never serve a VM before a tenant's start is refused. With no GPUNode and no binder in step 1, both figures come from the Node and Pod objects alone: free units are a node's allocatable count of the class's resource name minus what its pods request, over nodes that are Ready, not cordoned and carry no taint the class does not tolerate. One pass covers every class, because a class's ResourceNameConflict depends on the classes created before it. The KubeVirt CR is read on each pass and on a one-minute recheck instead of watched, so the controller needs no KubeVirt kinds served to start. The class status is readable by every authenticated user, so the inventory and load behind it, the allocatable and requested totals per class, go to metrics instead. Assisted-by: LLM Signed-off-by: Aleksei Sviridkin <[email protected]>
A VM of a licensed vGPU class mounts its license from a Secret in its own namespace, so the token reaches entitled tenants only and is rotated by a VM restart rather than by rebuilding a shared image. The copier keeps one copy per class in every namespace whose vGPU label is "true", with the token and a gridd.conf carrying the class's FeatureType, and deletes copies the label, the class or its license no longer call for. A missing hoster Secret, or one without the token, keeps the copies already written: deleting them would stop every restarting VM over what is usually a rotation in progress. New copies wait, and the class shows LicenseSecretMissing so the hoster sees why. Only Secrets carrying both the copy's name and the class label are ever written or deleted, so a tenant's own Secret of the same name is left alone. The token is read through the uncached reader and stays out of every cache. Assisted-by: LLM Signed-off-by: Aleksei Sviridkin <[email protected]>
The class status and the license copier run in cozystack-controller behind --enable-gpu, which the chart passes from gpu.enabled. The status controller is off without the flag, since it caches every Node. The copier always runs: without the flag it deletes every copy, so a token does not stay in tenant namespaces after GPU features are switched off, and clears the free counts and conditions the stopped status controller would otherwise leave stale. License Secrets are watched on the metadata-only Secret cache the CA projection already owns. The manager's own Secret cache is scoped by label to wildcard replicas, and a watch on it would never see a hoster's Secret. The envtest suite drives both controllers through their watches, since a mis-scoped watch fails without an error. No RBAC rule is added: the controller already reads every kind, holds every verb on cozystack.io and the cluster-wide Secret write. Assisted-by: LLM Signed-off-by: Aleksei Sviridkin <[email protected]>
GPUClass status and license copies matter only where gpu-operator hands GPUs to VirtualMachines, which is its default and vgpu variants in the iaas bundle. The platform now passes gpu.enabled to cozystack-controller there, so a hoster enabling VM GPUs gets the class controllers without editing the generated Package, and a cluster on the container variant or without gpu-operator keeps them off. Assisted-by: LLM Signed-off-by: Aleksei Sviridkin <[email protected]>
Aleksei Sviridkin (lexfrei)
force-pushed
the
feat/gpudevice-controller-pr
branch
from
November 3, 2026 12:08
ebca80f to
2b61498
Compare
12 tasks
Aleksei Sviridkin (lexfrei)
force-pushed
the
feat/gpudevice-quotas-pr
branch
from
November 3, 2026 16:57
02d1264 to
f921aca
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Builds on the GPU design approved in cozystack/community#99 at
30da976.What this PR does
GPU classes now show how many units are free, and a vGPU class's license reaches the tenants that may use it. This is the controller part of step 1 of the design, in
cozystack-controller:freeandmaxFreePerNodecome from node allocatable minus pod requests. Only nodes that are Ready, not cordoned and without a taint the class does not tolerate count (decision 0015). A class getsResourceNameConflictwhen an older class has its resource name, andResourceNameNotPermittedwhen KubeVirt'spermittedHostDevicesleaves the name out. Allocatable and requested units per class go to the metricscozystack_gpu_class_capacity_unitsandcozystack_gpu_class_used_units. The chart does not serve the metrics endpoint yet. That comes in a follow-up.licenseis copied asgpuclass-<class>-licenseinto every namespace labellednamespace.cozystack.io/vgpu: "true". A copy holds the token and agridd.confwith the class'sFeatureType. It is deleted when the namespace loses the label, or the class or itslicensegoes away. While the hoster's Secret is missing or has no token, existing copies stay and the class showsLicenseSecretMissing.--enable-gpu. With the flag off, the copier deletes every copy and clears the computed status. No RBAC rule is added.defaultandvgpuvariants.Disabling GPU-for-VMs deletes the managed license copies even if Helm retains the GPU operator Package through
helm.sh/resource-policy: keep. Existing VMs must stop using the platform license before disabling it, as required by the design's rollback procedure. A retained Package does not keep the license copies available for those VMs.The earlier version of this PR had the binder, the claim lifecycle and the GPU node agent. They are step 2 of the design now, or dropped in the case of
GPUNode(decision 0015).This needs the
GPUClassAPI from #4998 and the vGPU entitlement label from #5008. The VMI webhook that mounts the license copy into VMs is in #5030.Screenshots
Not applicable: no UI change.
Downstream repositories
The diff adds a controller, a
cozystack-controllerchart value and a platform helper. It changes no app chart, no key in the platformvalues.yaml, no CRD and no telemetry metric. The GPU user guide will come with the PR that makes class entries usable.Release note