···
{ config, pkgs, lib, ... }:
21
-
cfg = config.services.btrbk;
22
-
sshEnabled = cfg.sshAccess != [ ];
23
-
serviceEnabled = cfg.instances != { };
20
+
# The priority of an option or section.
21
+
# The configurations format are order-sensitive. Pairs are added as children of
22
+
# the last sections if possible, otherwise, they start a new section.
23
+
# We sort them in topological order:
25
+
# 2. Sections that may contain (1).
26
+
# 3. Sections that may contain (1) or (2).
28
+
prioOf = { name, value }:
29
+
if !isAttrs value then 0 # Leaf options.
31
+
target = 1; # Contains: options.
32
+
subvolume = 2; # Contains: options, target.
33
+
volume = 3; # Contains: options, target, subvolume.
34
+
}.${name} or (throw "Unknow section '${name}'");
36
+
genConfig' = set: concatStringsSep "\n" (genConfig set);
26
-
pairs = mapAttrsToList (name: value: { inherit name value; }) attr;
27
-
isSubsection = value:
28
-
if isAttrs value then true
29
-
else if isString value then false
30
-
else throw "invalid type in btrbk config ${typeOf value}";
31
-
sortedPairs = partition (x: isSubsection x.value) pairs;
39
+
pairs = mapAttrsToList (name: value: { inherit name value; }) set;
40
+
sortedPairs = sort (a: b: prioOf a < prioOf b) pairs;
34
-
# non subsections go first
36
-
map (pair: [ "${pair.name} ${pair.value}" ]) sortedPairs.wrong
38
-
++ # subsections go last
46
-
[ "${pair.name} ${childname}" ] ++ (map (x: " " + x) (attr2Lines value))
42
+
concatMap genPair sortedPairs;
43
+
genSection = sec: secName: value:
44
+
[ "${sec} ${secName}" ] ++ map (x: " " + x) (genConfig value);
45
+
genPair = { name, value }:
47
+
then [ "${name} ${value}" ]
48
+
else concatLists (mapAttrsToList (genSection name) value);
addDefaults = settings: { backend = "btrfs-progs-sudo"; } // settings;
55
-
mkConfigFile = settings: concatStringsSep "\n" (attr2Lines (addDefaults settings));
56
-
mkTestedConfigFile = name: settings:
58
-
configFile = pkgs.writeText "btrbk-${name}.conf" (mkConfigFile settings);
60
-
pkgs.runCommand "btrbk-${name}-tested.conf" { } ''
62
-
cp ${configFile} $out
63
-
if (set +o pipefail; ${pkgs.btrbk}/bin/btrbk -c $out ls foo 2>&1 | grep $out);
65
-
echo btrbk configuration is invalid
52
+
mkConfigFile = name: settings: pkgs.writeTextFile {
53
+
name = "btrbk-${name}.conf";
54
+
text = genConfig' (addDefaults settings);
57
+
${pkgs.btrbk}/bin/btrbk -c $out dryrun
58
+
# According to btrbk(1), exit status 2 means parse error
59
+
# for CLI options or the config file.
60
+
if [[ $? == 2 ]]; then
61
+
echo "Btrbk configuration is invalid:"
69
+
cfg = config.services.btrbk;
70
+
sshEnabled = cfg.sshAccess != [ ];
71
+
serviceEnabled = cfg.instances != { };
meta.maintainers = with lib.maintainers; [ oxalica ];
···
name = "btrbk/${name}.conf";
199
-
value.source = mkTestedConfigFile name instance.settings;
201
+
value.source = mkConfigFile name instance.settings;