mirror of
https://fastgit.cc/github.com/openclaw/openclaw
synced 2026-05-01 06:36:23 +08:00
fix: audit windows task managed env drift
This commit is contained in:
@@ -433,7 +433,7 @@ That stages grounded durable candidates into the short-term dreaming store while
|
||||
- `openclaw doctor --repair --force` overwrites custom supervisor configs.
|
||||
- `OPENCLAW_SERVICE_REPAIR_POLICY=external` keeps doctor read-only for gateway service lifecycle. It still reports service health and runs non-service repairs, but skips service install/start/restart/bootstrap, supervisor config rewrites, and legacy service cleanup because an external supervisor owns that lifecycle.
|
||||
- If token auth requires a token and `gateway.auth.token` is SecretRef-managed, doctor service install/repair validates the SecretRef but does not persist resolved plaintext token values into supervisor service environment metadata.
|
||||
- Doctor detects managed `.env`/SecretRef-backed service environment values that older LaunchAgent/systemd installs embedded inline and rewrites the service metadata so those values load from the runtime source instead of the supervisor definition.
|
||||
- Doctor detects managed `.env`/SecretRef-backed service environment values that older LaunchAgent, systemd, or Windows Scheduled Task installs embedded inline and rewrites the service metadata so those values load from the runtime source instead of the supervisor definition.
|
||||
- If token auth requires a token and the configured token SecretRef is unresolved, doctor blocks the install/repair path with actionable guidance.
|
||||
- If both `gateway.auth.token` and `gateway.auth.password` are configured and `gateway.auth.mode` is unset, doctor blocks install/repair until mode is set explicitly.
|
||||
- For Linux user-systemd units, doctor token drift checks now include both `Environment=` and `EnvironmentFile=` sources when comparing service auth metadata.
|
||||
|
||||
@@ -4,6 +4,7 @@ import path from "node:path";
|
||||
import { PassThrough } from "node:stream";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { installScheduledTask, readScheduledTaskCommand } from "./schtasks.js";
|
||||
import { auditGatewayServiceConfig, SERVICE_AUDIT_CODES } from "./service-audit.js";
|
||||
|
||||
const schtasksCalls: string[][] = [];
|
||||
const schtasksResponses: { code: number; stdout: string; stderr: string }[] = [];
|
||||
@@ -243,4 +244,35 @@ describe("installScheduledTask", () => {
|
||||
expect(script).toContain('set "OPENCLAW_GATEWAY_PORT=18789"');
|
||||
});
|
||||
});
|
||||
|
||||
it("exposes Windows task script env values as inline for managed-env drift audit", async () => {
|
||||
await withUserProfileDir(async (_tmpDir, env) => {
|
||||
const { scriptPath } = await installScheduledTask({
|
||||
env,
|
||||
stdout: new PassThrough(),
|
||||
programArguments: ["node", "gateway.js"],
|
||||
environment: {
|
||||
OPENCLAW_SERVICE_MANAGED_ENV_KEYS: "TAVILY_API_KEY",
|
||||
TAVILY_API_KEY: "old-inline-value",
|
||||
},
|
||||
});
|
||||
|
||||
const command = await readScheduledTaskCommand(env);
|
||||
expect(command?.environmentValueSources).toMatchObject({
|
||||
OPENCLAW_SERVICE_MANAGED_ENV_KEYS: "inline",
|
||||
TAVILY_API_KEY: "inline",
|
||||
});
|
||||
expect(command?.sourcePath).toBe(scriptPath);
|
||||
|
||||
const audit = await auditGatewayServiceConfig({
|
||||
env,
|
||||
platform: "win32",
|
||||
command,
|
||||
expectedManagedServiceEnvKeys: ["TAVILY_API_KEY"],
|
||||
});
|
||||
expect(
|
||||
audit.issues.some((issue) => issue.code === SERVICE_AUDIT_CODES.gatewayManagedEnvEmbedded),
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -237,6 +237,10 @@ describe("readScheduledTaskCommand", () => {
|
||||
NODE_ENV: "production",
|
||||
OPENCLAW_PORT: "18789",
|
||||
},
|
||||
environmentValueSources: {
|
||||
NODE_ENV: "inline",
|
||||
OPENCLAW_PORT: "inline",
|
||||
},
|
||||
sourcePath: resolveTaskScriptPath(env),
|
||||
});
|
||||
},
|
||||
|
||||
@@ -150,6 +150,13 @@ export async function readScheduledTaskCommand(
|
||||
programArguments: parseCmdScriptCommandLine(commandLine),
|
||||
...(workingDirectory ? { workingDirectory } : {}),
|
||||
...(Object.keys(environment).length > 0 ? { environment } : {}),
|
||||
...(Object.keys(environment).length > 0
|
||||
? {
|
||||
environmentValueSources: Object.fromEntries(
|
||||
Object.keys(environment).map((key) => [key, "inline"]),
|
||||
),
|
||||
}
|
||||
: {}),
|
||||
sourcePath: scriptPath,
|
||||
};
|
||||
} catch {
|
||||
|
||||
Reference in New Issue
Block a user