"""Phase 3: Backup all configuration files before migration.""" import datetime from models import MigrationPlan from ssh_manager import SSHManager BACKUP_FILES = [ "/etc/network/interfaces", "/etc/hosts", "/etc/corosync/corosync.conf", "/etc/ceph/ceph.conf", ] CLUSTER_BACKUP_FILES = [ "/etc/pve/corosync.conf", "/etc/pve/ceph.conf", ] class Backup: """Creates backups of all config files on each node.""" def __init__(self, ssh: SSHManager): self.ssh = ssh def run(self, plan: MigrationPlan) -> bool: """Create backups on all reachable nodes. Returns True if all backups succeeded. """ print("\n=== Phase 3: Backup ===\n") timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") backup_dir = f"/root/network-migration-backup-{timestamp}" all_ok = True for node in plan.nodes: if not node.is_reachable: print(f" [{node.name}] Übersprungen (nicht erreichbar)") continue print(f" [{node.name}] Erstelle Backup in {backup_dir}/") # Create backup directory rc, _, err = self.ssh.run_on_node( node.ssh_host, f"mkdir -p {backup_dir}", node.is_local ) if rc != 0: print(f" [!] Fehler beim Erstellen des Backup-Verzeichnisses: {err}") all_ok = False continue # Backup per-node files for filepath in BACKUP_FILES: filename = filepath.replace("/", "_").lstrip("_") rc, _, _ = self.ssh.run_on_node( node.ssh_host, f"cp {filepath} {backup_dir}/{filename} 2>/dev/null", node.is_local, ) if rc == 0: print(f" OK: {filepath}") else: print(f" --: {filepath} (nicht vorhanden)") # Backup cluster files (only from local node since they're shared) if node.is_local: for filepath in CLUSTER_BACKUP_FILES: filename = filepath.replace("/", "_").lstrip("_") rc, _, _ = self.ssh.run_on_node( node.ssh_host, f"cp {filepath} {backup_dir}/{filename} 2>/dev/null", node.is_local, ) if rc == 0: print(f" OK: {filepath} (cluster)") else: print(f" --: {filepath} (nicht vorhanden)") if all_ok: print(f"\n Backup erfolgreich in {backup_dir}/") else: print("\n [!] Einige Backups sind fehlgeschlagen!") return all_ok