Skip to content

Commit

Permalink
Merge pull request #428 from glours/depends_on-required-attribut
Browse files Browse the repository at this point in the history
  • Loading branch information
ndeloof authored Jul 7, 2023
2 parents 09318c2 + e582172 commit 87ef292
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 15 deletions.
12 changes: 8 additions & 4 deletions loader/full-struct_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ func services(workingDir, homeDir string) []types.ServiceConfig {
},
ContainerName: "my-web-container",
DependsOn: types.DependsOnConfig{
"db": {Condition: types.ServiceConditionStarted},
"redis": {Condition: types.ServiceConditionStarted},
"db": {Condition: types.ServiceConditionStarted, Required: true},
"redis": {Condition: types.ServiceConditionStarted, Required: true},
},
Deploy: &types.DeployConfig{
Mode: "replicated",
Expand Down Expand Up @@ -657,8 +657,10 @@ services:
depends_on:
db:
condition: service_started
required: true
redis:
condition: service_started
required: true
deploy:
mode: replicated
replicas: 6
Expand Down Expand Up @@ -1228,10 +1230,12 @@ func fullExampleJSON(workingDir, homeDir string) string {
"container_name": "my-web-container",
"depends_on": {
"db": {
"condition": "service_started"
"condition": "service_started",
"required": true
},
"redis": {
"condition": "service_started"
"condition": "service_started",
"required": true
}
},
"deploy": {
Expand Down
17 changes: 14 additions & 3 deletions loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -1088,13 +1088,24 @@ var transformDependsOnConfig TransformerFunc = func(data interface{}) (interface
for _, serviceIntf := range value {
service, ok := serviceIntf.(string)
if !ok {
return data, errors.Errorf("invalid type %T for service depends_on elementn, expected string", value)
return data, errors.Errorf("invalid type %T for service depends_on element, expected string", value)
}
transformed[service] = map[string]interface{}{"condition": types.ServiceConditionStarted}
transformed[service] = map[string]interface{}{"condition": types.ServiceConditionStarted, "required": true}
}
return transformed, nil
case map[string]interface{}:
return groupXFieldsIntoExtensions(data.(map[string]interface{})), nil
transformed := map[string]interface{}{}
for service, val := range value {
dependsConfigIntf, ok := val.(map[string]interface{})
if !ok {
return data, errors.Errorf("invalid type %T for service depends_on element", value)
}
if _, ok := dependsConfigIntf["required"]; !ok {
dependsConfigIntf["required"] = true
}
transformed[service] = dependsConfigIntf
}
return groupXFieldsIntoExtensions(transformed), nil
default:
return data, errors.Errorf("invalid type %T for service depends_on", value)
}
Expand Down
34 changes: 33 additions & 1 deletion loader/loader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2428,7 +2428,7 @@ services:
Image: "busybox",
Environment: types.MappingWithEquals{},
Scale: 1,
DependsOn: types.DependsOnConfig{"imported": {Condition: "service_started"}},
DependsOn: types.DependsOnConfig{"imported": {Condition: "service_started", Required: true}},
},
{
Name: "imported",
Expand Down Expand Up @@ -2465,3 +2465,35 @@ func TestLoadWithIncludeCycle(t *testing.T) {
})
assert.Check(t, strings.HasPrefix(err.Error(), "include cycle detected"))
}

func TestLoadWithDependsOn(t *testing.T) {
p, err := loadYAML(`
name: test-depends-on
services:
foo:
image: nginx
depends_on:
bar:
condition: service_started
baz:
condition: service_healthy
required: false
qux:
condition: service_completed_successfully
required: true
`)
assert.NilError(t, err)
assert.DeepEqual(t, p.Services, types.Services{
{
Name: "foo",
Image: "nginx",
Environment: types.MappingWithEquals{},
Scale: 1,
DependsOn: types.DependsOnConfig{
"bar": {Condition: types.ServiceConditionStarted, Required: true},
"baz": {Condition: types.ServiceConditionHealthy, Required: false},
"qux": {Condition: types.ServiceConditionCompletedSuccessfully, Required: true},
},
},
})
}
4 changes: 4 additions & 0 deletions loader/normalize.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ func Normalize(project *types.Project) error {
s.DependsOn = setIfMissing(s.DependsOn, link, types.ServiceDependency{
Condition: types.ServiceConditionStarted,
Restart: true,
Required: true,
})
}

Expand All @@ -92,6 +93,7 @@ func Normalize(project *types.Project) error {
s.DependsOn = setIfMissing(s.DependsOn, name, types.ServiceDependency{
Condition: types.ServiceConditionStarted,
Restart: true,
Required: true,
})
}
}
Expand All @@ -102,6 +104,7 @@ func Normalize(project *types.Project) error {
s.DependsOn = setIfMissing(s.DependsOn, spec[0], types.ServiceDependency{
Condition: types.ServiceConditionStarted,
Restart: false,
Required: true,
})
}
}
Expand Down Expand Up @@ -194,6 +197,7 @@ func inferImplicitDependencies(service *types.ServiceConfig) {
if _, ok := service.DependsOn[d]; !ok {
service.DependsOn[d] = types.ServiceDependency{
Condition: types.ServiceConditionStarted,
Required: true,
}
}
}
Expand Down
18 changes: 11 additions & 7 deletions loader/normalize_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ func TestNormalizeDependsOn(t *testing.T) {
"bar": { // explicit depends_on never should be overridden
Condition: types.ServiceConditionHealthy,
Restart: false,
Required: true,
},
},
NetworkMode: "service:zot",
Expand All @@ -159,6 +160,7 @@ services:
depends_on:
zot:
condition: service_started
required: true
networks:
default: null
volumes_from:
Expand All @@ -168,9 +170,11 @@ services:
depends_on:
bar:
condition: service_healthy
required: true
zot:
condition: service_started
restart: true
required: true
network_mode: service:zot
zot:
networks:
Expand Down Expand Up @@ -200,19 +204,19 @@ func TestNormalizeImplicitDependencies(t *testing.T) {
Links: []string{"corge"},
DependsOn: map[string]types.ServiceDependency{
// explicit dependency MUST not be overridden
"foo": {Condition: types.ServiceConditionHealthy, Restart: false},
"foo": {Condition: types.ServiceConditionHealthy, Restart: false, Required: true},
},
},
},
}

