131 lines
3.5 KiB
TypeScript
131 lines
3.5 KiB
TypeScript
#!/usr/bin/env bun
|
|
|
|
import {$} from "bun";
|
|
|
|
const SERVICES = {
|
|
ap: "phone-ap",
|
|
web: "phone-web",
|
|
phone: "phone",
|
|
} as const;
|
|
|
|
const COMMANDS = {
|
|
status: "Show service status",
|
|
logs: "Show recent logs (last 50 lines)",
|
|
tail: "Tail logs in real-time",
|
|
restart: "Restart service (requires sudo)",
|
|
stop: "Stop service (requires sudo)",
|
|
start: "Start service (requires sudo)",
|
|
} as const;
|
|
|
|
const showHelp = () => {
|
|
console.log(`
|
|
Phone CLI - Service Management
|
|
|
|
Usage: cli SERVICE COMMAND [-v]
|
|
|
|
Services:
|
|
ap WiFi AP Monitor (phone-ap.service)
|
|
web Web Server (phone-web.service)
|
|
phone Phone Application (phone.service)
|
|
|
|
Commands:
|
|
status Show service status
|
|
logs Show recent logs (last 50 lines)
|
|
tail Tail logs in real-time
|
|
restart Restart service (requires sudo)
|
|
stop Stop service (requires sudo)
|
|
start Start service (requires sudo)
|
|
|
|
Options:
|
|
-v Verbose mode - show actual systemd commands
|
|
|
|
Examples:
|
|
cli ap status
|
|
cli web logs
|
|
cli phone tail
|
|
cli -v ap status
|
|
sudo cli ap restart
|
|
`);
|
|
};
|
|
|
|
// Parse arguments
|
|
const args = process.argv.slice(2);
|
|
|
|
// Check for help
|
|
if (args.length === 0 || args[0] === "help") {
|
|
showHelp();
|
|
process.exit(0);
|
|
}
|
|
|
|
// Extract verbose flag and remaining args
|
|
const verbose = args.includes("-v");
|
|
const [service, command] = args.filter(arg => arg !== "-v");
|
|
|
|
// Validate service
|
|
if (!service || !(service in SERVICES)) {
|
|
console.error(`❌ Unknown service: ${service || "(missing)"}`);
|
|
console.log(`Available services: ${Object.keys(SERVICES).join(", ")}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
// Validate command
|
|
if (!command || !(command in COMMANDS)) {
|
|
console.error(`❌ Unknown command: ${command || "(missing)"}`);
|
|
console.log(`Available commands: ${Object.keys(COMMANDS).join(", ")}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
// Get systemd service name
|
|
const serviceName = SERVICES[service as keyof typeof SERVICES];
|
|
|
|
// Execute command
|
|
console.log(`\n🔧 Phone CLI - ${service} ${command}\n`);
|
|
|
|
const logCommand = (cmd: string) => {
|
|
if (verbose) {
|
|
console.log(`→ ${cmd}\n`);
|
|
}
|
|
};
|
|
|
|
switch (command) {
|
|
case "status":
|
|
logCommand(`systemctl status ${serviceName}.service --no-pager -l`);
|
|
await $`systemctl status ${serviceName}.service --no-pager -l`.nothrow();
|
|
break;
|
|
|
|
case "logs":
|
|
console.log(`📋 Recent logs (last 50 lines):\n`);
|
|
logCommand(`journalctl -u ${serviceName}.service -n 50 --no-pager`);
|
|
await $`journalctl -u ${serviceName}.service -n 50 --no-pager`.nothrow();
|
|
break;
|
|
|
|
case "tail":
|
|
console.log(`📡 Tailing logs (Ctrl+C to stop)...\n`);
|
|
logCommand(`journalctl -u ${serviceName}.service -f --no-pager`);
|
|
await $`journalctl -u ${serviceName}.service -f --no-pager`.nothrow();
|
|
break;
|
|
|
|
case "restart":
|
|
console.log(`🔄 Restarting ${serviceName}.service...\n`);
|
|
logCommand(`sudo systemctl restart ${serviceName}.service`);
|
|
await $`sudo systemctl restart ${serviceName}.service`;
|
|
console.log(`✓ ${serviceName}.service restarted!`);
|
|
break;
|
|
|
|
case "stop":
|
|
console.log(`🛑 Stopping ${serviceName}.service...\n`);
|
|
logCommand(`sudo systemctl stop ${serviceName}.service`);
|
|
await $`sudo systemctl stop ${serviceName}.service`;
|
|
console.log(`✓ ${serviceName}.service stopped!`);
|
|
break;
|
|
|
|
case "start":
|
|
console.log(`▶️ Starting ${serviceName}.service...\n`);
|
|
logCommand(`sudo systemctl start ${serviceName}.service`);
|
|
await $`sudo systemctl start ${serviceName}.service`;
|
|
console.log(`✓ ${serviceName}.service started!`);
|
|
break;
|
|
}
|
|
|
|
console.log("");
|