feat: split persist module onto nixos and home ones

This commit is contained in:
Dmitriy Kholkin 2025-06-07 17:20:39 +03:00
parent 1c7a94546d
commit adda550db2
Signed by: AtaraxiaDev
GPG Key ID: FD266B810DF48DF2
3 changed files with 99 additions and 87 deletions

View File

@ -38,6 +38,13 @@ in
# Home-manager # Home-manager
home-manager.users.${defaultUser} = { home-manager.users.${defaultUser} = {
ataraxia.defaults.role = "desktop"; ataraxia.defaults.role = "desktop";
persist.state.directories = [
".config/sops/age"
"nixos-config"
"projects"
];
home.stateVersion = "25.05"; home.stateVersion = "25.05";
}; };

View File

@ -1,17 +1,23 @@
{ {
config, config,
lib, lib,
pkgs,
... ...
}: }:
let let
inherit (lib) inherit (lib)
escapeShellArg
mkEnableOption mkEnableOption
mkIf mkIf
mkOption mkOption
recursiveUpdate recursiveUpdate
; ;
inherit (lib.types) listOf path str; inherit (lib.types) listOf path str;
inherit (builtins) concatMap;
cfg = config.persist; cfg = config.persist;
username = config.home.username;
homeDir = config.home.homeDirectory;
absoluteHomePath = map (x: "${homeDir}/${x}");
in in
{ {
options = options =
@ -32,7 +38,7 @@ in
enable = mkEnableOption "A tmpfs root with explicit opt-in state"; enable = mkEnableOption "A tmpfs root with explicit opt-in state";
persistRoot = mkOption { persistRoot = mkOption {
type = path; type = path;
default = "/persist"; default = "/persist${config.home.homeDirectory}";
}; };
# Stuff that matters # Stuff that matters
# TODO backups # TODO backups
@ -53,11 +59,71 @@ in
}; };
}; };
config = mkIf cfg.enable { # TODO: filter persist paths like in nixos module
# Persist by default config =
persist.cache.directories = [ ".cache" ]; let
persist.state = { takeAll = what: concatMap (x: x.${what});
directories = [ ".local/share/nix" ]; persists = with cfg; [
state
cache
];
allFiles = takeAll "files" persists;
allDirs = takeAll "directories" persists;
in
mkIf cfg.enable {
home.persistence.${cfg.persistRoot} = {
allowOther = true;
directories = allDirs;
files = allFiles;
};
# Persist by default
persist.cache.directories = [ ".cache" ];
persist.state = {
directories = [
"Downloads"
"Documents"
"Music"
"Pictures"
"Videos"
".config/dconf"
".local/share/nix"
".ssh"
# { directory = ".ssh"; mode = "0700"; }
];
};
systemd.user = mkIf cfg.cache.clean.enable {
services."persist-cache-cleanup-${username}" = {
Unit = {
Description = "Cleaning up cache files and directories for user ${username}";
Wants = [ "modprobed-db.timer" ];
};
Service = {
ExecStart = pkgs.writeShellScript "" ''
${builtins.concatStringsSep "\n" (
map (x: "rm ${escapeShellArg x}") (absoluteHomePath cfg.cache.files)
)}
${builtins.concatStringsSep "\n" (
map (x: "rm -rf ${escapeShellArg x}") (absoluteHomePath cfg.cache.directories)
)}
'';
Type = "simple";
};
Install.WantedBy = [ "default.target" ];
};
timers."persist-cache-cleanup-${username}" = {
Unit = {
Description = "Run persist-cache-cleanup-${username} service by set schedule";
PartOf = [ "persist-cache-cleanup-${username}.service" ];
};
Timer = {
Persistent = true;
OnCalendar = cfg.cache.clean.dates;
};
Install.WantedBy = [ "timers.target" ];
};
};
}; };
};
} }

View File

