Webseite überarbeitet und Telegram Bot funktion hinzugefügt #1
89
main.py
89
main.py
@@ -174,6 +174,48 @@ class ConnectionManager:
|
||||
except: pass
|
||||
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) ---
|
||||
async def bootstrap_node(ip, user, password):
|
||||
await manager.broadcast(f"🔑 SSH-Handshake für {ip}...")
|
||||
@@ -187,35 +229,20 @@ async def bootstrap_node(ip, user, password):
|
||||
|
||||
# 2. System-Infos abrufen (Inventur)
|
||||
await manager.broadcast(f"🔍 Inventur auf {ip} wird durchgeführt...")
|
||||
info = await get_remote_info(ip, user)
|
||||
|
||||
# Befehlskette: Arch, OS-Name, Docker-Check
|
||||
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)"
|
||||
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
|
||||
if info:
|
||||
status = "Docker Aktiv" if info['docker'] else "Bereit (Kein Docker)"
|
||||
conn = get_db()
|
||||
conn.execute('''
|
||||
UPDATE nodes SET os = ?, arch = ?, docker_installed = ?, status = ?
|
||||
WHERE ip = ?
|
||||
''', (os_name, arch, docker_val, status, ip))
|
||||
''', (info['os'], info['arch'], info['docker'], status, ip))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
await manager.broadcast(f"✅ Node {ip} konfiguriert ({os_name}, {arch}).")
|
||||
except Exception as e:
|
||||
await manager.broadcast(f"⚠️ Inventur auf {ip} unvollständig: {e}")
|
||||
|
||||
await manager.broadcast(f"✅ Node {ip} erkannt als {info['os']} ({info['arch']}).")
|
||||
else:
|
||||
await manager.broadcast(f"⚠️ Inventur auf {ip} fehlgeschlagen.")
|
||||
# --- ROUTES ---
|
||||
|
||||
@app.get("/")
|
||||
@@ -305,21 +332,15 @@ async def refresh_status(node_id: int):
|
||||
node = conn.execute('SELECT * FROM nodes WHERE id = ?', (node_id,)).fetchone()
|
||||
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)"
|
||||
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)"
|
||||
info = await get_remote_info(node['ip'], node['user'])
|
||||
|
||||
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=?',
|
||||
(new_status, os_name, arch, docker_val, node_id))
|
||||
(new_status, info['os'], info['arch'], info['docker'], node_id))
|
||||
conn.commit()
|
||||
result = {"status": new_status, "os": os_name, "arch": arch, "docker": docker_val}
|
||||
except:
|
||||
result = {"status": new_status, "os": info['os'], "arch": info['arch'], "docker": info['docker']}
|
||||
else:
|
||||
new_status = "Offline"
|
||||
conn.execute('UPDATE nodes SET status=? WHERE id=?', (new_status, node_id))
|
||||
conn.commit()
|
||||
|
||||
Reference in New Issue
Block a user