mirror of
https://github.com/moltbot/moltbot.git
synced 2026-03-07 22:44:16 +00:00
fix(docker): ensure agent directory permissions in docker-setup.sh (#28841)
* fix(docker): ensure agent directory permissions in docker-setup.sh * fix(docker): restrict chown to config-dir mount, not workspace The previous 'chown -R node:node /home/node/.openclaw' call crossed into the workspace bind mount on Linux hosts, recursively rewriting ownership of all user project files in the workspace directory. Fix: use 'find -xdev' to restrict chown to the config-dir filesystem only (won't cross bind-mount boundaries). Then separately chown only the OpenClaw metadata subdirectory (.openclaw/) within the workspace, leaving the user's project files untouched. Addresses review comment on PR #28841.
This commit is contained in:
@@ -162,9 +162,11 @@ fi
|
||||
|
||||
mkdir -p "$OPENCLAW_CONFIG_DIR"
|
||||
mkdir -p "$OPENCLAW_WORKSPACE_DIR"
|
||||
# Seed device-identity parent eagerly for Docker Desktop/Windows bind mounts
|
||||
# that reject creating new subdirectories from inside the container.
|
||||
# Seed directory tree eagerly so bind mounts work even on Docker Desktop/Windows
|
||||
# where the container (even as root) cannot create new host subdirectories.
|
||||
mkdir -p "$OPENCLAW_CONFIG_DIR/identity"
|
||||
mkdir -p "$OPENCLAW_CONFIG_DIR/agents/main/agent"
|
||||
mkdir -p "$OPENCLAW_CONFIG_DIR/agents/main/sessions"
|
||||
|
||||
export OPENCLAW_CONFIG_DIR
|
||||
export OPENCLAW_WORKSPACE_DIR
|
||||
@@ -346,6 +348,22 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
# Ensure bind-mounted data directories are writable by the container's `node`
|
||||
# user (uid 1000). Host-created dirs inherit the host user's uid which may
|
||||
# differ, causing EACCES when the container tries to mkdir/write.
|
||||
# Running a brief root container to chown is the portable Docker idiom --
|
||||
# it works regardless of the host uid and doesn't require host-side root.
|
||||
echo ""
|
||||
echo "==> Fixing data-directory permissions"
|
||||
# Use -xdev to restrict chown to the config-dir mount only — without it,
|
||||
# the recursive chown would cross into the workspace bind mount and rewrite
|
||||
# ownership of all user project files on Linux hosts.
|
||||
# After fixing the config dir, only the OpenClaw metadata subdirectory
|
||||
# (.openclaw/) inside the workspace gets chowned, not the user's project files.
|
||||
docker compose "${COMPOSE_ARGS[@]}" run --rm --user root --entrypoint sh openclaw-cli -c \
|
||||
'find /home/node/.openclaw -xdev -exec chown node:node {} +; \
|
||||
[ -d /home/node/.openclaw/workspace/.openclaw ] && chown -R node:node /home/node/.openclaw/workspace/.openclaw || true'
|
||||
|
||||
echo ""
|
||||
echo "==> Onboarding (interactive)"
|
||||
echo "Docker setup pins Gateway mode to local."
|
||||
|
||||
@@ -171,6 +171,30 @@ describe("docker-setup.sh", () => {
|
||||
expect(identityDirStat.isDirectory()).toBe(true);
|
||||
});
|
||||
|
||||
it("precreates agent data dirs to avoid EACCES in container", async () => {
|
||||
const activeSandbox = requireSandbox(sandbox);
|
||||
const configDir = join(activeSandbox.rootDir, "config-agent-dirs");
|
||||
const workspaceDir = join(activeSandbox.rootDir, "workspace-agent-dirs");
|
||||
|
||||
const result = runDockerSetup(activeSandbox, {
|
||||
OPENCLAW_CONFIG_DIR: configDir,
|
||||
OPENCLAW_WORKSPACE_DIR: workspaceDir,
|
||||
});
|
||||
|
||||
expect(result.status).toBe(0);
|
||||
const agentDirStat = await stat(join(configDir, "agents", "main", "agent"));
|
||||
expect(agentDirStat.isDirectory()).toBe(true);
|
||||
const sessionsDirStat = await stat(join(configDir, "agents", "main", "sessions"));
|
||||
expect(sessionsDirStat.isDirectory()).toBe(true);
|
||||
|
||||
// Verify that a root-user chown step runs before onboarding.
|
||||
const log = await readFile(activeSandbox.logPath, "utf8");
|
||||
const chownIdx = log.indexOf("--user root");
|
||||
const onboardIdx = log.indexOf("onboard");
|
||||
expect(chownIdx).toBeGreaterThanOrEqual(0);
|
||||
expect(onboardIdx).toBeGreaterThan(chownIdx);
|
||||
});
|
||||
|
||||
it("reuses existing config token when OPENCLAW_GATEWAY_TOKEN is unset", async () => {
|
||||
const activeSandbox = requireSandbox(sandbox);
|
||||
const configDir = join(activeSandbox.rootDir, "config-token-reuse");
|
||||
|
||||
Reference in New Issue
Block a user