134 lines
3.6 KiB
Nix
134 lines
3.6 KiB
Nix
|
{ config, pkgs, lib, inputs, ... }:
|
||
|
let
|
||
|
cfg = config.persist;
|
||
|
|
||
|
takeAll = what: builtins.concatMap (x: x.${what});
|
||
|
|
||
|
persists = with cfg; [ state derivative cache ];
|
||
|
|
||
|
absoluteHomeFiles = map (x: "${cfg.homeDir}/${x}");
|
||
|
|
||
|
allHomeFiles = takeAll "homeFiles" persists;
|
||
|
|
||
|
absoluteEtcFiles = map (x: "/etc/${x}");
|
||
|
|
||
|
allEtcFiles = absoluteEtcFiles (takeAll "etcFiles" persists);
|
||
|
|
||
|
allDirectories = takeAll "directories" persists;
|
||
|
in {
|
||
|
options = with lib;
|
||
|
with types;
|
||
|
let
|
||
|
common = {
|
||
|
directories = mkOption {
|
||
|
type = listOf path;
|
||
|
default = [ ];
|
||
|
};
|
||
|
etcFiles = 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 = "/persist";
|
||
|
};
|
||
|
|
||
|
homeDir = mkOption {
|
||
|
type = path;
|
||
|
default = "/home/balsoft";
|
||
|
};
|
||
|
|
||
|
# 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
|
||
|
# Eugh
|
||
|
(let
|
||
|
module = (import "${inputs.impermanence}/home-manager.nix" {
|
||
|
inherit pkgs lib;
|
||
|
config = lib.recursiveUpdate config.home-manager.users.balsoft {
|
||
|
home.persistence."${cfg.persistRoot}${cfg.homeDir}" = {
|
||
|
directories = [ ];
|
||
|
files = allHomeFiles;
|
||
|
allowOther = false;
|
||
|
removePrefixDirectory = false;
|
||
|
};
|
||
|
};
|
||
|
});
|
||
|
in {
|
||
|
config.home-manager.users.balsoft = lib.mkIf cfg.enable module.config;
|
||
|
})
|
||
|
];
|
||
|
|
||
|
config = lib.mkIf cfg.enable {
|
||
|
environment.persistence.${cfg.persistRoot} = {
|
||
|
directories = allDirectories;
|
||
|
files = allEtcFiles;
|
||
|
};
|
||
|
|
||
|
fileSystems."/" = {
|
||
|
device = "none";
|
||
|
options = [ "defaults" "size=4G" "mode=755" ];
|
||
|
fsType = "tmpfs";
|
||
|
};
|
||
|
|
||
|
boot.initrd.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}")
|
||
|
(absoluteEtcFiles cfg.cache.etcFiles
|
||
|
++ absoluteHomeFiles cfg.cache.homeFiles))}
|
||
|
|
||
|
${builtins.concatStringsSep "\n"
|
||
|
(map (x: "rm -rf ${lib.escapeShellArg x}") cfg.cache.directories)}
|
||
|
'';
|
||
|
startAt = cfg.cache.clean.dates;
|
||
|
};
|
||
|
|
||
|
};
|
||
|
}
|