nixdots/hosts/herugrim/impermanence.nix

111 lines
4.1 KiB
Nix
Raw Normal View History

2024-04-07 12:38:24 +00:00
{ config, pkgs, ... }:
let
impermanence = builtins.fetchTarball "https://github.com/nix-community/impermanence/archive/master.tar.gz";
in
{
imports = [ "${impermanence}/nixos.nix" ];
users = {
# This option makes it that users are not mutable outside our configuration
# If you are using impermanence, this will actually be the case regardless of this setting,
# however, setting this explicitly is a good idea, because nix will warn us if
# our users don't have passwords set
mutableUsers = false;
# Each existing user needs to have a password file defined here
# otherwise, they will not be available to login.
# These password files can be generated using the following command:
# mkpasswd -m sha-512 > /persist/system/passwords/myuser
users = {
root = {
# password file needs to be in a volume marked `neededForRoot = true`
hashedPasswordFile = "/persist/passwords/root";
};
itsdrike = {
hashedPasswordFile = "/persist/passwords/itsdrike";
};
};
};
# Some people use /nix/persist/system instead, leaving the persistent files in /nix subvolume
# I much prefer using a standalone subvolume for this though.
environment.persistence."/persist/system" = {
hideMounts = true;
directories = [
"/etc/nixos" # nixos configuration source
"/etc/NetworkManager/system-connections" # saved network connections
"/var/db/sudo" # keeps track of who got the sudo lecture already
"/var/lib/systemd/coredump" # recorded coredumps
];
files = [
"/etc/machine-id"
# ssh stuff
"/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"
];
};
# For some reason, NetworkManager needs this instead of the impermanence mode to not get screwed up
systemd.tmpfiles.rules = [
"L /var/lib/NetworkManager/secret_key - - - - /persist/system/var/lib/NetworkManager/secret_key"
"L /var/lib/NetworkManager/seen-bssids - - - - /persist/system/var/lib/NetworkManager/seen-bssids"
"L /var/lib/NetworkManager/timestamps - - - - /persist/system/var/lib/NetworkManager/timestamps"
];
boot.initrd.systemd = {
enable = true; # This enables systemd support in stage 1 - required for below setup
services.rollback = {
description = "Rollback BTRFS root subvolume to a pristine state";
wantedBy = [ "initrd.target" ];
# make sure it's done after decryption (i.e. LUKS/TPM process)
after = [ "systemd-cryptsetup@cryptfs.service" ];
# mount the root fs before clearing
before = [ "sysroot.mount" ];
unitConfig.DefaultDependencies = "no";
serviceConfig.Type = "oneshot";
script = ''
mkdir -p /mnt
# We first mount the btrfs root to /mnt
# so we can manipulate btrfs subvolumes.
mount /dev/mapper/cryptfs /mnt
# While we're tempted to just delete /root and create
# a new snapshot from /root-blank, /root is already
# populated at this point with a number of subvolumes,
# which makes `btrfs subvolume delete` fail.
# So, we remove them first.
#
# /root contains subvolumes:
# - /root/var/lib/portables
# - /root/var/lib/machines
#
# These are probably related to systemd-nspawn, but
# since I don't use it, I'm not 100% sure.
# Anyhow, deleting these subvolumes hasn't resulted in
# any issues so far, except for fairly benign-looking
# errors from systemd-tmpfiles.
btrfs subvolume list -o /mnt/root |
cut -f9 -d' ' |
while read subvolume; do
echo "deleting /$subvolume subvolume..."
btrfs subvolume delete "/mnt/$subvolume"
done &&
echo "deleting /root subvolume..." &&
btrfs subvolume delete /mnt/root
echo "restoring blank /root subvolume..."
btrfs subvolume snapshot /mnt/root-blank /mnt/root
# Once we're done rolling back to a blank snapshot,
# we can unmount /mnt and continue on the boot process.
umount /mnt
'';
};
};
}