Files
EJClaw/setup/restart-stack.ts
2026-03-29 07:08:01 +09:00

64 lines
1.8 KiB
TypeScript

import { execFileSync } from 'child_process';
import { pathToFileURL } from 'url';
import { getServiceManager, isRoot } from './platform.js';
import { getConfiguredServiceNames } from './service-defs.js';
type ServiceManager = ReturnType<typeof getServiceManager>;
interface RestartStackDeps {
execFileSyncImpl?: typeof execFileSync;
runningAsRoot?: boolean;
serviceManager?: ServiceManager;
}
export function restartStackServices(
projectRoot: string,
deps: RestartStackDeps = {},
): string[] {
const serviceManager = deps.serviceManager ?? getServiceManager();
if (serviceManager !== 'systemd') {
throw new Error(
'restart:stack only supports Linux systemd services in this repo',
);
}
const services = getConfiguredServiceNames(projectRoot);
if (services.length === 0) {
throw new Error('No EJClaw services are configured in this project');
}
const execImpl = deps.execFileSyncImpl ?? execFileSync;
const systemctlArgs = deps.runningAsRoot ?? isRoot() ? [] : ['--user'];
execImpl('systemctl', [...systemctlArgs, 'restart', ...services], {
stdio: 'ignore',
});
for (const service of services) {
execImpl('systemctl', [...systemctlArgs, 'is-active', '--quiet', service], {
stdio: 'ignore',
});
}
return services;
}
export async function run(_args: string[]): Promise<void> {
const services = restartStackServices(process.cwd());
console.log(`Restarted and verified: ${services.join(', ')}`);
}
if (process.argv[1]) {
const isMain =
import.meta.url === pathToFileURL(process.argv[1]).href ||
import.meta.url === pathToFileURL(process.argv[1]).toString();
if (isMain) {
run([]).catch((error) => {
const message = error instanceof Error ? error.message : String(error);
console.error(message);
process.exit(1);
});
}
}