Repository navigation
test(e2e): write stack Compose files from a container so macOS VMs read them whole - #893
Conversation
…ad them whole On macOS Docker VMs (seen with OrbStack 2.2.4), once a container has written a bind-mounted file, later host-side rewrites of that file can stay invisible to new containers for a few seconds. The stack-recreate scenario rewrote docker-compose.yml from the host right after the digest-pin updater had rewritten it from a container, so the next updater read the new file cut off at the old size, Compose rejected it, and the runtime-state preflight failed closed. Write the stack Compose files from a container as the host user, like write_volume_file does for volumes.
Reviewer's guide (collapsed on small PRs)Reviewer's GuideThe E2E harness now writes generated Compose files from a host-user container, matching the updater’s file-share side and preventing macOS/OrbStack stale-size reads during stack recreation without changing product behavior. File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="tests/e2e-docker-compose.sh" line_range="412" />
<code_context>
+# Writing from a container keeps every write on the updater's side of the file
+# share; running as the host user keeps the file owner unchanged.
+write_stack_compose_file(){
+ docker run -i --rm --user "$(id -u):$(id -g)" -v "$STACK_DIR:$STACK_DIR" "$IMAGE" \
+ bash -c 'cat > "$1"' _ "$COMPOSE_FILE"
+}
</code_context>
<issue_to_address>
**Compose file write fails**
When the e2e test runs with a rootless or user-namespace-remapped Docker daemon, `write_stack_compose_file` runs `docker` with the host UID/GID, which the daemon maps to subordinate host IDs. Then `cat > "$1"` cannot create or truncate `docker-compose.yml`, so the e2e script stops before its scenarios run.
Run the writer in a way that gives it write access to the bind-mounted directory under these daemon mappings.
Also at `tests/e2e-docker-compose.sh:413`.
</issue_to_address>Sourcery assessment
Approval pending. 1 finding to address first.
Blocking findings: tests/e2e-docker-compose.sh:412
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
…ad them whole On macOS Docker VMs (seen with OrbStack 2.2.4), once a container has written a bind-mounted file, later host-side rewrites of that file can stay invisible to new containers for a few seconds. The stack-recreate scenario rewrote docker-compose.yml from the host right after the digest-pin updater had rewritten it from a container, so the next updater read the new file cut off at the old size, Compose rejected it, and the runtime-state preflight failed closed. Write the stack Compose files from a container as the host user, like write_volume_file does for volumes.
e57f90c to
db6b90a
Compare
…for rootless Docker
…to fix/e2e-macos-compose-writes # Conflicts: # tests/e2e-docker-compose.sh
|



Summary
tests/e2e-docker-compose.shfailed on macOS with OrbStack in the stack-recreate scenario: the updater logged "Could not verify whether selected services are running; the update was not applied." The cause is in the test harness, not the updater. The harness rewrote the stack'sdocker-compose.ymlfrom the host after an updater container had already rewritten it. On a macOS Docker VM, containers then kept seeing the old file size for a few seconds. The next updater read the new file cut off at the old size, Compose rejected it, and WUDup correctly refused to update.What the run showed:
phase=preflight,reason=runtime-state-unavailable,note=Compose project identity is unavailable.Stack discovery'sdocker compose -f docker-compose.yml config --format jsonhad failed withservices.sidecar.depends_on.app must be a mapping.alpinecontainer saw 326 bytes and the same inode. 326 bytes is the digest-pinned file the previous scenario's updater wrote, and cutting the new file at 326 bytes ends atdepends_on:/app:.alpineand thewudupimage reproduces it. A container writes the file and stays running a few seconds, the host rewrites the file, and the next container still reads the old size. If the writing container exits immediately, the host rewrite shows up right away. Container-to-host writes were always visible immediately./var→/private/varsymlink hypothesis was ruled out: the Composeworking_dirandconfig_fileslabels matched the paths the updater used.Change:
write_stack_compose_filewrites the stack Compose files from a container running as the host user, the same waywrite_volume_filealready writes volume files. All writes then happen on the same side of the file share as the updater, and the file owner stays the same as before. Writing to a temp file and renaming it on the host did not fix this, because containers kept resolving the path to the old inode.Scope
Checklist
README.mdordocs/updated if install, deployment, config, or user-facing behavior changed: N/A - no user-facing changedocs/examples/template.envordocs/examples/webui.env.exampleupdated if environment variables or example config changed: N/ACHANGELOG.mdedit needed outside release prepTest plan
tests/run-all.sh: N/A - only the Docker E2E harness changedFocused test(s):
bash -n tests/e2e-docker-compose.shshellcheck tests/e2e-docker-compose.shDocker or Compose validation, if container behavior changed:
tests/e2e-docker-compose.shon macOS with OrbStack 2.2.4 (Docker 29.8.2, API 1.56): failed before the change; passed after it, three times with a prebuilt image and once with the script's own builddocker e2e(Linux): pending on this PR