Webseite überarbeitet und Telegram Bot funktion hinzugefügt #1

Merged
pi-farm merged 59 commits from dev into main 2026-03-07 23:50:03 +00:00
Showing only changes of commit f36b72a528 - Show all commits

91
main.py
View File

@@ -174,6 +174,48 @@ class ConnectionManager:
except: pass except: pass
manager = ConnectionManager() manager = ConnectionManager()
async def get_remote_info(ip, user):
"""Versucht Linux/Mac-Infos zu lesen, falls fehlgeschlagen, dann Windows."""
# 1. Versuch: Linux/Mac
linux_cmd = "uname -m && (sw_vers -productName 2>/dev/null || grep PRETTY_NAME /etc/os-release 2>/dev/null | cut -d= -f2 || uname -s) && (command -v docker >/dev/null 2>&1 && echo 1 || echo 0)"
ssh_cmd = f"ssh -o StrictHostKeyChecking=no -o ConnectTimeout=3 {user}@{ip} \"{linux_cmd}\""
try:
output = subprocess.check_output(ssh_cmd, shell=True, stderr=subprocess.DEVNULL).decode().strip().split('\n')
if len(output) >= 2:
return {
"arch": output[0],
"os": output[1].replace('"', ''),
"docker": int(output[2]) if len(output) > 2 else 0
}
except:
pass # Linux-Versuch gescheitert, weiter zu Windows
# 2. Versuch: Windows (CMD)
# ver = OS Version, echo %PROCESSOR_ARCHITECTURE% = Arch, where docker = Docker Check
win_cmd = 'ver && echo %PROCESSOR_ARCHITECTURE% && (where docker >nul 2>&1 && echo 1 || echo 0)'
ssh_cmd = f"ssh -o StrictHostKeyChecking=no -o ConnectTimeout=3 {user}@{ip} \"{win_cmd}\""
try:
output = subprocess.check_output(ssh_cmd, shell=True).decode().strip().split('\n')
# Windows Output sieht oft so aus: ["Microsoft Windows [Version 10.0...]", "AMD64", "1"]
raw_os = output[0] if len(output) > 0 else "Windows"
os_name = "Windows"
if "Version 10" in raw_os: os_name = "Windows 10/11"
elif "Version 11" in raw_os: os_name = "Windows 11"
arch = output[1] if len(output) > 1 else "x86"
if "AMD64" in arch: arch = "x86-64"
docker_val = int(output[2]) if len(output) > 2 else 0
return {"arch": arch, "os": os_name, "docker": docker_val}
except Exception as e:
print(f"Windows-Check fehlgeschlagen für {ip}: {e}")
return None
# Nutze diese Funktion nun in bootstrap_node und refresh_status
# --- ERWEITERTES NODE BOOTSTRAPPING (Inventur) --- # --- ERWEITERTES NODE BOOTSTRAPPING (Inventur) ---
async def bootstrap_node(ip, user, password): async def bootstrap_node(ip, user, password):
await manager.broadcast(f"🔑 SSH-Handshake für {ip}...") await manager.broadcast(f"🔑 SSH-Handshake für {ip}...")
@@ -186,36 +228,21 @@ async def bootstrap_node(ip, user, password):
return return
# 2. System-Infos abrufen (Inventur) # 2. System-Infos abrufen (Inventur)
await manager.broadcast(f"🔍 Inventur auf {ip} wird durchgeführt...") await manager.broadcast(f"🔍 Inventur auf {ip} wird durchgeführt...")
info = await get_remote_info(ip, user)
# Befehlskette: Arch, OS-Name, Docker-Check if info:
inspect_cmd = "uname -m && (sw_vers -productName 2>/dev/null || grep PRETTY_NAME /etc/os-release 2>/dev/null | cut -d= -f2 || uname -s) && (command -v docker >/dev/null 2>&1 && echo 1 || echo 0)" status = "Docker Aktiv" if info['docker'] else "Bereit (Kein Docker)"
ssh_cmd = f"ssh -o StrictHostKeyChecking=no {user}@{ip} \"{inspect_cmd}\""
try:
output = subprocess.check_output(ssh_cmd, shell=True).decode().strip().split('\n')
arch = output[0] if len(output) > 0 else "Unbekannt"
# Mapping für Architektur
if "aarch64" in arch.lower(): arch = "arm64"
elif "x86_64" in arch.lower(): arch = "x86-64"
os_name = output[1].replace('"', '') if len(output) > 1 else "Linux"
docker_val = int(output[2]) if len(output) > 2 else 0
status = "Docker Aktiv" if docker_val else "Bereit (Kein Docker)"
# Datenbank Update
conn = get_db() conn = get_db()
conn.execute(''' conn.execute('''
UPDATE nodes SET os = ?, arch = ?, docker_installed = ?, status = ? UPDATE nodes SET os = ?, arch = ?, docker_installed = ?, status = ?
WHERE ip = ? WHERE ip = ?
''', (os_name, arch, docker_val, status, ip)) ''', (info['os'], info['arch'], info['docker'], status, ip))
conn.commit() conn.commit()
conn.close() conn.close()
await manager.broadcast(f"✅ Node {ip} konfiguriert ({os_name}, {arch}).") await manager.broadcast(f"✅ Node {ip} erkannt als {info['os']} ({info['arch']}).")
except Exception as e: else:
await manager.broadcast(f"⚠️ Inventur auf {ip} unvollständig: {e}") await manager.broadcast(f"⚠️ Inventur auf {ip} fehlgeschlagen.")
# --- ROUTES --- # --- ROUTES ---
@app.get("/") @app.get("/")
@@ -305,21 +332,15 @@ async def refresh_status(node_id: int):
node = conn.execute('SELECT * FROM nodes WHERE id = ?', (node_id,)).fetchone() node = conn.execute('SELECT * FROM nodes WHERE id = ?', (node_id,)).fetchone()
if not node: return {"status": "Offline"} if not node: return {"status": "Offline"}
inspect_cmd = "uname -m && (sw_vers -productName 2>/dev/null || grep PRETTY_NAME /etc/os-release 2>/dev/null | cut -d= -f2 || uname -s) && (command -v docker >/dev/null 2>&1 && echo 1 || echo 0)" info = await get_remote_info(node['ip'], node['user'])
ssh_cmd = f"ssh -o StrictHostKeyChecking=no -o ConnectTimeout=3 {node['user']}@{node['ip']} \"{inspect_cmd}\""
try:
output = subprocess.check_output(ssh_cmd, shell=True).decode().strip().split('\n')
arch = output[0]; os_name = output[1].replace('"', ''); docker_val = int(output[2])
if "aarch64" in arch.lower(): arch = "arm64"
elif "x86_64" in arch.lower(): arch = "x86-64"
new_status = "Docker Aktiv" if docker_val else "Bereit (Kein Docker)"
if info:
new_status = "Docker Aktiv" if info['docker'] else "Bereit (Kein Docker)"
conn.execute('UPDATE nodes SET status=?, os=?, arch=?, docker_installed=? WHERE id=?', conn.execute('UPDATE nodes SET status=?, os=?, arch=?, docker_installed=? WHERE id=?',
(new_status, os_name, arch, docker_val, node_id)) (new_status, info['os'], info['arch'], info['docker'], node_id))
conn.commit() conn.commit()
result = {"status": new_status, "os": os_name, "arch": arch, "docker": docker_val} result = {"status": new_status, "os": info['os'], "arch": info['arch'], "docker": info['docker']}
except: else:
new_status = "Offline" new_status = "Offline"
conn.execute('UPDATE nodes SET status=? WHERE id=?', (new_status, node_id)) conn.execute('UPDATE nodes SET status=? WHERE id=?', (new_status, node_id))
conn.commit() conn.commit()