feat(guests): bind-mount host pool paths into guests #32
Reference in New Issue
Block a user
Delete Branch "task-0006-guest-storage-placement"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Adds the Host-side
mountsplacement to the guest builder, letting a Host mount shared pool paths into a Guest and write to them without permission errors.guests.<path>.mountsis an attribute set keyed by the guest-interior path, each value carryinghostPathand areadOnlyflag defaulting tofalse.It is realized as the nested container's
bindMounts, with the container'smountPointdefaulting to the key, so a Guest sees exactly the data it should at any granularity — a single folder or a whole pool, read-write or read-only per mount.The upstream
bindMountsdefault is read-only, soisReadOnlyis driven explicitly fromreadOnlyto make read-write the default here, matching the migration reality that services must write to their pools.privateUsers = "no"(identity 1:1, no user namespace).With the shared
storagegroup from the storage foundation (identical gid on host and Guest), a guest process writing as that group lands on a bind-mounted pool as the same group — the whole "no permission errors" mechanism, and the privileged-container equivalent trusted from Proxmox.Deviations
neogaiais a laptop with no ZFS pools, so a committed mount would point at a non-existent host path and fail the bind at container start.This mirrors the storage and networking foundations (tasks 0005 and 0003): verify by ad-hoc enablement rather than commit a placement a host cannot honestly carry.
Verified through
extendModules, setting two mounts on the sample guest: the resolvedbindMountscarried the righthostPath,mountPoint, and per-mountisReadOnly;privateUsersresolved to"no"; thestoragegid was identical (10000) on host and guest interior; the full toplevel built; andnix flake checkpasses on the committed tree.privateUsers = "no"is the current NixOS default, pinned explicitly because the option documents"pick"(a shifting map that would break pool writes) as its recommended value, so the load-bearing property does not drift with the default.Review
Risk
Overall: High
lib.nix;mountsdefaults to{}, so no existing guest is touched and there are no cross-file caller changes.mountsyet, so reverting fully undoes it.nix flake checkbuilds the toplevel; no test exercises an actual mount mapping or the uid/gid landing behaviour (that is the VM integration test, task 0010).privateUsers = "no"deliberately removes the user namespace and read-write bind mounts let guest processes write host pool data as the shared group.mapAttrs, no tangled logic.Standards
No findings left unaddressed. The triplicated identity-mapping rationale was consolidated to one canonical statement (the
privateUserscomment), the redundantbindMounts"what" comment was removed, andhostPathwas retyped frompathtostrto match upstream and drop the path-literal footgun. The reviewer's "storage group does not exist" flag was a false positive — it is defined inbase.nix(merged from task 0005), which the reviewer's grep did not cover.Spec
No findings left unaddressed. All four acceptance criteria are met; the
hostPathtype nit (the only spec-axis finding) was fixed in the diff.— Claude