fix: honor gateway service override labels

This commit is contained in:
Peter Steinberger
2026-01-13 05:58:46 +00:00
parent 42ff634a9d
commit 5918def440
16 changed files with 128 additions and 35 deletions

View File

@@ -19,6 +19,15 @@ const formatLine = (label: string, value: string) => {
const rich = isRich();
return `${colorize(rich, theme.muted, `${label}:`)} ${colorize(rich, theme.command, value)}`;
};
function resolveLaunchAgentLabel(params?: {
env?: Record<string, string | undefined>;
profile?: string;
}): string {
const envLabel = params?.env?.CLAWDBOT_LAUNCHD_LABEL?.trim();
if (envLabel) return envLabel;
return resolveGatewayLaunchAgentLabel(params?.profile);
}
function resolveHomeDir(env: Record<string, string | undefined>): string {
const home = env.HOME?.trim() || env.USERPROFILE?.trim();
if (!home) throw new Error("Missing HOME");
@@ -284,9 +293,12 @@ export function parseLaunchctlPrint(output: string): LaunchctlPrintInfo {
return info;
}
export async function isLaunchAgentLoaded(profile?: string): Promise<boolean> {
export async function isLaunchAgentLoaded(params?: {
env?: Record<string, string | undefined>;
profile?: string;
}): Promise<boolean> {
const domain = resolveGuiDomain();
const label = resolveGatewayLaunchAgentLabel(profile);
const label = resolveLaunchAgentLabel(params);
const res = await execLaunchctl(["print", `${domain}/${label}`]);
return res.code === 0;
}
@@ -461,13 +473,15 @@ function isLaunchctlNotLoaded(res: {
export async function stopLaunchAgent({
stdout,
env,
profile,
}: {
stdout: NodeJS.WritableStream;
env?: Record<string, string | undefined>;
profile?: string;
}): Promise<void> {
const domain = resolveGuiDomain();
const label = resolveGatewayLaunchAgentLabel(profile);
const label = resolveLaunchAgentLabel({ env, profile });
const res = await execLaunchctl(["bootout", `${domain}/${label}`]);
if (res.code !== 0 && !isLaunchctlNotLoaded(res)) {
throw new Error(
@@ -548,13 +562,15 @@ export async function installLaunchAgent({
export async function restartLaunchAgent({
stdout,
env,
profile,
}: {
stdout: NodeJS.WritableStream;
env?: Record<string, string | undefined>;
profile?: string;
}): Promise<void> {
const domain = resolveGuiDomain();
const label = resolveGatewayLaunchAgentLabel(profile);
const label = resolveLaunchAgentLabel({ env, profile });
const res = await execLaunchctl(["kickstart", "-k", `${domain}/${label}`]);
if (res.code !== 0) {
throw new Error(

View File

@@ -45,14 +45,19 @@ export type GatewayService = {
stdout: NodeJS.WritableStream;
}) => Promise<void>;
stop: (args: {
env?: Record<string, string | undefined>;
profile?: string;
stdout: NodeJS.WritableStream;
}) => Promise<void>;
restart: (args: {
env?: Record<string, string | undefined>;
profile?: string;
stdout: NodeJS.WritableStream;
}) => Promise<void>;
isLoaded: (args: { profile?: string }) => Promise<boolean>;
isLoaded: (args: {
env?: Record<string, string | undefined>;
profile?: string;
}) => Promise<boolean>;
readCommand: (env: Record<string, string | undefined>) => Promise<{
programArguments: string[];
workingDirectory?: string;
@@ -77,15 +82,21 @@ export function resolveGatewayService(): GatewayService {
await uninstallLaunchAgent(args);
},
stop: async (args) => {
await stopLaunchAgent({ stdout: args.stdout, profile: args.profile });
await stopLaunchAgent({
stdout: args.stdout,
profile: args.profile,
env: args.env,
});
},
restart: async (args) => {
await restartLaunchAgent({
stdout: args.stdout,
profile: args.profile,
env: args.env,
});
},
isLoaded: async (args) => isLaunchAgentLoaded(args.profile),
isLoaded: async (args) =>
isLaunchAgentLoaded({ profile: args.profile, env: args.env }),
readCommand: readLaunchAgentProgramArguments,
readRuntime: readLaunchAgentRuntime,
};
@@ -106,15 +117,18 @@ export function resolveGatewayService(): GatewayService {
await stopSystemdService({
stdout: args.stdout,
profile: args.profile,
env: args.env,
});
},
restart: async (args) => {
await restartSystemdService({
stdout: args.stdout,
profile: args.profile,
env: args.env,
});
},
isLoaded: async (args) => isSystemdServiceEnabled(args.profile),
isLoaded: async (args) =>
isSystemdServiceEnabled({ profile: args.profile, env: args.env }),
readCommand: readSystemdServiceExecStart,
readRuntime: async (env) => await readSystemdServiceRuntime(env),
};
@@ -132,7 +146,10 @@ export function resolveGatewayService(): GatewayService {
await uninstallScheduledTask(args);
},
stop: async (args) => {
await stopScheduledTask({ stdout: args.stdout, profile: args.profile });
await stopScheduledTask({
stdout: args.stdout,
profile: args.profile,
});
},
restart: async (args) => {
await restartScheduledTask({

View File

@@ -46,6 +46,14 @@ function resolveSystemdServiceName(
return resolveGatewaySystemdServiceName(env.CLAWDBOT_PROFILE);
}
function resolveSystemdServiceNameFromParams(params?: {
env?: Record<string, string | undefined>;
profile?: string;
}): string {
if (params?.env) return resolveSystemdServiceName(params.env);
return resolveGatewaySystemdServiceName(params?.profile);
}
function resolveSystemdUnitPath(
env: Record<string, string | undefined>,
): string {
@@ -466,13 +474,15 @@ export async function uninstallSystemdService({
export async function stopSystemdService({
stdout,
env,
profile,
}: {
stdout: NodeJS.WritableStream;
env?: Record<string, string | undefined>;
profile?: string;
}): Promise<void> {
await assertSystemdAvailable();
const serviceName = resolveGatewaySystemdServiceName(profile);
const serviceName = resolveSystemdServiceNameFromParams({ env, profile });
const unitName = `${serviceName}.service`;
const res = await execSystemctl(["--user", "stop", unitName]);
if (res.code !== 0) {
@@ -485,13 +495,15 @@ export async function stopSystemdService({
export async function restartSystemdService({
stdout,
env,
profile,
}: {
stdout: NodeJS.WritableStream;
env?: Record<string, string | undefined>;
profile?: string;
}): Promise<void> {
await assertSystemdAvailable();
const serviceName = resolveGatewaySystemdServiceName(profile);
const serviceName = resolveSystemdServiceNameFromParams({ env, profile });
const unitName = `${serviceName}.service`;
const res = await execSystemctl(["--user", "restart", unitName]);
if (res.code !== 0) {
@@ -502,11 +514,12 @@ export async function restartSystemdService({
stdout.write(`${formatLine("Restarted systemd service", unitName)}\n`);
}
export async function isSystemdServiceEnabled(
profile?: string,
): Promise<boolean> {
export async function isSystemdServiceEnabled(params?: {
env?: Record<string, string | undefined>;
profile?: string;
}): Promise<boolean> {
await assertSystemdAvailable();
const serviceName = resolveGatewaySystemdServiceName(profile);
const serviceName = resolveSystemdServiceNameFromParams(params);
const unitName = `${serviceName}.service`;
const res = await execSystemctl(["--user", "is-enabled", unitName]);
return res.code === 0;