Skip to content

Switch root once in init and run the headers worker from the image - #479

Closed
sjmiller609 wants to merge 1 commit into
hypeship/init-move-rootfrom
hypeship/init-single-root-switch
Closed

sjmiller609 wants to merge 1 commit into
hypeship/init-move-rootfrom
hypeship/init-single-root-switch

Conversation

@sjmiller609

Copy link
Copy Markdown
Collaborator

Stacked on #478. Follow-up cleanup from review; #478 stands on its own.

summary

  • one root switch: switchRoot moves from runExecMode/runSystemdMode into main.go, after the shared phases and before mode dispatch. Everything after that line, in either mode, sees only the image rootfs.
  • explicit precondition: switchRoot makes / MS_PRIVATE|MS_REC before MS_MOVE instead of relying on the initrd tree happening to be private.
  • one headers-worker path: both modes now stage /kernel-headers.tar.gz into the image at /opt/hypeman/kernel-headers.tar.gz before the switch (systemd mode also copies the init binary, as before) and run the worker from image paths after it. This drops initrdKernelHeadersPaths, the --headers-worker initrd variant, and the CLONE_NEWNS unshare. Exec mode re-execs /proc/self/exe, which still resolves after the switch. Exec-mode guests now see the tarball bind mount at /opt/hypeman/kernel-headers.tar.gz, as systemd-mode guests already did.
  • systemd unit injection runs after the switch against /; the helpers take a root argument and use filepath.Join.
  • tests: newIntegrationManagers fixture shared by the systemd, vGPU, and nested-docker tests. New assertions in both TestSystemdMode and TestNestedDockerExecRoot: the guest / is the image overlay in /proc/self/mountinfo, and /run/hypeman/kernel-headers.status reaches ready with headers and the build symlink installed. The dockerd readiness check uses EventuallyWithT so a failure reports the last docker info output instead of an empty string.
  • comments and READMEs updated to describe the root switch rather than a chroot.

testing

on a KVM dev box:

  • TestNestedDockerExecRoot and TestSystemdMode pass with the new root and headers assertions in both modes
  • TestBuilderPersistentCacheReuse, TestExecInstanceNonTTY, TestExecWithDebianMinimal, TestCpToAndFromInstance, TestCpDirectoryToInstance, TestVolumeMultiAttachReadOnly pass
  • go vet and go test ./lib/system/init/ pass

Move the root switch out of the two mode functions into main.go, after
the shared phases and before mode dispatch, so everything after one
point sees only the image rootfs. Make / private before MS_MOVE instead
of relying on the initrd tree being private.

Stage the kernel headers tarball into the image before the switch in
both modes and run the worker from image paths afterwards, which drops
the initrd path variant and the mount-namespace unshare. systemd unit
injection now runs after the switch against /.

Tests: share the manager fixture across the integration tests, assert
the guest root is the image overlay and that kernel headers install in
both exec and systemd mode, and fix the dockerd readiness failure
message, which formatted its output before polling.
@sjmiller609

Copy link
Copy Markdown
Collaborator Author

closing: too much change for what it buys. the useful subset (make / private before MS_MOVE, stale comments, guest-root assertion and readiness message fix in the tests) is folded into #478.

@sjmiller609
sjmiller609 deleted the hypeship/init-single-root-switch branch September 15, 2026 13:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant