Skip to content

fix(vm): unpack registry images correctly and validate prepared disks - #3524

Merged
drew merged 2 commits into
NVIDIA:mainfrom
EmilienM:2358-vm-umoci-raw-unpack/em
Sep 21, 2026
Merged

drew merged 2 commits into
NVIDIA:mainfrom
EmilienM:2358-vm-umoci-raw-unpack/em

Conversation

@EmilienM

@EmilienM EmilienM commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Fix VM registry image prep, which has failed for every image other than the bootstrap image since umoci raw unpack was introduced. The failure was masked as success and the broken disk was cached. VM E2E started hitting it after #3446: the bootstrap image is now nvcr.io/nvidia/base/ubuntu:24.04, so --from base goes through registry prep and every sandbox fails with FATAL: prepared image disk missing /image-rootfs.

A second commit gets VM E2E green again: the tests behind conformance needed curl/python3, which the new default image doesn't ship.

Related Issue

Fixes #2358

Builds on #2360 by @s2cube, which the vouch gate auto-closed. Its driver.rs changes no longer applied cleanly, so this is a rework with co-author credit.

Changes

fix(vm): unpack registry images correctly and validate prepared disks

  • Guest prep script: umoci raw unpack extracts directly into the target (no bundle-style rootfs/); verified with umoci v0.6.0 on the community base image. The rootfs is now built under image-rootfs.partial and renamed to /image-rootfs only after every step succeeds (unpack or tar extract, runtime install, identity marker, payload cleanup).
  • Driver: guest exit codes don't survive the libkrun boundary, so the prep VM always "succeeds". Before caching, the driver now checks the prepared disk for /image-rootfs with a read-only debugfs stat. On failure nothing is cached and the error carries the prep console tail.
  • Prep disk sizing: payload*3 + 512 MiB to payload*4 + 1 GiB. The community base image needs 1.40 GB (OCI payload) + 3.32 GB (unpacked blocks), which didn't fit in the old 4.74 GB before ext4 metadata. The disk file is sparse, so the headroom costs no host disk.
  • Unit test for the debugfs check, plus one sentence in the crate README.

test(e2e): run tool-dependent VM tests from the community base image

Testing

  • mise run pre-commit passes
  • Unit tests added/updated (openshell-driver-vm: 171 passed, clippy clean)
  • E2E tests added/updated (if applicable): VM tests updated to request the image they need

Local mise run e2e:vm with the new default image (KVM, image not in local podman, so the registry path runs like CI) passes end to end:

  • Conformance (smoke, sandbox-lifecycle), host_gateway_alias (2/2), vm_overlay (1/1), vm_gateway_start (1/1), vm_corporate_proxy (3/3, including the fake-proxy routes).
  • The cached prepared disk is keyed by the same manifest digest as the failing CI runs (sha256:aeef1c63…), contains a complete /image-rootfs with the identity marker, and has no leftover .partial directory.

Reviews: two adversarial review agents (correctness and architecture) ran on the fix commit and their confirmed findings are applied (rename-last in the guest script, non-ext4 rejection test). The fix commit was also reviewed by gpt-6-astra (xhigh). The test commit is a small argument change, validated by the E2E run above.

Checklist

  • Follows Conventional Commits
  • Commits are signed off (DCO)
  • Architecture docs updated (if applicable): no architecture doc covers image prep; crate README updated

🤖 Generated with Claude Code

The registry image-prep path expected `umoci raw unpack` to produce a
bundle-style rootfs/ subdirectory, but it extracts the image filesystem
directly into the target. Every registry prep therefore failed after a
successful unpack. Guest init exit codes do not survive the libkrun
boundary, so the failure looked like success and the broken disk was
cached, making every later sandbox for that image fail with "prepared
image disk missing /image-rootfs".

VM E2E started hitting this after the bootstrap image moved to
nvcr.io/nvidia/base/ubuntu:24.04: `--from base` no longer matches the
bootstrap image, so it now goes through registry prep.

- Accept umoci's direct extraction layout in the guest prep script.
- Build the image rootfs under a partial directory and rename it to
  /image-rootfs only after every prep step succeeds.
