mirror of https://github.com/docker/compose.git
up should not silently ignore missing depends_on service
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
parent
6f6e1635fd
commit
06ec06472f
2
go.mod
2
go.mod
|
@ -5,7 +5,7 @@ go 1.20
|
|||
require (
|
||||
github.com/AlecAivazis/survey/v2 v2.3.6
|
||||
github.com/buger/goterm v1.0.4
|
||||
github.com/compose-spec/compose-go v1.13.5
|
||||
github.com/compose-spec/compose-go v1.14.0
|
||||
github.com/containerd/console v1.0.3
|
||||
github.com/containerd/containerd v1.6.21
|
||||
github.com/cucumber/godog v0.0.0-00010101000000-000000000000 // replaced; see replace for the actual version used
|
||||
|
|
4
go.sum
4
go.sum
|
@ -157,8 +157,8 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH
|
|||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/compose-spec/compose-go v1.13.5 h1:ogqJOGEbe3uRxMg0ZEufOoCQTpX61l8tUeyW4UQgEBk=
|
||||
github.com/compose-spec/compose-go v1.13.5/go.mod h1:m0o4G6MQDHjjz9rY7No9FpnNi+9sKic262rzrwuCqic=
|
||||
github.com/compose-spec/compose-go v1.14.0 h1:/+tQxBEPIrfsi87Qh7/VjMzcJN3BRNER/RO71ku+u6E=
|
||||
github.com/compose-spec/compose-go v1.14.0/go.mod h1:m0o4G6MQDHjjz9rY7No9FpnNi+9sKic262rzrwuCqic=
|
||||
github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA=
|
||||
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
|
||||
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
|
||||
|
|
|
@ -106,11 +106,6 @@ func (s *composeService) create(ctx context.Context, project *types.Project, opt
|
|||
}
|
||||
}
|
||||
|
||||
err = prepareServicesDependsOn(project)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return newConvergence(options.Services, observedState, s).apply(ctx, project, options)
|
||||
}
|
||||
|
||||
|
@ -147,72 +142,6 @@ func prepareNetworks(project *types.Project) {
|
|||
}
|
||||
}
|
||||
|
||||
func prepareServicesDependsOn(p *types.Project) error {
|
||||
allServices := types.Project{}
|
||||
allServices.Services = p.AllServices()
|
||||
|
||||
for i, service := range p.Services {
|
||||
var dependencies []string
|
||||
networkDependency := getDependentServiceFromMode(service.NetworkMode)
|
||||
if networkDependency != "" {
|
||||
dependencies = append(dependencies, networkDependency)
|
||||
}
|
||||
|
||||
ipcDependency := getDependentServiceFromMode(service.Ipc)
|
||||
if ipcDependency != "" {
|
||||
dependencies = append(dependencies, ipcDependency)
|
||||
}
|
||||
|
||||
pidDependency := getDependentServiceFromMode(service.Pid)
|
||||
if pidDependency != "" {
|
||||
dependencies = append(dependencies, pidDependency)
|
||||
}
|
||||
|
||||
for _, vol := range service.VolumesFrom {
|
||||
spec := strings.Split(vol, ":")
|
||||
if len(spec) == 0 {
|
||||
continue
|
||||
}
|
||||
if spec[0] == "container" {
|
||||
continue
|
||||
}
|
||||
dependencies = append(dependencies, spec[0])
|
||||
}
|
||||
|
||||
for _, link := range service.Links {
|
||||
dependencies = append(dependencies, strings.Split(link, ":")[0])
|
||||
}
|
||||
|
||||
for d := range service.DependsOn {
|
||||
dependencies = append(dependencies, d)
|
||||
}
|
||||
|
||||
if len(dependencies) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// Verify dependencies exist in the project, whether disabled or not
|
||||
deps, err := allServices.GetServices(dependencies...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if service.DependsOn == nil {
|
||||
service.DependsOn = make(types.DependsOnConfig)
|
||||
}
|
||||
|
||||
for _, d := range deps {
|
||||
if _, ok := service.DependsOn[d.Name]; !ok {
|
||||
service.DependsOn[d.Name] = types.ServiceDependency{
|
||||
Condition: types.ServiceConditionStarted,
|
||||
}
|
||||
}
|
||||
}
|
||||
p.Services[i] = service
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *composeService) ensureNetworks(ctx context.Context, networks types.Networks) error {
|
||||
for _, network := range networks {
|
||||
err := s.ensureNetwork(ctx, network)
|
||||
|
@ -640,8 +569,8 @@ func setLimits(limits *types.Resource, resources *container.Resources) {
|
|||
resources.NanoCPUs = int64(f * 1e9)
|
||||
}
|
||||
}
|
||||
if limits.PIds > 0 {
|
||||
resources.PidsLimit = &limits.PIds
|
||||
if limits.Pids > 0 {
|
||||
resources.PidsLimit = &limits.Pids
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -743,7 +672,10 @@ func getVolumesFrom(project *types.Project, volumesFrom []string) ([]string, []s
|
|||
}
|
||||
|
||||
func getDependentServiceFromMode(mode string) string {
|
||||
if strings.HasPrefix(mode, types.NetworkModeServicePrefix) {
|
||||
if strings.HasPrefix(
|
||||
mode,
|
||||
types.NetworkModeServicePrefix,
|
||||
) {
|
||||
return mode[len(types.NetworkModeServicePrefix):]
|
||||
}
|
||||
return ""
|
||||
|
|
|
@ -23,6 +23,8 @@ import (
|
|||
"sync"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/docker/compose/v2/pkg/api"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/docker/compose/v2/pkg/utils"
|
||||
|
@ -76,7 +78,7 @@ func downDirectionTraversal(visitorFn func(context.Context, string) error) *grap
|
|||
|
||||
// InDependencyOrder applies the function to the services of the project taking in account the dependency order
|
||||
func InDependencyOrder(ctx context.Context, project *types.Project, fn func(context.Context, string) error, options ...func(*graphTraversal)) error {
|
||||
graph, err := NewGraph(project.Services, ServiceStopped)
|
||||
graph, err := NewGraph(project, ServiceStopped)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -89,7 +91,7 @@ func InDependencyOrder(ctx context.Context, project *types.Project, fn func(cont
|
|||
|
||||
// InReverseDependencyOrder applies the function to the services of the project in reverse order of dependencies
|
||||
func InReverseDependencyOrder(ctx context.Context, project *types.Project, fn func(context.Context, string) error, options ...func(*graphTraversal)) error {
|
||||
graph, err := NewGraph(project.Services, ServiceStarted)
|
||||
graph, err := NewGraph(project, ServiceStarted)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -252,19 +254,28 @@ func (v *Vertex) GetChildren() []*Vertex {
|
|||
}
|
||||
|
||||
// NewGraph returns the dependency graph of the services
|
||||
func NewGraph(services types.Services, initialStatus ServiceStatus) (*Graph, error) {
|
||||
func NewGraph(project *types.Project, initialStatus ServiceStatus) (*Graph, error) {
|
||||
graph := &Graph{
|
||||
lock: sync.RWMutex{},
|
||||
Vertices: map[string]*Vertex{},
|
||||
}
|
||||
|
||||
for _, s := range services {
|
||||
for _, s := range project.Services {
|
||||
graph.AddVertex(s.Name, s.Name, initialStatus)
|
||||
}
|
||||
|
||||
for _, s := range services {
|
||||
for _, s := range project.Services {
|
||||
for _, name := range s.GetDependencies() {
|
||||
_ = graph.AddEdge(s.Name, name)
|
||||
err := graph.AddEdge(s.Name, name)
|
||||
if err != nil {
|
||||
if api.IsNotFoundError(err) {
|
||||
ds, err := project.GetDisabledService(name)
|
||||
if err == nil {
|
||||
return nil, fmt.Errorf("service %s is required by %s but is disabled. Can be enabled by profiles %s", name, s.Name, ds.Profiles)
|
||||
}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,10 +315,10 @@ func (g *Graph) AddEdge(source string, destination string) error {
|
|||
destinationVertex := g.Vertices[destination]
|
||||
|
||||
if sourceVertex == nil {
|
||||
return fmt.Errorf("could not find %s", source)
|
||||
return errors.Wrapf(api.ErrNotFound, "could not find %s", source)
|
||||
}
|
||||
if destinationVertex == nil {
|
||||
return fmt.Errorf("could not find %s", destination)
|
||||
return errors.Wrapf(api.ErrNotFound, "could not find %s", destination)
|
||||
}
|
||||
|
||||
// If they are already connected
|
||||
|
|
|
@ -270,7 +270,7 @@ func TestBuildGraph(t *testing.T) {
|
|||
Services: tC.services,
|
||||
}
|
||||
|
||||
graph, err := NewGraph(project.Services, ServiceStopped)
|
||||
graph, err := NewGraph(&project, ServiceStopped)
|
||||
assert.NilError(t, err, fmt.Sprintf("failed to build graph for: %s", tC.desc))
|
||||
|
||||
for k, vertex := range graph.Vertices {
|
||||
|
|
Loading…
Reference in New Issue