# { ... }: # { # # Set up impernance configuration for things like bluetooth # # In this configuration with /etc and /var/log being persistent, only directories outside of that need to be done here. See hardware configuration for all mountpoints. # 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" # "/var/lib/homeassistant" # "/var/lib/mosquitto" # "/var/lib/music-assistant" # "/var/lib/postgresql" # "/var/lib/zigbee2mqtt" # { # directory = "/var/lib/colord"; # user = "colord"; # group = "colord"; # mode = "u=rwx,g=rx,o="; # } # { # directory = "/etc/nix"; # user = "root"; # group = "root"; # mode = "u=rwx,g=rx,o=rx"; # } # { # directory = "/var/lib/private/authentik/media"; # user = "authentik"; # group = "authentik"; # mode = "u=rwx,g=,o="; # } # { # directory = "/var/lib/private"; # mode = "u=rwx,g=rx,o="; # } # { # directory = "/media/nas"; # user = "nas-apps"; # group = "jallen-nas"; # mode = "u=rwx,g=rx,o=rx"; # } # { # directory = "/var/lib/crowdsec"; # user = "crowdsec"; # group = "crowdsec"; # mode = "u=rwx,g=rwx,o=rx"; # } # { # directory = "/plugins-storage"; # user = "traefik"; # group = "traefik"; # mode = "u=rwx,g=rwx,o=rx"; # } # ]; # files = [ # "/etc/machine-id" # ]; # }; # security.sudo.extraConfig = '' # # rollback results in sudo lectures after each reboot # Defaults lecture = never # ''; # } { config, lib, ... }: with lib; { system.activationScripts = { "var-lib-private-permissions" = { deps = [ "createPersistentStorageDirs" ]; text = '' mkdir -p /var/lib/private chmod 0700 /var/lib/private ''; }; }; boot.initrd.systemd.services.rootfs-cleanup = { description = "Clean file system root"; wantedBy = [ "initrd.target" ]; after = [ "initrd-root-device.target" ]; before = [ "sysroot.mount" ]; unitConfig.DefaultDependencies = "no"; serviceConfig.Type = "oneshot"; script = if config.fileSystems."/".fsType == "btrfs" then '' # workaround for machines without working rtc battery # The time may not yet be correctly set, so wait until it is if [[ $(date '+%s') -lt 1730469314 ]]; then sleep 30 # this should hopefully be enough fi mkdir /btrfs_tmp mount ${config.fileSystems."/".device} -t btrfs /btrfs_tmp if [[ -e /btrfs_tmp/root ]]; then mkdir -p /btrfs_tmp/old_roots timestamp=$(date --date="@$(stat -c %X /btrfs_tmp/root)" "+%Y-%m-%d_%H:%M:%S") mv /btrfs_tmp/root "/btrfs_tmp/old_roots/$timestamp" fi delete_subvolume_recursively() { IFS=$'\n' for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do delete_subvolume_recursively "/btrfs_tmp/$i" done btrfs subvolume delete "$1" || rm -rf "$1" } for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -atime +30); do delete_subvolume_recursively "$i" done btrfs subvolume create /btrfs_tmp/root umount /btrfs_tmp '' else '' # workaround for machines without working rtc battery # The time may not yet be correctly set, so wait until it is if [[ $(date '+%s') -lt 1730469314 ]]; then sleep 30 # this should hopefully be enough fi if [[ -e /root_tmp/root ]]; then mkdir -p /root_tmp/old_roots timestamp=$(date --date="@$(stat -c %X /root_tmp/root)" "+%Y-%m-%d_%H:%M:%S") mv /root_tmp/root "/root_tmp/old_roots/$timestamp" fi for i in $(find /root_tmp/old_roots/ -maxdepth 1 -atime +30); do bcachefs subvolume delete $i done bcachefs subvolume create /root_tmp/root ''; }; assertions = [ { assertion = hasAttr "/" config.fileSystems; message = "To use impermanence, you need to define a root volume"; } { assertion = if hasAttr "/" config.fileSystems then config.fileSystems."/".fsType == "btrfs" || config.fileSystems."/".fsType == "bcachefs" else false; message = "rootfs must be btrfs or bcachefs"; } { assertion = if hasAttr "/" config.fileSystems then any ( t: t == "subvol=root" || t == "subvol=/root" || t == "X-mount.subdir=root" ) config.fileSystems."/".options else false; message = "rootfs must mount subvolume root"; } { assertion = !config.boot.isContainer; message = "impermanence is not supported in containers"; } ]; fileSystems."/persistent" = { neededForBoot = true; }; environment.persistence."/persistent" = { enable = true; hideMounts = true; directories = [ "/var/log" "/var/lib/nixos" "/var/cache" ]; files = [ "/etc/ssh/ssh_host_ecdsa_key" "/etc/ssh/ssh_host_ecdsa_key.pub" "/etc/ssh/ssh_host_ed25519_key" "/etc/ssh/ssh_host_ed25519_key.pub" "/etc/ssh/ssh_host_rsa_key" "/etc/ssh/ssh_host_rsa_key.pub" ]; }; systemd.tmpfiles.rules = [ "d /persistent/var/cache 1777 root root 7d -" ]; }