Command --> get_output_of_command()
This commit is contained in:
+28
-29
@@ -4,6 +4,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import subprocess
|
||||||
from subprocess import Popen, PIPE, check_output
|
from subprocess import Popen, PIPE, check_output
|
||||||
import config
|
import config
|
||||||
from sys import exit
|
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():
|
def find_backup_pool():
|
||||||
print("Suche nach externer Festplatte für Backups")
|
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()):
|
for key in list(config.backup_pool.keys()):
|
||||||
uuid = config.backup_pool[key]
|
uuid = config.backup_pool[key]
|
||||||
if uuid in present_uuids.stdout.decode():
|
if uuid in present_uuids:
|
||||||
print("Gefundene Platte: " + key)
|
print("Gefundene Platte: " + key)
|
||||||
return key
|
return key
|
||||||
else:
|
else:
|
||||||
@@ -46,27 +38,24 @@ class Dataset:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_local_pool(cls) -> list[Dataset]:
|
def from_local_pool(cls) -> list[Dataset]:
|
||||||
datasets_str = (
|
datasets_str = get_output_of_command(
|
||||||
Command([config.ZFS, "list", "-H", "-d", "1", "-o", "name", config.local_pool])
|
[config.ZFS, "list", "-H", "-d", "1", "-o", "name", config.local_pool]
|
||||||
.stdout.strip()
|
|
||||||
.decode()
|
|
||||||
)
|
)
|
||||||
# we omit the first return value, which is the pool, not the dataset
|
# we omit the first return value, which is the pool, not the dataset
|
||||||
datasets_list = datasets_str.split("\n")[1:]
|
datasets_list = datasets_str.split("\n")[1:]
|
||||||
to_backup = [Dataset(d) for d in datasets_list if d not in config.do_not_backup]
|
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:
|
for item in to_backup:
|
||||||
print(" " + str(item))
|
print(" " + str(item))
|
||||||
return to_backup
|
return to_backup
|
||||||
|
|
||||||
|
|
||||||
def get_snapshots(pool):
|
def get_snapshots(pool):
|
||||||
return (
|
return get_output_of_command(
|
||||||
Command([config.ZFS, "list", "-r", "-t", "snapshot", "-o", "name", "-H", pool])
|
[config.ZFS, "list", "-r", "-t", "snapshot", "-o", "name", "-H", pool]
|
||||||
.stdout.strip()
|
).split()
|
||||||
.decode()
|
|
||||||
.split("\n")
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def last_snapshot(pool):
|
def last_snapshot(pool):
|
||||||
@@ -90,9 +79,9 @@ def last_snapshot(pool):
|
|||||||
def export_pool(pool):
|
def export_pool(pool):
|
||||||
container_name = "crypt-" + pool
|
container_name = "crypt-" + pool
|
||||||
print("Exportiere Pool " + pool)
|
print("Exportiere Pool " + pool)
|
||||||
Command([config.ZPOOL, "export", pool])
|
get_output_of_command([config.ZPOOL, "export", pool])
|
||||||
print("Schließe verschlüsselten Container")
|
print("Schließe verschlüsselten Container")
|
||||||
Command([config.CRYPTSETUP, "close", container_name])
|
get_output_of_command([config.CRYPTSETUP, "close", container_name])
|
||||||
print("Fertig!")
|
print("Fertig!")
|
||||||
print("Sie können die externe Festplatte jetzt entfernen.")
|
print("Sie können die externe Festplatte jetzt entfernen.")
|
||||||
|
|
||||||
@@ -100,7 +89,7 @@ def export_pool(pool):
|
|||||||
def import_pool(pool):
|
def import_pool(pool):
|
||||||
uuid = config.backup_pool[pool]
|
uuid = config.backup_pool[pool]
|
||||||
container_name = "crypt-" + 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:
|
if container_name in present_mappers:
|
||||||
msg = (
|
msg = (
|
||||||
"verschlüsselter Container "
|
"verschlüsselter Container "
|
||||||
@@ -109,12 +98,14 @@ def import_pool(pool):
|
|||||||
)
|
)
|
||||||
raise Exception(msg)
|
raise Exception(msg)
|
||||||
print("Öffne verschlüsselten Container\n")
|
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("")
|
||||||
print("Importiere Pool " + pool)
|
print("Importiere Pool " + pool)
|
||||||
# -N: no mount
|
# -N: no mount
|
||||||
# -d: directory to search the pool in
|
# -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):
|
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
|
# -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.
|
# -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.
|
# -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()
|
exit_code = send.wait()
|
||||||
if exit_code != 0:
|
if exit_code != 0:
|
||||||
raise Exception("Kritisches Kommando fehlgeschlagen. Breche ab.")
|
raise Exception("Kritisches Kommando fehlgeschlagen. Breche ab.")
|
||||||
@@ -195,6 +188,12 @@ def clean_old_snapshots(dataset, pool):
|
|||||||
zfs_destroy(to_delete, recursive=True)
|
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):
|
def zfs_destroy(full_name, recursive=False):
|
||||||
if config.local_pool in full_name:
|
if config.local_pool in full_name:
|
||||||
msg = "Wollte in falschem Pool löschen! Dies sollte niemals passieren! Abbruch!"
|
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:
|
if recursive:
|
||||||
cmdline.append("-r")
|
cmdline.append("-r")
|
||||||
cmdline.append(full_name)
|
cmdline.append(full_name)
|
||||||
Command(cmdline)
|
get_output_of_command(cmdline)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|||||||
Reference in New Issue
Block a user