mirror of
https://github.com/docker/compose.git
synced 2026-10-12 02:13:08 +00:00
runPreStart executes a service's pre_start hooks sequentially as ephemeral containers that share the first non-running replica's volumes via VolumesFrom and attach to the same networks. A non-zero hook exit gates service start. per_replica: false is the only currently supported mode; per_replica: true is rejected up front. The donor replica is the lowest-numbered one so the choice is deterministic. ContainerWait uses WaitConditionNextExit, and the wait loop deterministically handles the daemon's clean-close (nil on Error + exit code on Result) and transport-error races to avoid spurious hook failures. The log stream is opened before ContainerStart to avoid racing AutoRemove on fast-exiting hooks, and runs under a derived context so a daemon that keeps the connection open cannot deadlock the call. Hook containers carry project/service/version labels; the two cleanup paths force-remove the never-started container explicitly and warn when removal fails. pre_start runs once per service when no replica is already running (initial up, force-recreate or spec change), and is skipped on scale-up so additional replicas don't re-trigger the hooks. Coverage: 11 unit tests (including scheduler-race stress) with goroutine-leak verification via goleak, plus 10 E2E tests (success path, hook failure gating start, build-image inheritance, idempotent re-up, spec change, force-recreate, mid-sequence failure, ordering, scale-up, scaled service). Signed-off-by: Guillaume Lours <[email protected]>