2026-08-16 11:03:25 +02:00
|
|
|
import os from "node:os";
|
|
|
|
|
import path from "node:path";
|
|
|
|
|
|
|
|
|
|
export const SERVICE_NAME = "triggershell";
|
|
|
|
|
|
|
|
|
|
export interface UnitOptions {
|
|
|
|
|
execPath: string;
|
|
|
|
|
binPath: string;
|
|
|
|
|
configPath: string;
|
|
|
|
|
configDir: string;
|
|
|
|
|
port?: number;
|
|
|
|
|
host?: string;
|
|
|
|
|
scope: "user" | "system";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function renderUnit(opts: UnitOptions): string {
|
|
|
|
|
const args = ["start", "--config", opts.configPath, "--no-browser"];
|
|
|
|
|
if (opts.port !== undefined) args.push("--port", String(opts.port));
|
|
|
|
|
if (opts.host !== undefined) args.push("--host", opts.host);
|
|
|
|
|
|
|
|
|
|
const execStart = [opts.execPath, opts.binPath, ...args]
|
|
|
|
|
.map((part) => (part.includes(" ") ? `"${part}"` : part))
|
|
|
|
|
.join(" ");
|
|
|
|
|
|
2026-08-16 13:55:25 +02:00
|
|
|
const wantedBy =
|
|
|
|
|
opts.scope === "user" ? "default.target" : "multi-user.target";
|
2026-08-16 11:03:25 +02:00
|
|
|
|
|
|
|
|
return `[Unit]
|
|
|
|
|
Description=TriggerShell - self-hosted script runner
|
|
|
|
|
After=network.target
|
|
|
|
|
|
|
|
|
|
[Service]
|
|
|
|
|
Type=simple
|
|
|
|
|
ExecStart=${execStart}
|
|
|
|
|
WorkingDirectory=${opts.configDir}
|
|
|
|
|
Restart=on-failure
|
|
|
|
|
RestartSec=2
|
|
|
|
|
Environment=NODE_ENV=production
|
|
|
|
|
|
|
|
|
|
[Install]
|
|
|
|
|
WantedBy=${wantedBy}
|
|
|
|
|
`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function userUnitPath(): string {
|
2026-08-16 13:55:25 +02:00
|
|
|
return path.join(
|
|
|
|
|
os.homedir(),
|
|
|
|
|
".config",
|
|
|
|
|
"systemd",
|
|
|
|
|
"user",
|
|
|
|
|
`${SERVICE_NAME}.service`,
|
|
|
|
|
);
|
2026-08-16 11:03:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function systemUnitPath(): string {
|
|
|
|
|
return path.join("/etc", "systemd", "system", `${SERVICE_NAME}.service`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function isRoot(): boolean {
|
|
|
|
|
return process.getuid?.() === 0;
|
|
|
|
|
}
|