added live windows
This commit is contained in:
@@ -962,6 +962,14 @@ wss.on("connection", (ws) => {
|
||||
writeProxyCredentials(msg.credentials);
|
||||
} else if (msg.action === "docker_logs") {
|
||||
handleDockerLogs(ws, msg.tab, msg.tail);
|
||||
} else if (msg.action === "live_ssh_start") {
|
||||
startLiveSSH(ws);
|
||||
} else if (msg.action === "live_ssh_input") {
|
||||
if (ws._sshSock) ws._sshSock.write(msg.data);
|
||||
} else if (msg.action === "live_ssh_close") {
|
||||
if (ws._sshSock) { ws._sshSock.end(); ws._sshSock = null; }
|
||||
} else if (msg.action === "check_desktop") {
|
||||
checkDesktopAvailable(ws);
|
||||
}
|
||||
} catch {}
|
||||
});
|
||||
@@ -971,6 +979,121 @@ wss.on("connection", (ws) => {
|
||||
});
|
||||
});
|
||||
|
||||
// ── Live SSH ─────────────────────────────────────────────
|
||||
|
||||
function startLiveSSH(clientWs) {
|
||||
// Bestehende Session schliessen
|
||||
if (clientWs._sshSock) {
|
||||
try { clientWs._sshSock.end(); } catch (_) {}
|
||||
clientWs._sshSock = null;
|
||||
}
|
||||
|
||||
const createBody = JSON.stringify({
|
||||
AttachStdin: true, AttachStdout: true, AttachStderr: true, Tty: true,
|
||||
Cmd: ["ssh", "-tt", "aria-wohnung"],
|
||||
});
|
||||
|
||||
const createReq = http.request({
|
||||
socketPath: "/var/run/docker.sock",
|
||||
path: "/containers/aria-core/exec",
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(createBody) },
|
||||
}, (res) => {
|
||||
let data = "";
|
||||
res.on("data", (c) => data += c);
|
||||
res.on("end", () => {
|
||||
if (res.statusCode !== 201) {
|
||||
clientWs.send(JSON.stringify({ type: "live_ssh_error", error: `Exec create failed: HTTP ${res.statusCode}` }));
|
||||
return;
|
||||
}
|
||||
const execId = JSON.parse(data).Id;
|
||||
const startBody = JSON.stringify({ Detach: false, Tty: true });
|
||||
|
||||
const sock = net.connect({ path: "/var/run/docker.sock" }, () => {
|
||||
const req = `POST /exec/${execId}/start HTTP/1.1\r\nHost: localhost\r\nContent-Type: application/json\r\nConnection: Upgrade\r\nUpgrade: tcp\r\nContent-Length: ${Buffer.byteLength(startBody)}\r\n\r\n${startBody}`;
|
||||
sock.write(req);
|
||||
});
|
||||
|
||||
let headersParsed = false;
|
||||
let headerBuf = "";
|
||||
|
||||
sock.on("data", (chunk) => {
|
||||
if (!headersParsed) {
|
||||
headerBuf += chunk.toString("utf-8");
|
||||
const headerEnd = headerBuf.indexOf("\r\n\r\n");
|
||||
if (headerEnd === -1) return;
|
||||
const headers = headerBuf.slice(0, headerEnd);
|
||||
const remaining = chunk.slice(chunk.length - (headerBuf.length - headerEnd - 4));
|
||||
headersParsed = true;
|
||||
|
||||
if (!headers.includes("200") && !headers.includes("101")) {
|
||||
clientWs.send(JSON.stringify({ type: "live_ssh_error", error: `SSH start failed` }));
|
||||
sock.end();
|
||||
return;
|
||||
}
|
||||
|
||||
log("info", "server", "Live SSH-Session gestartet");
|
||||
clientWs.send(JSON.stringify({ type: "live_ssh_connected" }));
|
||||
clientWs._sshSock = sock;
|
||||
|
||||
if (remaining.length > 0) {
|
||||
clientWs.send(JSON.stringify({ type: "live_ssh_data", data: remaining.toString("base64") }));
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Stream-Daten ans Frontend
|
||||
try {
|
||||
clientWs.send(JSON.stringify({ type: "live_ssh_data", data: chunk.toString("base64") }));
|
||||
} catch (_) { sock.end(); }
|
||||
});
|
||||
|
||||
sock.on("close", () => {
|
||||
clientWs._sshSock = null;
|
||||
try { clientWs.send(JSON.stringify({ type: "live_ssh_closed" })); } catch (_) {}
|
||||
log("info", "server", "Live SSH-Session beendet");
|
||||
});
|
||||
|
||||
sock.on("error", (err) => {
|
||||
clientWs._sshSock = null;
|
||||
try { clientWs.send(JSON.stringify({ type: "live_ssh_error", error: err.message })); } catch (_) {}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
createReq.on("error", (err) => {
|
||||
clientWs.send(JSON.stringify({ type: "live_ssh_error", error: `Docker: ${err.message}` }));
|
||||
});
|
||||
createReq.end(createBody);
|
||||
}
|
||||
|
||||
function checkDesktopAvailable(clientWs) {
|
||||
// Pruefen ob VNC auf der VM laeuft (Port 5900/5901)
|
||||
const checkSock = net.connect({ host: "host.docker.internal", port: 5901 }, () => {
|
||||
checkSock.end();
|
||||
clientWs.send(JSON.stringify({
|
||||
type: "desktop_status",
|
||||
available: true,
|
||||
url: `http://${clientWs._socket?.remoteAddress || "localhost"}:6080/vnc.html?autoconnect=true`,
|
||||
message: "VNC Desktop verfuegbar",
|
||||
}));
|
||||
});
|
||||
checkSock.on("error", () => {
|
||||
clientWs.send(JSON.stringify({
|
||||
type: "desktop_status",
|
||||
available: false,
|
||||
message: "Kein VNC-Server auf aria-wohnung gefunden (Port 5901)",
|
||||
}));
|
||||
});
|
||||
checkSock.setTimeout(3000, () => {
|
||||
checkSock.destroy();
|
||||
clientWs.send(JSON.stringify({
|
||||
type: "desktop_status",
|
||||
available: false,
|
||||
message: "VNC-Server nicht erreichbar (Timeout)",
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
// ── Start ───────────────────────────────────────────────
|
||||
|
||||
server.listen(HTTP_PORT, "0.0.0.0", () => {
|
||||
|
||||
Reference in New Issue
Block a user