Repository navigation
fix: repair CDI and verify allocation health with scoped device access - #14
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 |
simongdavies
left a comment
There was a problem hiding this comment.
@antsok Thanks very much for the PR, just a couple of minor comments, the main issue is the CI failure - Thanks !
| return fmt.Errorf("KVM_CREATE_VM: %w", errno) | ||
| } | ||
| return syscall.Close(int(vm)) | ||
| case "mshv": |
There was a problem hiding this comment.
Could we do something similar for mshv e.g. https://github.com/rust-vmm/mshv/blob/68af39fde2dd0c3bcf7b09ef088d897975ce6f00/mshv-ioctls/src/ioctls/system.rs#L356-L363
There was a problem hiding this comment.
Implemented in 0d3e036. MSHV readiness now creates a non-isolated partition with the backward-compatible MSHV_CREATE_PARTITION arguments and immediately closes its descriptor, within the existing two-second helper deadline. It uses kernel-default CPU/XSAVE features and does not initialize the partition or allocate guest memory or vCPUs.
Code review is complete, and Linux race tests, vet, formatting, and amd64/arm64 builds pass. Regression tests cover ioctl failures, descriptor cleanup, and rejection of a non-hypervisor device; the opt-in live test disables test stubs. Actual MSHV partition creation remains unverified because neither my WSL nor Docker environment exposes /dev/mshv.
Could we use the main Hyperlight repository's Azure Linux MSHV runner pools to validate this change, or is another MSHV environment available for this repository? From device-plugin/, the check is TEST_MSHV_LIVE=1 go test -count=1 -run '^TestMSHVLivePartitionCreation$' ./....
There was a problem hiding this comment.
Yes we could use one the hyperlight mshv node pools for that, they are available to all repos in the org, lets do that as a follow up.
Signed-off-by: Anton Sokolovskyi <anton@sokolit.com>
|
Updated the CI check to accept KIND’s expected change of /dev/kvm’s group to the node’s own kvm GID, while requiring its permissions, owner and device numbers to remain unchanged. The check then requires exact metadata preservation through plugin testing and cleanup, without changing the existing KIND configuration. |
Signed-off-by: Anton Sokolovskyi <anton@sokolit.com>


Summary
Repair the plugin-owned CDI specification before health advertisement and allocation, and refuse workloads when device usability or repair cannot be established. Provide the trusted plugin with explicit hypervisor access through a separate, non-privileged bootstrap device-plugin DaemonSet.
Refs #13 and sokolaidev/maf-extensions#1423.
Changes
kvmgroup. Plugin testing and cleanup must preserve the validated metadata exactly. If startup validation does not complete, the cleanup check uses the original snapshot.Verification
11c6f0a, hosted lint, build, device-plugin tests and Hyperlight guest execution passed. Integration Tests failed at the final metadata comparison because the host KVM GID differed.791d799, actionlint, YAML parsing andgit diff --checkpassed. The exact Bash assertions passed 24 fixture cases covering accepted startup transitions, dynamic node GIDs, unexpected changes to each metadata field, failed or malformed group lookup, missing/non-character devices, and cleanup after early failure.791d799and0d3e036.0d3e036, Linux Go 1.25.14 race tests, vet, formatting after checkout newline normalization, amd64/arm64 builds, andgit diff --checkpassed. Tests cover request layout, creation errors, partition/device descriptor cleanup, and rejection of/dev/nullas an MSHV device. The non-hypervisor regression failed against the preceding implementation as expected./dev/mshvis absent. Successful partition creation on a real MSHV host has not been verified.791d799required maintainer approval at the last check. Hosted validation for the new MSHV commit is pending.Notes for reviewers
Review the bootstrap device-access design, CDI repair and health transitions, and the two-phase metadata check. Reserve
hyperlight.dev/device-accessfor trusted infrastructure; workloads continue to requesthyperlight.dev/hypervisor.MSHV now checks partition creation rather than only device identity and read/write access. Real MSHV validation is still pending; from
device-plugin/, runTEST_MSHV_LIVE=1 go test -count=1 -run '^TestMSHVLivePartitionCreation ./...on an MSHV host. This does not test guest execution. Local assertions and earlier live evidence do not establish a passing hosted workflow for the current commit.