persist module

This commit is contained in:
Dmitriy Kholkin 2022-12-14 23:46:25 +03:00
parent 346dfd683c
commit 167d11428c
30 changed files with 284 additions and 15 deletions

View File

@ -23,6 +23,7 @@
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
impermanence.url = "github:nix-community/impermanence";
arkenfox-userjs = {
url = "github:arkenfox/user.js";
flake = false;

145
modules/persist.nix Normal file
View File

@ -0,0 +1,145 @@
{ config, pkgs, lib, inputs, ... }:
let
cfg = config.persist;
takeAll = what: concatMap (x: x.${what});
persists = with cfg; [ state derivative cache ];
absoluteHomeFiles = map (x: "${cfg.homeDir}/${x}");
allFiles = takeAll "files" persists;
allHomeFiles = takeAll "homeFiles" persists;
allDirectories = takeAll "directories" persists;
allHomeDirectories = takeAll "homeDirectories" persists;
inherit (builtins) concatMap;
inherit (lib) mkIf;
homeDirectory = config.home-manager.users.${config.mainuser}.home.homeDirectory;
in {
options = let
inherit (lib) mkOption mkEnableOption;
inherit (lib.types) listOf path str;
common = {
directories = mkOption {
type = listOf path;
default = [ ];
};
files = mkOption {
type = listOf str;
default = [ ];
};
homeDirectories = mkOption {
type = listOf str;
default = [ ];
};
homeFiles = mkOption {
type = listOf str;
default = [ ];
};
};
in {
persist = {
enable = mkEnableOption "a tmpfs root with explicit opt-in state";
persistRoot = mkOption {
type = path;
default = "/persistent";
};
homeDir = mkOption {
type = path;
default = homeDirectory;
};
# Stuff that matters
# TODO backups of this stuff
state = {
# backup = {...};
} // common;
# Stuff that can be computed from declarative+state, but is never invalidated (so shouldn't be cleaned up)
derivative = common;
# Stuff that's just there to speed up the system
# It's cleaned up regularly, to solve the cache invalidation problem once and for all
cache = {
clean = {
enable = mkEnableOption "cleaning the cache files and directories";
dates = mkOption {
type = str;
default = "weekly";
description =
"A systemd.time calendar description of when to clean the cache files";
};
};
} // common;
};
};
imports = [ inputs.impermanence.nixosModules.impermanence ];
config = mkIf cfg.enable {
environment.persistence.${cfg.persistRoot} = {
directories = allDirectories;
files = allFiles;
};
home-manager.users.${config.mainuser} = {
imports = [ inputs.impermanence.nixosModules.home-manager.impermanence ];
home.persistence."${cfg.persistRoot}${homeDirectory}" = {
directories = allHomeDirectories;
files = allHomeFiles;
allowOther = false;
removePrefixDirectory = false;
};
};
fileSystems."/" = lib.mkIf (config.deviceSpecific.devInfo.fileSystem != "zfs") {
device = "none";
options = [ "defaults" "size=2G" "mode=755" ];
fsType = "tmpfs";
};
boot.initrd = lib.mkIf (config.deviceSpecific.devInfo.fileSystem != "zfs") {
postMountCommands =
assert config.fileSystems
? ${cfg.persistRoot}
&& config.fileSystems.${cfg.persistRoot}.neededForBoot; ''
mkdir -p /mnt-root/nix
mount --bind /mnt-root${cfg.persistRoot}/nix /mnt-root/nix
chmod 755 /mnt-root
'';
};
# Euuuugh
systemd.services.persist-cache-cleanup = lib.mkIf cfg.cache.clean.enable {
description = "Cleaning up cache files and directories";
script = ''
${builtins.concatStringsSep "\n" (map (x: "rm ${lib.escapeShellArg x}")
(cfg.cache.files
++ absoluteHomeFiles cfg.cache.homeFiles))}
${builtins.concatStringsSep "\n" (map (x: "rm -rf ${lib.escapeShellArg x}")
(cfg.cache.directories ++ cfg.cache.homeDirectories))}
'';
startAt = cfg.cache.clean.dates;
};
# system.activationScripts = {
# homedir.text = builtins.concatStringsSep "\n" (map (dir: ''
# mkdir -p ${cfg.persistRoot}${dir}
# chown ${config.mainuser}:users ${cfg.persistRoot}${dir}
# '') (builtins.filter (lib.hasPrefix homeDirectory) allDirectories));
# };
};
}

View File

@ -61,7 +61,7 @@ let
lib.escapeShellArg config.secretsConfig.repo
} "${password-store}"
fi
cat ${password-store}/spotify.gpg | ${pkgs.gnupg}/bin/gpg --decrypt > /dev/null
cat ${password-store}/ssh-builder.gpg | ${pkgs.gnupg}/bin/gpg --decrypt > /dev/null
[ ! -z "${allServices}" ] && doas systemctl restart ${allServices}
'';
@ -150,6 +150,9 @@ in {
args = [ "restart" ] ++ allServicesMap;
}];
config.persist.derivative.directories = [ "/var/secrets" ];
config.persist.derivative.homeDirectories = [ password-store ];
config.home-manager.users.${config.mainuser} = {
systemd.user.services.activate-secrets = {
Service = {

View File

@ -2,9 +2,13 @@
programs.steam.enable = true;
hardware.steam-hardware.enable = true;
# startupApplications = [
# "${pkgs.steam}/bin/steam"
# ];
startupApplications = [
"${pkgs.steam}/bin/steam"
];
persist.state.homeDirectories = [
".local/share/Steam"
];
# systemd.user.services.x11-ownership = rec {
# # serviceConfig.Type = "oneshot";

View File

@ -9,4 +9,6 @@ in {
] else [
pkgs.tor-browser-bundle-bin
];
persist.state.homeDirectories = [ ".local/share/tor-browser" ];
}

View File

@ -21,5 +21,8 @@ in {
virtualisation.waydroid.enable = true;
# virtualisation.lxd.enable = true;
home-manager.users.${config.mainuser}.home.packages = [ pkgs.waydroid-script ];
persist.state.directories = [ "/var/lib/waydroid" ];
persist.state.homeDirectories = [ ".local/share/waydroid" ];
};
}

20
profiles/bluetooth.nix Normal file
View File

@ -0,0 +1,20 @@
{ config, pkgs, lib, ... }: {
hardware.bluetooth = {
enable = !isServer;
# package = pkgs.bluez;
};
# systemd.services.bluetooth.serviceConfig.ExecStart = lib.mkForce [
# ""
# "${pkgs.bluez}/libexec/bluetooth/bluetoothd -f /etc/bluetooth/main.conf -E"
# ];
persist.state.directories = [ "/var/lib/bluetooth" ];
home-manager.users.${config.mainuser}.programs.zsh.shellAliases = let
headphones = "D8:37:3B:60:5D:55";
in {
"hpc" = "bluetoothctl connect ${headphones}";
"hpd" = "bluetoothctl disconnect ${headphones}";
};
}

View File

@ -7,6 +7,8 @@ with config.deviceSpecific; {
numDevices = 1;
};
persist.state.files = [ "/etc/machine-id" ];
boot = if !isServer && !isISO then {
loader = {
timeout = lib.mkForce 4;
@ -36,6 +38,7 @@ with config.deviceSpecific; {
};
cleanTmpDir = true;
zfs.forceImportAll = false;
} else if isServer then {
kernelPackages = pkgs.linuxPackages_hardened;
kernelModules = [ "tcp_bbr" ];
@ -64,9 +67,11 @@ with config.deviceSpecific; {
"vm.swappiness" = if config.deviceSpecific.isSSD then 1 else 10;
};
cleanTmpDir = true;
zfs.forceImportAll = false;
} else {
kernelPackages = lib.mkForce pkgs.linuxPackages_latest;
kernelParams = lib.mkForce [ "zswap.enabled=0" ];
supportedFilesystems = lib.mkForce [ "ext4" "vfat" "btrfs" "ntfs" ];
zfs.forceImportAll = false;
};
}

View File

@ -5,7 +5,11 @@ in {
config = lib.mkIf vpn.enable {
services.mullvad-vpn.enable = true;
services.mullvad-vpn.enableExcludeWrapper = true;
home-manager.users.${config.mainuser}.home.packages = [ pkgs.mullvad-vpn ];
services.mullvad-vpn.package = pkgs.mullvad-vpn;
startupApplications = [ "${pkgs.mullvad-vpn}/share/mullvad/mullvad-gui" ];
persist.state.homeDirectories = [
".config/Mullvad VPN"
];
};
}

View File

@ -53,4 +53,8 @@ with config.deviceSpecific;
0.0.0.0 remote-config-proxy-prd.uca.cloud.unity3d.com
'';
};
persist.state.directories = lib.mkIf config.networkmanager.enable [
"/etc/NetworkManager/system-connections"
];
}

