From 55035ba890074484ed21ae7bf4d40b4283d30c16 Mon Sep 17 00:00:00 2001 From: jonnybravo Date: Fri, 19 Sep 2025 09:58:36 +0200 Subject: [PATCH] add --- setup_host.py | 93 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 62 insertions(+), 31 deletions(-) diff --git a/setup_host.py b/setup_host.py index de4f3b3..19befdf 100755 --- a/setup_host.py +++ b/setup_host.py @@ -8,6 +8,7 @@ import argparse import time import json + def run_command(command_str, description, ignore_errors=False): print(f"\n--- {description} ---") try: @@ -30,30 +31,36 @@ def run_command(command_str, description, ignore_errors=False): sys.exit(1) return None + def wait_for_network(container_name): print(f"\n--- Warte auf Netzwerk für Container '{container_name}' ---") for i in range(30): print(f"Versuch {i+1}/30...") try: - result = run_command(f"lxc list {container_name} --format json", "Frage Container-Status ab", ignore_errors=True) + result = run_command(f"lxc list { + container_name} --format json", "Frage Container-Status ab", ignore_errors=True) if result and result.returncode == 0: data = json.loads(result.stdout) if data and data[0]["state"] and data[0]["state"]["network"] and "eth0" in data[0]["state"]["network"]: addresses = data[0]["state"]["network"]["eth0"]["addresses"] for addr in addresses: if addr["family"] == "inet": - print(f"Container '{container_name}' hat IP-Adresse {addr['address']} erhalten.") + print(f"Container '{ + container_name}' hat IP-Adresse {addr['address']} erhalten.") return except (json.JSONDecodeError, IndexError, KeyError): pass time.sleep(2) - print(f"FEHLER: Container '{container_name}' hat nach 60 Sekunden keine IP-Adresse erhalten.", file=sys.stderr) + print(f"FEHLER: Container '{ + container_name}' hat nach 60 Sekunden keine IP-Adresse erhalten.", file=sys.stderr) sys.exit(1) + def get_container_ip(container_name): for _ in range(15): try: - result = run_command(f"lxc list {container_name} --format json", "Frage Container-IP ab", ignore_errors=True) + result = run_command(f"lxc list { + container_name} --format json", "Frage Container-IP ab", ignore_errors=True) if result and result.returncode == 0: data = json.loads(result.stdout) if data and data[0]["state"] and data[0]["state"]["network"] and "eth0" in data[0]["state"]["network"]: @@ -66,19 +73,29 @@ def get_container_ip(container_name): time.sleep(2) return None + def main(): - parser = argparse.ArgumentParser(description="Erstellt und konfiguriert mehrere LXD-Container.") - parser.add_argument("-c", "--count", type=int, default=1, help="Anzahl der zu erstellenden Container.") - parser.add_argument("-b", "--basename", default="vm", help="Basisname für die Container.") - parser.add_argument("--hostname-template", default="{basename}-{i:02d}", help="Vorlage für den Hostnamen, z.B. 'webserver-{i}'. Unterstützt {basename} und {i}.") - parser.add_argument("-p", "--root-password", required=True, help="Root-Passwort für alle Container.") - parser.add_argument("--port-start", type=int, default=2201, help="Start-Port für die SSH-Weiterleitung.") - parser.add_argument("--image", default="images:archlinux", help="Zu verwendendes Image (z.B. images:archlinux, ubuntu:22.04).") - parser.add_argument("--no-port-forward", action="store_true", help="Überspringt die Einrichtung der SSH-Port-Weiterleitung.") + parser = argparse.ArgumentParser( + description="Erstellt und konfiguriert mehrere LXD-Container.") + parser.add_argument("-c", "--count", type=int, default=1, + help="Anzahl der zu erstellenden Container.") + parser.add_argument("-b", "--basename", default="vm", + help="Basisname für die Container.") + parser.add_argument("--hostname-template", default="{basename}-{i:02d}", + help="Vorlage für den Hostnamen, z.B. 'webserver-{i}'. Unterstützt {basename} und {i}.") + parser.add_argument("-p", "--root-password", required=True, + help="Root-Passwort für alle Container.") + parser.add_argument("--port-start", type=int, default=2201, + help="Start-Port für die SSH-Weiterleitung.") + parser.add_argument("--image", default="images:archlinux", + help="Zu verwendendes Image (z.B. images:archlinux, ubuntu:22.04).") + parser.add_argument("--no-port-forward", action="store_true", + help="Überspringt die Einrichtung der SSH-Port-Weiterleitung.") args = parser.parse_args() if args.count > 1 and '{i}' not in args.hostname_template: - print("FEHLER: Bei --count > 1 muss die --hostname-template den Platzhalter '{i}' enthalten, um eindeutige Namen zu gewährleisten.", file=sys.stderr) + print( + "FEHLER: Bei --count > 1 muss die --hostname-template den Platzhalter '{i}' enthalten, um eindeutige Namen zu gewährleisten.", file=sys.stderr) sys.exit(1) run_command("command -v lxc >/dev/null", "Prüfe, ob LXD installiert ist") @@ -86,8 +103,10 @@ def main(): if not os.path.exists("out"): os.makedirs("out") + with open(csv_path, "w") as f: + f.write("name,ip\n") elif not os.path.isdir("out"): - os.remove("out") + # os.remove("out") os.makedirs("out") clients = [] @@ -96,14 +115,17 @@ def main(): vm_name = args.hostname_template.format(basename=args.basename, i=i) ssh_port = args.port_start + i - 1 - print(f"{ '=' * 20} ERSTELLE CONTAINER: {vm_name} {'=' * 20}") + print(f"{'=' * 20} ERSTELLE CONTAINER: {vm_name} {'=' * 20}") - run_command(f"lxc delete {vm_name} --force", f"{vm_name} vorsorglich löschen", ignore_errors=True) - run_command(f"lxc launch {args.image} {vm_name}", f"Starte {vm_name} von Image") + run_command(f"lxc delete {vm_name} --force", + f"{vm_name} vorsorglich löschen", ignore_errors=True) + run_command(f"lxc launch {args.image} { + vm_name}", f"Starte {vm_name} von Image") wait_for_network(vm_name) distro_id_command = "lxc exec {} -- cat /etc/os-release | grep '^ID=' | cut -d'=' -f2" - distro_id_result = run_command(distro_id_command.format(vm_name), f"Ermittle Distributions-ID für {vm_name}") + distro_id_result = run_command(distro_id_command.format( + vm_name), f"Ermittle Distributions-ID für {vm_name}") distro_id = distro_id_result.stdout.strip().replace('"', '') install_cmd = "" @@ -114,17 +136,22 @@ def main(): elif distro_id == "fedora": install_cmd = "dnf install -y python3" else: - print(f"FEHLER: Nicht unterstützte Distribution: {distro_id}", file=sys.stderr) + print(f"FEHLER: Nicht unterstützte Distribution: { + distro_id}", file=sys.stderr) sys.exit(1) - - run_command(f"lxc exec {vm_name} -- {install_cmd}", f"Installiere Python in {vm_name}") - run_command(f"lxc file push setup_container.py {vm_name}/root/", f"Kopiere Setup-Skript nach {vm_name}") - run_command(f"lxc exec {vm_name} -- python3 /root/setup_container.py '{args.root_password}' '{vm_name}' '{distro_id}'", f"Führe Konfiguration in {vm_name} aus") - + run_command(f"lxc exec {vm_name} -- {install_cmd}", + f"Installiere Python in {vm_name}") + + run_command(f"lxc file push setup_container.py { + vm_name}/root/", f"Kopiere Setup-Skript nach {vm_name}") + run_command(f"lxc exec {vm_name} -- python3 /root/setup_container.py '{ + args.root_password}' '{vm_name}' '{distro_id}'", f"Führe Konfiguration in {vm_name} aus") + ssh_info = "" if not args.no_port_forward: - run_command(f"lxc config device add {vm_name} ssh-proxy proxy listen=tcp:0.0.0.0:{ssh_port} connect=tcp:127.0.0.1:22", f"Richte Port-Weiterleitung für {vm_name} ein") + run_command(f"lxc config device add {vm_name} ssh-proxy proxy listen=tcp:0.0.0.0:{ + ssh_port} connect=tcp:127.0.0.1:22", f"Richte Port-Weiterleitung für {vm_name} ein") ssh_info = f"SSH-Zugang: ssh root@localhost -p {ssh_port}" else: print("\n--- Überspringe Port-Weiterleitung ---") @@ -132,22 +159,26 @@ def main(): ip_address = get_container_ip(vm_name) if ip_address: clients.append({"name": vm_name, "ip": ip_address}) - print(f"\n>>> Container {vm_name} erfolgreich erstellt und konfiguriert! <<<") + print(f"\n>>> Container { + vm_name} erfolgreich erstellt und konfiguriert! <<<") if ssh_info: print(ssh_info) print(f"IP-Adresse: {ip_address}") else: - print(f"\nFEHLER: IP-Adresse für Container {vm_name} konnte nicht abgerufen werden.", file=sys.stderr) + print(f"\nFEHLER: IP-Adresse für Container { + vm_name} konnte nicht abgerufen werden.", file=sys.stderr) if clients: csv_path = "out/clients.csv" - with open(csv_path, "w") as f: - f.write("name,ip\n") + with open(csv_path, "a") as f: + # f.write("name,ip\n") for client in clients: f.write(f"{client['name']},{client['ip']}\n") - print(f"\nAlle Container wurden erstellt und in {csv_path} gespeichert.") + print(f"\nAlle Container wurden erstellt und in { + csv_path} gespeichert.") else: print("\nKeine Container wurden erstellt.") + if __name__ == "__main__": - main() \ No newline at end of file + main()