fix: stabilize launchd CA env tests (#27915) (thanks @Lukavyi)

This commit is contained in:
Ayaan Zaidi 2026-02-27 08:11:01 +05:30 committed by Ayaan Zaidi
parent 6b59c87570
commit 9d52dcf1f4
3 changed files with 29 additions and 14 deletions

View File

@ -69,6 +69,7 @@ Docs: https://docs.openclaw.ai
- CLI/Daemon status TLS probe: use `wss://` and forward local TLS certificate fingerprint for TLS-enabled gateway daemon probes so `openclaw daemon status` works with `gateway.bind=lan` + `gateway.tls.enabled=true`. (#24234) thanks @liuy.
- Podman/Default bind: change `run-openclaw-podman.sh` default gateway bind from `lan` to `loopback` and document explicit LAN opt-in with Control UI origin configuration. (#27491) thanks @robbyczgw-cla.
- Daemon/macOS launchd: forward proxy env vars into supervised service environments, keep LaunchAgent `KeepAlive=true` semantics, and harden restart sequencing to `print -> bootout -> wait old pid exit -> bootstrap -> kickstart`. (#27276) thanks @frankekn.
- Daemon/macOS TLS certs: default LaunchAgent service env `NODE_EXTRA_CA_CERTS` to `/etc/ssl/cert.pem` (while preserving explicit overrides) so HTTPS clients no longer fail with local-issuer errors under launchd. (#27915) Thanks @Lukavyi.
- Gateway/macOS restart-loop hardening: detect OpenClaw-managed supervisor markers during SIGUSR1 restart handoff, clean stale gateway PIDs before `/restart` launchctl/systemctl triggers, and set LaunchAgent `ThrottleInterval=60` to bound launchd retry storms during lock-release races. Landed from contributor PRs #27655 (@taw0002), #27448 (@Sid-Qin), and #27650 (@kevinWangSheng). (#27605, #27590, #26904, #26736)
- Models/MiniMax auth header defaults: set `authHeader: true` for both onboarding-generated MiniMax API providers and implicit built-in MiniMax (`minimax`, `minimax-portal`) provider templates so first requests no longer fail with MiniMax `401 authentication_error` due to missing `Authorization` header. Landed from contributor PRs #27622 by @riccoyuanft and #27631 by @kevinWangSheng. (#27600, #15303)
- Models/Google Antigravity IDs: normalize bare `gemini-3-pro`, `gemini-3.1-pro`, and `gemini-3-1-pro` model IDs to the default `-low` thinking tier so provider requests no longer fail with 404 when the tier suffix is omitted. (#24145) Thanks @byungsker.

View File

@ -333,12 +333,18 @@ describe("buildServiceEnvironment", () => {
const env = buildServiceEnvironment({
env: { HOME: "/home/user" },
port: 18789,
platform: "darwin",
});
if (process.platform === "darwin") {
expect(env.NODE_EXTRA_CA_CERTS).toBe("/etc/ssl/cert.pem");
} else {
expect(env.NODE_EXTRA_CA_CERTS).toBeUndefined();
}
expect(env.NODE_EXTRA_CA_CERTS).toBe("/etc/ssl/cert.pem");
});
it("does not default NODE_EXTRA_CA_CERTS on non-macOS", () => {
const env = buildServiceEnvironment({
env: { HOME: "/home/user" },
port: 18789,
platform: "linux",
});
expect(env.NODE_EXTRA_CA_CERTS).toBeUndefined();
});
it("respects user-provided NODE_EXTRA_CA_CERTS over the default", () => {
@ -388,12 +394,17 @@ describe("buildNodeServiceEnvironment", () => {
it("defaults NODE_EXTRA_CA_CERTS to system cert bundle on macOS for node services", () => {
const env = buildNodeServiceEnvironment({
env: { HOME: "/home/user" },
platform: "darwin",
});
if (process.platform === "darwin") {
expect(env.NODE_EXTRA_CA_CERTS).toBe("/etc/ssl/cert.pem");
} else {
expect(env.NODE_EXTRA_CA_CERTS).toBeUndefined();
}
expect(env.NODE_EXTRA_CA_CERTS).toBe("/etc/ssl/cert.pem");
});
it("does not default NODE_EXTRA_CA_CERTS on non-macOS for node services", () => {
const env = buildNodeServiceEnvironment({
env: { HOME: "/home/user" },
platform: "linux",
});
expect(env.NODE_EXTRA_CA_CERTS).toBeUndefined();
});
it("respects user-provided NODE_EXTRA_CA_CERTS for node services", () => {

View File

@ -236,12 +236,13 @@ export function buildServiceEnvironment(params: {
port: number;
token?: string;
launchdLabel?: string;
platform?: NodeJS.Platform;
}): Record<string, string | undefined> {
const { env, port, token, launchdLabel } = params;
const platform = params.platform ?? process.platform;
const profile = env.OPENCLAW_PROFILE;
const resolvedLaunchdLabel =
launchdLabel ||
(process.platform === "darwin" ? resolveGatewayLaunchAgentLabel(profile) : undefined);
launchdLabel || (platform === "darwin" ? resolveGatewayLaunchAgentLabel(profile) : undefined);
const systemdUnit = `${resolveGatewaySystemdServiceName(profile)}.service`;
const stateDir = env.OPENCLAW_STATE_DIR;
const configPath = env.OPENCLAW_CONFIG_PATH;
@ -252,7 +253,7 @@ export function buildServiceEnvironment(params: {
// cannot locate the system CA bundle. Default to /etc/ssl/cert.pem so TLS verification
// works correctly when running as a LaunchAgent without extra user configuration.
const nodeCaCerts =
env.NODE_EXTRA_CA_CERTS ?? (process.platform === "darwin" ? "/etc/ssl/cert.pem" : undefined);
env.NODE_EXTRA_CA_CERTS ?? (platform === "darwin" ? "/etc/ssl/cert.pem" : undefined);
return {
HOME: env.HOME,
TMPDIR: tmpDir,
@ -274,8 +275,10 @@ export function buildServiceEnvironment(params: {
export function buildNodeServiceEnvironment(params: {
env: Record<string, string | undefined>;
platform?: NodeJS.Platform;
}): Record<string, string | undefined> {
const { env } = params;
const platform = params.platform ?? process.platform;
const stateDir = env.OPENCLAW_STATE_DIR;
const configPath = env.OPENCLAW_CONFIG_PATH;
const tmpDir = env.TMPDIR?.trim() || os.tmpdir();
@ -284,7 +287,7 @@ export function buildNodeServiceEnvironment(params: {
// cannot locate the system CA bundle. Default to /etc/ssl/cert.pem so TLS verification
// works correctly when running as a LaunchAgent without extra user configuration.
const nodeCaCerts =
env.NODE_EXTRA_CA_CERTS ?? (process.platform === "darwin" ? "/etc/ssl/cert.pem" : undefined);
env.NODE_EXTRA_CA_CERTS ?? (platform === "darwin" ? "/etc/ssl/cert.pem" : undefined);
return {
HOME: env.HOME,
TMPDIR: tmpDir,