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