mirror of
https://github.com/nix-community/home-manager
synced 2024-12-24 10:49:48 +01:00
borgmatic: optionally exclude HM symlinks from backup
Co-authored-by: Naïm Favier <n@monade.li> Co-authored-by: Robert Helgesson <robert@rycee.net>
This commit is contained in:
parent
2ddd4e151d
commit
a8f5ca239f
5 changed files with 171 additions and 3 deletions
|
@ -43,7 +43,10 @@ let
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
configModule = types.submodule {
|
configModule = types.submodule ({ config, ... }: {
|
||||||
|
config.location.extraConfig.exclude_from =
|
||||||
|
mkIf config.location.excludeHomeManagerSymlinks
|
||||||
|
(mkAfter [ (toString hmExcludeFile) ]);
|
||||||
options = {
|
options = {
|
||||||
location = {
|
location = {
|
||||||
sourceDirectories = mkOption {
|
sourceDirectories = mkOption {
|
||||||
|
@ -59,6 +62,18 @@ let
|
||||||
literalExpression ''["ssh://myuser@myrepo.myserver.com/./repo"]'';
|
literalExpression ''["ssh://myuser@myrepo.myserver.com/./repo"]'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
excludeHomeManagerSymlinks = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
description = ''
|
||||||
|
Whether to exclude Home Manager generated symbolic links from
|
||||||
|
the backups. This facilitates restoring the whole home
|
||||||
|
directory when the Nix store doesn't contain the latest
|
||||||
|
Home Manager generation.
|
||||||
|
'';
|
||||||
|
default = false;
|
||||||
|
example = true;
|
||||||
|
};
|
||||||
|
|
||||||
extraConfig = extraConfigOption;
|
extraConfig = extraConfigOption;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -120,10 +135,18 @@ let
|
||||||
extraConfig = extraConfigOption;
|
extraConfig = extraConfigOption;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
});
|
||||||
|
|
||||||
removeNullValues = attrSet: filterAttrs (key: value: value != null) attrSet;
|
removeNullValues = attrSet: filterAttrs (key: value: value != null) attrSet;
|
||||||
|
|
||||||
|
hmFiles = builtins.attrValues config.home.file;
|
||||||
|
hmSymlinks = (lib.filter (file: !file.recursive) hmFiles);
|
||||||
|
hmExcludePattern = file: ''
|
||||||
|
${config.home.homeDirectory}/${file.target}
|
||||||
|
'';
|
||||||
|
hmExcludePatterns = lib.concatMapStrings hmExcludePattern hmSymlinks;
|
||||||
|
hmExcludeFile = pkgs.writeText "hm-symlinks.txt" hmExcludePatterns;
|
||||||
|
|
||||||
writeConfig = config:
|
writeConfig = config:
|
||||||
generators.toYAML { } {
|
generators.toYAML { } {
|
||||||
location = removeNullValues {
|
location = removeNullValues {
|
||||||
|
|
|
@ -1 +1,7 @@
|
||||||
{ borgmatic-program-basic-configuration = ./basic-configuration.nix; }
|
{
|
||||||
|
borgmatic-program-basic-configuration = ./basic-configuration.nix;
|
||||||
|
borgmatic-program-include-hm-symlinks = ./include-hm-symlinks.nix;
|
||||||
|
borgmatic-program-exclude-hm-symlinks = ./exclude-hm-symlinks.nix;
|
||||||
|
borgmatic-program-exclude-hm-symlinks-nothing-else =
|
||||||
|
./exclude-hm-symlinks-nothing-else.nix;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
backups = config.programs.borgmatic.backups;
|
||||||
|
excludeFile = pkgs.writeText "excludeFile.txt" "/foo/bar";
|
||||||
|
in {
|
||||||
|
config = {
|
||||||
|
programs.borgmatic = {
|
||||||
|
enable = true;
|
||||||
|
backups = {
|
||||||
|
main = {
|
||||||
|
location = {
|
||||||
|
sourceDirectories = [ "/my-stuff-to-backup" ];
|
||||||
|
repositories = [ "/mnt/disk1" ];
|
||||||
|
excludeHomeManagerSymlinks = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
test.stubs.borgmatic = { };
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
config_file=$TESTED/home-files/.config/borgmatic.d/main.yaml
|
||||||
|
assertFileExists $config_file
|
||||||
|
|
||||||
|
yq=${pkgs.yq-go}/bin/yq
|
||||||
|
|
||||||
|
hmExclusionsFile=$($yq '.location.exclude_from[0]' $config_file)
|
||||||
|
expected_content='/home/hm-user/.config/borgmatic.d/main.yaml'
|
||||||
|
|
||||||
|
grep --quiet "$expected_content" "$hmExclusionsFile"
|
||||||
|
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
echo "Expected to find $expected_content in file $hmExclusionsFile but didn't" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
54
tests/modules/programs/borgmatic/exclude-hm-symlinks.nix
Normal file
54
tests/modules/programs/borgmatic/exclude-hm-symlinks.nix
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
backups = config.programs.borgmatic.backups;
|
||||||
|
excludeFile = pkgs.writeText "excludeFile.txt" "/foo/bar";
|
||||||
|
in {
|
||||||
|
config = {
|
||||||
|
programs.borgmatic = {
|
||||||
|
enable = true;
|
||||||
|
backups = {
|
||||||
|
main = {
|
||||||
|
location = {
|
||||||
|
sourceDirectories = [ "/my-stuff-to-backup" ];
|
||||||
|
repositories = [ "/mnt/disk1" ];
|
||||||
|
excludeHomeManagerSymlinks = true;
|
||||||
|
extraConfig = { exclude_from = [ (toString excludeFile) ]; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
test.stubs.borgmatic = { };
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
config_file=$TESTED/home-files/.config/borgmatic.d/main.yaml
|
||||||
|
assertFileExists $config_file
|
||||||
|
|
||||||
|
declare -A expectations
|
||||||
|
|
||||||
|
expectations[location.exclude_from[0]]="${excludeFile}"
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
hmExclusionsFile=$($yq '.location.exclude_from[1]' $config_file)
|
||||||
|
expected_content='/home/hm-user/.config/borgmatic.d/main.yaml'
|
||||||
|
|
||||||
|
grep --quiet "$expected_content" "$hmExclusionsFile"
|
||||||
|
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
echo "Expected to find $expected_content in file $hmExclusionsFile but didn't" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
45
tests/modules/programs/borgmatic/include-hm-symlinks.nix
Normal file
45
tests/modules/programs/borgmatic/include-hm-symlinks.nix
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
backups = config.programs.borgmatic.backups;
|
||||||
|
excludeFile = pkgs.writeText "excludeFile.txt" "/foo/bar";
|
||||||
|
in {
|
||||||
|
config = {
|
||||||
|
programs.borgmatic = {
|
||||||
|
enable = true;
|
||||||
|
backups = {
|
||||||
|
main = {
|
||||||
|
location = {
|
||||||
|
sourceDirectories = [ "/my-stuff-to-backup" ];
|
||||||
|
repositories = [ "/mnt/disk1" ];
|
||||||
|
excludeHomeManagerSymlinks = false;
|
||||||
|
extraConfig = { exclude_from = [ (toString excludeFile) ]; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
test.stubs.borgmatic = { };
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
config_file=$TESTED/home-files/.config/borgmatic.d/main.yaml
|
||||||
|
assertFileExists $config_file
|
||||||
|
|
||||||
|
declare -A expectations
|
||||||
|
|
||||||
|
expectations[location.exclude_from[0]]="${excludeFile}"
|
||||||
|
|
||||||
|
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