learning_ai_common_plat/dashboards/admin-web/src/lib/docker-control.ts

64 lines
1.7 KiB
TypeScript

import http from 'node:http';
import { RESTARTABLE_SERVICE_CONTAINERS } from '@/lib/ops-stack';
const DOCKER_SOCKET_PATH = '/var/run/docker.sock';
function dockerRequest(
method: string,
path: string,
body?: string
): Promise<{ statusCode: number; body: string }> {
return new Promise((resolve, reject) => {
const req = http.request(
{
socketPath: DOCKER_SOCKET_PATH,
path,
method,
headers: body
? {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(body),
}
: undefined,
},
res => {
let data = '';
res.setEncoding('utf8');
res.on('data', chunk => {
data += chunk;
});
res.on('end', () => {
resolve({
statusCode: res.statusCode ?? 500,
body: data,
});
});
}
);
req.on('error', reject);
if (body) {
req.write(body);
}
req.end();
});
}
export function isRestartableService(serviceId: string): boolean {
return Boolean(RESTARTABLE_SERVICE_CONTAINERS[serviceId]);
}
export async function restartServiceContainer(serviceId: string): Promise<{ container: string }> {
const container = RESTARTABLE_SERVICE_CONTAINERS[serviceId];
if (!container) {
throw new Error('Service is not restartable from admin ops');
}
const response = await dockerRequest('POST', `/containers/${encodeURIComponent(container)}/restart?t=10`);
if (![204, 304].includes(response.statusCode)) {
throw new Error(response.body || `Docker restart failed with status ${response.statusCode}`);
}
return { container };
}