From 3d24d3c5eeb207df8e3481e4ddf8ff19811028d3 Mon Sep 17 00:00:00 2001 From: timeshifter Date: Thu, 25 Nov 2021 15:51:38 +0100 Subject: [PATCH] Command --> get_output_of_command() --- zfs-backup.py | 57 +++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/zfs-backup.py b/zfs-backup.py index 1355376..5e72f29 100755 --- a/zfs-backup.py +++ b/zfs-backup.py @@ -4,6 +4,7 @@ from __future__ import annotations import os +import subprocess from subprocess import Popen, PIPE, check_output import config from sys import exit @@ -16,21 +17,12 @@ Erstes Backup muss für alle notwendigen Datasets durchgeführt werden mit """ -class Command: - def __init__(self, command, strict=True): - process = Popen(command, stdout=PIPE) - self.stdout, self.stderr = process.communicate() - self.exit_code = process.wait() - if strict and self.exit_code != 0: - raise Exception("Kritisches Kommando fehlgeschlagen. Breche ab.") - - def find_backup_pool(): print("Suche nach externer Festplatte für Backups") - present_uuids = Command(["ls", "/dev/disk/by-uuid"]) + present_uuids = get_output_of_command(["ls", "/dev/disk/by-uuid"]) for key in list(config.backup_pool.keys()): uuid = config.backup_pool[key] - if uuid in present_uuids.stdout.decode(): + if uuid in present_uuids: print("Gefundene Platte: " + key) return key else: @@ -46,27 +38,24 @@ class Dataset: @classmethod def from_local_pool(cls) -> list[Dataset]: - datasets_str = ( - Command([config.ZFS, "list", "-H", "-d", "1", "-o", "name", config.local_pool]) - .stdout.strip() - .decode() + datasets_str = get_output_of_command( + [config.ZFS, "list", "-H", "-d", "1", "-o", "name", config.local_pool] ) # we omit the first return value, which is the pool, not the dataset datasets_list = datasets_str.split("\n")[1:] to_backup = [Dataset(d) for d in datasets_list if d not in config.do_not_backup] - print("Folgende Datasets und alle darunter befindlichen Kinder werden gesichert:") + print( + "Folgende Datasets und alle darunter befindlichen Kinder werden gesichert:" + ) for item in to_backup: print(" " + str(item)) return to_backup def get_snapshots(pool): - return ( - Command([config.ZFS, "list", "-r", "-t", "snapshot", "-o", "name", "-H", pool]) - .stdout.strip() - .decode() - .split("\n") - ) + return get_output_of_command( + [config.ZFS, "list", "-r", "-t", "snapshot", "-o", "name", "-H", pool] + ).split() def last_snapshot(pool): @@ -90,9 +79,9 @@ def last_snapshot(pool): def export_pool(pool): container_name = "crypt-" + pool print("Exportiere Pool " + pool) - Command([config.ZPOOL, "export", pool]) + get_output_of_command([config.ZPOOL, "export", pool]) print("Schließe verschlüsselten Container") - Command([config.CRYPTSETUP, "close", container_name]) + get_output_of_command([config.CRYPTSETUP, "close", container_name]) print("Fertig!") print("Sie können die externe Festplatte jetzt entfernen.") @@ -100,7 +89,7 @@ def export_pool(pool): def import_pool(pool): uuid = config.backup_pool[pool] container_name = "crypt-" + pool - present_mappers = Command(["ls", "/dev/mapper/"]).stdout.decode().strip() + present_mappers = get_output_of_command(["ls", "/dev/mapper/"]) if container_name in present_mappers: msg = ( "verschlüsselter Container " @@ -109,12 +98,14 @@ def import_pool(pool): ) raise Exception(msg) print("Öffne verschlüsselten Container\n") - Command([config.CRYPTSETUP, "open", "/dev/disk/by-uuid/" + uuid, container_name]) + get_output_of_command( + [config.CRYPTSETUP, "open", "/dev/disk/by-uuid/" + uuid, container_name] + ) print("") print("Importiere Pool " + pool) # -N: no mount # -d: directory to search the pool in - Command([config.ZPOOL, "import", "-N", "-d", "/dev/mapper", pool]) + get_output_of_command([config.ZPOOL, "import", "-N", "-d", "/dev/mapper", pool]) def present_locally(snapshot): @@ -157,7 +148,9 @@ def do_backup(dataset, last_local_snapshot, last_remote_snapshot, backup_pool): # -d Discard the first element of the sent snapshot's file system name # -F Force a rollback of the file system to the most recent snapshot before performing the receive operation. # -u File system that is associated with the received stream is not mounted. - check_output([config.ZFS, "receive", "-d", "-F", "-u", backup_pool], stdin=send.stdout) + check_output( + [config.ZFS, "receive", "-d", "-F", "-u", backup_pool], stdin=send.stdout + ) exit_code = send.wait() if exit_code != 0: raise Exception("Kritisches Kommando fehlgeschlagen. Breche ab.") @@ -195,6 +188,12 @@ def clean_old_snapshots(dataset, pool): zfs_destroy(to_delete, recursive=True) +def get_output_of_command(cmdline: str | list[str]): + if isinstance(cmdline, str): + cmdline = [cmdline] + return subprocess.check_output(cmdline).strip().decode() + + def zfs_destroy(full_name, recursive=False): if config.local_pool in full_name: msg = "Wollte in falschem Pool löschen! Dies sollte niemals passieren! Abbruch!" @@ -204,7 +203,7 @@ def zfs_destroy(full_name, recursive=False): if recursive: cmdline.append("-r") cmdline.append(full_name) - Command(cmdline) + get_output_of_command(cmdline) def main():