rework backup interface to no longer need to list backups to restore them

This commit is contained in:
Jörg Thalheim 2024-03-20 07:13:01 +01:00
parent f5d32d0b22
commit 92ac151292
3 changed files with 16 additions and 38 deletions

View File

@ -15,7 +15,7 @@ in
{ {
options = { options = {
name = lib.mkOption { name = lib.mkOption {
type = lib.types.str; type = lib.types.strMatching "^[a-zA-Z0-9._-]+$";
default = name; default = name;
description = "the name of the backup job"; description = "the name of the backup job";
}; };
@ -96,11 +96,11 @@ in
# TODO list needs to run locally or on the remote machine # TODO list needs to run locally or on the remote machine
list = '' list = ''
set -efu set -efu
# 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}"}]' '' # we need yes here to skip the changed url verification
''yes y | borg-job-${dest.name} list --json | jq '[.archives[] | {"name": ("${dest.name}::${dest.repo}::" + .name)}]' ''
) (lib.attrValues cfg.destinations) ) (lib.attrValues cfg.destinations)
}) | jq -s 'add' }) | jq -s 'add'
''; '';
@ -114,7 +114,8 @@ in
set -efu set -efu
cd / cd /
IFS=';' read -ra FOLDER <<< "$FOLDERS" IFS=';' read -ra FOLDER <<< "$FOLDERS"
yes y | borg-job-"$JOB_NAME" extract --list "$NAME" "''${FOLDER[@]}" job_name=$(echo "$NAME" | cut -d'::' -f1)
yes y | borg-job-"$job_name" extract --list "$NAME" "''${FOLDER[@]}"
''; '';
}; };
}; };

View File

@ -18,25 +18,21 @@
list = lib.mkOption { list = lib.mkOption {
type = lib.types.str; type = lib.types.str;
description = '' description = ''
script to list backups Command to list backups.
''; '';
}; };
restore = lib.mkOption { restore = lib.mkOption {
type = lib.types.str; type = lib.types.str;
description = '' description = ''
script to restore a backup Command to restore a backup.
should take an optional service name as argument The name of the backup and the folders to restore will be
gets ARCHIVE_ID, LOCATION, JOB and FOLDERS as environment variables set as environment variables NAME and FOLDERS respectively.
ARCHIVE_ID is the id of the backup
LOCATION is the remote identifier of the backup
JOB is the job name of the backup
FOLDERS is a colon separated list of folders to restore
''; '';
}; };
create = lib.mkOption { create = lib.mkOption {
type = lib.types.str; type = lib.types.str;
description = '' description = ''
script to start a backup Command to start a backup
''; '';
}; };
}; };

View File

@ -4,22 +4,16 @@ import subprocess
from ..errors import ClanError from ..errors import ClanError
from ..machines.machines import Machine from ..machines.machines import Machine
from .list import Backup, list_backups
def restore_service( def restore_service(machine: Machine, name: str, provider: str, service: str) -> None:
machine: Machine, backup: Backup, provider: str, service: str
) -> None:
backup_metadata = json.loads(machine.eval_nix("config.clanCore.backups")) backup_metadata = json.loads(machine.eval_nix("config.clanCore.backups"))
backup_folders = json.loads(machine.eval_nix("config.clanCore.state")) backup_folders = json.loads(machine.eval_nix("config.clanCore.state"))
folders = backup_folders[service]["folders"] folders = backup_folders[service]["folders"]
env = {} env = {}
env["NAME"] = backup.name env["NAME"] = name
env["FOLDERS"] = ":".join(folders) env["FOLDERS"] = ":".join(folders)
if backup.job_name is not None:
env["JOB_NAME"] = backup.job_name
proc = machine.target_host.run( proc = machine.target_host.run(
[ [
"bash", "bash",
@ -65,35 +59,22 @@ def restore_service(
def restore_backup( def restore_backup(
machine: Machine, machine: Machine,
backups: list[Backup],
provider: str, provider: str,
name: str, name: str,
service: str | None = None, service: str | None = None,
) -> None: ) -> None:
if service is None: if service is None:
for backup in backups: backup_folders = json.loads(machine.eval_nix("config.clanCore.state"))
if backup.name == name: for _service in backup_folders:
backup_folders = json.loads(machine.eval_nix("config.clanCore.state")) restore_service(machine, name, provider, _service)
for _service in backup_folders:
restore_service(machine, backup, provider, _service)
break
else:
raise ClanError(f"backup {name} not found")
else: else:
for backup in backups: restore_service(machine, name, provider, service)
if backup.name == name:
restore_service(machine, backup, provider, service)
break
else:
raise ClanError(f"backup {name} not found")
def restore_command(args: argparse.Namespace) -> None: def restore_command(args: argparse.Namespace) -> None:
machine = Machine(name=args.machine, flake=args.flake) machine = Machine(name=args.machine, flake=args.flake)
backups = list_backups(machine=machine, provider=args.provider)
restore_backup( restore_backup(
machine=machine, machine=machine,
backups=backups,
provider=args.provider, provider=args.provider,
name=args.name, name=args.name,
service=args.service, service=args.service,