main.py aktualisiert
This commit is contained in:
81
main.py
81
main.py
@@ -224,40 +224,75 @@ async def terminal_websocket(websocket: WebSocket, ip: str):
|
|||||||
# --- WEBSOCKET CHAT UPDATE ---
|
# --- WEBSOCKET CHAT UPDATE ---
|
||||||
|
|
||||||
@app.websocket("/ws/chat")
|
@app.websocket("/ws/chat")
|
||||||
async def websocket_chat(websocket: WebSocket):
|
async def chat_endpoint(websocket: WebSocket):
|
||||||
await websocket.accept()
|
await websocket.accept()
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
data = await websocket.receive_text()
|
user_msg = await websocket.receive_text()
|
||||||
# Hole Antwort von der gewählten KI
|
|
||||||
ai_msg = await get_ai_response(data)
|
# 1. Dynamischen Prompt laden
|
||||||
await websocket.send_text(ai_msg)
|
sys_prompt = get_system_prompt()
|
||||||
|
|
||||||
|
# 2. KI fragen
|
||||||
|
ai_response = await get_ai_response(user_msg, sys_prompt)
|
||||||
|
|
||||||
|
# 3. XML-Tags auslesen (<EXECUTE target="IP">Befehl</EXECUTE>)
|
||||||
|
commands_to_run = re.findall(r'<EXECUTE target="(.*?)">(.*?)</EXECUTE>', ai_response, re.IGNORECASE | re.DOTALL)
|
||||||
|
|
||||||
|
# 4. XML-Tags für das UI ausblenden, damit der Chat sauber aussieht
|
||||||
|
clean_chat_msg = re.sub(r'<EXECUTE.*?>.*?</EXECUTE>', '', ai_response, flags=re.IGNORECASE | re.DOTALL).strip()
|
||||||
|
|
||||||
|
if clean_chat_msg:
|
||||||
|
await websocket.send_text(clean_chat_msg)
|
||||||
|
|
||||||
|
# 5. Gefundene Befehle an den Pi schicken!
|
||||||
|
for target_ip, cmd in commands_to_run:
|
||||||
|
target_ip = target_ip.strip()
|
||||||
|
cmd = cmd.strip()
|
||||||
|
|
||||||
|
conn = get_db()
|
||||||
|
node = conn.execute('SELECT * FROM nodes WHERE ip = ? OR name = ?', (target_ip, target_ip)).fetchone()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
if node:
|
||||||
|
# Leite Aufgabe an die System Logs weiter
|
||||||
|
asyncio.create_task(run_remote_task(node['ip'], node['user'], cmd, "KI-Kommando"))
|
||||||
|
else:
|
||||||
|
await websocket.send_text(f"⚠️ Konnte Node {target_ip} in DB nicht finden.")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Chat Error: {e}")
|
print(f"Chat Fehler: {e}")
|
||||||
|
|
||||||
# --- Status in DB aktualisieren Helper ---
|
|
||||||
def update_node_status(ip, new_status):
|
|
||||||
conn = get_db()
|
|
||||||
conn.execute('UPDATE nodes SET status = ? WHERE ip = ?', (new_status, ip))
|
|
||||||
conn.commit()
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
# --- Erweiterter Remote-Task ---
|
|
||||||
async def run_remote_task(ip, user, cmd, task_name):
|
async def run_remote_task(ip, user, cmd, task_name):
|
||||||
await manager.broadcast(f"🚀 KI-Task: {task_name} auf {ip}")
|
await manager.broadcast(f"🚀 KI-Task gestartet: {cmd} auf {ip}")
|
||||||
|
|
||||||
ssh_cmd = f"ssh -o StrictHostKeyChecking=no {user}@{ip} '{cmd}'"
|
ssh_cmd = f"ssh -o StrictHostKeyChecking=no {user}@{ip} '{cmd}'"
|
||||||
process = subprocess.Popen(ssh_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
|
|
||||||
|
|
||||||
for line in process.stdout:
|
# Asynchroner Subprozess, damit das restliche Dashboard nicht einfriert
|
||||||
await manager.broadcast(f"🛠️ {line.strip()[:80]}")
|
process = await asyncio.create_subprocess_shell(
|
||||||
|
ssh_cmd,
|
||||||
|
stdout=asyncio.subprocess.PIPE,
|
||||||
|
stderr=asyncio.subprocess.STDOUT
|
||||||
|
)
|
||||||
|
|
||||||
# WICHTIG: Wenn Docker installiert wurde, Status ändern!
|
# Lese die Logs Zeile für Zeile, während sie entstehen
|
||||||
if "docker" in task_name.lower():
|
while True:
|
||||||
|
line = await process.stdout.readline()
|
||||||
|
if not line:
|
||||||
|
break
|
||||||
|
decoded_line = line.decode('utf-8', errors='ignore').strip()
|
||||||
|
if decoded_line:
|
||||||
|
await manager.broadcast(f"🛠️ {decoded_line}")
|
||||||
|
|
||||||
|
await process.wait()
|
||||||
|
|
||||||
|
# Falls es ein Docker-Befehl war, Status updaten
|
||||||
|
if "docker" in cmd.lower():
|
||||||
update_node_status(ip, "Docker Aktiv")
|
update_node_status(ip, "Docker Aktiv")
|
||||||
await manager.broadcast(f"✨ Datenbank aktualisiert: {ip} ist nun 'Docker Aktiv'")
|
await manager.broadcast(f"✨ {ip} ist nun 'Docker Aktiv'")
|
||||||
|
|
||||||
|
await manager.broadcast(f"✅ Befehl auf {ip} abgeschlossen.")
|
||||||
|
|
||||||
await manager.broadcast(f"✅ {task_name} fertig.")
|
|
||||||
|
|
||||||
# --- Neuer Endpunkt: Manueller Refresh-Check ---
|
# --- Neuer Endpunkt: Manueller Refresh-Check ---
|
||||||
@app.get("/refresh_status/{node_id}")
|
@app.get("/refresh_status/{node_id}")
|
||||||
async def refresh_status(node_id: int):
|
async def refresh_status(node_id: int):
|
||||||
|
|||||||
Reference in New Issue
Block a user