Skip to content

Commit

Permalink
Merge pull request #350 from ndeloof/depends_on_restart
Browse files Browse the repository at this point in the history
introduce `restart` for depends_on
  • Loading branch information
ndeloof authored Feb 17, 2023
2 parents b16c6a1 + 6bce3b9 commit c5cb8b2
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 38 deletions.
2 changes: 1 addition & 1 deletion loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ func Load(configDetails types.ConfigDetails, options ...func(*Options)) (*types.
}

if !opts.SkipNormalization {
err = normalize(project, opts.ResolvePaths)
err = Normalize(project, opts.ResolvePaths)
if err != nil {
return nil, err
}
Expand Down
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
49 changes: 46 additions & 3 deletions loader/normalize.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@ import (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/compose-spec/compose-go/errdefs"
"github.com/compose-spec/compose-go/types"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)

// normalize compose project by moving deprecated attributes to their canonical position and injecting implicit defaults
func normalize(project *types.Project, resolvePaths bool) error {
// Normalize compose project by moving deprecated attributes to their canonical position and injecting implicit defaults
func Normalize(project *types.Project, resolvePaths bool) error {
absWorkingDir, err := filepath.Abs(project.WorkingDir)
if err != nil {
return err
Expand Down Expand Up @@ -95,6 +96,37 @@ func normalize(project *types.Project, resolvePaths bool) error {
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)
if err != nil {
return err
Expand Down Expand Up @@ -131,9 +163,20 @@ 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 {
if scale > 1 {
logrus.Warn("`scale` is deprecated. Use the `deploy.replicas` element")
if s.Deploy == nil {
s.Deploy = &types.DeployConfig{}
Expand Down
66 changes: 62 additions & 4 deletions loader/normalize_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ networks:
mynet:
name: myProject_mynet
`
err := normalize(&project, false)
err := Normalize(&project, false)
assert.NilError(t, err)
marshal, err := yaml.Marshal(project)
assert.NilError(t, err)
Expand Down Expand Up @@ -118,7 +118,7 @@ networks:
default:
name: myProject_default
`, filepath.Join(wd, "testdata"))
err := normalize(&project, true)
err := Normalize(&project, true)
assert.NilError(t, err)
marshal, err := yaml.Marshal(project)
assert.NilError(t, err)
Expand All @@ -142,7 +142,7 @@ func TestNormalizeAbsolutePaths(t *testing.T) {
WorkingDir: absWorkingDir,
ComposeFiles: []string{absComposeFile, absOverrideFile},
}
err := normalize(&project, false)
err := Normalize(&project, false)
assert.NilError(t, err)
assert.DeepEqual(t, expected, project)
}
Expand Down Expand Up @@ -180,7 +180,65 @@ func TestNormalizeVolumes(t *testing.T) {
WorkingDir: absCwd,
ComposeFiles: []string{},
}
err := normalize(&project, false)
err := Normalize(&project, false)
assert.NilError(t, err)
assert.DeepEqual(t, expected, project)
}

func TestNormalizeDependsOn(t *testing.T) {
project := types.Project{
Name: "myProject",
Networks: types.Networks{},
Volumes: types.Volumes{},
Services: []types.ServiceConfig{
{
Name: "foo",
DependsOn: map[string]types.ServiceDependency{
"bar": { // explicit depends_on never should be overridden
Condition: types.ServiceConditionHealthy,
Restart: false,
},
},
NetworkMode: "service:zot",
},
{
Name: "bar",
VolumesFrom: []string{"zot"},
},
{
Name: "zot",
},
},
}

expected := `name: myProject
services:
bar:
depends_on:
zot:
condition: service_started
networks:
default: null
volumes_from:
- zot
foo:
depends_on:
bar:
condition: service_healthy
zot:
condition: service_started
restart: true
network_mode: service:zot
zot:
networks:
default: null
networks:
default:
name: myProject_default
`
err := Normalize(&project, true)
assert.NilError(t, err)
marshal, err := yaml.Marshal(project)
assert.NilError(t, err)
assert.DeepEqual(t, expected, string(marshal))
}
1 change: 1 addition & 0 deletions schema/compose-spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@
"type": "object",
"additionalProperties": false,
"properties": {
"restart": {"type": "boolean"},
"condition": {
"type": "string",
"enum": ["service_started", "service_healthy", "service_completed_successfully"]
Expand Down
33 changes: 5 additions & 28 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 @@ -1007,6 +983,7 @@ type DependsOnConfig map[string]ServiceDependency

type ServiceDependency struct {
Condition string `yaml:",omitempty" json:"condition,omitempty"`
Restart bool `yaml:",omitempty" json:"restart,omitempty"`
Extensions map[string]interface{} `yaml:",inline" json:"-"`
}

Expand Down

0 comments on commit c5cb8b2

Please sign in to comment.