- Check the prepared disk for /image-rootfs before caching it. On
  failure, leave the cache untouched and report the prep console tail.
- Size the prep disk to hold the payload and the unpacked rootfs at the
  same time. The community base image needs 1.40 GB + 3.32 GB, which
  did not fit in the old payload*3 + 512 MiB.

Fixes NVIDIA#2358

Co-authored-by: s2cube <26961336+s2cube@users.noreply.github.com>
Signed-off-by: Emilien Macchi <emacchi@redhat.com>
@copy-pr-bot

copy-pr-bot Bot commented Sep 21, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@mrunalp

mrunalp commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

/ok to test af3c7f3

@mrunalp mrunalp added the test:e2e Requires end-to-end coverage label Sep 21, 2026
@github-actions

Copy link
Copy Markdown

Label test:e2e applied for af3c7f3. Open the existing run and click Re-run all jobs to execute with the label set. The run will execute the standard E2E suite after building the required gateway, sandbox, and supervisor images once. The matching required CI gate status on this PR will flip green automatically once the run finishes.

The host_gateway_alias and vm_corporate_proxy workloads run curl and
python3. The VM driver now defaults to nvcr.io/nvidia/base/ubuntu:24.04,
which ships neither, so these tests fail in VM E2E with "command not
found". Request the community base image explicitly with `--from base`.

Docker, Podman, and Kubernetes E2E already default to that image, so
their behavior is unchanged.

Signed-off-by: Emilien Macchi <emacchi@redhat.com>
@drew

drew commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

/ok to test 3cd2ddf

@drew
drew merged commit cb6e88a into NVIDIA:main Sep 21, 2026
88 of 91 checks passed
@drew

drew commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

gator-agent

PR Review Status

This focused fix for the confirmed VM image-preparation bug in #2358 is project-valid. The independent initial review found no blocking defects or non-blocking suggestions in the current patch.

Action required: A maintainer should inspect or re-run the failed docker-e2e / E2E (python) job; both VM E2E jobs passed, but the aggregate required E2E gate is red.

Blocking findings:

  • No blocking findings remain

Carried findings:

  • None

Non-blocking suggestions:

  • None
Gator metadata
  • Validation: Linked issue bug(vm-driver): registry image prep expects bundle-style rootfs/ from umoci raw unpack — failure masked as success and broken disk cached forever #2358 documents a reproduced VM registry-preparation bug and a maintainer triage confirmed the repair direction.
  • Docs: The VM crate README is updated; Fern docs are not needed because this restores the existing image-preparation contract without changing the user workflow.
  • Checks: Branch Checks, Helm Lint, and Trivy Changes are green. The required E2E gate failed in docker-e2e / E2E (python) while the VM managed and external-driver E2E jobs passed.
  • E2E: test:e2e is applied and the current-head workflow completed with the aggregate gate failing.
  • Head SHA: 3cd2ddfa1ebf90d3c10356d5218bfad3b6d90149
  • Base SHA: fa8f6d394983b541ac31363f8a2d5ea027b08acf
  • Merge base SHA: fa8f6d394983b541ac31363f8a2d5ea027b08acf
  • Patch ID: 238b9e1e50b8dde1058db24df7388f55c0bd174d
  • Gator payload: 10
  • Review mode: initial
  • Previous reviewed SHA: none
  • Review budget exhausted: no
  • Maintainer decision required: no
  • Next state: gator:watch-pipeline

@drew drew added the gator:watch-pipeline Gator is monitoring PR CI/CD status label Sep 21, 2026
@drew

drew commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

gator-agent

Monitoring Complete

Monitoring is complete because this PR has merged.

Final status: The initial code review found no blocking findings. The VM E2E jobs passed; the aggregate E2E gate was still reporting a separate Docker Python job failure at the last pre-merge check.

I removed the active gator:* label because there is nothing left for gator to monitor on this PR.

@drew drew removed the gator:watch-pipeline Gator is monitoring PR CI/CD status label Sep 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test:e2e Requires end-to-end coverage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(vm-driver): registry image prep expects bundle-style rootfs/ from umoci raw unpack — failure masked as success and broken disk cached forever

3 participants