Skip to content

Commit 2f4f78b

Browse files
authored
Merge pull request moby#50327 from Adrien-Atmosphere/50326-wait-for-dependent-containers
Wait for container dependencies upon daemon start up
2 parents 87fdd1b + d4e026f commit 2f4f78b

2 files changed

Lines changed: 32 additions & 2 deletions

File tree

daemon/container.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1+
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
2+
//go:build go1.23
3+
14
package daemon
25

36
import (
47
"context"
58
"fmt"
9+
"maps"
610
"os"
711
"path/filepath"
812
"runtime"
13+
"slices"
914
"strings"
1015
"time"
1116

@@ -196,6 +201,31 @@ func (daemon *Daemon) GetByName(name string) (*container.Container, error) {
196201
return e, nil
197202
}
198203

204+
// GetDependentContainers returns a list of containers that depend on the given container.
205+
// Dependencies are determined by:
206+
// - Network mode dependencies (--network=container:xxx)
207+
// - Legacy container links (--link)
208+
//
209+
// This is primarily used during daemon startup to determine container startup order,
210+
// ensuring that dependent containers are started after their dependencies are running.
211+
// Upon error, it returns the last known dependent containers, which may be empty.
212+
func (daemon *Daemon) GetDependentContainers(c *container.Container) []*container.Container {
213+
var dependentContainers []*container.Container
214+
215+
if c.HostConfig.NetworkMode.IsContainer() {
216+
// If the container is using a network mode that depends on another container,
217+
// we need to find that container and add it to the dependency map.
218+
dependencyContainer, err := daemon.GetContainer(c.HostConfig.NetworkMode.ConnectedContainer())
219+
if err != nil {
220+
log.G(context.TODO()).WithError(err).Errorf("Could not find dependent container for %s", c.ID)
221+
return dependentContainers
222+
}
223+
dependentContainers = append(dependentContainers, dependencyContainer)
224+
}
225+
226+
return append(dependentContainers, slices.Collect(maps.Values(daemon.linkIndex.children(c)))...)
227+
}
228+
199229
func (daemon *Daemon) setSecurityOptions(cfg *config.Config, container *container.Container, hostConfig *containertypes.HostConfig) error {
200230
container.Lock()
201231
defer container.Unlock()

daemon/daemon.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -575,8 +575,8 @@ func (daemon *Daemon) restore(cfg *configStore) error {
575575
logger.Debug("starting container")
576576

577577
// ignore errors here as this is a best effort to wait for children
578-
// (legacy links) to be running before we try to start the container
579-
if children := daemon.linkIndex.children(c); len(children) > 0 {
578+
// (legacy links or container network) to be running before we try to start the container
579+
if children := daemon.GetDependentContainers(c); len(children) > 0 {
580580
timeout := time.NewTimer(5 * time.Second)
581581
defer timeout.Stop()
582582

0 commit comments

Comments
 (0)