Updates
This commit is contained in:
@@ -20,6 +20,10 @@ export default function ServiceCluster({ service }: Props) {
|
||||
NormalizedServerObject | undefined
|
||||
>(cluster_servers?.[0]);
|
||||
|
||||
const is_servers_odd_number = cluster_servers?.length
|
||||
? Boolean(cluster_servers.length % 2)
|
||||
: false;
|
||||
|
||||
return (
|
||||
<Stack className="w-full grid-cell col-span-1 gap-0">
|
||||
<Row className="nested-grid-frame xl:grid-cols-2">
|
||||
@@ -33,6 +37,7 @@ export default function ServiceCluster({ service }: Props) {
|
||||
/>
|
||||
);
|
||||
})}
|
||||
{is_servers_odd_number ? <div className="grid-cell" /> : null}
|
||||
</Row>
|
||||
|
||||
{/* <Row className="p-4">
|
||||
|
||||
@@ -30,23 +30,20 @@ export default function ServiceClusters() {
|
||||
|
||||
const cluster_servers = targetCluster?.servers;
|
||||
|
||||
const [targetServer, setTargetServer] = useState<
|
||||
NormalizedServerObject | undefined
|
||||
>(cluster_servers?.[0]);
|
||||
// const [targetServer, setTargetServer] = useState<
|
||||
// NormalizedServerObject | undefined
|
||||
// >(cluster_servers?.[0]);
|
||||
|
||||
function killAllPorts(port: number) {
|
||||
function killAllPorts() {
|
||||
ws.sendData({
|
||||
event: "client:kill-port",
|
||||
server: targetServer,
|
||||
service: _.omit(service, ["servers"]),
|
||||
port,
|
||||
event: "client:kill-all-ports",
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack className="w-full nested-grid-frame grid-cols-1">
|
||||
<Stack className="grid-cell gap-0">
|
||||
<Row className="p-4 flex-nowrap">
|
||||
<Row className="grid-cell-content flex-nowrap">
|
||||
<Row className="w-full justify-between">
|
||||
<Row>
|
||||
<H2>Cluster #{clusterIndex}</H2>
|
||||
@@ -62,6 +59,7 @@ export default function ServiceClusters() {
|
||||
}}
|
||||
changeHandler={(v) => {
|
||||
setTargetCluster(undefined);
|
||||
killAllPorts();
|
||||
setTimeout(() => {
|
||||
setTargetCluster(
|
||||
all_services.find(
|
||||
|
||||
@@ -39,6 +39,20 @@ const schema = {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
tableName: "users_ports",
|
||||
fields: [
|
||||
{
|
||||
fieldName: "user_id",
|
||||
dataType: "INTEGER",
|
||||
},
|
||||
{
|
||||
fieldName: "port",
|
||||
dataType: "INTEGER",
|
||||
unique: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
+19
-1
@@ -1,5 +1,6 @@
|
||||
export const NSQLiteTables = [
|
||||
"users",
|
||||
"users_ports",
|
||||
] as const
|
||||
|
||||
export type NSQLITE_TEST_DB_USERS = {
|
||||
@@ -24,4 +25,21 @@ export type NSQLITE_TEST_DB_USERS = {
|
||||
is_super_admin?: number;
|
||||
}
|
||||
|
||||
export type NSQLITE_TEST_DB_ALL_TYPEDEFS = NSQLITE_TEST_DB_USERS
|
||||
export type NSQLITE_TEST_DB_USERS_PORTS = {
|
||||
/**
|
||||
* The unique identifier of the record.
|
||||
*/
|
||||
id?: number;
|
||||
/**
|
||||
* The time when the record was created. (Unix Timestamp)
|
||||
*/
|
||||
created_at?: number;
|
||||
/**
|
||||
* The time when the record was updated. (Unix Timestamp)
|
||||
*/
|
||||
updated_at?: number;
|
||||
user_id?: number;
|
||||
port?: number;
|
||||
}
|
||||
|
||||
export type NSQLITE_TEST_DB_ALL_TYPEDEFS = NSQLITE_TEST_DB_USERS & NSQLITE_TEST_DB_USERS_PORTS
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AppData } from "@/src/data/app-data";
|
||||
import { NSQLITE_TEST_DB_USERS_PORTS, NSQLiteTables } from "@/src/db/types";
|
||||
import {
|
||||
NormalizedServerObject,
|
||||
ParsedDeploymentServiceConfig,
|
||||
@@ -11,6 +11,7 @@ import getNextAvailablePort from "@/src/utils/grab-next-available-port";
|
||||
import grabSSHPrefix from "@/src/utils/grab-ssh-prefix";
|
||||
import grabTtydCmd from "@/src/utils/grab-ttyd-cmd";
|
||||
import grabConnectedWebsocketUserdata from "@/src/websocket/(utils)/grab-connected-websocket-user-data";
|
||||
import BunSQLite from "@moduletrace/bun-sqlite";
|
||||
import { exec } from "child_process";
|
||||
|
||||
const { TURBOCI_SSH_KEY_FILE } = grabDirNames();
|
||||
@@ -37,7 +38,9 @@ export default async function grabTtydServerInfo({
|
||||
const final_log = passed_log_cmd || final_first_log;
|
||||
|
||||
if (paradigm == "logs" && !final_log) {
|
||||
throw new Error(`Service Doesn't have logs.`);
|
||||
throw new Error(
|
||||
`Service \`${service?.service_name}\` Doesn't have logs.`,
|
||||
);
|
||||
}
|
||||
|
||||
const available_port = getNextAvailablePort();
|
||||
@@ -70,6 +73,14 @@ export default async function grabTtydServerInfo({
|
||||
|
||||
const connected_user_data = grabConnectedWebsocketUserdata({ user });
|
||||
|
||||
await BunSQLite.insert<
|
||||
NSQLITE_TEST_DB_USERS_PORTS,
|
||||
(typeof NSQLiteTables)[number]
|
||||
>({
|
||||
data: [{ user_id: user.id, port: available_port }],
|
||||
table: "users_ports",
|
||||
});
|
||||
|
||||
connected_user_data.child_processes.push(ttyd_exec);
|
||||
connected_user_data.ports.push(available_port);
|
||||
|
||||
|
||||
@@ -14,4 +14,12 @@ export const AdminAsideLinks: (
|
||||
title: "Services",
|
||||
url: "/admin/services",
|
||||
},
|
||||
{
|
||||
title: "Users",
|
||||
url: "/admin/users",
|
||||
},
|
||||
{
|
||||
title: "Settings",
|
||||
url: "/admin/settings",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import Layout from "@/src/layouts/login";
|
||||
import H2 from "@/twui/components/layout/H2";
|
||||
|
||||
export default function PageNotFound() {
|
||||
return (
|
||||
<Layout>
|
||||
<H2>Page Not Found!</H2>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
@@ -70,9 +70,9 @@ export default async function relayExecSSH({
|
||||
}
|
||||
|
||||
let relayCmd = ``;
|
||||
relayCmd += `/bin/bash << 'EOF'\n`;
|
||||
relayCmd += `/bin/bash << 'TURBOCIRELAYEXECEOF'\n`;
|
||||
relayCmd += `${relaySh}\n`;
|
||||
relayCmd += `EOF\n`;
|
||||
relayCmd += `TURBOCIRELAYEXECEOF\n`;
|
||||
|
||||
if (detached) {
|
||||
exec(relayCmd);
|
||||
|
||||
@@ -1,20 +1,51 @@
|
||||
import { AppData } from "@/src/data/app-data";
|
||||
import { NSQLITE_TEST_DB_USERS_PORTS, NSQLiteTables } from "@/src/db/types";
|
||||
import { User } from "@/src/types";
|
||||
import BunSQLite from "@moduletrace/bun-sqlite";
|
||||
import { execSync, ExecSyncOptions } from "child_process";
|
||||
import killPort from "./kill-port";
|
||||
|
||||
type Params = {
|
||||
exec_options?: ExecSyncOptions;
|
||||
user: User;
|
||||
};
|
||||
|
||||
export default async function killAllTtydPorts(params?: Params) {
|
||||
const start_port = AppData["DynamicPortStart"];
|
||||
const end_port = start_port + 100;
|
||||
const kill_ports_cmd = `ss -tlnp | awk 'NR>1 {split($4, a, ":"); port=a[length(a)]; if (port >= ${start_port} && port <= ${end_port}) print $6}' | grep -oP 'pid=\\K[0-9]+' | xargs -r kill -9`;
|
||||
|
||||
execSync(kill_ports_cmd, {
|
||||
...params?.exec_options,
|
||||
export default async function killAllTtydPorts({ user }: Params) {
|
||||
const user_ports_res = await BunSQLite.select<
|
||||
NSQLITE_TEST_DB_USERS_PORTS,
|
||||
(typeof NSQLiteTables)[number]
|
||||
>({
|
||||
table: "users_ports",
|
||||
query: { query: { user_id: { value: String(user.id) } } },
|
||||
});
|
||||
|
||||
if (user_ports_res?.payload?.[0]) {
|
||||
for (let i = 0; i < user_ports_res.payload.length; i++) {
|
||||
const user_port = user_ports_res.payload[i];
|
||||
if (!user_port.port) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await killPort({ port: user_port.port });
|
||||
|
||||
await BunSQLite.delete<
|
||||
NSQLITE_TEST_DB_USERS_PORTS,
|
||||
(typeof NSQLiteTables)[number]
|
||||
>({
|
||||
table: "users_ports",
|
||||
query: { query: { port: { value: String(user_port.port) } } },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// const start_port = AppData["DynamicPortStart"];
|
||||
// const end_port = start_port + 100;
|
||||
// const kill_ports_cmd = `ss -tlnp | awk 'NR>1 {split($4, a, ":"); port=a[length(a)]; if (port >= ${start_port} && port <= ${end_port}) print $6}' | grep -oP 'pid=\\K[0-9]+' | xargs -r kill -9`;
|
||||
|
||||
// execSync(kill_ports_cmd, {
|
||||
// ...exec_options,
|
||||
// });
|
||||
|
||||
// sudo ss -tlnp | awk 'NR>1 {split($4, a, ":"); port=a[length(a)]; if (port >= 4700 && port <= 4800) print $6}' | grep -oP 'pid=\K[0-9]+' | xargs -r sudo kill -9
|
||||
|
||||
// ss -tlnp | awk 'NR>1 {split($4, a, ":"); port=a[length(a)]; if (port >= 4700 && port <= 4800) print $6}' | grep -oP 'pid=\K[0-9]+' | xargs -r sudo kill -9
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
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";
|
||||
import killAllTtydPorts from "../(utils)/kill-all-ttyd-ports";
|
||||
|
||||
export default async function socketClientKillAllPorts({
|
||||
ws,
|
||||
@@ -11,18 +10,7 @@ export default async function socketClientKillAllPorts({
|
||||
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,
|
||||
);
|
||||
}
|
||||
}
|
||||
await killAllTtydPorts({ user });
|
||||
|
||||
sendData(ws, {
|
||||
event: "server:killed-all-ports",
|
||||
|
||||
@@ -27,7 +27,5 @@ export default async function socketClose({ ws }: Param) {
|
||||
existing_connected_user_data.child_processes = [];
|
||||
}
|
||||
|
||||
killAllTtydPorts({
|
||||
exec_options: { stdio: "inherit" },
|
||||
});
|
||||
killAllTtydPorts({ user });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user