mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
Merge pull request #50327 from Adrien-Atmosphere/50326-wait-for-dependent-containers
Wait for container dependencies upon daemon start up
This commit is contained in:
@@ -1,11 +1,16 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
|
||||
package daemon
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"maps"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -196,6 +201,31 @@ func (daemon *Daemon) GetByName(name string) (*container.Container, error) {
|
||||
return e, nil
|
||||
}
|
||||
|
||||
// GetDependentContainers returns a list of containers that depend on the given container.
|
||||
// Dependencies are determined by:
|
||||
// - Network mode dependencies (--network=container:xxx)
|
||||
// - Legacy container links (--link)
|
||||
//
|
||||
// This is primarily used during daemon startup to determine container startup order,
|
||||
// ensuring that dependent containers are started after their dependencies are running.
|
||||
// Upon error, it returns the last known dependent containers, which may be empty.
|
||||
func (daemon *Daemon) GetDependentContainers(c *container.Container) []*container.Container {
|
||||
var dependentContainers []*container.Container
|
||||
|
||||
if c.HostConfig.NetworkMode.IsContainer() {
|
||||
// If the container is using a network mode that depends on another container,
|
||||
// we need to find that container and add it to the dependency map.
|
||||
dependencyContainer, err := daemon.GetContainer(c.HostConfig.NetworkMode.ConnectedContainer())
|
||||
if err != nil {
|
||||
log.G(context.TODO()).WithError(err).Errorf("Could not find dependent container for %s", c.ID)
|
||||
return dependentContainers
|
||||
}
|
||||
dependentContainers = append(dependentContainers, dependencyContainer)
|
||||
}
|
||||
|
||||
return append(dependentContainers, slices.Collect(maps.Values(daemon.linkIndex.children(c)))...)
|
||||
}
|
||||
|
||||
func (daemon *Daemon) setSecurityOptions(cfg *config.Config, container *container.Container, hostConfig *containertypes.HostConfig) error {
|
||||
container.Lock()
|
||||
defer container.Unlock()
|
||||
|
||||
@@ -575,8 +575,8 @@ func (daemon *Daemon) restore(cfg *configStore) error {
|
||||
logger.Debug("starting container")
|
||||
|
||||
// ignore errors here as this is a best effort to wait for children
|
||||
// (legacy links) to be running before we try to start the container
|
||||
if children := daemon.linkIndex.children(c); len(children) > 0 {
|
||||
// (legacy links or container network) to be running before we try to start the container
|
||||
if children := daemon.GetDependentContainers(c); len(children) > 0 {
|
||||
timeout := time.NewTimer(5 * time.Second)
|
||||
defer timeout.Stop()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user