{ config, lib, namespace, ... }: with lib; let inherit (lib.${namespace}) mkOpt; cfg = config.${namespace}.impermanence; in { options.${namespace}.impermanence = { enable = mkEnableOption "enable impermanence"; persistencePath = mkOption { type = types.str; default = "/nix/persist/system"; description = "Path to the persistence directory"; }; # extraDirectories = mkOpt (types.listOf types.path) [ ] "Extra directory paths to add to impermanence"; extraDirectories = mkOpt (types.listOf ( types.either types.str ( types.submodule { options = { directory = mkOption { type = types.str; description = "Directory path"; }; user = mkOption { type = types.str; default = "root"; description = "Directory owner"; }; group = mkOption { type = types.str; default = "root"; description = "Directory group"; }; mode = mkOption { type = types.str; default = "u=rwx,g=rx,o="; description = "Directory permissions"; }; }; } ) )) [ ] "Extra directory paths to add to impermanence"; extraFiles = mkOpt (types.listOf types.path) [ ] "Extra file paths to add to impermanence"; }; config = mkIf cfg.enable { # /etc must be available before the impermanence bind-mounts are set up. fileSystems."/etc".neededForBoot = true; assertions = [ { assertion = lib.hasPrefix "/" cfg.persistencePath; message = "mjallen.impermanence.persistencePath must be an absolute path (got \"${cfg.persistencePath}\")."; } { assertion = cfg.persistencePath != "/"; message = "mjallen.impermanence.persistencePath must not be the filesystem root \"/\"."; } ]; environment.persistence."/nix/persist/system" = { hideMounts = true; directories = [ "/var/lib/bluetooth" "/var/lib/iwd" "/var/lib/nixos" "/var/lib/libvirt" "/var/lib/waydroid" "/var/lib/systemd/coredump" "/etc/NetworkManager/system-connections" "/var/lib/tailscale" { directory = "/var/lib/wallpapers"; user = "nobody"; group = "nobody"; mode = "u=rwx,g=rwx,o=rx"; } { directory = "/etc/nix"; user = "root"; group = "root"; mode = "u=rwx,g=rx,o=rx"; } { directory = "/var/lib/private"; mode = "u=rwx,g=rx,o="; } ] ++ cfg.extraDirectories; files = [ "/etc/machine-id" ] ++ cfg.extraFiles; }; security.sudo.extraConfig = '' # rollback results in sudo lectures after each reboot Defaults lecture = never ''; }; }