mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 08:10:42 +00:00
fix: persist gateway service wrappers
This commit is contained in:
@@ -10,6 +10,7 @@ import { resolveFutureConfigActionBlock } from "../../config/future-version-guar
|
||||
import { readConfigFileSnapshotForWrite } from "../../config/io.js";
|
||||
import { resolveGatewayPort } from "../../config/paths.js";
|
||||
import type { OpenClawConfig } from "../../config/types.js";
|
||||
import { OPENCLAW_WRAPPER_ENV_KEY, resolveOpenClawWrapperPath } from "../../daemon/program-args.js";
|
||||
import { readEmbeddedGatewayToken } from "../../daemon/service-audit.js";
|
||||
import { resolveGatewayService } from "../../daemon/service.js";
|
||||
import type { GatewayServiceCommandConfig } from "../../daemon/service.js";
|
||||
@@ -44,6 +45,13 @@ function mergeInstallInvocationEnv(params: {
|
||||
continue;
|
||||
}
|
||||
const upper = key.toUpperCase();
|
||||
if (upper === OPENCLAW_WRAPPER_ENV_KEY) {
|
||||
const value = rawValue.trim();
|
||||
if (value) {
|
||||
preservedServiceEnv[OPENCLAW_WRAPPER_ENV_KEY] = value;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
upper === "HOME" ||
|
||||
upper === "PATH" ||
|
||||
@@ -99,6 +107,19 @@ export async function runDaemonInstall(opts: DaemonInstallOptions) {
|
||||
fail('Invalid --runtime (use "node" or "bun")');
|
||||
return;
|
||||
}
|
||||
let wrapperPath: string | undefined;
|
||||
if (opts.wrapper !== undefined) {
|
||||
try {
|
||||
wrapperPath = await resolveOpenClawWrapperPath(opts.wrapper);
|
||||
if (!wrapperPath) {
|
||||
fail("Invalid --wrapper");
|
||||
return;
|
||||
}
|
||||
} catch (err) {
|
||||
fail(`Invalid --wrapper: ${String(err)}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const service = resolveGatewayService();
|
||||
let loaded = false;
|
||||
@@ -122,6 +143,14 @@ export async function runDaemonInstall(opts: DaemonInstallOptions) {
|
||||
env: process.env,
|
||||
existingServiceEnv,
|
||||
});
|
||||
if (!wrapperPath) {
|
||||
try {
|
||||
wrapperPath = await resolveOpenClawWrapperPath(installEnv[OPENCLAW_WRAPPER_ENV_KEY]);
|
||||
} catch (err) {
|
||||
fail(`Invalid ${OPENCLAW_WRAPPER_ENV_KEY}: ${String(err)}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (loaded) {
|
||||
if (!opts.force) {
|
||||
const autoRefreshMessage = await getGatewayServiceAutoRefreshMessage({
|
||||
@@ -130,6 +159,7 @@ export async function runDaemonInstall(opts: DaemonInstallOptions) {
|
||||
installEnv,
|
||||
port,
|
||||
runtime: runtimeRaw,
|
||||
wrapperPath,
|
||||
existingEnvironment: existingServiceEnv,
|
||||
config: cfg,
|
||||
});
|
||||
@@ -182,6 +212,7 @@ export async function runDaemonInstall(opts: DaemonInstallOptions) {
|
||||
env: installEnv,
|
||||
port,
|
||||
runtime: runtimeRaw,
|
||||
wrapperPath,
|
||||
existingEnvironment: existingServiceEnv,
|
||||
warn: (message) => {
|
||||
if (json) {
|
||||
@@ -217,6 +248,7 @@ async function getGatewayServiceAutoRefreshMessage(params: {
|
||||
installEnv: NodeJS.ProcessEnv;
|
||||
port: number;
|
||||
runtime: GatewayDaemonRuntime;
|
||||
wrapperPath?: string;
|
||||
existingEnvironment?: Record<string, string | undefined>;
|
||||
config: OpenClawConfig;
|
||||
}): Promise<string | undefined> {
|
||||
@@ -231,6 +263,7 @@ async function getGatewayServiceAutoRefreshMessage(params: {
|
||||
env: params.installEnv,
|
||||
port: params.port,
|
||||
runtime: params.runtime,
|
||||
wrapperPath: params.wrapperPath,
|
||||
existingEnvironment: params.existingEnvironment,
|
||||
warn: () => undefined,
|
||||
config: params.config,
|
||||
@@ -242,6 +275,26 @@ async function getGatewayServiceAutoRefreshMessage(params: {
|
||||
return "Gateway service OPENCLAW_GATEWAY_TOKEN differs from the current install plan; refreshing the install.";
|
||||
}
|
||||
}
|
||||
const wrapperRequested = Boolean(
|
||||
params.wrapperPath || normalizeOptionalString(params.installEnv[OPENCLAW_WRAPPER_ENV_KEY]),
|
||||
);
|
||||
if (wrapperRequested) {
|
||||
const plannedInstall = await buildGatewayInstallPlan({
|
||||
env: params.installEnv,
|
||||
port: params.port,
|
||||
runtime: params.runtime,
|
||||
wrapperPath: params.wrapperPath,
|
||||
existingEnvironment: params.existingEnvironment,
|
||||
warn: () => undefined,
|
||||
config: params.config,
|
||||
});
|
||||
if (
|
||||
plannedInstall.programArguments.join("\u0000") !==
|
||||
currentCommand.programArguments.join("\u0000")
|
||||
) {
|
||||
return "Gateway service command differs from the current wrapper install plan; refreshing the install.";
|
||||
}
|
||||
}
|
||||
const currentExecPath = currentCommand.programArguments[0]?.trim();
|
||||
if (!currentExecPath) {
|
||||
return undefined;
|
||||
|
||||
@@ -77,6 +77,7 @@ export function addGatewayServiceCommands(parent: Command, opts?: { statusDescri
|
||||
.option("--port <port>", "Gateway port")
|
||||
.option("--runtime <runtime>", "Daemon runtime (node|bun). Default: node")
|
||||
.option("--token <token>", "Gateway token (token auth)")
|
||||
.option("--wrapper <path>", "Executable wrapper for generated service ProgramArguments")
|
||||
.option("--force", "Reinstall/overwrite if already installed", false)
|
||||
.option("--json", "Output JSON", false)
|
||||
.action(async (cmdOpts, command) => {
|
||||
|
||||
@@ -19,6 +19,7 @@ export type DaemonInstallOptions = {
|
||||
port?: string | number;
|
||||
runtime?: string;
|
||||
token?: string;
|
||||
wrapper?: string;
|
||||
force?: boolean;
|
||||
json?: boolean;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user