This commit is contained in:
Benjamin Toby 2026-03-10 16:53:06 +00:00
parent c4c2caa6f0
commit d8ee723dae
8 changed files with 83 additions and 29 deletions

View File

@ -49,24 +49,30 @@ export default function DeploymentService({ service }: Props) {
const portRef = useRef<number>(undefined); const portRef = useRef<number>(undefined);
useEffect(() => { function killPort(port: number) {
setReady(false);
console.log("portRef", portRef);
if (targetServer && portRef.current) {
ws.sendData({ ws.sendData({
event: "client:kill-port", event: "client:kill-port",
server: targetServer, server: targetServer,
service: _.omit(service, ["servers"]), service: _.omit(service, ["servers"]),
port: portRef.current, port,
}); });
} }
useEffect(() => {
setTargetServer(targetCluster?.servers?.[0]);
}, [targetCluster]);
useEffect(() => {
setReady(false);
if (targetServer && portRef.current) {
killPort(portRef.current);
}
setTimeout(() => { setTimeout(() => {
setReady(true); setReady(true);
}, 2000); }, 2000);
}, [targetCluster, targetServer]); }, [targetServer]);
return ( return (
<Stack className="grid-cell"> <Stack className="grid-cell">
@ -88,9 +94,9 @@ export default function DeploymentService({ service }: Props) {
<Stack className="gap-0"> <Stack className="gap-0">
<Row className="p-4 grid md:grid-cols-2"> <Row className="p-4 grid md:grid-cols-2">
<Select <Select
options={all_clusters.map((cl) => ({ options={all_clusters.map((cl, index) => ({
value: cl.service_name, value: cl.service_name,
title: `Cluster #${targetClusterIndex}`, title: `Cluster #${index + 1}`,
}))} }))}
changeHandler={(v) => { changeHandler={(v) => {
setTargetCluster( setTargetCluster(

View File

@ -7,7 +7,9 @@ export default function DeploymentServices() {
const { pageProps } = useContext(AppContext); const { pageProps } = useContext(AppContext);
const { deployment, children_services } = pageProps; const { deployment, children_services } = pageProps;
const services = deployment?.services; const services = deployment?.services.filter(
(srv) => !Boolean(srv.parent_service_name),
);
return ( return (
<Stack className="w-full nested-grid-frame xl:grid-cols-2"> <Stack className="w-full nested-grid-frame xl:grid-cols-2">

View File

@ -12,9 +12,10 @@ import { twMerge } from "tailwind-merge";
import Select from "@/twui/components/form/Select"; import Select from "@/twui/components/form/Select";
import ServiceClusterServer from "../(partials)/cluster-server"; import ServiceClusterServer from "../(partials)/cluster-server";
import H2 from "@/twui/components/layout/H2"; import H2 from "@/twui/components/layout/H2";
import _ from "lodash";
export default function ServiceClusters() { export default function ServiceClusters() {
const { pageProps } = useContext(AppContext); const { pageProps, ws } = useContext(AppContext);
const { service, deployment, children_services } = pageProps; const { service, deployment, children_services } = pageProps;
const all_services = [service, ...(children_services || [])]; const all_services = [service, ...(children_services || [])];
@ -33,6 +34,15 @@ export default function ServiceClusters() {
NormalizedServerObject | undefined NormalizedServerObject | undefined
>(cluster_servers?.[0]); >(cluster_servers?.[0]);
function killAllPorts(port: number) {
ws.sendData({
event: "client:kill-port",
server: targetServer,
service: _.omit(service, ["servers"]),
port,
});
}
return ( return (
<Stack className="w-full nested-grid-frame grid-cols-1"> <Stack className="w-full nested-grid-frame grid-cols-1">
<Stack className="grid-cell gap-0"> <Stack className="grid-cell gap-0">
@ -43,9 +53,9 @@ export default function ServiceClusters() {
</Row> </Row>
<Row> <Row>
<Select <Select
options={all_services.map((srv) => ({ options={all_services.map((srv, index) => ({
value: srv?.service_name!, value: srv?.service_name!,
title: `Cluster #${clusterIndex}`, title: `Cluster #${index + 1}`,
}))} }))}
wrapperWrapperProps={{ wrapperWrapperProps={{
className: `max-w-[250px]`, className: `max-w-[250px]`,

View File

@ -232,6 +232,7 @@ export const WebSocketEvents = [
"client:ping", "client:ping",
"client:service-server-logs", "client:service-server-logs",
"client:kill-port", "client:kill-port",
"client:kill-all-ports",
"client:service-server-shell", "client:service-server-shell",
"server:ping", "server:ping",
@ -242,6 +243,7 @@ export const WebSocketEvents = [
"server:update", "server:update",
"server:service-server-logs", "server:service-server-logs",
"server:killed-port", "server:killed-port",
"server:killed-all-ports",
"server:service-server-shell", "server:service-server-shell",
] as const; ] as const;

View File

@ -1,7 +1,4 @@
import { exec, execSync, type ExecSyncOptions } from "child_process"; import { exec, execSync, type ExecSyncOptions } from "child_process";
import grabSSHPrefix from "./grab-ssh-prefix";
import { writeFileSync } from "fs";
import { TCIConfig } from "../types";
import turboCIPkgrabDirNames from "./turboci-pkg-grab-dir-names"; import turboCIPkgrabDirNames from "./turboci-pkg-grab-dir-names";
type Param = { type Param = {
@ -28,13 +25,10 @@ export default async function relayExecSSH({
bun, bun,
}: Param): Promise<string | undefined> { }: Param): Promise<string | undefined> {
try { try {
const { const { relayServerBunScriptsDir, relayServerBunScriptFile } =
relayServerBunScriptsDir, turboCIPkgrabDirNames();
relayServerBunScriptFile,
relayShExecFile,
} = turboCIPkgrabDirNames();
let relaySh = `#!/bin/bash\n`; let relaySh = `\n`;
const parsedCmd = const parsedCmd =
typeof cmd == "string" typeof cmd == "string"
@ -75,10 +69,10 @@ export default async function relayExecSSH({
console.log("===================================================="); console.log("====================================================");
} }
writeFileSync(relayShExecFile, relaySh);
let relayCmd = ``; let relayCmd = ``;
relayCmd += `chmod +x ${relayShExecFile} && /bin/bash ${relayShExecFile}\n`; relayCmd += `/bin/bash << 'EOF'\n`;
relayCmd += `${relaySh}\n`;
relayCmd += `EOF\n`;
if (detached) { if (detached) {
exec(relayCmd); exec(relayCmd);

View File

@ -0,0 +1,33 @@
import { WebSocketMessageParam } from "@/src/types";
import sendData from "../(utils)/send-data";
import sendError from "../(utils)/send-error";
import grabConnectedWebsocketUserdata from "../(utils)/grab-connected-websocket-user-data";
import killPort from "../(utils)/kill-port";
export default async function socketClientKillAllPorts({
ws,
data,
}: WebSocketMessageParam) {
try {
const user = ws.data.user;
const connected_user_data = grabConnectedWebsocketUserdata({ user });
for (let i = 0; i < connected_user_data.ports.length; i++) {
const port = connected_user_data.ports[i];
if (port) {
await killPort({ port, exec_options: { stdio: "inherit" } });
connected_user_data.ports = connected_user_data.ports.filter(
(p) => p != port,
);
}
}
sendData(ws, {
event: "server:killed-all-ports",
});
} catch (error: any) {
sendError(ws, "Service Server Logs Error! " + error.message);
}
}

View File

@ -16,8 +16,6 @@ export default async function socketClientKillPort({
const connected_user_data = grabConnectedWebsocketUserdata({ user }); const connected_user_data = grabConnectedWebsocketUserdata({ user });
console.log("port", port);
if (port) { if (port) {
await killPort({ port, exec_options: { stdio: "inherit" } }); await killPort({ port, exec_options: { stdio: "inherit" } });

View File

@ -10,6 +10,7 @@ import debugLog from "@moduletrace/datasquirel/dist/package-shared/utils/logging
import socketClientServiceServerLogs from "./events/client-service-server-logs"; import socketClientServiceServerLogs from "./events/client-service-server-logs";
import socketClientKillPort from "./events/client-kill-port"; import socketClientKillPort from "./events/client-kill-port";
import socketClientServiceServerShell from "./events/client-service-server-shell"; import socketClientServiceServerShell from "./events/client-service-server-shell";
import socketClientKillAllPorts from "./events/client-kill-all-ports";
type Param = { type Param = {
ws: ServerWebSocket<WebSocketData>; ws: ServerWebSocket<WebSocketData>;
@ -64,6 +65,14 @@ export default async function socketMessage({ ws, message }: Param) {
}); });
await socketClientKillPort(websocketMessageParams); await socketClientKillPort(websocketMessageParams);
break; break;
case "client:kill-all-ports":
debugLog({
log: `${userRef} Killing All Ports ...`,
addTime: true,
label,
});
await socketClientKillAllPorts(websocketMessageParams);
break;
default: default:
break; break;