Conversation
Signed-off-by: Anton Sokolovskyi <anton@sokolit.com>
7bfac2b to
8ac6e3e
Compare
Signed-off-by: Anton Sokolovskyi <anton@sokolit.com>
Signed-off-by: Anton Sokolovskyi <anton@sokolit.com>
Signed-off-by: Anton Sokolovskyi <anton@sokolit.com>
Standard AKS verification of upstream PR #14Verified on 2026-09-24 using source One temporary, tainted Standard_D4ads_v5 node ran AKS 1.35.7, Ubuntu 24.04.5, kernel 6.8.0-1067-azure and containerd 2.3.3-2. Both candidate DaemonSets ran without privilege, with all capabilities dropped, RuntimeDefault seccomp and no service-account token. Runtime inspection confirmed zero effective capabilities. A temporary privileged diagnostic pod performed fault injection, kubelet restart and host-process checks; it was removed during cleanup. No RBAC or admission-policy changes were made. Two advertised slots permitted an existing guest plus a fresh validation guest; this is not a capacity benchmark.
Runtime image: The local harness needed two timing corrections: wait for asynchronous node-capacity publication, and exclude terminating DaemonSet pods when selecting the replacement. Their cleanup paths passed; the affected recovery/restart checks subsequently passed. No product source was changed. The downstream session supervisor deliberately retires a session when its controller stream closes or its lease expires. Exit 70 during kubelet restart is consistent with that contract; the exact retirement trigger was not captured. The existing session was not resumed. Plugin re-registration, fresh allocation and exact-owner cleanup passed. This observation does not establish a device-plugin recovery defect; preserving sessions across transport interruptions would be separate downstream lifecycle work. Scope limits: one Standard AKS KVM node, no AKS Automatic/KIND/MSHV validation, no production capacity claim, and no physical host-device removal or host permission changes. The production upstream pin remains unchanged pending upstream acceptance. The exact-head PR Validation workflow still requires maintainer approval; these live results do not make CI green. |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Deployment manifests still need capability dropping and an explicit termination-log path.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 2
Open (4)
What changed in this PR
This PR repairs CDI state and gates Hyperlight allocation on verified device readiness using scoped bootstrap access.
Changes:
- Adds bounded device probing, CDI reconciliation, cancellation-safe health tracking, and readiness checks.
- Adds bootstrap DaemonSets, host-device validation, regression tests, and CI verification.
- Requires capability dropping for plugin containers and an explicit termination-log path in the manifests.
| File | Summary |
|---|---|
docs/architecture.md |
Documents scoped access and readiness behavior. |
device-plugin/readiness_regression_test.go |
Tests cancellation and host-device recovery. |
device-plugin/probe_linux.go |
Adds bounded probing and device identity checks. |
device-plugin/main.go |
Implements readiness, CDI repair, registration, and allocation. |
device-plugin/main_test.go |
Adds CDI, readiness, registration, and bootstrap tests. |
deploy/manifests/device-plugin.yaml |
Updates DaemonSets with scoped access and health probes. |
deploy/local/device-plugin.yaml |
Mirrors deployment changes for local environments. |
.github/workflows/pr-validation.yml |
Adds readiness tests and device metadata verification. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Signed-off-by: Anton Sokolovskyi <anton@sokolit.com>
|
Copilot review comments are addressed |