expected := types.DependsOnConfig{
"foo": {Condition: types.ServiceConditionHealthy, Restart: false},
"bar": {Condition: types.ServiceConditionStarted, Restart: true},
"baz": {Condition: types.ServiceConditionStarted, Restart: true},
"qux": {Condition: types.ServiceConditionStarted, Restart: true},
"quux": {Condition: types.ServiceConditionStarted},
"corge": {Condition: types.ServiceConditionStarted, Restart: true},
"foo": {Condition: types.ServiceConditionHealthy, Restart: false, Required: true},
"bar": {Condition: types.ServiceConditionStarted, Restart: true, Required: true},
"baz": {Condition: types.ServiceConditionStarted, Restart: true, Required: true},
"qux": {Condition: types.ServiceConditionStarted, Restart: true, Required: true},
"quux": {Condition: types.ServiceConditionStarted, Required: true},
"corge": {Condition: types.ServiceConditionStarted, Restart: true, Required: true},
}
err := Normalize(&project)
assert.NilError(t, err)
Expand Down
1 change: 1 addition & 0 deletions types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1025,6 +1025,7 @@ type ServiceDependency struct {
Condition string `yaml:"condition,omitempty" json:"condition,omitempty"`
Restart bool `yaml:"restart,omitempty" json:"restart,omitempty"`
Extensions Extensions `yaml:"#extensions,inline" json:"-"`
Required bool `yaml:"required" json:"required"`
}

type ExtendsConfig struct {
Expand Down

0 comments on commit 87ef292

Please sign in to comment.