nixos/btrbk: inherit lib functions to simplify use-sites
This commit is contained in:
parent
60e13131b6
commit
085a5256c1
|
@ -1,18 +1,36 @@
|
||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
let
|
let
|
||||||
|
inherit (lib)
|
||||||
|
concatMapStringsSep
|
||||||
|
concatStringsSep
|
||||||
|
filterAttrs
|
||||||
|
flatten
|
||||||
|
isAttrs
|
||||||
|
isString
|
||||||
|
literalExpression
|
||||||
|
mapAttrs'
|
||||||
|
mapAttrsToList
|
||||||
|
mkIf
|
||||||
|
mkOption
|
||||||
|
optionalString
|
||||||
|
partition
|
||||||
|
typeOf
|
||||||
|
types
|
||||||
|
;
|
||||||
|
|
||||||
cfg = config.services.btrbk;
|
cfg = config.services.btrbk;
|
||||||
sshEnabled = cfg.sshAccess != [ ];
|
sshEnabled = cfg.sshAccess != [ ];
|
||||||
serviceEnabled = cfg.instances != { };
|
serviceEnabled = cfg.instances != { };
|
||||||
attr2Lines = attr:
|
attr2Lines = attr:
|
||||||
let
|
let
|
||||||
pairs = lib.attrsets.mapAttrsToList (name: value: { inherit name value; }) attr;
|
pairs = mapAttrsToList (name: value: { inherit name value; }) attr;
|
||||||
isSubsection = value:
|
isSubsection = value:
|
||||||
if builtins.isAttrs value then true
|
if isAttrs value then true
|
||||||
else if builtins.isString value then false
|
else if isString value then false
|
||||||
else throw "invalid type in btrbk config ${builtins.typeOf value}";
|
else throw "invalid type in btrbk config ${typeOf value}";
|
||||||
sortedPairs = lib.lists.partition (x: isSubsection x.value) pairs;
|
sortedPairs = partition (x: isSubsection x.value) pairs;
|
||||||
in
|
in
|
||||||
lib.flatten (
|
flatten (
|
||||||
# non subsections go first
|
# non subsections go first
|
||||||
(
|
(
|
||||||
map (pair: [ "${pair.name} ${pair.value}" ]) sortedPairs.wrong
|
map (pair: [ "${pair.name} ${pair.value}" ]) sortedPairs.wrong
|
||||||
|
@ -22,7 +40,7 @@ let
|
||||||
map
|
map
|
||||||
(
|
(
|
||||||
pair:
|
pair:
|
||||||
lib.mapAttrsToList
|
mapAttrsToList
|
||||||
(
|
(
|
||||||
childname: value:
|
childname: value:
|
||||||
[ "${pair.name} ${childname}" ] ++ (map (x: " " + x) (attr2Lines value))
|
[ "${pair.name} ${childname}" ] ++ (map (x: " " + x) (attr2Lines value))
|
||||||
|
@ -34,7 +52,7 @@ let
|
||||||
)
|
)
|
||||||
;
|
;
|
||||||
addDefaults = settings: { backend = "btrfs-progs-sudo"; } // settings;
|
addDefaults = settings: { backend = "btrfs-progs-sudo"; } // settings;
|
||||||
mkConfigFile = settings: lib.concatStringsSep "\n" (attr2Lines (addDefaults settings));
|
mkConfigFile = settings: concatStringsSep "\n" (attr2Lines (addDefaults settings));
|
||||||
mkTestedConfigFile = name: settings:
|
mkTestedConfigFile = name: settings:
|
||||||
let
|
let
|
||||||
configFile = pkgs.writeText "btrbk-${name}.conf" (mkConfigFile settings);
|
configFile = pkgs.writeText "btrbk-${name}.conf" (mkConfigFile settings);
|
||||||
|
@ -55,38 +73,38 @@ in
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
services.btrbk = {
|
services.btrbk = {
|
||||||
extraPackages = lib.mkOption {
|
extraPackages = mkOption {
|
||||||
description = "Extra packages for btrbk, like compression utilities for <literal>stream_compress</literal>";
|
description = "Extra packages for btrbk, like compression utilities for <literal>stream_compress</literal>";
|
||||||
type = lib.types.listOf lib.types.package;
|
type = types.listOf types.package;
|
||||||
default = [ ];
|
default = [ ];
|
||||||
example = lib.literalExpression "[ pkgs.xz ]";
|
example = literalExpression "[ pkgs.xz ]";
|
||||||
};
|
};
|
||||||
niceness = lib.mkOption {
|
niceness = mkOption {
|
||||||
description = "Niceness for local instances of btrbk. Also applies to remote ones connecting via ssh when positive.";
|
description = "Niceness for local instances of btrbk. Also applies to remote ones connecting via ssh when positive.";
|
||||||
type = lib.types.ints.between (-20) 19;
|
type = types.ints.between (-20) 19;
|
||||||
default = 10;
|
default = 10;
|
||||||
};
|
};
|
||||||
ioSchedulingClass = lib.mkOption {
|
ioSchedulingClass = mkOption {
|
||||||
description = "IO scheduling class for btrbk (see ionice(1) for a quick description). Applies to local instances, and remote ones connecting by ssh if set to idle.";
|
description = "IO scheduling class for btrbk (see ionice(1) for a quick description). Applies to local instances, and remote ones connecting by ssh if set to idle.";
|
||||||
type = lib.types.enum [ "idle" "best-effort" "realtime" ];
|
type = types.enum [ "idle" "best-effort" "realtime" ];
|
||||||
default = "best-effort";
|
default = "best-effort";
|
||||||
};
|
};
|
||||||
instances = lib.mkOption {
|
instances = mkOption {
|
||||||
description = "Set of btrbk instances. The instance named <literal>btrbk</literal> is the default one.";
|
description = "Set of btrbk instances. The instance named <literal>btrbk</literal> is the default one.";
|
||||||
type = with lib.types;
|
type = with types;
|
||||||
attrsOf (
|
attrsOf (
|
||||||
submodule {
|
submodule {
|
||||||
options = {
|
options = {
|
||||||
onCalendar = lib.mkOption {
|
onCalendar = mkOption {
|
||||||
type = lib.types.nullOr lib.types.str;
|
type = types.nullOr types.str;
|
||||||
default = "daily";
|
default = "daily";
|
||||||
description = ''
|
description = ''
|
||||||
How often this btrbk instance is started. See systemd.time(7) for more information about the format.
|
How often this btrbk instance is started. See systemd.time(7) for more information about the format.
|
||||||
Setting it to null disables the timer, thus this instance can only be started manually.
|
Setting it to null disables the timer, thus this instance can only be started manually.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
settings = lib.mkOption {
|
settings = mkOption {
|
||||||
type = let t = lib.types.attrsOf (lib.types.either lib.types.str (t // { description = "instances of this type recursively"; })); in t;
|
type = let t = types.attrsOf (types.either types.str (t // { description = "instances of this type recursively"; })); in t;
|
||||||
default = { };
|
default = { };
|
||||||
example = {
|
example = {
|
||||||
snapshot_preserve_min = "2d";
|
snapshot_preserve_min = "2d";
|
||||||
|
@ -108,16 +126,16 @@ in
|
||||||
);
|
);
|
||||||
default = { };
|
default = { };
|
||||||
};
|
};
|
||||||
sshAccess = lib.mkOption {
|
sshAccess = mkOption {
|
||||||
description = "SSH keys that should be able to make or push snapshots on this system remotely with btrbk";
|
description = "SSH keys that should be able to make or push snapshots on this system remotely with btrbk";
|
||||||
type = with lib.types; listOf (
|
type = with types; listOf (
|
||||||
submodule {
|
submodule {
|
||||||
options = {
|
options = {
|
||||||
key = lib.mkOption {
|
key = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
description = "SSH public key allowed to login as user <literal>btrbk</literal> to run remote backups.";
|
description = "SSH public key allowed to login as user <literal>btrbk</literal> to run remote backups.";
|
||||||
};
|
};
|
||||||
roles = lib.mkOption {
|
roles = mkOption {
|
||||||
type = listOf (enum [ "info" "source" "target" "delete" "snapshot" "send" "receive" ]);
|
type = listOf (enum [ "info" "source" "target" "delete" "snapshot" "send" "receive" ]);
|
||||||
example = [ "source" "info" "send" ];
|
example = [ "source" "info" "send" ];
|
||||||
description = "What actions can be performed with this SSH key. See ssh_filter_btrbk(1) for details";
|
description = "What actions can be performed with this SSH key. See ssh_filter_btrbk(1) for details";
|
||||||
|
@ -130,7 +148,7 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
config = lib.mkIf (sshEnabled || serviceEnabled) {
|
config = mkIf (sshEnabled || serviceEnabled) {
|
||||||
environment.systemPackages = [ pkgs.btrbk ] ++ cfg.extraPackages;
|
environment.systemPackages = [ pkgs.btrbk ] ++ cfg.extraPackages;
|
||||||
security.sudo.extraRules = [
|
security.sudo.extraRules = [
|
||||||
{
|
{
|
||||||
|
@ -157,14 +175,14 @@ in
|
||||||
(
|
(
|
||||||
v:
|
v:
|
||||||
let
|
let
|
||||||
options = lib.concatMapStringsSep " " (x: "--" + x) v.roles;
|
options = concatMapStringsSep " " (x: "--" + x) v.roles;
|
||||||
ioniceClass = {
|
ioniceClass = {
|
||||||
"idle" = 3;
|
"idle" = 3;
|
||||||
"best-effort" = 2;
|
"best-effort" = 2;
|
||||||
"realtime" = 1;
|
"realtime" = 1;
|
||||||
}.${cfg.ioSchedulingClass};
|
}.${cfg.ioSchedulingClass};
|
||||||
in
|
in
|
||||||
''command="${pkgs.util-linux}/bin/ionice -t -c ${toString ioniceClass} ${lib.optionalString (cfg.niceness >= 1) "${pkgs.coreutils}/bin/nice -n ${toString cfg.niceness}"} ${pkgs.btrbk}/share/btrbk/scripts/ssh_filter_btrbk.sh --sudo ${options}" ${v.key}''
|
''command="${pkgs.util-linux}/bin/ionice -t -c ${toString ioniceClass} ${optionalString (cfg.niceness >= 1) "${pkgs.coreutils}/bin/nice -n ${toString cfg.niceness}"} ${pkgs.btrbk}/share/btrbk/scripts/ssh_filter_btrbk.sh --sudo ${options}" ${v.key}''
|
||||||
)
|
)
|
||||||
cfg.sshAccess;
|
cfg.sshAccess;
|
||||||
};
|
};
|
||||||
|
@ -174,7 +192,7 @@ in
|
||||||
"d /var/lib/btrbk/.ssh 0700 btrbk btrbk"
|
"d /var/lib/btrbk/.ssh 0700 btrbk btrbk"
|
||||||
"f /var/lib/btrbk/.ssh/config 0700 btrbk btrbk - StrictHostKeyChecking=accept-new"
|
"f /var/lib/btrbk/.ssh/config 0700 btrbk btrbk - StrictHostKeyChecking=accept-new"
|
||||||
];
|
];
|
||||||
environment.etc = lib.mapAttrs'
|
environment.etc = mapAttrs'
|
||||||
(
|
(
|
||||||
name: instance: {
|
name: instance: {
|
||||||
name = "btrbk/${name}.conf";
|
name = "btrbk/${name}.conf";
|
||||||
|
@ -182,7 +200,7 @@ in
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
cfg.instances;
|
cfg.instances;
|
||||||
systemd.services = lib.mapAttrs'
|
systemd.services = mapAttrs'
|
||||||
(
|
(
|
||||||
name: _: {
|
name: _: {
|
||||||
name = "btrbk-${name}";
|
name = "btrbk-${name}";
|
||||||
|
@ -204,7 +222,7 @@ in
|
||||||
)
|
)
|
||||||
cfg.instances;
|
cfg.instances;
|
||||||
|
|
||||||
systemd.timers = lib.mapAttrs'
|
systemd.timers = mapAttrs'
|
||||||
(
|
(
|
||||||
name: instance: {
|
name: instance: {
|
||||||
name = "btrbk-${name}";
|
name = "btrbk-${name}";
|
||||||
|
@ -219,7 +237,7 @@ in
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
(lib.filterAttrs (name: instance: instance.onCalendar != null)
|
(filterAttrs (name: instance: instance.onCalendar != null)
|
||||||
cfg.instances);
|
cfg.instances);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue