Merge 3129e59c63 into da71eaebd2
This commit is contained in:
commit
f9b0ab6e5d
@ -59,7 +59,7 @@ vi.mock("../daemon/legacy.js", () => ({
|
|||||||
|
|
||||||
vi.mock("../daemon/inspect.js", () => ({
|
vi.mock("../daemon/inspect.js", () => ({
|
||||||
findExtraGatewayServices: (env: unknown, opts?: unknown) => findExtraGatewayServices(env, opts),
|
findExtraGatewayServices: (env: unknown, opts?: unknown) => findExtraGatewayServices(env, opts),
|
||||||
renderGatewayServiceCleanupHints: () => [],
|
renderGatewayServiceCleanupHints: (_services: unknown[]) => [],
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("../infra/ports.js", () => ({
|
vi.mock("../infra/ports.js", () => ({
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import {
|
|||||||
} from "../../config/config.js";
|
} from "../../config/config.js";
|
||||||
import type { GatewayBindMode, GatewayControlUiConfig } from "../../config/types.js";
|
import type { GatewayBindMode, GatewayControlUiConfig } from "../../config/types.js";
|
||||||
import { readLastGatewayErrorLine } from "../../daemon/diagnostics.js";
|
import { readLastGatewayErrorLine } from "../../daemon/diagnostics.js";
|
||||||
import type { FindExtraGatewayServicesOptions } from "../../daemon/inspect.js";
|
import type { ExtraGatewayService, FindExtraGatewayServicesOptions } from "../../daemon/inspect.js";
|
||||||
import { findExtraGatewayServices } from "../../daemon/inspect.js";
|
import { findExtraGatewayServices } from "../../daemon/inspect.js";
|
||||||
import { resolveGatewayService } from "../../daemon/service.js";
|
import { resolveGatewayService } from "../../daemon/service.js";
|
||||||
import type { ServiceConfigAudit } from "../../daemon/service-audit.js";
|
import type { ServiceConfigAudit } from "../../daemon/service-audit.js";
|
||||||
@ -92,7 +92,7 @@ export type DaemonStatus = {
|
|||||||
error?: string;
|
error?: string;
|
||||||
url?: string;
|
url?: string;
|
||||||
};
|
};
|
||||||
extraServices: Array<{ label: string; detail: string; scope: string }>;
|
extraServices: ExtraGatewayService[];
|
||||||
};
|
};
|
||||||
|
|
||||||
function shouldReportPortUsage(status: PortUsageStatus | undefined, rpcOk?: boolean) {
|
function shouldReportPortUsage(status: PortUsageStatus | undefined, rpcOk?: boolean) {
|
||||||
|
|||||||
@ -292,7 +292,7 @@ export function printDaemonStatus(status: DaemonStatus, opts: { json: boolean })
|
|||||||
for (const svc of extraServices) {
|
for (const svc of extraServices) {
|
||||||
defaultRuntime.error(`- ${errorText(svc.label)} (${svc.scope}, ${svc.detail})`);
|
defaultRuntime.error(`- ${errorText(svc.label)} (${svc.scope}, ${svc.detail})`);
|
||||||
}
|
}
|
||||||
for (const hint of renderGatewayServiceCleanupHints()) {
|
for (const hint of renderGatewayServiceCleanupHints(extraServices)) {
|
||||||
defaultRuntime.error(`${errorText("Cleanup hint:")} ${hint}`);
|
defaultRuntime.error(`${errorText("Cleanup hint:")} ${hint}`);
|
||||||
}
|
}
|
||||||
spacer();
|
spacer();
|
||||||
|
|||||||
@ -248,7 +248,7 @@ export async function maybeScanExtraGatewayServices(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const cleanupHints = renderGatewayServiceCleanupHints();
|
const cleanupHints = renderGatewayServiceCleanupHints(extraServices);
|
||||||
if (cleanupHints.length > 0) {
|
if (cleanupHints.length > 0) {
|
||||||
note(cleanupHints.map((hint) => `- ${hint}`).join("\n"), "Cleanup hints");
|
note(cleanupHints.map((hint) => `- ${hint}`).join("\n"), "Cleanup hints");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,29 +27,46 @@ export type FindExtraGatewayServicesOptions = {
|
|||||||
const EXTRA_MARKERS = ["openclaw", "clawdbot", "moltbot"] as const;
|
const EXTRA_MARKERS = ["openclaw", "clawdbot", "moltbot"] as const;
|
||||||
const execFileAsync = promisify(execFile);
|
const execFileAsync = promisify(execFile);
|
||||||
|
|
||||||
export function renderGatewayServiceCleanupHints(
|
export function renderGatewayServiceCleanupHints(services: ExtraGatewayService[]): string[] {
|
||||||
env: Record<string, string | undefined> = process.env as Record<string, string | undefined>,
|
const hints: string[] = [];
|
||||||
): string[] {
|
for (const svc of services) {
|
||||||
const profile = env.OPENCLAW_PROFILE;
|
switch (svc.platform) {
|
||||||
switch (process.platform) {
|
case "darwin": {
|
||||||
case "darwin": {
|
hints.push(`launchctl bootout gui/$UID/${svc.label}`);
|
||||||
const label = resolveGatewayLaunchAgentLabel(profile);
|
const plistPath = extractPlistPath(svc.detail);
|
||||||
return [`launchctl bootout gui/$UID/${label}`, `rm ~/Library/LaunchAgents/${label}.plist`];
|
if (plistPath) {
|
||||||
|
hints.push(`rm ${plistPath}`);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "linux": {
|
||||||
|
const unitName = svc.label.endsWith(".service") ? svc.label : `${svc.label}.service`;
|
||||||
|
hints.push(`systemctl --user disable --now ${unitName}`);
|
||||||
|
const unitPath = extractUnitPath(svc.detail);
|
||||||
|
if (unitPath) {
|
||||||
|
hints.push(`rm ${unitPath}`);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "win32": {
|
||||||
|
hints.push(`schtasks /Delete /TN "${svc.label}" /F`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case "linux": {
|
|
||||||
const unit = resolveGatewaySystemdServiceName(profile);
|
|
||||||
return [
|
|
||||||
`systemctl --user disable --now ${unit}.service`,
|
|
||||||
`rm ~/.config/systemd/user/${unit}.service`,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
case "win32": {
|
|
||||||
const task = resolveGatewayWindowsTaskName(profile);
|
|
||||||
return [`schtasks /Delete /TN "${task}" /F`];
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
return hints;
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractPlistPath(detail: string): string | null {
|
||||||
|
if (!detail.startsWith("plist:")) return null;
|
||||||
|
const value = detail.slice("plist:".length).trim();
|
||||||
|
return value.length > 0 ? value : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractUnitPath(detail: string): string | null {
|
||||||
|
if (!detail.startsWith("unit:")) return null;
|
||||||
|
const value = detail.slice("unit:".length).trim();
|
||||||
|
return value.length > 0 ? value : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveHomeDir(env: Record<string, string | undefined>): string {
|
function resolveHomeDir(env: Record<string, string | undefined>): string {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user