fix(download): dump volumes and secrets per default into /tmp/backup.tar.gz
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
Moritz 2023-10-18 14:10:58 +02:00
parent 79d19e7ac5
commit 66e1c9617d

View File

@ -7,6 +7,8 @@ import subprocess
import logging import logging
import docker import docker
import restic import restic
import tarfile
import io
from datetime import datetime, timezone from datetime import datetime, timezone
from restic.errors import ResticFailedError from restic.errors import ResticFailedError
from pathlib import Path from pathlib import Path
@ -235,50 +237,66 @@ def list_files(snapshot, path):
@click.option('volumes', '--volumes', '-v', is_flag=True) @click.option('volumes', '--volumes', '-v', is_flag=True)
@click.option('secrets', '--secrets', '-c', is_flag=True) @click.option('secrets', '--secrets', '-c', is_flag=True)
def download(snapshot, path, volumes, secrets): def download(snapshot, path, volumes, secrets):
if sum(map(bool, [path, volumes, secrets])) != 1: file_dumps = []
logging.error( if not any([path, volumes, secrets]):
"Please specify exactly one of '--path', '--volumes', '--secrets'") volumes = secrets = True
exit(1)
if path: if path:
path = path.removesuffix('/') path = path.removesuffix('/')
binary_output = dump(snapshot, path)
files = list_files(snapshot, path) files = list_files(snapshot, path)
filetype = [f.get('type') for f in files if f.get('path') == path][0] filetype = [f.get('type') for f in files if f.get('path') == path][0]
filename = "/tmp/" + Path(path).name filename = Path(path).name
if filetype == 'dir': if filetype == 'dir':
filename = filename + ".tar" filename = filename + ".tar"
output = dump(snapshot, path) tarinfo = tarfile.TarInfo(name=filename)
with open(filename, "wb") as file: tarinfo.size = len(binary_output)
file.write(output) file_dumps.append((binary_output, tarinfo))
print(filename) if volumes:
elif volumes:
if not SERVICE: if not SERVICE:
logging.error("Please specify '--host' when using '--volumes'") logging.error("Please specify '--host' when using '--volumes'")
exit(1) exit(1)
filename = f"/tmp/{SERVICE}.tar"
files = list_files(snapshot, VOLUME_PATH) files = list_files(snapshot, VOLUME_PATH)
for f in files[1:]: for f in files[1:]:
path = f['path'] path = f['path']
if SERVICE in path and f['type'] == 'dir': if Path(path).name.startswith(SERVICE) and f['type'] == 'dir':
content = dump(snapshot, path) binary_output = dump(snapshot, path)
# Concatenate tar files (extract with tar -xi) filename = f"{Path(path).name}.tar"
with open(filename, "ab") as file: tarinfo = tarfile.TarInfo(name=filename)
file.write(content) tarinfo.size = len(binary_output)
elif secrets: file_dumps.append((binary_output, tarinfo))
if secrets:
if not SERVICE: if not SERVICE:
logging.error("Please specify '--host' when using '--secrets'") logging.error("Please specify '--host' when using '--secrets'")
exit(1) exit(1)
filename = f"/tmp/SECRETS_{SERVICE}.json" filename = f"{SERVICE}.json"
files = list_files(snapshot, SECRET_PATH) files = list_files(snapshot, SECRET_PATH)
secrets = {} secrets = {}
for f in files[1:]: for f in files[1:]:
path = f['path'] path = f['path']
if SERVICE in path and f['type'] == 'file': if Path(path).name.startswith(SERVICE) and f['type'] == 'file':
secret = dump(snapshot, path).decode() secret = dump(snapshot, path).decode()
secret_name = path.removeprefix(f'{SECRET_PATH}{SERVICE}_') secret_name = path.removeprefix(f'{SECRET_PATH}{SERVICE}_')
secrets[secret_name] = secret secrets[secret_name] = secret
with open(filename, "w") as file: binary_output = json.dumps(secrets).encode()
json.dump(secrets, file) tarinfo = tarfile.TarInfo(name=filename)
print(filename) tarinfo.size = len(binary_output)
file_dumps.append((binary_output, tarinfo))
with tarfile.open('/tmp/backup.tar.gz', "w:gz") as tar:
print(f"Writing files to /tmp/backup.tar.gz...")
for binary_output, tarinfo in file_dumps:
tar.addfile(tarinfo, fileobj=io.BytesIO(binary_output))
size = get_formatted_size('/tmp/backup.tar.gz')
print(f"Backup has been written to /tmp/backup.tar.gz with a size of {size}")
def get_formatted_size(file_path):
file_size = os.path.getsize(file_path)
units = ['Bytes', 'KB', 'MB', 'GB', 'TB']
for unit in units:
if file_size < 1024:
return f"{round(file_size, 3)} {unit}"
file_size /= 1024
return f"{round(file_size, 3)} {units[-1]}"
def dump(snapshot, path): def dump(snapshot, path):
@ -286,7 +304,7 @@ def dump(snapshot, path):
if SERVICE: if SERVICE:
cmd = cmd + ['--tag', SERVICE] cmd = cmd + ['--tag', SERVICE]
cmd = cmd + [snapshot, path] cmd = cmd + [snapshot, path]
logging.debug(f"Dumping {path} from snapshot '{snapshot}'") print(f"Dumping {path} from snapshot '{snapshot}'")
output = subprocess.run(cmd, capture_output=True) output = subprocess.run(cmd, capture_output=True)
if output.returncode: if output.returncode:
logging.error( logging.error(