mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-11 04:24:31 +00:00
fix(sandbox): fallback docker user to workspace owner uid/gid
Co-authored-by: LucasAIBuilder <LucasAIBuilder@users.noreply.github.com>
This commit is contained in:
@@ -14,7 +14,7 @@ import { createSandboxFsBridge } from "./fs-bridge.js";
|
||||
import { maybePruneSandboxes } from "./prune.js";
|
||||
import { resolveSandboxRuntimeStatus } from "./runtime-status.js";
|
||||
import { resolveSandboxScopeKey, resolveSandboxWorkspaceDir } from "./shared.js";
|
||||
import type { SandboxContext, SandboxWorkspaceInfo } from "./types.js";
|
||||
import type { SandboxContext, SandboxDockerConfig, SandboxWorkspaceInfo } from "./types.js";
|
||||
import { ensureSandboxWorkspace } from "./workspace.js";
|
||||
|
||||
async function ensureSandboxWorkspaceLayout(params: {
|
||||
@@ -64,6 +64,29 @@ async function ensureSandboxWorkspaceLayout(params: {
|
||||
return { agentWorkspaceDir, scopeKey, sandboxWorkspaceDir, workspaceDir };
|
||||
}
|
||||
|
||||
export async function resolveSandboxDockerUser(params: {
|
||||
docker: SandboxDockerConfig;
|
||||
workspaceDir: string;
|
||||
stat?: (workspaceDir: string) => Promise<{ uid: number; gid: number }>;
|
||||
}): Promise<SandboxDockerConfig> {
|
||||
const configuredUser = params.docker.user?.trim();
|
||||
if (configuredUser) {
|
||||
return params.docker;
|
||||
}
|
||||
const stat = params.stat ?? ((workspaceDir: string) => fs.stat(workspaceDir));
|
||||
try {
|
||||
const workspaceStat = await stat(params.workspaceDir);
|
||||
const uid = Number.isInteger(workspaceStat.uid) ? workspaceStat.uid : null;
|
||||
const gid = Number.isInteger(workspaceStat.gid) ? workspaceStat.gid : null;
|
||||
if (uid === null || gid === null || uid < 0 || gid < 0) {
|
||||
return params.docker;
|
||||
}
|
||||
return { ...params.docker, user: `${uid}:${gid}` };
|
||||
} catch {
|
||||
return params.docker;
|
||||
}
|
||||
}
|
||||
|
||||
function resolveSandboxSession(params: { config?: OpenClawConfig; sessionKey?: string }) {
|
||||
const rawSessionKey = params.sessionKey?.trim();
|
||||
if (!rawSessionKey) {
|
||||
@@ -102,11 +125,17 @@ export async function resolveSandboxContext(params: {
|
||||
workspaceDir: params.workspaceDir,
|
||||
});
|
||||
|
||||
const docker = await resolveSandboxDockerUser({
|
||||
docker: cfg.docker,
|
||||
workspaceDir,
|
||||
});
|
||||
const resolvedCfg = docker === cfg.docker ? cfg : { ...cfg, docker };
|
||||
|
||||
const containerName = await ensureSandboxContainer({
|
||||
sessionKey: rawSessionKey,
|
||||
workspaceDir,
|
||||
agentWorkspaceDir,
|
||||
cfg,
|
||||
cfg: resolvedCfg,
|
||||
});
|
||||
|
||||
const evaluateEnabled =
|
||||
@@ -132,7 +161,7 @@ export async function resolveSandboxContext(params: {
|
||||
scopeKey,
|
||||
workspaceDir,
|
||||
agentWorkspaceDir,
|
||||
cfg,
|
||||
cfg: resolvedCfg,
|
||||
evaluateEnabled,
|
||||
bridgeAuth,
|
||||
});
|
||||
@@ -142,12 +171,12 @@ export async function resolveSandboxContext(params: {
|
||||
sessionKey: rawSessionKey,
|
||||
workspaceDir,
|
||||
agentWorkspaceDir,
|
||||
workspaceAccess: cfg.workspaceAccess,
|
||||
workspaceAccess: resolvedCfg.workspaceAccess,
|
||||
containerName,
|
||||
containerWorkdir: cfg.docker.workdir,
|
||||
docker: cfg.docker,
|
||||
tools: cfg.tools,
|
||||
browserAllowHostControl: cfg.browser.allowHostControl,
|
||||
containerWorkdir: resolvedCfg.docker.workdir,
|
||||
docker: resolvedCfg.docker,
|
||||
tools: resolvedCfg.tools,
|
||||
browserAllowHostControl: resolvedCfg.browser.allowHostControl,
|
||||
browser: browser ?? undefined,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user