Skip to content

Commit

Permalink
normalize implicit dependencies as explicit depends_on
Browse files Browse the repository at this point in the history
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
  • Loading branch information
ndeloof committed Feb 16, 2023
1 parent 873a781 commit 6b1865f
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 32 deletions.
4 changes: 2 additions & 2 deletions loader/loader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,7 @@ services:
build:
context: ./web
links:
- bar
- db
pid: host
db:
image: db
Expand Down Expand Up @@ -837,7 +837,7 @@ services:
image: web
build: .
links:
- bar
- db
db:
image: db
build:
Expand Down
43 changes: 43 additions & 0 deletions loader/normalize.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/compose-spec/compose-go/errdefs"
"github.com/compose-spec/compose-go/types"
Expand Down Expand Up @@ -93,6 +94,37 @@ func normalize(project *types.Project, resolvePaths bool) error {
if extendFile := s.Extends["file"]; extendFile != nil && *extendFile != "" {
p := absPath(project.WorkingDir, *extendFile)
s.Extends["file"] = &p
}

for _, link := range s.Links {
parts := strings.Split(link, ":")
if len(parts) == 2 {
link = parts[0]
}
s.DependsOn = setIfMissing(s.DependsOn, link, types.ServiceDependency{
Condition: types.ServiceConditionStarted,
Restart: true,
})
}

for _, namespace := range []string{s.NetworkMode, s.Ipc, s.Pid, s.Uts, s.Cgroup} {
if strings.HasPrefix(namespace, types.ServicePrefix) {
name := namespace[len(types.ServicePrefix):]
s.DependsOn = setIfMissing(s.DependsOn, name, types.ServiceDependency{
Condition: types.ServiceConditionStarted,
Restart: true,
})
}
}

for _, vol := range s.VolumesFrom {
if !strings.HasPrefix(s.Pid, types.ContainerPrefix) {
spec := strings.Split(vol, ":")
s.DependsOn = setIfMissing(s.DependsOn, spec[0], types.ServiceDependency{
Condition: types.ServiceConditionStarted,
Restart: false,
})
}
}

err := relocateLogDriver(&s)
Expand Down Expand Up @@ -131,6 +163,17 @@ func normalize(project *types.Project, resolvePaths bool) error {
return nil
}

// setIfMissing adds a ServiceDependency for service if not already defined
func setIfMissing(d types.DependsOnConfig, service string, dep types.ServiceDependency) types.DependsOnConfig {
if d == nil {
d = types.DependsOnConfig{}
}
if _, ok := d[service]; !ok {
d[service] = dep
}
return d
}

func relocateScale(s *types.ServiceConfig) error {
scale := uint64(s.Scale)
if scale != 1 {
Expand Down
36 changes: 6 additions & 30 deletions types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,35 +256,11 @@ const (

// GetDependencies retrieve all services this service depends on
func (s ServiceConfig) GetDependencies() []string {
dependencies := make(set)
for dependency := range s.DependsOn {
dependencies.append(dependency)
}
for _, link := range s.Links {
parts := strings.Split(link, ":")
if len(parts) == 2 {
dependencies.append(parts[0])
} else {
dependencies.append(link)
}
}
if strings.HasPrefix(s.NetworkMode, ServicePrefix) {
dependencies.append(s.NetworkMode[len(ServicePrefix):])
}
if strings.HasPrefix(s.Ipc, ServicePrefix) {
dependencies.append(s.Ipc[len(ServicePrefix):])
var dependencies []string
for service := range s.DependsOn {
dependencies = append(dependencies, service)
}
if strings.HasPrefix(s.Pid, ServicePrefix) {
dependencies.append(s.Pid[len(ServicePrefix):])
}
for _, vol := range s.VolumesFrom {
if !strings.HasPrefix(s.Pid, ContainerPrefix) {
spec := strings.Split(vol, ":")
dependencies.append(spec[0])
}
}

return dependencies.toSlice()
return dependencies
}

type set map[string]struct{}
Expand Down Expand Up @@ -357,12 +333,12 @@ type ThrottleDevice struct {
// ShellCommand is a string or list of string args.
//
// When marshaled to YAML, nil command fields will be omitted if `omitempty`
// is specified as a struct tag. Explicitly empty commands (i.e. `[]` or `''`)
// is specified as a struct tag. Explicitly empty commands (i.e. `[]` or ``)
// will serialize to an empty array (`[]`).
//
// When marshaled to JSON, the `omitempty` struct must NOT be specified.
// If the command field is nil, it will be serialized as `null`.
// Explicitly empty commands (i.e. `[]` or `''`) will serialize to an empty
// Explicitly empty commands (i.e. `[]` or ``) will serialize to an empty
// array (`[]`).
//
// The distinction between nil and explicitly empty is important to distinguish
Expand Down

0 comments on commit 6b1865f

Please sign in to comment.