Add panel feature updates across API, daemon, and web

This commit is contained in:
2026-03-02 21:53:54 +00:00
parent 6b463c2b1a
commit afc64b83c1
49 changed files with 7040 additions and 305 deletions
+157 -3
View File
@@ -27,11 +27,31 @@ export interface DaemonCreateServerRequest {
install_plugin_urls: string[];
}
export interface DaemonUpdateServerRequest {
uuid: string;
docker_image: string;
memory_limit: number;
disk_limit: number;
cpu_limit: number;
startup_command: string;
environment: Record<string, string>;
ports: DaemonPortMapping[];
}
interface DaemonServerResponse {
uuid: string;
status: string;
}
interface DaemonManagedDatabaseCredentialsRaw {
database_name: string;
username: string;
password: string;
host: string;
port: number;
phpmyadmin_url: string;
}
interface DaemonNodeStatusRaw {
version: string;
is_healthy: boolean;
@@ -124,6 +144,15 @@ export interface DaemonBackupResponse {
success: boolean;
}
export interface DaemonManagedDatabaseCredentials {
databaseName: string;
username: string;
password: string;
host: string;
port: number;
phpMyAdminUrl: string | null;
}
export interface DaemonNodeStatus {
version: string;
isHealthy: boolean;
@@ -156,11 +185,31 @@ interface DaemonServiceClient extends grpc.Client {
metadata: grpc.Metadata,
callback: UnaryCallback<DaemonServerResponse>,
): void;
updateServer(
request: DaemonUpdateServerRequest,
metadata: grpc.Metadata,
callback: UnaryCallback<DaemonServerResponse>,
): void;
deleteServer(
request: { uuid: string },
metadata: grpc.Metadata,
callback: UnaryCallback<EmptyResponse>,
): void;
createDatabase(
request: { server_uuid: string; name: string; password?: string },
metadata: grpc.Metadata,
callback: UnaryCallback<DaemonManagedDatabaseCredentialsRaw>,
): void;
updateDatabasePassword(
request: { username: string; password: string },
metadata: grpc.Metadata,
callback: UnaryCallback<EmptyResponse>,
): void;
deleteDatabase(
request: { database_name: string; username: string },
metadata: grpc.Metadata,
callback: UnaryCallback<EmptyResponse>,
): void;
setPowerState(
request: { uuid: string; action: number },
metadata: grpc.Metadata,
@@ -388,6 +437,12 @@ function toBuffer(data: Uint8Array | Buffer): Buffer {
const DEFAULT_CONNECT_TIMEOUT_MS = 8_000;
const DEFAULT_RPC_TIMEOUT_MS = 20_000;
const POWER_RPC_TIMEOUT_MS = 45_000;
interface DaemonRequestTimeoutOptions {
connectTimeoutMs?: number;
rpcTimeoutMs?: number;
}
export async function daemonGetNodeStatus(
node: DaemonNodeConnection,
@@ -464,6 +519,104 @@ export async function daemonDeleteServer(
}
}
export async function daemonUpdateServer(
node: DaemonNodeConnection,
request: DaemonUpdateServerRequest,
): Promise<DaemonServerResponse> {
const client = createClient(node);
try {
await waitForReady(client, DEFAULT_CONNECT_TIMEOUT_MS);
return await callUnary<DaemonServerResponse>(
(callback) => client.updateServer(request, getMetadata(node.daemonToken), callback),
DEFAULT_RPC_TIMEOUT_MS,
);
} finally {
client.close();
}
}
export async function daemonCreateDatabase(
node: DaemonNodeConnection,
request: { serverUuid: string; name: string; password?: string },
): Promise<DaemonManagedDatabaseCredentials> {
const client = createClient(node);
try {
await waitForReady(client, DEFAULT_CONNECT_TIMEOUT_MS);
const response = await callUnary<DaemonManagedDatabaseCredentialsRaw>(
(callback) =>
client.createDatabase(
{
server_uuid: request.serverUuid,
name: request.name,
password: request.password ?? '',
},
getMetadata(node.daemonToken),
callback,
),
DEFAULT_RPC_TIMEOUT_MS,
);
return {
databaseName: response.database_name,
username: response.username,
password: response.password,
host: response.host,
port: Number(response.port),
phpMyAdminUrl: response.phpmyadmin_url.trim() ? response.phpmyadmin_url : null,
};
} finally {
client.close();
}
}
export async function daemonUpdateDatabasePassword(
node: DaemonNodeConnection,
request: { username: string; password: string },
): Promise<void> {
const client = createClient(node);
try {
await waitForReady(client, DEFAULT_CONNECT_TIMEOUT_MS);
await callUnary<EmptyResponse>(
(callback) =>
client.updateDatabasePassword(
{
username: request.username,
password: request.password,
},
getMetadata(node.daemonToken),
callback,
),
DEFAULT_RPC_TIMEOUT_MS,
);
} finally {
client.close();
}
}
export async function daemonDeleteDatabase(
node: DaemonNodeConnection,
request: { databaseName: string; username: string },
): Promise<void> {
const client = createClient(node);
try {
await waitForReady(client, DEFAULT_CONNECT_TIMEOUT_MS);
await callUnary<EmptyResponse>(
(callback) =>
client.deleteDatabase(
{
database_name: request.databaseName,
username: request.username,
},
getMetadata(node.daemonToken),
callback,
),
DEFAULT_RPC_TIMEOUT_MS,
);
} finally {
client.close();
}
}
export async function daemonSetPowerState(
node: DaemonNodeConnection,
serverUuid: string,
@@ -474,7 +627,7 @@ export async function daemonSetPowerState(
await waitForReady(client, DEFAULT_CONNECT_TIMEOUT_MS);
await callUnary<EmptyResponse>(
(callback) => client.setPowerState({ uuid: serverUuid, action: POWER_ACTIONS[action] }, getMetadata(node.daemonToken), callback),
DEFAULT_RPC_TIMEOUT_MS,
POWER_RPC_TIMEOUT_MS,
);
} finally {
client.close();
@@ -484,13 +637,14 @@ export async function daemonSetPowerState(
export async function daemonGetServerStatus(
node: DaemonNodeConnection,
serverUuid: string,
timeouts: DaemonRequestTimeoutOptions = {},
): Promise<DaemonStatusResponse> {
const client = createClient(node);
try {
await waitForReady(client, DEFAULT_CONNECT_TIMEOUT_MS);
await waitForReady(client, timeouts.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS);
return await callUnary<DaemonStatusResponse>(
(callback) => client.getServerStatus({ uuid: serverUuid }, getMetadata(node.daemonToken), callback),
DEFAULT_RPC_TIMEOUT_MS,
timeouts.rpcTimeoutMs ?? DEFAULT_RPC_TIMEOUT_MS,
);
} finally {
client.close();