Summary
Repair the plugin-owned CDI specification before health advertisement and allocation, and refuse workloads when device usability or repair cannot be established. Give the trusted plugin explicit hypervisor access through a separate, non-privileged bootstrap device-plugin DaemonSet. Validate both its injected device and the host device path required for CDI injection.
Refs #13 and sokolaidev/maf-extensions#1423.
Changes
Atomically repair missing, malformed or stale CDI, including kind, name, path, permissions, UID/GID and extra container edits. Bound UID/GID to the CDI uint32 field type, preserve the invalid-value fallback, refuse non-regular owned paths, and leave unrelated CDI files untouched.
Run bounded KVM API-version/empty-VM checks. Bootstrap registers one
hyperlight.dev/device-accessallocation and returns only a read/write DeviceSpec for the detected hypervisor. The main DaemonSet requests it, and separately mounts the host device directory read-only at/host-devfor character-device and device-number validation. Neither component changes host device permissions or requires a privileged container.Keep caller cancellation separate from shared health. A subsequent probe waits for cancelled-helper cleanup within its two-second budget before starting a fresh check. A helper that cannot exit remains a bounded device failure, with at most one outstanding helper. Broadcast completed health transitions immediately to every ListAndWatch stream.
Bound kubelet registration, stop failed servers before retrying, and distinguish gRPC liveness from readiness. Readiness requires successful registration, an active health stream and a completed successful check.
Add regression coverage, bootstrap gRPC tests, and CI verification of main-plugin KVM access. CI compares host device mode, ownership and device number after cleanup, including when earlier integration steps fail.
Verification
Linux Go 1.25: full
go test -race -count=1 -timeout=90s ./...,go vet ./..., formatting check and static Linux build passed. The full suite ran as UID/GID 65534, including unwritable CDI storage and recovery.Both new regression tests failed against the previous code, then passed with the fixes: host-device disappearance must refuse allocation and publish unhealthy status; cancelling a helper must not poison the next independent check. Additional tests cover host-path symlinks/non-devices, device-number mismatch, recovery, and cancellation while waiting for helper cleanup.
Both manifests and the workflow parse successfully; read-only host identity mounts, scoped device grants and the final metadata comparison were checked. The exact comparison commands accepted unchanged temporary-file metadata and rejected deliberate mode drift.
Local WSL KVM: temporary character nodes reproduced a private device that remains usable after its host counterpart disappears. The updated helper refused missing/replaced host nodes and recovered after restoration. The real host device was unchanged.
Earlier local WSL/runc verification showed that a host-device-directory mount alone denies KVM access, while an explicit grant for only KVM permits API-version and empty-VM creation with all process capabilities dropped. These were manually constructed OCI specs, not a Kubernetes/AKS deployment.
Live Standard AKS KVM validation passed at
52bf3f203cfca36843afb36d18b0551b1f6ca00e: 12 positive restricted, non-root application runs, automatic missing/stale/malformed CDI repair, unhealthy allocation refusal, restoration after read-only storage and synthetic missing/unusable-device faults, registration recovery, and fresh execution after plugin/kubelet restart. Both plugin DaemonSets ran without privilege and with all capabilities dropped. A temporary privileged diagnostic pod was used for host fault injection and observation, then removed.During allocation-triggered repair, 6,813 concurrent CDI reads saw only complete stale or desired content, with zero read errors; repair was observed after 2.93 seconds. Unrelated CDI and real host KVM metadata were preserved. All 15 application pod UIDs were checked for surviving processes; application pods, ownership ledgers, temporary namespaces and the temporary node pool were cleaned up.
Existing guests retained state through CDI faults and plugin restart. During a real kubelet restart, the plugin re-registered in 5.01 seconds and fresh execution passed, while the existing supervised session exited 70. That matches the downstream design's retirement on lost controller stream/lease; the exact retirement trigger was not captured. Session continuity across transport interruptions is separate downstream lifecycle work, not a demonstrated plugin recovery defect.
Detailed AKS validation report, including configuration, fault mechanisms, cleanup and scope limits.
Notes for reviewers
The bootstrap design adds one small infrastructure container per enabled node and a second device-plugin socket/resource. Reserve
hyperlight.dev/device-accessfor trusted infrastructure using cluster admission or quota policy; workloads continue to requesthyperlight.dev/hypervisor. Bootstrap health describes available device access, while the main plugin validates host identity and KVM usability.The deployment topology remains subject to upstream review. Live evidence covers one Standard AKS KVM node, not AKS Automatic, production capacity or uninterrupted sessions across kubelet restart. Not verified: KIND execution with this change or MSHV VM creation. MSHV retains a character-device/read-write-open check only. The downstream production source/image pin remains unchanged pending upstream acceptance. The exact-head PR Validation workflow requires maintainer approval; local and live checks are not a green CI claim.