diff --git a/backupbot.py b/backupbot.py index 0f4286c..47f48b4 100755 --- a/backupbot.py +++ b/backupbot.py @@ -195,7 +195,10 @@ def ls(snapshot, path): def list_files(snapshot, path): - cmd = restic.cat.base_command() + ['ls', snapshot] + cmd = restic.cat.base_command() + ['ls'] + if SERVICE: + cmd = cmd + ['--tag', SERVICE] + cmd.append(snapshot) if path: cmd.append(path) output = restic.internal.command_executor.execute(cmd) @@ -207,18 +210,63 @@ def list_files(snapshot, path): @cli.command() @click.option('snapshot', '--snapshot', '-s', envvar='SNAPSHOT', default='latest') @click.option('path', '--path', '-p', envvar='INCLUDE_PATH') -def download(snapshot, path): - path = path.removesuffix('/') - files = list_files(snapshot, path) - filetype = [f.get('type') for f in files if f.get('path') == path][0] - cmd = restic.cat.base_command() + ['dump', snapshot, path] - output = subprocess.run(cmd, capture_output=True).stdout - filename = "/tmp/" + Path(path).name - if filetype == 'dir': - filename = filename + ".tar" - with open(filename, "wb") as file: - file.write(output) - print(filename) +@click.option('volumes', '--volumes', '-v', is_flag=True) +@click.option('secrets', '--secrets', '-c', is_flag=True) +def download(snapshot, path, volumes, secrets): + if sum(map(bool, [path, volumes, secrets])) != 1: + logging.error("Please specify exactly one of '--path', '--volumes', '--secrets'") + exit(1) + if path: + path = path.removesuffix('/') + files = list_files(snapshot, path) + filetype = [f.get('type') for f in files if f.get('path') == path][0] + filename = "/tmp/" + Path(path).name + if filetype == 'dir': + filename = filename + ".tar" + output = dump(snapshot, path) + with open(filename, "wb") as file: + file.write(output) + print(filename) + elif volumes: + if not SERVICE: + logging.error("Please specify '--host' when using '--volumes'") + exit(1) + filename = f"/tmp/{SERVICE}.tar" + files = list_files(snapshot, VOLUME_PATH) + for f in files[1:]: + path = f[ 'path' ] + if SERVICE in path and f['type'] == 'dir': + content = dump(snapshot, path) + # Concatenate tar files (extract with tar -xi) + with open(filename, "ab") as file: + file.write(content) + elif secrets: + if not SERVICE: + logging.error("Please specify '--host' when using '--secrets'") + exit(1) + filename = f"/tmp/SECRETS_{SERVICE}.json" + files = list_files(snapshot, SECRET_PATH) + secrets = {} + for f in files[1:]: + path = f[ 'path' ] + if SERVICE in path and f['type'] == 'file': + secret = dump(snapshot, path).decode() + secrets[path.removeprefix(SERVICE)] = secret + with open(filename, "w") as file: + json.dump(secrets, file) + print(filename) + +def dump(snapshot, path): + cmd = restic.cat.base_command() + ['dump'] + if SERVICE: + cmd = cmd + ['--tag', SERVICE] + cmd = cmd +[snapshot, path] + logging.debug(f"Dumping {path} from snapshot '{snapshot}'") + output = subprocess.run(cmd, capture_output=True) + if output.returncode: + logging.error(f"error while dumping {path} from snapshot '{snapshot}': {output.stderr}") + exit(1) + return output.stdout if __name__ == '__main__':