/** * CLI Router for Onebox */ import { logger } from './onebox.logging.ts'; import { projectInfo } from './onebox.info.ts'; import { Onebox } from './onebox.classes.onebox.ts'; export async function runCli(): Promise { const args = Deno.args; if (args.length === 0 || args.includes('--help') || args.includes('-h')) { printHelp(); return; } if (args.includes('--version') || args.includes('-v')) { console.log(`${projectInfo.name} v${projectInfo.version}`); return; } const command = args[0]; const subcommand = args[1]; try { // Initialize Onebox const onebox = new Onebox(); await onebox.init(); // Route commands switch (command) { case 'service': await handleServiceCommand(onebox, subcommand, args.slice(2)); break; case 'registry': await handleRegistryCommand(onebox, subcommand, args.slice(2)); break; case 'dns': await handleDnsCommand(onebox, subcommand, args.slice(2)); break; case 'ssl': await handleSslCommand(onebox, subcommand, args.slice(2)); break; case 'nginx': 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; case 'status': await handleStatusCommand(onebox); break; default: logger.error(`Unknown command: ${command}`); printHelp(); Deno.exit(1); } // Cleanup await onebox.shutdown(); } catch (error) { logger.error(error.message); Deno.exit(1); } } // Service commands async function handleServiceCommand(onebox: Onebox, subcommand: string, args: string[]) { switch (subcommand) { case 'add': { const name = args[0]; const image = getArg(args, '--image'); const domain = getArg(args, '--domain'); const port = parseInt(getArg(args, '--port') || '80', 10); const envArgs = args.filter((a) => a.startsWith('--env=')).map((a) => a.slice(6)); const envVars: Record = {}; for (const env of envArgs) { const [key, value] = env.split('='); envVars[key] = value; } await onebox.services.deployService({ name, image, port, domain, envVars }); break; } case 'remove': await onebox.services.removeService(args[0]); break; case 'start': await onebox.services.startService(args[0]); break; case 'stop': await onebox.services.stopService(args[0]); break; case 'restart': await onebox.services.restartService(args[0]); break; case 'list': { const services = onebox.services.listServices(); logger.table( ['Name', 'Image', 'Status', 'Domain', 'Port'], services.map((s) => [s.name, s.image, s.status, s.domain || '-', s.port.toString()]) ); break; } case 'logs': { const logs = await onebox.services.getServiceLogs(args[0]); console.log(logs); break; } default: logger.error(`Unknown service subcommand: ${subcommand}`); } } // Registry commands async function handleRegistryCommand(onebox: Onebox, subcommand: string, args: string[]) { switch (subcommand) { case 'add': { const url = getArg(args, '--url'); const username = getArg(args, '--username'); const password = getArg(args, '--password'); await onebox.registries.addRegistry(url, username, password); break; } case 'remove': await onebox.registries.removeRegistry(getArg(args, '--url')); break; case 'list': { const registries = onebox.registries.listRegistries(); logger.table( ['URL', 'Username'], registries.map((r) => [r.url, r.username]) ); break; } default: logger.error(`Unknown registry subcommand: ${subcommand}`); } } // DNS commands async function handleDnsCommand(onebox: Onebox, subcommand: string, args: string[]) { switch (subcommand) { case 'add': await onebox.dns.addDNSRecord(args[0]); break; case 'remove': await onebox.dns.removeDNSRecord(args[0]); break; case 'list': { const records = onebox.dns.listDNSRecords(); logger.table( ['Domain', 'Type', 'Value'], records.map((r) => [r.domain, r.type, r.value]) ); break; } case 'sync': await onebox.dns.syncFromCloudflare(); break; default: logger.error(`Unknown dns subcommand: ${subcommand}`); } } // SSL commands async function handleSslCommand(onebox: Onebox, subcommand: string, args: string[]) { switch (subcommand) { case 'renew': if (args[0]) { await onebox.ssl.renewCertificate(args[0]); } else { await onebox.ssl.renewExpiring(); } break; case 'list': { const certs = onebox.ssl.listCertificates(); logger.table( ['Domain', 'Expiry', 'Issuer'], certs.map((c) => [c.domain, new Date(c.expiryDate).toISOString(), c.issuer]) ); break; } case 'force-renew': await onebox.ssl.renewCertificate(args[0]); break; default: logger.error(`Unknown ssl subcommand: ${subcommand}`); } } // Nginx commands async function handleNginxCommand(onebox: Onebox, subcommand: string, _args: string[]) { switch (subcommand) { case 'reload': await onebox.nginx.reload(); break; case 'test': await onebox.nginx.test(); break; case 'status': { const status = await onebox.nginx.getStatus(); logger.info(`Nginx status: ${status}`); break; } default: logger.error(`Unknown nginx subcommand: ${subcommand}`); } } // Daemon commands async function handleDaemonCommand(onebox: Onebox, subcommand: string, _args: string[]) { switch (subcommand) { case 'install': await onebox.daemon.installService(); break; case 'start': await onebox.startDaemon(); break; case 'stop': await onebox.stopDaemon(); break; case 'logs': { const command = new Deno.Command('journalctl', { args: ['-u', 'smartdaemon_onebox', '-f'], stdout: 'inherit', stderr: 'inherit', }); await command.output(); break; } case 'status': { const status = await onebox.daemon.getServiceStatus(); logger.info(`Daemon status: ${status}`); break; } default: logger.error(`Unknown daemon subcommand: ${subcommand}`); } } // Config commands async function handleConfigCommand(onebox: Onebox, subcommand: string, args: string[]) { switch (subcommand) { case 'show': { const settings = onebox.database.getAllSettings(); logger.table( ['Key', 'Value'], Object.entries(settings).map(([k, v]) => [k, v]) ); break; } case 'set': onebox.database.setSetting(args[0], args[1]); logger.success(`Setting ${args[0]} updated`); break; default: logger.error(`Unknown config subcommand: ${subcommand}`); } } // Status command async function handleStatusCommand(onebox: Onebox) { const status = await onebox.getSystemStatus(); console.log(JSON.stringify(status, null, 2)); } // Helpers function getArg(args: string[], flag: string): string { const arg = args.find((a) => a.startsWith(`${flag}=`)); return arg ? arg.split('=')[1] : ''; } function printHelp(): void { console.log(` Onebox v${projectInfo.version} - Self-hosted container platform Usage: onebox [options] Commands: service add --image [--domain ] [--port ] [--env KEY=VALUE] service remove service start service stop service restart service list service logs registry add --url --username --password registry remove --url registry list dns add dns remove dns list dns sync ssl renew [domain] ssl list ssl force-renew nginx reload nginx test nginx status daemon install daemon start daemon stop daemon logs daemon status config show config set status Options: --help, -h Show this help message --version, -v Show version --debug Enable debug logging Examples: 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 `); }