

























@@ -50,6 +50,27 @@ function createGatewayAudit({
5050});
5151}
525253+async function writeSystemdUnitForAudit(home: string, lines: string[]) {
54+const unitDir = path.join(home, ".config", "systemd", "user");
55+const unitPath = path.join(unitDir, "openclaw-gateway.service");
56+await fs.mkdir(unitDir, { recursive: true });
57+await fs.writeFile(
58+unitPath,
59+[
60+"[Unit]",
61+"Description=OpenClaw Gateway",
62+"[Service]",
63+ ...lines,
64+"ExecStart=/usr/bin/node gateway",
65+"",
66+"[Install]",
67+"WantedBy=default.target",
68+"",
69+].join("\n"),
70+"utf8",
71+);
72+}
73+5374function expectTokenAudit(
5475audit: Awaited<ReturnType<typeof auditGatewayServiceConfig>>,
5576{
@@ -378,6 +399,54 @@ describe("auditGatewayServiceConfig", () => {
378399expectTokenAudit(audit, { embedded: true, mismatch: true });
379400});
380401402+it.each(["process", "none"])(
403+`warns when KillMode is %s in explicit unit file`,
404+async (killMode) => {
405+const home = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-service-audit-killmode-"));
406+await writeSystemdUnitForAudit(home, [
407+"After=network-online.target",
408+"Wants=network-online.target",
409+"RestartSec=5",
410+`KillMode=${killMode}`,
411+]);
412+413+const audit = await auditGatewayServiceConfig({
414+env: { HOME: home },
415+platform: "linux",
416+command: {
417+programArguments: ["/usr/bin/node", "gateway"],
418+environment: { PATH: "/usr/bin:/bin" },
419+},
420+});
421+expect(
422+audit.issues.some(
423+(entry) => entry.code === SERVICE_AUDIT_CODES.systemdKillModeProcessOrNone,
424+),
425+).toBe(true);
426+},
427+);
428+429+it("does not warn when KillMode is control-group", async () => {
430+const home = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-service-audit-killmode-"));
431+await writeSystemdUnitForAudit(home, [
432+"After=network-online.target",
433+"Wants=network-online.target",
434+"RestartSec=5",
435+"KillMode=control-group",
436+]);
437+const audit = await auditGatewayServiceConfig({
438+env: { HOME: home },
439+platform: "linux",
440+command: {
441+programArguments: ["/usr/bin/node", "gateway"],
442+environment: { PATH: "/usr/bin:/bin" },
443+},
444+});
445+expect(
446+audit.issues.some((entry) => entry.code === SERVICE_AUDIT_CODES.systemdKillModeProcessOrNone),
447+).toBe(false);
448+});
449+381450it("flags embedded service token even when it matches config token", async () => {
382451const audit = await createGatewayAudit({
383452expectedGatewayToken: "new-token",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。