feat(guests): let a guest nest OCI containers (task 0009) #35

Merged
alexion merged 1 commits from task-0009-guest-nesting into main 2026-07-25 22:31:53 -04:00
Owner

Summary

Adds a nesting placement field to the Host-side guest interface — a bool, off by default — that makes the OCI fallback a plain Guest.
With nesting on, the guest's container gains the prerequisites its interior needs to run Podman and other OCI containers:

  • the CAP_NET_ADMIN capability an OCI runtime uses to build its bridges and firewall rules, and
  • the /dev/net/tun and /dev/fuse device nodes it reaches for to network those containers and back their overlay storage.

Off, both the capability and device lists are empty, so a non-nesting guest is untouched.
A privileged container-backend guest already retains CAP_SYS_ADMIN and the broad nspawn capability set, so network administration is the one capability the runtime is missing.

A new nesting-sample guest defines an oci-containers workload on Podman in its interior, and neogaia enables it with nesting on, so the whole path builds end to end through the Host's nix flake check — which pulls in podman and the generated container unit for the nested system.

Deviations

  • cgroup delegation is not toggled by nesting. The NixOS container backend sets Delegate = true on every container unit unconditionally, so the delegated cgroup subtree an OCI runtime manages is always present. Re-emitting it under nesting would be redundant, and forcing it off for non-nesting guests to make it literally "absent" would drop a harmless, useful default for no gain. The Skeleton records the prerequisite as satisfied-elsewhere with an absence-pointer comment.
  • The two behaviors the build seam cannot prove — that the interior Podman actually starts a container and that its networking works — are left to manual verification on the target Host and to the VM integration test of the next task, per the spec's testing decisions.

Review

Risk

Overall: HIGH

  • Blast radius: Low — a default-off option plus one sample guest and its host enable; no existing behavior changes.
  • Reversibility: Low — pure config additions, no migrations or deletions; trivial to revert.
  • Test coverage: Medium — nix flake check proves evaluation/build, not that the interior Podman workload actually runs.
  • Sensitive domain: High — grants CAP_NET_ADMIN plus /dev/net/tun and /dev/fuse, loosening nspawn confinement for any guest that opts in.
  • Size & complexity: Low — small, readable diff with straightforward optionals gating.
  • Runtime criticality: Medium — touches container/guest infrastructure, though the grant is opt-in and off by default.

Unaddressed findings

Standards

  • Duplicated limits clump and flat-key repetition across the two guest blocks on neogaia (Duplicated Code / Data Clumps, judgement calls) — kept as-is: the Host file is deliberately a flat declarative checklist and the two guests are independent placements that happen to share modest caps, so a shared let binding would trade that flatness for little gain.

Spec

  • The cgroup-delegation prerequisite is not granted-by / absent-without the nesting flag — accepted deviation, explained under Deviations above and recorded in the code with an absence-pointer comment.
  • The nesting-sample guest is enabled permanently on neogaia — this is how acceptance criterion four is verified on the one Host's nix flake check, following the walking-skeleton guest's established precedent; it is a minimal smoke test and turns off with one line.

— Claude

## Summary Adds a `nesting` placement field to the Host-side guest interface — a bool, off by default — that makes the OCI fallback a plain Guest. With `nesting` on, the guest's container gains the prerequisites its interior needs to run Podman and other OCI containers: - the `CAP_NET_ADMIN` capability an OCI runtime uses to build its bridges and firewall rules, and - the `/dev/net/tun` and `/dev/fuse` device nodes it reaches for to network those containers and back their overlay storage. Off, both the capability and device lists are empty, so a non-nesting guest is untouched. A privileged container-backend guest already retains `CAP_SYS_ADMIN` and the broad nspawn capability set, so network administration is the one capability the runtime is missing. A new `nesting-sample` guest defines an `oci-containers` workload on Podman in its interior, and `neogaia` enables it with `nesting` on, so the whole path builds end to end through the Host's `nix flake check` — which pulls in `podman` and the generated container unit for the nested system. ### Deviations - **cgroup delegation is not toggled by `nesting`.** The NixOS container backend sets `Delegate = true` on every container unit unconditionally, so the delegated cgroup subtree an OCI runtime manages is always present. Re-emitting it under `nesting` would be redundant, and forcing it off for non-nesting guests to make it literally "absent" would drop a harmless, useful default for no gain. The Skeleton records the prerequisite as satisfied-elsewhere with an absence-pointer comment. - The two behaviors the build seam cannot prove — that the interior Podman actually starts a container and that its networking works — are left to manual verification on the target Host and to the VM integration test of the next task, per the spec's testing decisions. ## Review ### Risk **Overall: HIGH** - Blast radius: Low — a default-off option plus one sample guest and its host enable; no existing behavior changes. - Reversibility: Low — pure config additions, no migrations or deletions; trivial to revert. - Test coverage: Medium — `nix flake check` proves evaluation/build, not that the interior Podman workload actually runs. - Sensitive domain: High — grants `CAP_NET_ADMIN` plus `/dev/net/tun` and `/dev/fuse`, loosening nspawn confinement for any guest that opts in. - Size & complexity: Low — small, readable diff with straightforward `optionals` gating. - Runtime criticality: Medium — touches container/guest infrastructure, though the grant is opt-in and off by default. ### Unaddressed findings **Standards** - Duplicated `limits` clump and flat-key repetition across the two guest blocks on `neogaia` (Duplicated Code / Data Clumps, judgement calls) — kept as-is: the Host file is deliberately a flat declarative checklist and the two guests are independent placements that happen to share modest caps, so a shared `let` binding would trade that flatness for little gain. **Spec** - The cgroup-delegation prerequisite is not granted-by / absent-without the `nesting` flag — accepted deviation, explained under Deviations above and recorded in the code with an absence-pointer comment. - The `nesting-sample` guest is enabled permanently on `neogaia` — this is how acceptance criterion four is verified on the one Host's `nix flake check`, following the walking-skeleton guest's established precedent; it is a minimal smoke test and turns off with one line. — Claude
alexion added 1 commit 2026-07-25 22:11:34 -04:00
Add a `nesting` placement field to the Host-side guest interface, a bool
off by default. On, it grants the guest's container the prerequisites its
interior needs to run Podman and other OCI containers: the `CAP_NET_ADMIN`
capability an OCI runtime uses to build its bridges and firewall rules,
and the `/dev/net/tun` and `/dev/fuse` device nodes it reaches for to
network those containers and back their overlay storage. Off, both the
capability and device lists are empty, so a non-nesting guest is untouched.

cgroup delegation, the other nested prerequisite, the NixOS container
backend already grants every container unconditionally, so the Skeleton
records it with an absence pointer rather than re-emitting it.

Add a nesting-sample guest whose interior defines an `oci-containers`
workload on Podman, and enable it on neogaia with `nesting` on, so the
path builds end to end through the Host's `nix flake check` — which pulls
in podman and the generated container unit for the nested system.
alexion merged commit 969737b6b5 into main 2026-07-25 22:31:53 -04:00
alexion deleted branch task-0009-guest-nesting 2026-07-25 22:31:53 -04:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: alexion/dotfiles#35