View File

@ -1,4 +1,4 @@
{ config, lib, pkgs, inputs, system, ... }:
{ config, lib, pkgs, inputs, ... }:
with config.deviceSpecific; {
nix = rec {
nixPath = lib.mkForce [ "self=/etc/self/compat" "nixpkgs=/etc/nixpkgs" ];
@ -53,4 +53,6 @@ with config.deviceSpecific; {
environment.etc.nixpkgs.source = inputs.nixpkgs;
environment.etc.self.source = inputs.self;
persist.state.homeDirectories = [ ".local/share/nix" ];
}

View File

@ -14,4 +14,6 @@
wantedBy = [ "multi-user.target" ];
};
networking.firewall.allowedTCPPorts = [ 23045 23046 ];
persist.state.homeDirectories = [ ".config/a2ln" ];
}

View File

@ -72,4 +72,8 @@ in {
partOf = [ "duplicacy-prune.service" ];
timerConfig.OnCalendar = [ "*-*-* 01:00:00" ];
};
# FIXME!
persist.state.directories = lib.mkIf config.deviceSpecific.devInfo.fileSystem != "zfs"
[ "/backup" ];
}

View File

@ -56,4 +56,6 @@
ignoreregex =
'';
};
persist.state.directories = [ "/var/lib/fail2ban" ];
}

