Skip to content

Commit 5722260

Browse files
committed
normalize implicit dependencies as explicit depends_on
Signed-off-by: Nicolas De Loof <[email protected]>
1 parent 873a781 commit 5722260

File tree

4 files changed

+108
-31
lines changed

4 files changed

+108
-31
lines changed

loader/loader_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,7 @@ services:
783783
build:
784784
context: ./web
785785
links:
786-
- bar
786+
- db
787787
pid: host
788788
db:
789789
image: db
@@ -837,7 +837,7 @@ services:
837837
image: web
838838
build: .
839839
links:
840-
- bar
840+
- db
841841
db:
842842
image: db
843843
build:

loader/normalize.go

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"fmt"
2121
"os"
2222
"path/filepath"
23+
"strings"
2324

2425
"github.com/compose-spec/compose-go/errdefs"
2526
"github.com/compose-spec/compose-go/types"
@@ -95,6 +96,37 @@ func normalize(project *types.Project, resolvePaths bool) error {
9596
s.Extends["file"] = &p
9697
}
9798

99+
for _, link := range s.Links {
100+
parts := strings.Split(link, ":")
101+
if len(parts) == 2 {
102+
link = parts[0]
103+
}
104+
s.DependsOn = setIfMissing(s.DependsOn, link, types.ServiceDependency{
105+
Condition: types.ServiceConditionStarted,
106+
Restart: true,
107+
})
108+
}
109+
110+
for _, namespace := range []string{s.NetworkMode, s.Ipc, s.Pid, s.Uts, s.Cgroup} {
111+
if strings.HasPrefix(namespace, types.ServicePrefix) {
112+
name := namespace[len(types.ServicePrefix):]
113+
s.DependsOn = setIfMissing(s.DependsOn, name, types.ServiceDependency{
114+
Condition: types.ServiceConditionStarted,
115+
Restart: true,
116+
})
117+
}
118+
}
119+
120+
for _, vol := range s.VolumesFrom {
121+
if !strings.HasPrefix(s.Pid, types.ContainerPrefix) {
122+
spec := strings.Split(vol, ":")
123+
s.DependsOn = setIfMissing(s.DependsOn, spec[0], types.ServiceDependency{
124+
Condition: types.ServiceConditionStarted,
125+
Restart: false,
126+
})
127+
}
128+
}
129+
98130
err := relocateLogDriver(&s)
99131
if err != nil {
100132
return err
@@ -131,9 +163,20 @@ func normalize(project *types.Project, resolvePaths bool) error {
131163
return nil
132164
}
133165

166+
// setIfMissing adds a ServiceDependency for service if not already defined
167+
func setIfMissing(d types.DependsOnConfig, service string, dep types.ServiceDependency) types.DependsOnConfig {
168+
if d == nil {
169+
d = types.DependsOnConfig{}
170+
}
171+
if _, ok := d[service]; !ok {
172+
d[service] = dep
173+
}
174+
return d
175+
}
176+
134177
func relocateScale(s *types.ServiceConfig) error {
135178
scale := uint64(s.Scale)
136-
if scale != 1 {
179+
if scale > 1 {
137180
logrus.Warn("`scale` is deprecated. Use the `deploy.replicas` element")
138181
if s.Deploy == nil {
139182
s.Deploy = &types.DeployConfig{}

loader/normalize_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,3 +184,61 @@ func TestNormalizeVolumes(t *testing.T) {
184184
assert.NilError(t, err)
185185
assert.DeepEqual(t, expected, project)
186186
}
187+
188+
func TestNormalizeDependsOn(t *testing.T) {
189+
project := types.Project{
190+
Name: "myProject",
191+
Networks: types.Networks{},
192+
Volumes: types.Volumes{},
193+
Services: []types.ServiceConfig{
194+
{
195+
Name: "foo",
196+
DependsOn: map[string]types.ServiceDependency{
197+
"bar": { // explicit depends_on never should be overridden
198+
Condition: types.ServiceConditionHealthy,
199+
Restart: false,
200+
},
201+
},
202+
NetworkMode: "service:zot",
203+
},
204+
{
205+
Name: "bar",
206+
VolumesFrom: []string{"zot"},
207+
},
208+
{
209+
Name: "zot",
210+
},
211+
},
212+
}
213+
214+
expected := `name: myProject
215+
services:
216+
bar:
217+
depends_on:
218+
zot:
219+
condition: service_started
220+
networks:
221+
default: null
222+
volumes_from:
223+
- zot
224+
foo:
225+
depends_on:
226+
bar:
227+
condition: service_healthy
228+
zot:
229+
condition: service_started
230+
restart: true
231+
network_mode: service:zot
232+
zot:
233+
networks:
234+
default: null
235+
networks:
236+
default:
237+
name: myProject_default
238+
`
239+
err := normalize(&project, true)
240+
assert.NilError(t, err)
241+
marshal, err := yaml.Marshal(project)
242+
assert.NilError(t, err)
243+
assert.DeepEqual(t, expected, string(marshal))
244+
}

types/types.go

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -256,35 +256,11 @@ const (
256256

257257
// GetDependencies retrieve all services this service depends on
258258
func (s ServiceConfig) GetDependencies() []string {
259-
dependencies := make(set)
260-
for dependency := range s.DependsOn {
261-
dependencies.append(dependency)
262-
}
263-
for _, link := range s.Links {
264-
parts := strings.Split(link, ":")
265-
if len(parts) == 2 {
266-
dependencies.append(parts[0])
267-
} else {
268-
dependencies.append(link)
269-
}
270-
}
271-
if strings.HasPrefix(s.NetworkMode, ServicePrefix) {
272-
dependencies.append(s.NetworkMode[len(ServicePrefix):])
273-
}
274-
if strings.HasPrefix(s.Ipc, ServicePrefix) {
275-
dependencies.append(s.Ipc[len(ServicePrefix):])
259+
var dependencies []string
260+
for service := range s.DependsOn {
261+
dependencies = append(dependencies, service)
276262
}
277-
if strings.HasPrefix(s.Pid, ServicePrefix) {
278-
dependencies.append(s.Pid[len(ServicePrefix):])
279-
}
280-
for _, vol := range s.VolumesFrom {
281-
if !strings.HasPrefix(s.Pid, ContainerPrefix) {
282-
spec := strings.Split(vol, ":")
283-
dependencies.append(spec[0])
284-
}
285-
}
286-
287-
return dependencies.toSlice()
263+
return dependencies
288264
}
289265

290266
type set map[string]struct{}

0 commit comments

Comments
 (0)