From 134cc64aff0da73d22443aedc261cc07c3e54bd6 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 26 Apr 2026 09:17:34 +0100 Subject: [PATCH] fix: keep host plugin registry out of live Docker state --- scripts/lib/live-docker-stage.sh | 6 ++++-- scripts/test-projects.test-support.mjs | 2 ++ test/scripts/live-docker-stage.test.ts | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 test/scripts/live-docker-stage.test.ts diff --git a/scripts/lib/live-docker-stage.sh b/scripts/lib/live-docker-stage.sh index b79791f4e39..4b3d3f2ccd8 100644 --- a/scripts/lib/live-docker-stage.sh +++ b/scripts/lib/live-docker-stage.sh @@ -69,14 +69,16 @@ openclaw_live_stage_state_dir() { mkdir -p "$dest_dir" if [ -d "$source_dir" ]; then # Sandbox workspaces can accumulate root-owned artifacts from prior Docker - # runs. They are not needed for live-test auth/config staging and can make - # temp-dir cleanup fail on exit, so keep them out of the staged state copy. + # runs. The persisted plugin registry contains host-absolute paths that are + # not portable into Linux containers. Neither is needed for live-test + # auth/config staging, so keep them out of the staged state copy. set +e tar -C "$source_dir" \ --warning=no-file-changed \ --ignore-failed-read \ --exclude=workspace \ --exclude=sandboxes \ + --exclude=plugins/installs.json \ --exclude=relay.sock \ --exclude='*.sock' \ --exclude='*/*.sock' \ diff --git a/scripts/test-projects.test-support.mjs b/scripts/test-projects.test-support.mjs index 825d68edd00..01bb27ecddc 100644 --- a/scripts/test-projects.test-support.mjs +++ b/scripts/test-projects.test-support.mjs @@ -228,6 +228,7 @@ const TOOLING_SOURCE_TEST_TARGETS = new Map([ ["scripts/github/barnacle-auto-response.mjs", ["test/scripts/barnacle-auto-response.test.ts"]], ["scripts/changed-lanes.mjs", ["test/scripts/changed-lanes.test.ts"]], ["scripts/check-changed.mjs", ["test/scripts/changed-lanes.test.ts"]], + ["scripts/lib/live-docker-stage.sh", ["test/scripts/live-docker-stage.test.ts"]], ["scripts/lib/vitest-local-scheduling.mjs", ["test/scripts/vitest-local-scheduling.test.ts"]], [ "scripts/run-vitest.mjs", @@ -251,6 +252,7 @@ const TOOLING_SOURCE_TEST_TARGETS = new Map([ const TOOLING_TEST_TARGETS = new Map([ ["test/scripts/barnacle-auto-response.test.ts", ["test/scripts/barnacle-auto-response.test.ts"]], ["test/scripts/changed-lanes.test.ts", ["test/scripts/changed-lanes.test.ts"]], + ["test/scripts/live-docker-stage.test.ts", ["test/scripts/live-docker-stage.test.ts"]], ["test/scripts/test-projects.test.ts", ["test/scripts/test-projects.test.ts"]], [ "test/scripts/vitest-local-scheduling.test.ts", diff --git a/test/scripts/live-docker-stage.test.ts b/test/scripts/live-docker-stage.test.ts new file mode 100644 index 00000000000..e785bba5694 --- /dev/null +++ b/test/scripts/live-docker-stage.test.ts @@ -0,0 +1,18 @@ +import { readFileSync } from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { describe, expect, it } from "vitest"; + +const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); +const stageScriptPath = path.join(repoRoot, "scripts/lib/live-docker-stage.sh"); + +describe("live Docker state staging", () => { + it("keeps host-only generated registry state out of the container copy", () => { + const script = readFileSync(stageScriptPath, "utf8"); + + expect(script).toContain("--exclude=workspace"); + expect(script).toContain("--exclude=sandboxes"); + expect(script).toContain("--exclude=plugins/installs.json"); + expect(script).toContain("host-absolute paths"); + }); +});