From 1974fd0293745d5bfa586f979e2433cf5b81a1c8 Mon Sep 17 00:00:00 2001 From: admin Date: Mon, 3 Aug 2026 12:28:01 +0000 Subject: [PATCH] fix: save state in deploy_all, discover nodes from systemd --- python/deploy.py | 70 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 21 deletions(-) diff --git a/python/deploy.py b/python/deploy.py index 463e175..c735659 100644 --- a/python/deploy.py +++ b/python/deploy.py @@ -218,15 +218,18 @@ def remove_node(name): # ─── Status ──────────────────────────────────────────────────────────── def show_status(): - s = load_state() - if not s.get("nodes"): - print("No nodes deployed.") + # Check systemd for running instances if state is empty + r = run("systemctl list-units 'wallarm-node@*' --no-legend 2>/dev/null") + if not r.stdout.strip(): + print("No nodes running.") return print("\n─── Node Status ───") - for n in s["nodes"]: - r = run(f"systemctl is-active wallarm-node@{n['name']}") - status = "●" if r.stdout.strip() == "active" else "○" - print(f" {status} {n['name']} — {r.stdout.strip()} — {n.get('address','')}") + for line in r.stdout.strip().split("\n"): + parts = line.split() + if len(parts) >= 4: + name = parts[0].replace("wallarm-node@", "").replace(".service", "") + status = "●" if parts[3] == "running" else "○" + print(f" {status} {name} — {parts[3]}") # ─── Tunnel ──────────────────────────────────────────────────────────── @@ -301,19 +304,34 @@ def deploy_menu(): # ─── Edit Menu ───────────────────────────────────────────────────────── -def edit_menu(): +def list_nodes(): + """Discover nodes from systemd if state is empty.""" s = load_state() - if not s.get("nodes"): + if s.get("nodes"): + return s["nodes"] + # Fall back to systemd discovery + r = run("systemctl list-units 'wallarm-node@*' --no-legend 2>/dev/null") + nodes = [] + for line in r.stdout.strip().split("\n"): + parts = line.split() + if len(parts) >= 4: + name = parts[0].replace("wallarm-node@", "").replace(".service", "") + nodes.append({"name": name, "address": "", "upstream_ip": "", "upstream_port": 0}) + return nodes + +def edit_menu(): + nodes = list_nodes() + if not nodes: print("No nodes.") return print("\n─── Edit Node ───") - for i, n in enumerate(s["nodes"]): + for i, n in enumerate(nodes): r = run(f"systemctl is-active wallarm-node@{n['name']}") st = "●" if r.stdout.strip() == "active" else "○" print(f" [{i+1}] {st} {n['name']} {n.get('address','')} → {n.get('upstream_ip','')}:{n.get('upstream_port','')}") c = input("\nSelect: ").strip() - if not c.isdigit(): return - n = s["nodes"][int(c)-1] + if not c.isdigit() or int(c) < 1 or int(c) > len(nodes): return + n = nodes[int(c)-1] port = input(f"Port [{n['address'].split(':')[-1]}]: ").strip() ip = input(f"Upstream IP [{n.get('upstream_ip','')}]: ").strip() @@ -341,18 +359,18 @@ def edit_menu(): # ─── Remove Menu ─────────────────────────────────────────────────────── def remove_menu(): - s = load_state() - if not s.get("nodes"): + nodes = list_nodes() + if not nodes: print("No nodes.") return print("\n─── Remove Node ───") - for i, n in enumerate(s["nodes"]): + for i, n in enumerate(nodes): r = run(f"systemctl is-active wallarm-node@{n['name']}") st = "●" if r.stdout.strip() == "active" else "○" print(f" [{i+1}] {st} {n['name']} {n.get('address','')}") c = input("\nSelect: ").strip() - if not c.isdigit(): return - n = s["nodes"][int(c)-1] + if not c.isdigit() or int(c) < 1 or int(c) > len(nodes): return + n = nodes[int(c)-1] remove_node(n["name"]) # ─── Main ────────────────────────────────────────────────────────────── @@ -403,10 +421,20 @@ def deploy_all(): print(f"✓ {name} already deployed") continue print(f"\nDeploying {name}...") - install_node(name, nc["token"], nc.get("cloud","EU"), - str(nc.get("port","8081")), nc.get("upstream_ip","127.0.0.1"), - str(nc.get("upstream_port","80")), nc.get("labels",f"group={name}"), - nc.get("mode","monitoring")) + try: + install_node(name, nc["token"], nc.get("cloud","EU"), + str(nc.get("port","8081")), nc.get("upstream_ip","127.0.0.1"), + str(nc.get("upstream_port","80")), nc.get("labels",f"group={name}"), + nc.get("mode","monitoring")) + s = load_state() + s.setdefault("nodes", []).append({ + "name": name, "type": "native", "address": f"0.0.0.0:{nc.get('port','8081')}", + "upstream_ip": nc.get("upstream_ip",""), "upstream_port": int(nc.get("upstream_port",80)), + "status": "running", "created_at": time.strftime("%Y-%m-%dT%H:%M:%SZ") + }) + save_state(s) + except Exception as e: + print(f"❌ {name}: {e}") # Clean up if os.path.islink("/opt/wallarm"): os.remove("/opt/wallarm")