add localbackup provider
This commit is contained in:
@@ -97,12 +97,12 @@ in
|
|||||||
list = ''
|
list = ''
|
||||||
set -efu
|
set -efu
|
||||||
# we need yes here to skip the changed url verification
|
# we need yes here to skip the changed url verification
|
||||||
${
|
(${
|
||||||
lib.concatMapStringsSep "\\\n" (
|
lib.concatMapStringsSep "\n" (
|
||||||
dest:
|
dest:
|
||||||
''yes y | borg-job-${dest.name} list --json | jq '[.archives[] | {"name": ("${dest.repo}::" + .name), "job_name": "${dest.name}"}]' ''
|
''yes y | borg-job-${dest.name} list --json | jq '[.archives[] | {"name": ("${dest.repo}::" + .name), "job_name": "${dest.name}"}]' ''
|
||||||
) (lib.attrValues cfg.destinations)
|
) (lib.attrValues cfg.destinations)
|
||||||
} | jq -s 'add'
|
}) | jq -s 'add'
|
||||||
'';
|
'';
|
||||||
create = ''
|
create = ''
|
||||||
${lib.concatMapStringsSep "\n" (dest: ''
|
${lib.concatMapStringsSep "\n" (dest: ''
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
borgbackup = ./borgbackup.nix;
|
borgbackup = ./borgbackup.nix;
|
||||||
|
localbackup = ./localbackup.nix;
|
||||||
deltachat = ./deltachat.nix;
|
deltachat = ./deltachat.nix;
|
||||||
moonlight = ./moonlight.nix;
|
moonlight = ./moonlight.nix;
|
||||||
sunshine = ./sunshine.nix;
|
sunshine = ./sunshine.nix;
|
||||||
|
|||||||
151
clanModules/localbackup.nix
Normal file
151
clanModules/localbackup.nix
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.clan.localbackup;
|
||||||
|
rsnapshotConfig = target: states: ''
|
||||||
|
config_version 1.2
|
||||||
|
snapshot_root ${target}
|
||||||
|
sync_first 1
|
||||||
|
cmd_cp ${pkgs.coreutils}/bin/cp
|
||||||
|
cmd_rm ${pkgs.coreutils}/bin/rm
|
||||||
|
cmd_rsync ${pkgs.rsync}/bin/rsync
|
||||||
|
cmd_ssh ${pkgs.openssh}/bin/ssh
|
||||||
|
cmd_logger ${pkgs.inetutils}/bin/logger
|
||||||
|
cmd_du ${pkgs.coreutils}/bin/du
|
||||||
|
cmd_rsnapshot_diff ${pkgs.rsnapshot}/bin/rsnapshot-diff
|
||||||
|
retain snapshot ${builtins.toString config.clan.localbackup.snapshots}
|
||||||
|
${lib.concatMapStringsSep "\n" (state: ''
|
||||||
|
${lib.concatMapStringsSep "\n" (folder: ''
|
||||||
|
backup ${folder} ${config.networking.hostName}/
|
||||||
|
'') state.folders}
|
||||||
|
'') states}
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.clan.localbackup = {
|
||||||
|
targets = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf (
|
||||||
|
lib.types.submodule (
|
||||||
|
{ name, ... }:
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
name = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = name;
|
||||||
|
description = "the name of the backup job";
|
||||||
|
};
|
||||||
|
directory = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "the directory to backup";
|
||||||
|
};
|
||||||
|
mountpoint = lib.mkOption {
|
||||||
|
type = lib.types.nullOr (lib.types.strMatching "^[a-zA-Z0-9./_-]+$");
|
||||||
|
default = null;
|
||||||
|
description = "mountpoint of the directory to backup. If set, the directory will be mounted before the backup and unmounted afterwards";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
description = "List of directories where backups are stored";
|
||||||
|
};
|
||||||
|
|
||||||
|
snapshots = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = 20;
|
||||||
|
description = "Number of snapshots to keep";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
setupMount =
|
||||||
|
mountpoint:
|
||||||
|
lib.optionalString (mountpoint != null) ''
|
||||||
|
mkdir -p ${lib.escapeShellArg mountpoint}
|
||||||
|
if mountpoint -q ${lib.escapeShellArg mountpoint}; then
|
||||||
|
umount ${lib.escapeShellArg mountpoint}
|
||||||
|
fi
|
||||||
|
mount ${lib.escapeShellArg mountpoint}
|
||||||
|
trap "umount ${lib.escapeShellArg mountpoint}" EXIT
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
lib.mkIf (cfg.targets != [ ]) {
|
||||||
|
environment.systemPackages = [
|
||||||
|
(pkgs.writeShellScriptBin "localbackup-create" ''
|
||||||
|
set -efu -o pipefail
|
||||||
|
export PATH=${
|
||||||
|
lib.makeBinPath [
|
||||||
|
pkgs.rsnapshot
|
||||||
|
pkgs.coreutils
|
||||||
|
pkgs.util-linux
|
||||||
|
]
|
||||||
|
}
|
||||||
|
${lib.concatMapStringsSep "\n" (target: ''
|
||||||
|
(
|
||||||
|
echo "Creating backup '${target.name}'"
|
||||||
|
${setupMount target.mountpoint}
|
||||||
|
rsnapshot -c "${pkgs.writeText "rsnapshot.conf" (rsnapshotConfig target.directory (lib.attrValues config.clanCore.state))}" sync
|
||||||
|
rsnapshot -c "${pkgs.writeText "rsnapshot.conf" (rsnapshotConfig target.directory (lib.attrValues config.clanCore.state))}" snapshot
|
||||||
|
)
|
||||||
|
'') (builtins.attrValues cfg.targets)}
|
||||||
|
'')
|
||||||
|
(pkgs.writeShellScriptBin "localbackup-list" ''
|
||||||
|
set -efu -o pipefail
|
||||||
|
export PATH=${
|
||||||
|
lib.makeBinPath [
|
||||||
|
pkgs.jq
|
||||||
|
pkgs.findutils
|
||||||
|
pkgs.coreutils
|
||||||
|
pkgs.util-linux
|
||||||
|
]
|
||||||
|
}
|
||||||
|
(${
|
||||||
|
lib.concatMapStringsSep "\n" (target: ''
|
||||||
|
(
|
||||||
|
${setupMount target.mountpoint}
|
||||||
|
find ${lib.escapeShellArg target.directory} -mindepth 1 -maxdepth 1 -name "snapshot.*" -print0 -type d \
|
||||||
|
| jq -Rs 'split("\u0000") | .[] | select(. != "") | { "name": ("${target.mountpoint}::" + .)}'
|
||||||
|
)
|
||||||
|
'') (builtins.attrValues cfg.targets)
|
||||||
|
}) | jq -s .
|
||||||
|
'')
|
||||||
|
(pkgs.writeShellScriptBin "localbackup-restore" ''
|
||||||
|
set -efu -o pipefail
|
||||||
|
export PATH=${
|
||||||
|
lib.makeBinPath [
|
||||||
|
pkgs.rsync
|
||||||
|
pkgs.coreutils
|
||||||
|
pkgs.util-linux
|
||||||
|
pkgs.gawk
|
||||||
|
]
|
||||||
|
}
|
||||||
|
mountpoint=$(awk -F'::' '{print $1}' <<< $NAME)
|
||||||
|
backupname=''${NAME#$mountpoint::}
|
||||||
|
|
||||||
|
mkdir -p "$mountpoint"
|
||||||
|
if mountpoint -q "$mountpoint"; then
|
||||||
|
umount "$mountpoint"
|
||||||
|
fi
|
||||||
|
mount "$mountpoint"
|
||||||
|
trap "umount $mountpoint" EXIT
|
||||||
|
|
||||||
|
IFS=';' read -ra FOLDER <<< "$FOLDERS"
|
||||||
|
for folder in "''${FOLDER[@]}"; do
|
||||||
|
rsync -a "$backupname/${config.networking.hostName}$folder/" "$folder"
|
||||||
|
done
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
|
||||||
|
clanCore.backups.providers.localbackup = {
|
||||||
|
# TODO list needs to run locally or on the remote machine
|
||||||
|
list = "localbackup-list";
|
||||||
|
create = "localbackup-create";
|
||||||
|
restore = "localbackup-restore";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user