feat(systemd): replace smartdaemon-based service management with native systemd commands
This commit is contained in:
89
ts/cli.ts
89
ts/cli.ts
@@ -7,6 +7,7 @@ import { projectInfo } from './info.ts';
|
||||
import { getErrorMessage } from './utils/error.ts';
|
||||
import { Onebox } from './classes/onebox.ts';
|
||||
import { OneboxDaemon } from './classes/daemon.ts';
|
||||
import { OneboxSystemd } from './classes/systemd.ts';
|
||||
|
||||
export async function runCli(): Promise<void> {
|
||||
const args = Deno.args;
|
||||
@@ -25,6 +26,19 @@ export async function runCli(): Promise<void> {
|
||||
const subcommand = args[1];
|
||||
|
||||
try {
|
||||
// === LIGHTWEIGHT COMMANDS (no init()) ===
|
||||
if (command === 'systemd') {
|
||||
await handleSystemdCommand(subcommand, args.slice(2));
|
||||
return;
|
||||
}
|
||||
|
||||
if (command === 'upgrade') {
|
||||
await handleUpgradeCommand();
|
||||
return;
|
||||
}
|
||||
|
||||
// === HEAVY COMMANDS (require full init()) ===
|
||||
|
||||
// Server command has special handling (doesn't shut down)
|
||||
if (command === 'server') {
|
||||
const onebox = new Onebox();
|
||||
@@ -60,10 +74,6 @@ export async function runCli(): Promise<void> {
|
||||
await handleNginxCommand(onebox, subcommand, args.slice(2));
|
||||
break;
|
||||
|
||||
case 'daemon':
|
||||
await handleDaemonCommand(onebox, subcommand, args.slice(2));
|
||||
break;
|
||||
|
||||
case 'config':
|
||||
await handleConfigCommand(onebox, subcommand, args.slice(2));
|
||||
break;
|
||||
@@ -72,10 +82,6 @@ export async function runCli(): Promise<void> {
|
||||
await handleStatusCommand(onebox);
|
||||
break;
|
||||
|
||||
case 'upgrade':
|
||||
await handleUpgradeCommand();
|
||||
break;
|
||||
|
||||
default:
|
||||
logger.error(`Unknown command: ${command}`);
|
||||
printHelp();
|
||||
@@ -282,7 +288,7 @@ async function handleServerCommand(onebox: Onebox, args: string[]) {
|
||||
await OneboxDaemon.ensureNoDaemon();
|
||||
} catch (error) {
|
||||
logger.error('Cannot start in ephemeral mode: Daemon is already running');
|
||||
logger.info('Stop the daemon first: onebox daemon stop');
|
||||
logger.info('Stop the daemon first: onebox systemd stop');
|
||||
logger.info('Or run without --ephemeral to use the existing daemon');
|
||||
Deno.exit(1);
|
||||
}
|
||||
@@ -326,39 +332,49 @@ async function handleServerCommand(onebox: Onebox, args: string[]) {
|
||||
}
|
||||
}
|
||||
|
||||
// Daemon commands
|
||||
async function handleDaemonCommand(onebox: Onebox, subcommand: string, _args: string[]) {
|
||||
// Systemd service commands (lightweight — no Onebox init)
|
||||
async function handleSystemdCommand(subcommand: string, _args: string[]) {
|
||||
const systemd = new OneboxSystemd();
|
||||
|
||||
switch (subcommand) {
|
||||
case 'install':
|
||||
await onebox.daemon.installService();
|
||||
case 'enable':
|
||||
await systemd.enable();
|
||||
break;
|
||||
|
||||
case 'disable':
|
||||
await systemd.disable();
|
||||
break;
|
||||
|
||||
case 'start':
|
||||
await onebox.startDaemon();
|
||||
await systemd.start();
|
||||
break;
|
||||
|
||||
case 'stop':
|
||||
await onebox.stopDaemon();
|
||||
await systemd.stop();
|
||||
break;
|
||||
|
||||
case 'logs': {
|
||||
const command = new Deno.Command('journalctl', {
|
||||
args: ['-u', 'smartdaemon_onebox', '-f'],
|
||||
stdout: 'inherit',
|
||||
stderr: 'inherit',
|
||||
});
|
||||
await command.output();
|
||||
case 'status': {
|
||||
const status = await systemd.getStatus();
|
||||
logger.info(`Service status: ${status}`);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'status': {
|
||||
const status = await onebox.daemon.getServiceStatus();
|
||||
logger.info(`Daemon status: ${status}`);
|
||||
case 'logs':
|
||||
await systemd.showLogs();
|
||||
break;
|
||||
|
||||
case 'start-daemon': {
|
||||
// This is what systemd's ExecStart calls — full init + daemon loop
|
||||
const onebox = new Onebox();
|
||||
await onebox.init();
|
||||
await onebox.daemon.start();
|
||||
// start() blocks (keepAlive loop) until SIGTERM/SIGINT
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
logger.error(`Unknown daemon subcommand: ${subcommand}`);
|
||||
logger.error(`Unknown systemd subcommand: ${subcommand}`);
|
||||
logger.info('Available: enable, disable, start, stop, status, logs');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -506,11 +522,12 @@ Commands:
|
||||
nginx test
|
||||
nginx status
|
||||
|
||||
daemon install
|
||||
daemon start
|
||||
daemon stop
|
||||
daemon logs
|
||||
daemon status
|
||||
systemd enable Install and enable systemd service
|
||||
systemd disable Stop, disable, and remove systemd service
|
||||
systemd start Start onebox via systemctl
|
||||
systemd stop Stop onebox via systemctl
|
||||
systemd status Show systemd service status
|
||||
systemd logs Follow service logs (journalctl)
|
||||
|
||||
config show
|
||||
config set <key> <value>
|
||||
@@ -530,15 +547,15 @@ Development Workflow:
|
||||
onebox service add ... # In another terminal
|
||||
|
||||
Production Workflow:
|
||||
onebox daemon install # Install systemd service
|
||||
onebox daemon start # Start daemon
|
||||
onebox service add ... # CLI uses daemon
|
||||
onebox systemd enable # Install and enable systemd service
|
||||
onebox systemd start # Start via systemctl
|
||||
onebox service add ... # CLI manages services
|
||||
|
||||
Examples:
|
||||
onebox server --ephemeral # Start dev server
|
||||
onebox service add myapp --image nginx:latest --domain app.example.com --port 80
|
||||
onebox registry add --url registry.example.com --username user --password pass
|
||||
onebox daemon install
|
||||
onebox daemon start
|
||||
onebox systemd enable
|
||||
onebox systemd start
|
||||
`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user