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.users.${defaultUser} = {
ataraxia.defaults.role = "desktop";
persist.state.directories = [
".config/sops/age"
"nixos-config"
"projects"
];
home.stateVersion = "25.05";
};

View File

@ -1,17 +1,23 @@
{
config,
lib,
pkgs,
...
}:
let
inherit (lib)
escapeShellArg
mkEnableOption
mkIf
mkOption
recursiveUpdate
;
inherit (lib.types) listOf path str;
inherit (builtins) concatMap;
cfg = config.persist;
username = config.home.username;
homeDir = config.home.homeDirectory;
absoluteHomePath = map (x: "${homeDir}/${x}");
in
{
options =
@ -32,7 +38,7 @@ in
enable = mkEnableOption "A tmpfs root with explicit opt-in state";
persistRoot = mkOption {
type = path;
default = "/persist";
default = "/persist${config.home.homeDirectory}";
};
# Stuff that matters
# TODO backups
@ -53,11 +59,71 @@ in
};
};
config = mkIf cfg.enable {
# Persist by default
persist.cache.directories = [ ".cache" ];
persist.state = {
directories = [ ".local/share/nix" ];
# TODO: filter persist paths like in nixos module
config =
let
takeAll = what: concatMap (x: x.${what});
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
inherit (lib)
escapeShellArg
filterAttrs
mapAttrs
mapAttrs'
hasPrefix
hasSuffix
mkEnableOption
mkDefault
mkIf
mkMerge
mkOption
nameValuePair
optionalAttrs
pipe
optionalString
recursiveUpdate
removePrefix
subtractLists
unique
;
inherit (lib.types) listOf path str;
inherit (builtins) concatMap;
inherit (builtins) any concatMap filter;
cfg = config.persist;
btrfs = config.ataraxia.filesystems.btrfs.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
{
imports = [ inputs.impermanence.nixosModules.impermanence ];
@ -74,12 +71,6 @@ in
config =
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});
persists = with cfg; [
state
@ -88,79 +79,27 @@ in
allFiles = takeAll "files" persists;
allDirectories = takeAll "directories" persists;
# Remove btrfs + zfs mountpoints from list of dirs to persist
filteredDirs = subtractLists 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;
filteredDirs = subtractListsPrefix mountpoints allDirectories;
in
mkIf cfg.enable {
environment.persistence.${cfg.persistRoot} = {
hideMounts = true;
directories = filteredDirs;
files = allFiles;
users = usersFlatten;
# users = usersFlatten;
};
systemd.services =
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)
)}
programs.fuse.userAllowOther = mkDefault true;
${builtins.concatStringsSep "\n" (
map (x: "rm -rf ${escapeShellArg x}") (absoluteHomePath cfg.cache.directories)
)}
'';
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)}
systemd.services.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)}
'';
startAt = cfg.cache.clean.dates;
};
}
];
${builtins.concatStringsSep "\n" (map (x: "rm -rf ${escapeShellArg x}") cfg.cache.directories)}
'';
startAt = cfg.cache.clean.dates;
};
fileSystems.${cfg.persistRoot}.neededForBoot = true;
# Persist by default