fix(compose): build sidecar images and adopt foreign containers on the native path - #115
Conversation
…e native path Two gaps versus the shellout backend, both found adversarially reviewing the switch to ComposeBackendNative as the only backend in dap: 1. Non-primary services with `build:` were never built — the orchestrator only creates containers from images and the pull-retry is gated on a non-empty reference, so a `build:` sidecar reached ContainerCreate with an empty image. Engine.Up now builds every selected sidecar before the orchestrator runs (image:+build: tags the built image with image:, build-only gets compose v2's <project>-<service> default) and pins the result via ApplyBuildOverride, so hashing, drift detection and pull-retry all see a concrete reference. 2. ensureService recreated any existing container whose dev.containers.config-hash / image-digest labels did not match — including containers the orchestrator did not create (shellout backend, plain docker compose), which have no such labels at all. Removing them destroys the writable layer the shellout path's NoRecreate contract preserved across restarts. Such containers are now adopted: started if stopped, otherwise left alone. Drift-based recreation still applies to containers carrying our labels, and Recreate-mode Ups still tear the whole project down first. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 30 minutes Limit details: You’ve used the included review currently available. Your 66 included PR review attempts over the past 7 days set your current allowance at 1 review per hour. You’re in a promotional period — use the checkbox below to run this review for free:
On-demand reviews are free for the next 29 days. After that, they cost $0.25 per reviewed file. How can I continue?Run this review now using the option above, or comment You can also wait for the limit to reset, then comment An organization admin can change what happens after included review limits in Billing. How do review limits work?CodeRabbit enforces per-developer PR review limits within each organization. For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
Comment |
Two gaps in the native compose orchestrator versus the shellout backend, both surfaced by adversarial review of crunchloop/dap#4828 (which makes
ComposeBackendNativethe only backend):1. Non-primary
build:services were never builtThe orchestrator only creates containers from images (
serviceToRunSpecusessvc.Image; the missing-image pull-retry is gated on a non-empty reference), andprepareComposeServiceImageonly handles the primary service. Abuild:sidecar reachedContainerCreatewith an empty image and the Up failed — the shellout backend delegated todocker compose up, which builds implicitly.Fix:
Engine.upComposeNativenow builds every selected non-primarybuild:service before the orchestrator runs, honoring compose semantics (image:+build:tags the result withimage:; build-only gets compose v2's<project>-<service>default), then pins each viaApplyBuildOverrideso hashing, drift detection, and pull-retry all see a concrete reference.runServicesselection is honored; build order is deterministic.2. Foreign containers were destroyed on non-recreate Ups
ensureServicerecreated any existing container whosedev.containers.config-hash/image-digestlabels didn't match — including containers this orchestrator never created (shellout backend, plaindocker compose up), which carry no such labels at all. Removing them destroys the writable layer (in-container$HOME, etc.) that the shellout path'sNoRecreatecontract preserved — a data-loss hazard for every workspace migrating from shellout to native on its first resume.Fix: a container with the compose project/service labels but no
dev.containers.config-hashlabel is adopted: started if stopped, otherwise left alone. Drift-based recreation still applies to containers carrying our labels, and Recreate-mode Ups still tear the whole project down before the orchestrator runs, so forced refreshes behave exactly as before.Tests
compose: foreign-container adoption (exited → started, running → hands-off; no remove, no create).image:+build:tagging, plain-image untouched,runServicesexclusion, project mutation to image-only).go test ./compose/ .green;cmd/devcontainerandruntime/applecontainerfail locally only on the pre-existing missinglibACBridge.dylibembed (built by the Makefile in CI).Needed for crunchloop/dap#4828 — will be consumed as v0.4.1.
🤖 Generated with Claude Code