feat: add uptime runner agent
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
import { DEFAULT_CONFIG_PATH } from './config.ts';
|
||||
|
||||
const SERVICE_FILE_PATH = '/etc/systemd/system/uptimerunner.service';
|
||||
|
||||
export class UptimeRunnerSystemd {
|
||||
private readonly serviceTemplate = `[Unit]
|
||||
Description=uptime.link Runner Agent
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/local/bin/uptimerunner run --config ${DEFAULT_CONFIG_PATH}
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
User=root
|
||||
Group=root
|
||||
Environment=PATH=/usr/bin:/usr/local/bin
|
||||
WorkingDirectory=/opt/uptimerunner
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
`;
|
||||
|
||||
public async install(): Promise<void> {
|
||||
this.assertRoot();
|
||||
await Deno.writeTextFile(SERVICE_FILE_PATH, this.serviceTemplate);
|
||||
await run('systemctl', ['daemon-reload']);
|
||||
await run('systemctl', ['enable', 'uptimerunner.service']);
|
||||
console.log(`Service installed: ${SERVICE_FILE_PATH}`);
|
||||
}
|
||||
|
||||
public async uninstall(): Promise<void> {
|
||||
this.assertRoot();
|
||||
await run('systemctl', ['disable', '--now', 'uptimerunner.service']).catch(() => null);
|
||||
await Deno.remove(SERVICE_FILE_PATH).catch(() => null);
|
||||
await run('systemctl', ['daemon-reload']);
|
||||
console.log('Service removed.');
|
||||
}
|
||||
|
||||
public async start(): Promise<void> {
|
||||
await run('systemctl', ['start', 'uptimerunner.service']);
|
||||
}
|
||||
|
||||
public async stop(): Promise<void> {
|
||||
await run('systemctl', ['stop', 'uptimerunner.service']);
|
||||
}
|
||||
|
||||
public async restart(): Promise<void> {
|
||||
await run('systemctl', ['restart', 'uptimerunner.service']);
|
||||
}
|
||||
|
||||
public async status(): Promise<void> {
|
||||
await run('systemctl', ['status', 'uptimerunner.service', '--no-pager']);
|
||||
}
|
||||
|
||||
public async logs(): Promise<void> {
|
||||
await run('journalctl', ['-u', 'uptimerunner.service', '-n', '120', '--no-pager']);
|
||||
}
|
||||
|
||||
private assertRoot(): void {
|
||||
if (Deno.uid && Deno.uid() !== 0) {
|
||||
throw new Error('This service command must run as root.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function run(commandArg: string, argsArg: string[]): Promise<void> {
|
||||
const command = new Deno.Command(commandArg, {
|
||||
args: argsArg,
|
||||
stdout: 'inherit',
|
||||
stderr: 'inherit',
|
||||
});
|
||||
const output = await command.output();
|
||||
if (!output.success) {
|
||||
throw new Error(`${commandArg} ${argsArg.join(' ')} exited with ${output.code}`);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user