@ -7,28 +7,25 @@
let let
inherit (lib) inherit (lib)
escapeShellArg escapeShellArg
filterAttrs hasPrefix
mapAttrs hasSuffix
mapAttrs'
mkEnableOption mkEnableOption
mkDefault
mkIf mkIf
mkMerge
mkOption mkOption
nameValuePair optionalString
optionalAttrs
pipe
recursiveUpdate recursiveUpdate
removePrefix
subtractLists
unique unique
; ;
inherit (lib.types) listOf path str; inherit (lib.types) listOf path str;
inherit (builtins) concatMap; inherit (builtins) any concatMap filter;
cfg = config.persist; cfg = config.persist;
btrfs = config.ataraxia.filesystems.btrfs.mountpoints; btrfs = config.ataraxia.filesystems.btrfs.mountpoints;
zfs = config.ataraxia.filesystems.zfs.mountpoints; zfs = config.ataraxia.filesystems.zfs.mountpoints;
mountpoints = unique (btrfs ++ zfs); mountpoints = map (x: "${x}${optionalString (!(hasSuffix "/" x)) "/"}") (unique (btrfs ++ zfs));
subtractListsPrefix = a: filter (dir: !(any (pref: hasPrefix pref dir) a));
in in
{ {
imports = [ inputs.impermanence.nixosModules.impermanence ]; imports = [ inputs.impermanence.nixosModules.impermanence ];
@ -74,12 +71,6 @@ in
config = config =
let let
# TODO: fix infinite recursion (can't get user home directory)
# userPersists = lib.mapAttrs (name: cfg:
# cfg.persist // {
# home = config.users.users.${name}.home;
# }
# ) config.home-manager.users;
takeAll = what: concatMap (x: x.${what}); takeAll = what: concatMap (x: x.${what});
persists = with cfg; [ persists = with cfg; [
state state
@ -88,79 +79,27 @@ in
allFiles = takeAll "files" persists; allFiles = takeAll "files" persists;
allDirectories = takeAll "directories" persists; allDirectories = takeAll "directories" persists;
# Remove btrfs + zfs mountpoints from list of dirs to persist # Remove btrfs + zfs mountpoints from list of dirs to persist
filteredDirs = subtractLists mountpoints allDirectories; filteredDirs = subtractListsPrefix mountpoints allDirectories;
userPersists = mapAttrs (_: cfg: cfg.persist) (
{ } // optionalAttrs (builtins.hasAttr "home-manager" config) config.home-manager.users
);
usersFlatten = mapAttrs (
name: cfg:
let
persists = with cfg; [
state
cache
];
allHomeFiles = takeAll "files" persists;
allHomeDirectories = takeAll "directories" persists;
# Remove btrfs + zfs mountpoints from list of dirs to persist
home = "/home/${name}";
filteredDirs = pipe allHomeDirectories [
(map (x: "${home}/${x}"))
(xs: subtractLists mountpoints xs)
(map (x: removePrefix home x))
];
in
{
inherit home;
directories = filteredDirs;
files = allHomeFiles;
}
) userPersists;
in in
mkIf cfg.enable { mkIf cfg.enable {
environment.persistence.${cfg.persistRoot} = { environment.persistence.${cfg.persistRoot} = {
hideMounts = true; hideMounts = true;
directories = filteredDirs; directories = filteredDirs;
files = allFiles; files = allFiles;
users = usersFlatten; # users = usersFlatten;
}; };
systemd.services = programs.fuse.userAllowOther = mkDefault true;
let
filtered = filterAttrs (_: cfg: cfg.cache.clean.enable) userPersists;
in
mkMerge [
(mapAttrs' (
name: cfg:
let
absoluteHomePath = map (x: "/home/${name}/${x}");
in
nameValuePair "persist-cache-cleanup-${name}" {
description = "Cleaning up cache files and directories for user ${name}";
script = ''
${builtins.concatStringsSep "\n" (
map (x: "rm ${escapeShellArg x}") (absoluteHomePath cfg.cache.files)
)}
${builtins.concatStringsSep "\n" ( systemd.services.persist-cache-cleanup = mkIf cfg.cache.clean.enable {
map (x: "rm -rf ${escapeShellArg x}") (absoluteHomePath cfg.cache.directories) description = "Cleaning up cache files and directories";
)} script = ''
''; ${builtins.concatStringsSep "\n" (map (x: "rm ${escapeShellArg x}") cfg.cache.files)}
startAt = cfg.cache.clean.dates;
}
) filtered)
{
persist-cache-cleanup = mkIf cfg.cache.clean.enable {
description = "Cleaning up cache files and directories";
script = ''
${builtins.concatStringsSep "\n" (map (x: "rm ${escapeShellArg x}") cfg.cache.files)}
${builtins.concatStringsSep "\n" (map (x: "rm -rf ${escapeShellArg x}") cfg.cache.directories)} ${builtins.concatStringsSep "\n" (map (x: "rm -rf ${escapeShellArg x}") cfg.cache.directories)}
''; '';
startAt = cfg.cache.clean.dates; startAt = cfg.cache.clean.dates;
}; };
}
];
fileSystems.${cfg.persistRoot}.neededForBoot = true; fileSystems.${cfg.persistRoot}.neededForBoot = true;
# Persist by default # Persist by default