UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

70 lines (69 loc) 5.79 kB
//#region src/daemon/service-types.ts const SERVICE_DEFINITION_ARTIFACTS = { "service-directory": "service directory (~/.config/systemd/user) or its nearest existing ancestor", "state-directory": "service state directory or its nearest existing ancestor", "definition-directory": "loaded service definition directory", "service-file": "service file" }; const SERVICE_DEFINITION_REASONS = { "unsafe-permissions": "is group/world-writable. Inspect ownership and permissions locally. If the path is yours and not intentionally shared, remove group/other write access with chmod go-w <path>, then retry. Use 0700 for private directories; ask the deployment owner about shared paths. Do not use recursive chmod or sudo to bypass this check.", "invalid-artifact": "has an unexpected file type. Inspect the service directories and files locally; have their owner repair the layout before retrying. Changing permissions alone will not repair it.", symlink: "is a symbolic link. Ask the deployment owner to replace the managed file through the deployment process; OpenClaw will not rewrite the link or its target.", "foreign-owner": "belongs to another account. Ask the privileged deployment owner to repair or replace it; do not take ownership or use --force to bypass this check.", "sealed-mount": "cannot be replaced on its mount. Ask the deployment owner to update the mounted artifact or deployment; chmod and --force cannot make it replaceable.", "system-owned": "is owned by a system service. Ask the privileged deployment owner to update it; do not create a competing user service.", "system-ownership-unverified": "has unverifiable system-service ownership. Restore system service-manager and filesystem inspection access from the service account, then retry; do not create a competing user service.", "inspection-failed": "cannot be safely inspected. Inspect service definition access and native service-manager availability from the service account, then retry. Do not share config or environment contents." }; function assertServiceDefinitionWritable(capability) { if (capability.kind === "writable") return; const reason = Object.hasOwn(SERVICE_DEFINITION_REASONS, capability.reason) ? capability.reason : "inspection-failed"; const artifact = capability.artifact && Object.hasOwn(SERVICE_DEFINITION_ARTIFACTS, capability.artifact) ? SERVICE_DEFINITION_ARTIFACTS[capability.artifact] : "service definition"; const code = capability.kind === "sealed" ? "SERVICE_DEFINITION_SEALED" : "SERVICE_DEFINITION_UNKNOWN"; throw new Error(`${code}: [${reason}] The ${artifact} ${SERVICE_DEFINITION_REASONS[reason]}`); } function resolveManagedGatewayServiceCommand(command) { return command?.managedDefinition ?? command ?? null; } /** Operator-owned launcher overrides cannot be repaired by rewriting the managed base. */ function hasGatewayServiceLauncherOverride(command, options) { const managedOverrides = command?.managedOverrides; const includeWorkingDirectory = options?.includeWorkingDirectory !== false; if (managedOverrides) return Boolean(managedOverrides.launcher && (includeWorkingDirectory || managedOverrides.launcher !== "working-directory")); const managedDefinition = command?.managedDefinition; return Boolean(managedDefinition && (includeWorkingDirectory && managedDefinition.workingDirectory !== command.workingDirectory || managedDefinition.programArguments.join("\0") !== command.programArguments.join("\0"))); } function hasGatewayServiceEnvironmentOverride(command, keys, options) { const managedOverrides = command?.managedOverrides; if (!managedOverrides) return hasGatewayServiceEnvironmentDifference(command, keys); const environment = managedOverrides.environment; if (environment === true || !environment) return environment === true && keys.length > 0; const normalize = options?.normalizeKey ?? ((key) => key); const ownedKeys = new Set(environment.keys?.map(normalize)); const sources = options?.environmentValueSources ?? command.managedDefinition?.environmentValueSources; return keys.some((key) => { const normalized = normalize(key); if (normalized !== null && ownedKeys.has(normalized)) return true; if (options?.ignoreResets) return false; const source = sources?.[key] ?? (options?.normalizeKey && Object.entries(sources ?? {}).find(([rawKey]) => normalize(rawKey) === normalized)?.[1]) ?? "inline"; return Boolean(environment.resetInline && source !== "file" || environment.resetFiles && source !== "inline"); }); } function hasGatewayServiceEnvironmentDifference(command, keys) { const managedDefinition = command?.managedDefinition; return Boolean(managedDefinition && keys.some((key) => command.environment?.[key] !== managedDefinition.environment?.[key] || (command.environmentValueSources?.[key] ?? "inline") !== (managedDefinition.environmentValueSources?.[key] ?? "inline"))); } /** Remove inherited operator overrides before a managed definition is rewritten. */ function resolveManagedGatewayServiceProcessEnv(command, processEnv) { const overrides = command?.managedOverrides?.environment; if (overrides === true || overrides?.resetInline || overrides?.resetFiles) return null; const managedEnvironment = resolveManagedGatewayServiceCommand(command)?.environment; const environment = { ...processEnv, ...managedEnvironment }; for (const key of [...Object.keys(command?.environment ?? {}), ...overrides?.keys ?? []]) if (!Object.hasOwn(managedEnvironment ?? {}, key)) delete environment[key]; return environment; } //#endregion export { resolveManagedGatewayServiceCommand as a, hasGatewayServiceLauncherOverride as i, hasGatewayServiceEnvironmentDifference as n, resolveManagedGatewayServiceProcessEnv as o, hasGatewayServiceEnvironmentOverride as r, assertServiceDefinitionWritable as t };