{ config, lib, inputs, ... }: let cfg = config.persist; takeAll = what: concatMap (x: x.${what}); persists = with cfg; [ state cache ]; absoluteHomePath = 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 or "/home/${config.mainuser}"; in { options = let inherit (lib) mkOption mkEnableOption; inherit (lib.types) listOf path str; common = { directories = mkOption { type = listOf str; default = [ ]; }; files = mkOption { type = listOf str; default = [ ]; }; homeFiles = mkOption { type = listOf str; default = [ ]; }; homeDirectories = 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 = homeDirectory; }; # Stuff that matters # TODO backups of this stuff state = { # backup = {...}; } // 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} = { hideMounts = true; directories = allDirectories; files = allFiles; users.${config.mainuser} = { home = "/home/${config.mainuser}"; directories = allHomeDirectories; files = allHomeFiles; }; }; 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 ++ absoluteHomePath cfg.cache.homeFiles))} ${builtins.concatStringsSep "\n" (map (x: "rm -rf ${lib.escapeShellArg x}") (cfg.cache.directories ++ absoluteHomePath cfg.cache.homeDirectories))} ''; startAt = cfg.cache.clean.dates; }; }; }