Add a third auto-loaded kind beside the host and the module: the guest, a reusable definition under guests/ that a host enables like a module and that realizes its interior as a systemd-nspawn nested container. Split the shared base config so a guest can stand on it. base.nix now holds the substrate both bases share — the primary user, home-manager, and the unstable/stable overlays. system.nix keeps the host-only machinery, and a new guest.nix is the slim guest-base: it imports the full modules tree, pins the interior release, and auto-enables the toolkit bundle and SSH so any guest is workable on sight. Give modules.ssh a guest flavor. A host restores its host keys from secrets as before, while a guest sets hostKeys.restore = false, names no sops files, and self-generates a host key, so it holds no age key of its own. The lib grows a guest helper that declares the guests.<path> namespace with an enable and a backend field. Only the container backend is built; microvm is a reserved value that trips a clear build-time assertion rather than silently building nothing. A sample guest exercises the whole path, and neogaia enables it, so the guest interior builds through the existing nix flake check seam.
76 lines
2.8 KiB
Nix
76 lines
2.8 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
# The host base: the host-only machinery a physical machine needs on top of the
|
|
# shared base — bootloader, secret decryption, and the maintenance timers.
|
|
let
|
|
user = config.user;
|
|
|
|
passwordSecret = "${user.name}-password";
|
|
in
|
|
{
|
|
imports = [ ./base.nix ];
|
|
|
|
# chaotic's binary cache, so the CachyOS kernel is fetched rather than compiled.
|
|
# The `extra-` prefix keeps cache.nixos.org alongside it.
|
|
nix.settings.extra-substituters = [ "https://nyx-cache.chaotic.cx/" ];
|
|
nix.settings.extra-trusted-public-keys = [
|
|
"nyx-cache.chaotic.cx:dJxTrgMC3V3cFfyIiBQDQorG6k1LsqurH/srpMSq7qk="
|
|
];
|
|
|
|
# A month of generations is kept, because on a rolling channel with a
|
|
# third-party kernel an old generation is a known-good system to boot when
|
|
# an update breaks something.
|
|
nix.gc.automatic = true;
|
|
nix.gc.dates = "Mon 03:15";
|
|
nix.gc.options = "--delete-older-than 30d";
|
|
|
|
# Deduplication runs on a timer, off the rebuild path, so it never adds
|
|
# latency to a `nixos-rebuild switch`.
|
|
# It falls on a different day from collection, so the two never contend.
|
|
nix.optimise.automatic = true;
|
|
nix.optimise.dates = [ "Thu 03:45" ];
|
|
|
|
# The EFI system partition holds a kernel and an initrd per entry at roughly
|
|
# 70 MiB apiece, and is fixed in size.
|
|
# An exhausted one fails at bootloader installation, after the build has
|
|
# already succeeded.
|
|
boot.loader.systemd-boot.configurationLimit = 15;
|
|
|
|
environment.systemPackages = [ pkgs.git ];
|
|
|
|
# Caps Lock is a second Escape.
|
|
# Shift+Caps Lock still toggles Caps Lock.
|
|
services.xserver.xkb.layout = "us";
|
|
services.xserver.xkb.options = "caps:escape_shifted_capslock";
|
|
|
|
# Compile the console keymap from the layout above, so the remap holds on a
|
|
# bare TTY and not only under a graphical session.
|
|
console.useXkbConfig = true;
|
|
|
|
# Decryption machinery every host depends on.
|
|
# The identity sits on the encrypted root, which is mounted early enough to
|
|
# satisfy the secret below.
|
|
# Clearing both `sshKeyPaths` defaults keeps the SSH host keys out of the
|
|
# decryption path.
|
|
sops.defaultSopsFile = ./secrets/shared.yaml;
|
|
sops.age.keyFile = "/var/lib/sops-nix/key.txt";
|
|
sops.age.sshKeyPaths = [ ];
|
|
sops.gnupg.sshKeyPaths = [ ];
|
|
|
|
# A password set by hand on a running machine otherwise takes precedence.
|
|
# That leaves the declared `hashedPasswordFile` below silently inert.
|
|
# Root has no declared password and is therefore locked.
|
|
# `sudo` from the wheel group is the way in.
|
|
users.mutableUsers = false;
|
|
|
|
# Decrypted in an earlier activation stage than ordinary secrets.
|
|
# That is early enough to precede the account that reads it.
|
|
sops.secrets.${passwordSecret}.neededForUsers = true;
|
|
|
|
users.users.${user.name}.hashedPasswordFile = config.sops.secrets.${passwordSecret}.path;
|
|
}
|