mirror of
https://github.com/nix-community/home-manager
synced 2024-11-14 07:09:45 +01:00
borgmatic: add option for pattern matching
Borgmatic has support for Borg's pattern matching. It is mutually exclusive with the existing `sourceDirectories` option, so assertions have been added to make sure that both are not set at the same time (but also that at least one of them is). Additionally, tests have been added to test the following configurations: `patterns` instead of `sourceDirectories`, both at the same time, and neither.
This commit is contained in:
parent
2d44ac2a82
commit
f16e7b5824
5 changed files with 150 additions and 3 deletions
|
@ -76,12 +76,39 @@ let
|
||||||
(mkAfter [ (toString hmExcludeFile) ]);
|
(mkAfter [ (toString hmExcludeFile) ]);
|
||||||
options = {
|
options = {
|
||||||
location = {
|
location = {
|
||||||
sourceDirectories = mkOption {
|
sourceDirectories = mkNullableOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
description = "Directories to backup.";
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Directories to backup.
|
||||||
|
|
||||||
|
Mutually exclusive with [](#opt-programs.borgmatic.backups._name_.location.patterns).
|
||||||
|
'';
|
||||||
example = literalExpression "[config.home.homeDirectory]";
|
example = literalExpression "[config.home.homeDirectory]";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
patterns = mkNullableOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Patterns to include/exclude.
|
||||||
|
|
||||||
|
See the output of `borg help patterns` for the syntax. Pattern paths
|
||||||
|
are relative to `/` even when a different recursion root is set.
|
||||||
|
|
||||||
|
Mutually exclusive with [](#opt-programs.borgmatic.backups._name_.location.sourceDirectories).
|
||||||
|
'';
|
||||||
|
example = literalExpression ''
|
||||||
|
[
|
||||||
|
"R /home/user"
|
||||||
|
"- home/user/.cache"
|
||||||
|
"- home/user/Downloads"
|
||||||
|
"+ home/user/Videos/Important Video"
|
||||||
|
"- home/user/Videos"
|
||||||
|
]
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
repositories = mkOption {
|
repositories = mkOption {
|
||||||
type = types.listOf (types.either types.str repositoryOption);
|
type = types.listOf (types.either types.str repositoryOption);
|
||||||
apply = cleanRepositories;
|
apply = cleanRepositories;
|
||||||
|
@ -194,6 +221,7 @@ let
|
||||||
writeConfig = config:
|
writeConfig = config:
|
||||||
generators.toYAML { } (removeNullValues ({
|
generators.toYAML { } (removeNullValues ({
|
||||||
source_directories = config.location.sourceDirectories;
|
source_directories = config.location.sourceDirectories;
|
||||||
|
patterns = config.location.patterns;
|
||||||
repositories = config.location.repositories;
|
repositories = config.location.repositories;
|
||||||
encryption_passcommand = config.storage.encryptionPasscommand;
|
encryption_passcommand = config.storage.encryptionPasscommand;
|
||||||
keep_within = config.retention.keepWithin;
|
keep_within = config.retention.keepWithin;
|
||||||
|
@ -247,7 +275,19 @@ in {
|
||||||
assertions = [
|
assertions = [
|
||||||
(lib.hm.assertions.assertPlatform "programs.borgmatic" pkgs
|
(lib.hm.assertions.assertPlatform "programs.borgmatic" pkgs
|
||||||
lib.platforms.linux)
|
lib.platforms.linux)
|
||||||
];
|
] ++ (mapAttrsToList (backup: opts: {
|
||||||
|
assertion = opts.location.sourceDirectories == null
|
||||||
|
|| opts.location.patterns == null;
|
||||||
|
message = ''
|
||||||
|
Borgmatic backup configuration "${backup}" cannot specify both 'location.sourceDirectories' and 'location.patterns'.
|
||||||
|
'';
|
||||||
|
}) cfg.backups) ++ (mapAttrsToList (backup: opts: {
|
||||||
|
assertion = !(opts.location.sourceDirectories == null
|
||||||
|
&& opts.location.patterns == null);
|
||||||
|
message = ''
|
||||||
|
Borgmatic backup configuration "${backup}" must specify one of 'location.sourceDirectories' or 'location.patterns'.
|
||||||
|
'';
|
||||||
|
}) cfg.backups);
|
||||||
|
|
||||||
xdg.configFile = with lib.attrsets;
|
xdg.configFile = with lib.attrsets;
|
||||||
mapAttrs' (configName: config:
|
mapAttrs' (configName: config:
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
backups = config.programs.borgmatic.backups;
|
||||||
|
|
||||||
|
in {
|
||||||
|
programs.borgmatic = {
|
||||||
|
enable = true;
|
||||||
|
backups = {
|
||||||
|
main = {
|
||||||
|
location = {
|
||||||
|
sourceDirectories = [ "/my-stuff-to-backup" ];
|
||||||
|
patterns = [ "R /" "+ my-stuff-to-backup" ];
|
||||||
|
repositories = [ "/mnt/disk1" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
test.stubs.borgmatic = { };
|
||||||
|
|
||||||
|
test.asserts.assertions.expected = [''
|
||||||
|
Borgmatic backup configuration "main" cannot specify both 'location.sourceDirectories' and 'location.patterns'.
|
||||||
|
''];
|
||||||
|
}
|
|
@ -1,5 +1,10 @@
|
||||||
{
|
{
|
||||||
borgmatic-program-basic-configuration = ./basic-configuration.nix;
|
borgmatic-program-basic-configuration = ./basic-configuration.nix;
|
||||||
|
borgmatic-program-patterns-configuration = ./patterns-configuration.nix;
|
||||||
|
borgmatic-program-both-sourcedirectories-and-patterns =
|
||||||
|
./both-sourcedirectories-and-patterns.nix;
|
||||||
|
borgmatic-program-neither-sourcedirectories-nor-patterns =
|
||||||
|
./neither-sourcedirectories-nor-patterns.nix;
|
||||||
borgmatic-program-include-hm-symlinks = ./include-hm-symlinks.nix;
|
borgmatic-program-include-hm-symlinks = ./include-hm-symlinks.nix;
|
||||||
borgmatic-program-exclude-hm-symlinks = ./exclude-hm-symlinks.nix;
|
borgmatic-program-exclude-hm-symlinks = ./exclude-hm-symlinks.nix;
|
||||||
borgmatic-program-exclude-hm-symlinks-nothing-else =
|
borgmatic-program-exclude-hm-symlinks-nothing-else =
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
backups = config.programs.borgmatic.backups;
|
||||||
|
|
||||||
|
in {
|
||||||
|
programs.borgmatic = {
|
||||||
|
enable = true;
|
||||||
|
backups = { main = { location = { repositories = [ "/mnt/disk1" ]; }; }; };
|
||||||
|
};
|
||||||
|
|
||||||
|
test.stubs.borgmatic = { };
|
||||||
|
|
||||||
|
test.asserts.assertions.expected = [''
|
||||||
|
Borgmatic backup configuration "main" must specify one of 'location.sourceDirectories' or 'location.patterns'.
|
||||||
|
''];
|
||||||
|
}
|
58
tests/modules/programs/borgmatic/patterns-configuration.nix
Normal file
58
tests/modules/programs/borgmatic/patterns-configuration.nix
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
boolToString = bool: if bool then "true" else "false";
|
||||||
|
backups = config.programs.borgmatic.backups;
|
||||||
|
|
||||||
|
in {
|
||||||
|
programs.borgmatic = {
|
||||||
|
enable = true;
|
||||||
|
backups = {
|
||||||
|
main = {
|
||||||
|
location = {
|
||||||
|
patterns = [
|
||||||
|
"R /home/user"
|
||||||
|
"+ home/user/stuff-to-backup"
|
||||||
|
"+ home/user/junk/important-file"
|
||||||
|
"- home/user/junk"
|
||||||
|
];
|
||||||
|
repositories = [ "/mnt/backup-drive" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
test.stubs.borgmatic = { };
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
config_file=$TESTED/home-files/.config/borgmatic.d/main.yaml
|
||||||
|
assertFileExists $config_file
|
||||||
|
|
||||||
|
declare -A expectations
|
||||||
|
|
||||||
|
expectations[patterns[0]]="${
|
||||||
|
builtins.elemAt backups.main.location.patterns 0
|
||||||
|
}"
|
||||||
|
expectations[patterns[1]]="${
|
||||||
|
builtins.elemAt backups.main.location.patterns 1
|
||||||
|
}"
|
||||||
|
expectations[patterns[2]]="${
|
||||||
|
builtins.elemAt backups.main.location.patterns 2
|
||||||
|
}"
|
||||||
|
expectations[patterns[3]]="${
|
||||||
|
builtins.elemAt backups.main.location.patterns 3
|
||||||
|
}"
|
||||||
|
|
||||||
|
yq=${pkgs.yq-go}/bin/yq
|
||||||
|
|
||||||
|
for filter in "''${!expectations[@]}"; do
|
||||||
|
expected_value="''${expectations[$filter]}"
|
||||||
|
actual_value="$($yq ".$filter" $config_file)"
|
||||||
|
|
||||||
|
if [[ "$actual_value" != "$expected_value" ]]; then
|
||||||
|
fail "Expected '$filter' to be '$expected_value' but was '$actual_value'"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
}
|
Loading…
Reference in a new issue