View File

@ -15,7 +15,7 @@
httpPort = 6000;
lfs.enable = true;
rootUrl = "https://code.ataraxiadev.com";
stateDir = "/gitea/data";
stateDir = "/gitea/data"; # FIXME!
settings = {
attachment = {
MAX_SIZE = 100;

View File

@ -146,4 +146,14 @@ in {
enableSubmissionSsl = true;
virusScanning = false;
};
# FIXME: ownership of mail directory
persist.state.directories = [
"/var/lib/dovecot"
"/var/lib/postfix"
"/var/lib/dhparams"
"/var/dkim"
config.mailserver.mailDirectory
];
}

View File

@ -17,4 +17,6 @@
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
};
persist.state.directories = [ "/var/microbin" ];
}

View File

@ -234,4 +234,8 @@
environment.systemPackages = with pkgs; [ python3 python3Packages.requests ];
networking.firewall.allowedTCPPorts = [ 80 443 8448 ];
persist.state.directories = [
"/var/lib/acme"
];
}

View File

@ -29,4 +29,6 @@
"listen.owner" = config.services.nginx.user;
"listen.group" = config.services.nginx.group;
};
persist.state.directories = [ "/var/lib/roundcube" ];
}

View File

@ -32,4 +32,6 @@
};
environmentFile = config.secrets.vaultwarden.decrypted;
};
persist.state.directories = [ "/var/lib/bitwarden_rs" ];
}

View File

@ -6,4 +6,6 @@
home-manager.users.${config.mainuser} = {
services.vscode-server.enable = true;
};
# persist.state.homeDirectories = [ ".vscode-server" ];
}

View File

