With raw names forbidden a GPU reaches a VM only through a GPUDevice
reference, which makes a held device a hard guarantee. A VMI carrying a
GPU entry (any gpus entry, a hostDevices entry or a resource of a GPU
resource name) without the device-reference label is refused, which
covers a VM written by a tenant super-admin, a VMIReplicaSet and a
worker pool. A pod requesting a GPU resource name is refused unless
kubevirt-controller creates it with a VMI owner, as it does for
virt-launcher and migration target pods.
The GPU resource names come from the settings ConfigMap the controller
publishes. The binding fails closed without it, and since the parameter
is resolved before any expression runs, the bindings select tenant
namespaces only; anything wider would block every pod in the cluster,
the controller's own included, until the ConfigMap exists. The
usage-monitor label policy now selects tenant namespaces the same way,
so the two cannot disagree on what a tenant namespace is, and its
ratchet also refuses changing the label's value, which could make an
object labelled before the policy start matching the monitor.
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
The GPU controller writes the usage records of held devices under a
WorkloadMonitor whose selector is a reserved label key, so the monitor
must match nothing and tenant labels cannot shape GPU usage records.
A write that adds the key to any object or subresource in a tenant
namespace is refused, whoever makes it, which also covers the
virt-launcher pods that copy a VM template's labels and the
DataVolumes created from a VM's dataVolumeTemplates.
The policy renders whether or not GPUs are on, so no tenant can place
the label before the hoster turns GPUs on. It ratchets: an object that
already carries the key can still be updated, lose its finalizers and
drop the key, so nothing labelled before the policy can get stuck. It
sees every write in those namespaces, so its expression reads only
metadata and guards each step.
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Whoever orders GPUDevice objects must not touch two parts of a device.
The device finalizer keeps a released device, its binding and its usage
record until no VMI uses it, so a tenant who could drop it could take a
held device out of the usage records. The template-device label is the
mark the VMI webhook is to set on devices it creates from a
deviceTemplate, and the GPU controller deletes devices so marked with
their VMI, so on a tenant's own order it would get that order deleted.
Both are refused for everyone but platform callers, matched by group
like the other cozystack-basics policies: cozy-system and kube-system
service accounts and cluster admins, plus kube-controller-manager,
which has no group of its own. The orphan and foregroundDeletion
finalizers belong to the API server and the garbage collector and stay
free.
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Held devices and their usage records name their class, so while the
class carries its protection finalizer, what it sells (vendor, model,
mode, profile, memory, maxCount and the kind of source) cannot change.
The policy relies on the GPU controller setting the finalizer on every
class, so a changed offer is a new class. resourceName and nodeSelector
stay open for host-layer changes and for moving the offer. CRD rules
cannot see finalizers, so this is an admission policy, and it reads the
stored object so the write that drops the finalizer cannot change the
spec as well.
A class being deleted waits only for the devices that already hold it,
so a second policy, evaluated once per class, refuses new orders of it.
The policies render only where the platform switched GPUs for VMs on.
Their tests evaluate the expressions read from the chart, compiled for
both the current library and the oldest served Kubernetes minor.
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>