Add `modules.storage.zfs`, the host-level pool import: a host declares its ZFS host id and the pools to import with their dataset mountpoints, and the module imports those pools as durable state rather than recreating them, so a service's data survives any rebuild or reimage. Add a shared `storage` group with a fixed gid to the base config both the host base and the guest-base build on, so a host and every guest carry the same number and an identity-mapped container write lands on the pool as that group without per-service permission juggling. No host enables the module: the only host is a laptop with no pools and a kernel with no ZFS build, so the enabled build was verified by ad-hoc enablement against a ZFS-supported kernel while the committed tree stays inert.
89 lines
2.7 KiB
Nix
89 lines
2.7 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
inputs,
|
|
...
|
|
}:
|
|
# The shared foundation both the host base and the guest-base build on: the
|
|
# primary user, home-manager, and the fresher/pinned package overlays.
|
|
let
|
|
inherit (lib) mkOption types;
|
|
user = config.user;
|
|
|
|
# Args to instantiate an extra nixpkgs source on the base platform.
|
|
pinArgs = prev: {
|
|
inherit (prev.stdenv.hostPlatform) system;
|
|
config.allowUnfree = true;
|
|
};
|
|
in
|
|
{
|
|
imports = [ inputs.home-manager.nixosModules.home-manager ];
|
|
|
|
options.user = {
|
|
name = mkOption {
|
|
type = types.str;
|
|
default = "alexion";
|
|
description = ''
|
|
The primary interactive user this system is built for. Drives both the
|
|
system account and the home-manager user in lockstep.
|
|
'';
|
|
};
|
|
description = mkOption {
|
|
type = types.str;
|
|
default = "Alexion";
|
|
description = "Human-readable description (GECOS field) for the primary user.";
|
|
};
|
|
};
|
|
|
|
config = {
|
|
# Reach fresher packages with `unstable.<name>` or pin with `stable.<name>`.
|
|
nixpkgs.overlays = [
|
|
(_final: prev: {
|
|
unstable = import inputs.nixpkgs-unstable (pinArgs prev);
|
|
stable = import inputs.nixpkgs-stable (pinArgs prev);
|
|
})
|
|
];
|
|
nixpkgs.config.allowUnfree = true;
|
|
|
|
# Flakes, so `nixos-rebuild switch` works from the console and a direnv
|
|
# `use flake` resolves inside a guest.
|
|
nix.settings.experimental-features = [
|
|
"nix-command"
|
|
"flakes"
|
|
];
|
|
|
|
# Primary user.
|
|
# The wheel group is the way in, since root is locked.
|
|
# No password is set here, since that is host-only.
|
|
# A guest therefore has none and is reached by SSH key or `machinectl`.
|
|
users.users.${user.name} = {
|
|
isNormalUser = true;
|
|
description = user.description;
|
|
extraGroups = [ "wheel" ];
|
|
};
|
|
|
|
# The shared write group.
|
|
# 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.
|
|
# 2000 clears the system-group ids assigned automatically and leaves headroom above the primary user, so nothing else claims it.
|
|
users.groups.storage.gid = 2000;
|
|
|
|
# home-manager as a NixOS module: one build produces the system and user
|
|
# environment together, sharing the system's pkgs and installing user
|
|
# packages into the system profile.
|
|
home-manager = {
|
|
useGlobalPkgs = true;
|
|
useUserPackages = true;
|
|
extraSpecialArgs = {
|
|
inherit inputs;
|
|
my = inputs.self.lib;
|
|
};
|
|
users.${user.name} = {
|
|
home.username = user.name;
|
|
home.homeDirectory = "/home/${user.name}";
|
|
home.stateVersion = "26.05";
|
|
};
|
|
};
|
|
};
|
|
}
|