main
 1{
 2  den,
 3  lib,
 4  ...
 5}: let
 6  # A single preserved file or directory entry, shaped like
 7  # `preservation.preserveAt."/…".files` / `.directories` entries.
 8  # Declared fields are checked, unknown fields pass through.
 9  mkEntryType = kind:
10    lib.types.submodule {
11      freeformType = lib.types.attrsOf lib.types.anything;
12      options.${kind} = lib.mkOption {
13        type = lib.types.str;
14      };
15    };
16
17  directoryEntry = mkEntryType "directory";
18  fileEntry = mkEntryType "file";
19
20  # Carrier options in the shape of `preservation.preserveAt."/…".users.*`:
21  #
22  #   persistence."<name>" = {
23  #     directories = [ … ];
24  #     files = [ … ];
25  #   };
26  persistenceOptions = lib.types.attrsOf (lib.types.submodule {
27    options = {
28      directories = lib.mkOption {
29        type = lib.types.listOf (lib.types.coercedTo lib.types.str (d: {directory = d;}) directoryEntry);
30        default = [];
31      };
32      files = lib.mkOption {
33        type = lib.types.listOf (lib.types.coercedTo lib.types.str (f: {file = f;}) fileEntry);
34        default = [];
35      };
36    };
37  });
38in {
39  flake-file.inputs.preservation = {
40    url = "github:nix-community/preservation";
41  };
42
43  den.aspects.disk.preservation = let
44    homeFiles = {
45      files = [
46        ".bash_history"
47      ];
48    };
49  in {
50    includes = with den.aspects.disk.preservation; [
51      persist-collector
52
53      btrfs
54    ];
55
56    persist = {
57      directories = [
58        "/etc/NetworkManager/system-connections"
59      ];
60      files = [
61        "/root/.bash_history"
62      ];
63    };
64    cache = {
65      directories = [
66        "/var/lib/nixos"
67        "/srv"
68      ];
69    };
70    persistHome = homeFiles;
71
72    provides.to-users = {
73      # Re-emit persistHome at user scopes: the aspect itself only runs at
74      # host scope, so its own `persistHome` attribute alone would not land.
75      persistHome = homeFiles;
76
77      hjem = {lib, ...}: {
78        options.environment.persistence = lib.mkOption {
79          type = persistenceOptions;
80          default = {};
81          description = ''
82            Preservation-shaped persistence carriers for this hjem user,
83            translated into `preservation.preserveAt` on the host.
84          '';
85        };
86
87        config = {
88          environment.persistence.persist = {};
89          environment.persistence.cache = {};
90        };
91      };
92    };
93  };
94}