Compare commits
1 Commits
7edc1ce94b
...
08393cb3f3
| Author | SHA1 | Date | |
|---|---|---|---|
| 08393cb3f3 |
@@ -30,6 +30,6 @@ Making the Guest a peer of Host and Module — same Auto-loader, same convention
|
|||||||
|
|
||||||
- The Skeleton grows a Guest realization: the Auto-loader discovers `guests/`, a Guest's interior compiles into a nested container, and placement fields wire VLAN attachment, MAC pinning, bind mounts, secret mounts, unit caps, and the nesting prerequisites.
|
- The Skeleton grows a Guest realization: the Auto-loader discovers `guests/`, a Guest's interior compiles into a nested container, and placement fields wire VLAN attachment, MAC pinning, bind mounts, secret mounts, unit caps, and the nesting prerequisites.
|
||||||
- The shared base config splits into a host base (`system.nix`) and a slim guest-base; both include the primary user, home-manager, and the shared overlays, and the guest-base auto-enables the `toolkit` bundle and `modules.ssh`.
|
- The shared base config splits into a host base (`system.nix`) and a slim guest-base; both include the primary user, home-manager, and the shared overlays, and the guest-base auto-enables the `toolkit` bundle and `modules.ssh`.
|
||||||
- Guests attach to host-level foundations declared once per Host: `modules.network` for the trunk and per-VLAN bridges, and `modules.zfs` with a shared fixed-gid `storage` group for identity-mapped pool writes.
|
- Guests attach to host-level foundations declared once per Host: `modules.network` for the trunk and per-VLAN bridges, and `modules.storage.zfs` with a shared fixed-gid `storage` group for identity-mapped pool writes.
|
||||||
- OCI software has a declarative home without a new mechanism: a Guest with `nesting` runs Podman in its interior.
|
- OCI software has a declarative home without a new mechanism: a Guest with `nesting` runs Podman in its interior.
|
||||||
- The `microvm` backend, multi-instance Guests, and the concrete homelab Host with its real trunk, VLAN, pool, and MAC values remain future work.
|
- The `microvm` backend, multi-instance Guests, and the concrete homelab Host with its real trunk, VLAN, pool, and MAC values remain future work.
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ The guest-base auto-enables it; a Host enables it explicitly, keeping the Host a
|
|||||||
This is a bundle wanted as a unit, distinct from the grouping-directory enables ADR 0004 rejected.
|
This is a bundle wanted as a unit, distinct from the grouping-directory enables ADR 0004 rejected.
|
||||||
- **`modules.network`** (new): the host-level networking foundation.
|
- **`modules.network`** (new): the host-level networking foundation.
|
||||||
A Host declares its trunk interface and the set of VLANs to materialize, and the Module emits one bridge per tagged VLAN with systemd-networkd and manages the Host's own management address.
|
A Host declares its trunk interface and the set of VLANs to materialize, and the Module emits one bridge per tagged VLAN with systemd-networkd and manages the Host's own management address.
|
||||||
- **`modules.zfs`** (new): the host-level pool import.
|
- **`modules.storage.zfs`** (new): the host-level pool import.
|
||||||
A Host declares its host id, the pools to import, and their dataset mountpoints; the pools are durable state that is imported, never rebuilt.
|
A Host declares its host id, the pools to import, and their dataset mountpoints; the pools are durable state that is imported, never rebuilt.
|
||||||
- **A shared `storage` group** with a fixed gid in the shared base gives 1:1 ownership between Host and Guest.
|
- **A shared `storage` group** with a fixed gid in the shared base gives 1:1 ownership between Host and Guest.
|
||||||
Because the container backend uses identity mapping, a guest service that writes as the `storage` group lands on the pool as that same group, which is the entire "no permission errors" mechanism.
|
Because the container backend uses identity mapping, a guest service that writes as the `storage` group lands on the pool as that same group, which is the entire "no permission errors" mechanism.
|
||||||
|
|||||||
@@ -5,17 +5,17 @@ blocked-by: 0002-guest-walking-skeleton
|
|||||||
|
|
||||||
## What to build
|
## What to build
|
||||||
|
|
||||||
The host-level pool-import foundation, `modules.zfs`, plus the shared `storage` group that makes identity-mapped pool writes work.
|
The host-level pool-import foundation, `modules.storage.zfs`, plus the shared `storage` group that makes identity-mapped pool writes work.
|
||||||
A Host declares its host id, the pools to import, and their dataset mountpoints; the pools are durable state that is imported, never rebuilt, so a service's data survives any rebuild or reimage.
|
A Host declares its host id, the pools to import, and their dataset mountpoints; the pools are durable state that is imported, never rebuilt, so a service's data survives any rebuild or reimage.
|
||||||
A shared `storage` group with a fixed gid lives in the shared portion of the base config that both the host base and the guest-base include, giving 1:1 group ownership between a Host and its Guests.
|
A shared `storage` group with a fixed gid lives in the shared portion of the base config that both the host base and the guest-base include, giving 1:1 group ownership between a Host and its Guests.
|
||||||
This slice establishes the group and the pool import; a Guest actually writing to a mount as that group is the Guest storage placement slice.
|
This slice establishes the group and the pool import; a Guest actually writing to a mount as that group is the Guest storage placement slice.
|
||||||
|
|
||||||
## Acceptance criteria
|
## Acceptance criteria
|
||||||
|
|
||||||
- [x] `modules.zfs` declares an `enable` option and its option path mirrors its file location per the Namespace convention.
|
- [x] `modules.storage.zfs` declares an `enable` option and its option path mirrors its file location per the Namespace convention.
|
||||||
- [x] A Host declares its host id, its pools, and their dataset mountpoints; enabling the Module imports those pools rather than recreating them.
|
- [x] A Host declares its host id, its pools, and their dataset mountpoints; enabling the Module imports those pools rather than recreating them.
|
||||||
- [x] A shared `storage` group with a fixed gid is defined in the shared base and is present identically on both a Host and its Guests.
|
- [x] A shared `storage` group with a fixed gid is defined in the shared base and is present identically on both a Host and its Guests.
|
||||||
- [x] A Host enabling `modules.zfs` builds, and the `storage` gid is verifiable by `nix eval`. Verified by ad-hoc enablement on `neogaia`; the enablement is not committed (see notes).
|
- [x] A Host enabling `modules.storage.zfs` builds, and the `storage` gid is verifiable by `nix eval`. Verified by ad-hoc enablement on `neogaia`; the enablement is not committed (see notes).
|
||||||
|
|
||||||
## Implementation Notes
|
## Implementation Notes
|
||||||
|
|
||||||
@@ -26,13 +26,9 @@ Declared dataset mountpoints become plain `fileSystems` entries with `fsType = "
|
|||||||
`pools` is typed `attrsOf (attrsOf path)` — pool name to a dataset-relative-path to mountpoint map — rather than a per-pool submodule.
|
`pools` is typed `attrsOf (attrsOf path)` — pool name to a dataset-relative-path to mountpoint map — rather than a per-pool submodule.
|
||||||
No per-pool option beyond the mount map is foreseen at host level, so the extra submodule layer would have been speculative.
|
No per-pool option beyond the mount map is foreseen at host level, so the extra submodule layer would have been speculative.
|
||||||
|
|
||||||
The Module is `modules.zfs`, a flat single-file module, not `modules.storage.zfs` under a `storage/` directory.
|
The `storage` group carries a fixed gid of 2000, placed in `base.nix` so a host and every guest built from this flake carry the identical number.
|
||||||
Nothing else lives under a storage namespace, and the sibling host-level foundation `modules.network` is likewise flat, so the extra directory level would have grouped a single member.
|
|
||||||
The spec and ADR 0006 were updated to name it `modules.zfs` to match.
|
|
||||||
|
|
||||||
The `storage` group carries a fixed gid of 10000, placed in `base.nix` so a host and every guest built from this flake carry the identical number.
|
|
||||||
That identity is the whole write mechanism: an identity-mapped container write lands on the pool as the same numeric group with no per-service permission juggling.
|
That identity is the whole write mechanism: an identity-mapped container write lands on the pool as the same numeric group with no per-service permission juggling.
|
||||||
10000 sits above the ids NixOS assigns automatically, so no generated account collides with it.
|
2000 sits above the ids NixOS assigns automatically, so no generated account collides with it.
|
||||||
This slice only defines the group and the import; a Guest actually writing to a mount as this group is the Guest storage placement slice.
|
This slice only defines the group and the import; a Guest actually writing to a mount as this group is the Guest storage placement slice.
|
||||||
|
|
||||||
No host commits an enablement of this Module.
|
No host commits an enablement of this Module.
|
||||||
|
|||||||
4
base.nix
4
base.nix
@@ -65,8 +65,8 @@ in
|
|||||||
# The shared write group.
|
# The shared write group.
|
||||||
# Its gid is fixed, so a host and every guest carry the same number.
|
# Its gid is fixed, so a host and every guest carry the same number.
|
||||||
# An identity-mapped container write then lands on the pool as this group, sparing every service the permission juggling.
|
# An identity-mapped container write then lands on the pool as this group, sparing every service the permission juggling.
|
||||||
# 10000 clears the system-group ids assigned automatically and leaves headroom above the primary user, so nothing else claims it.
|
# 2000 clears the system-group ids assigned automatically and leaves headroom above the primary user, so nothing else claims it.
|
||||||
users.groups.storage.gid = 10000;
|
users.groups.storage.gid = 2000;
|
||||||
|
|
||||||
# home-manager as a NixOS module: one build produces the system and user
|
# home-manager as a NixOS module: one build produces the system and user
|
||||||
# environment together, sharing the system's pkgs and installing user
|
# environment together, sharing the system's pkgs and installing user
|
||||||
|
|||||||
@@ -5,10 +5,10 @@
|
|||||||
}:
|
}:
|
||||||
# The host-level ZFS pool import: durable service state a host mounts, never rebuilds.
|
# The host-level ZFS pool import: durable service state a host mounts, never rebuilds.
|
||||||
let
|
let
|
||||||
cfg = config.modules.zfs;
|
cfg = config.modules.storage.zfs;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.modules.zfs = {
|
options.modules.storage.zfs = {
|
||||||
enable = lib.mkEnableOption "importing durable ZFS pools that hold service state";
|
enable = lib.mkEnableOption "importing durable ZFS pools that hold service state";
|
||||||
|
|
||||||
hostId = lib.mkOption {
|
hostId = lib.mkOption {
|
||||||
Reference in New Issue
Block a user