@ -4,7 +4,7 @@ with config.deviceSpecific; {
services.acpid.enable = !isServer;
services.acpid.logEvents = false;
hardware.bluetooth.enable = !isServer;
services.blueman.enable = !isServer;
services.btrbk.instances = lib.mkIf (devInfo.fileSystem == "btrfs") {

View File

@ -47,7 +47,7 @@ with config.deviceSpecific; {
systemConfig = ''
lxc.lxcpath = /var/lib/lxd/containers
${if devInfo.fileSystem == "zfs" then ''
lxc.bdev.zfs.root = rpool/lxd
lxc.bdev.zfs.root = rpool/nixos/lxd
'' else ""}
'';
defaultConfig = ''
@ -64,5 +64,10 @@ with config.deviceSpecific; {
internalInterfaces = [ "ve-+" ];
# externalInterface = "enp8s0";
};
persist.state.directories = lib.mkIf devInfo.fileSystem != "zfs" [
"/var/lib/docker"
"/var/lib/libvirt"
];
};
}

View File

@ -6,4 +6,6 @@
nix-direnv.enable = true;
};
};
persist.state.homeDirectories = [ ".local/share/direnv" ];
}

View File

@ -25,4 +25,6 @@ with config.deviceSpecific; {
};
};
};
persist.state.homeDirectories = [ ".local/share/gnupg" ];
}

View File

@ -36,4 +36,26 @@
systemd.services.systemd-timesyncd.wantedBy = [ "multi-user.target" ];
systemd.timers.systemd-timesyncd = { timerConfig.OnCalendar = "hourly"; };
persist.state.files = lib.mkIf (config.deviceSpecific.devInfo.fileSystem == "zfs") [
"/etc/zfs/zpool.cache"
];
persist.cache.homeDirectories = [
".cache"
".local/share/cargo"
];
persist.cache.directories = [
"/var/cache"
];
persist.state.directories = [
"/var/lib/nixos"
"/var/lib/systemd"
];
persist.state.homeDirectories = [
"projects"
"nixos-config"
] ++ lib.optionals (!config.deviceSpecific.isServer) [
"games"
# "persist"
];
}

View File

@ -5,4 +5,6 @@
enableZshIntegration = true;
};
};
persist.derivative.homeDirectories = [ ".cache/nix-index" ];
}

View File

@ -14,11 +14,7 @@ with config.deviceSpecific; {
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDP0/DReYSAfkucroMTdELzTORsGhhbEa+W0FDFBnwViHuoqoKvetCOkW657icexc5v/j6Ghy3+Li9twbHnEDzUJVtNtauhGMjOcUYt6pTbeJ09CGSAh+orxzeY4vXp7ANb91xW8yRn/EE4ALxqbLsc/D7TUMl11fmf0UW+kLgU5TcUYVSLMjQqBpD1Lo7lXLrImloDxe5fwoBDT09E59r9tq6+/3aHz8mpKRLsIQIV0Av00BRJ+/OVmZuBd9WS35rfkpUYmpEVInSJy3G4O6kCvY/zc9Bnh67l4kALZZ0+6W23kBGrzaRfaOtCEcscwfIu+6GXiHOL33rrMNNinF0T2942jGc18feL6P/LZCzqz8bGdFNxT43jAGPeDDcrJEWAJZFO3vVTP65dTRTHQG2KlQMzS7tcif6YUlY2JLJIb61ZfLoShH/ini/tqsGT0Be1f3ndOFt48h4XMW1oIF+EXaHYeO2UJ6855m8Wpxs4bP/jX6vMV38IvvnHy4tWD50= alukard@AMD-Workstation"
];
secrets.ssh-builder = {
permissions = "644";
decrypted = "/root/.ssh/ssh-builder";
};
secrets.ssh-builder = {};
programs.ssh.extraConfig = ''
Host nix-builder
hostname 192.168.0.100
@ -60,4 +56,13 @@ with config.deviceSpecific; {
'';
};
};
persist.state.files = [
"/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"
"/root/.ssh/known_hosts"
];
persist.state.homeDirectories = [ ".ssh" ];
}

View File

@ -10,7 +10,14 @@
};
environment.sessionVariables = {
# XDG_CURRENT_DESKTOP = "X-Generic";
DE = "generic";
};
persist.state.homeDirectories = [
"Documents"
"Downloads"
"Music"
"Pictures"
"Videos"
];
}

View File

@ -15,6 +15,7 @@
network
nix
overlay
persist
secrets
secrets-envsubst
security