mirror of
https://github.com/docker/compose.git
synced 2026-10-12 02:13:08 +00:00
executor: pre_start re-checks the daemon before running
The 'once per service, only when no replica is running' rule is decided at plan time from the observed state — the placement of the RunPreStart node stays a plan decision. But between observation and execution a replica can start (the general observe-to-execute drift window the plan design accepts): for pre_start that drift would re-run hooks the rule says must not run. The operation now re-checks the daemon at execution time and skips itself when a replica is already running — plan-time placement, runtime guard. Validated design decision for #14081 (start-candidates model). Signed-off-by: Nicolas De Loof <[email protected]>
This commit is contained in:
@@ -279,6 +279,19 @@ func (exec *planExecutor) checkWaitCondition(ctx context.Context, op Operation,
|
||||
// execRunPreStart runs the service's pre_start hooks on the replica the plan
|
||||
// selected (once per service, before any of its containers start).
|
||||
func (exec *planExecutor) execRunPreStart(ctx context.Context, op Operation) error {
|
||||
// The plan scheduled this node because no replica was running at
|
||||
// observation time. Re-check against the daemon at execution time: if a
|
||||
// replica started in the meantime (observe-to-execute drift), the
|
||||
// once-per-service rule says the hooks must not run again.
|
||||
running, err := exec.compose.getContainers(ctx, exec.project.Name, oneOffExclude, false, op.Service.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(running) > 0 {
|
||||
logrus.Debugf("skipping pre_start hooks of service %s: a replica is already running", op.Service.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
id, name := exec.resolveContainer(op)
|
||||
if id == "" {
|
||||
return fmt.Errorf("no container to run pre_start hooks for %s", op.ResourceID)
|
||||
|
||||
Reference in New Issue
Block a user