@@ -26,18 +26,12 @@ import (
26
26
27
27
// Normalize compose project by moving deprecated attributes to their canonical position and injecting implicit defaults
28
28
func Normalize (dict map [string ]any , env types.Mapping ) (map [string ]any , error ) {
29
- dict [ "networks" ] = normalizeNetworks (dict )
29
+ normalizeNetworks (dict )
30
30
31
31
if d , ok := dict ["services" ]; ok {
32
32
services := d .(map [string ]any )
33
33
for name , s := range services {
34
34
service := s .(map [string ]any )
35
- _ , hasNetworks := service ["networks" ]
36
- _ , hasNetworkMode := service ["network_mode" ]
37
- if ! hasNetworks && ! hasNetworkMode {
38
- // Service without explicit network attachment are implicitly exposed on default network
39
- service ["networks" ] = map [string ]any {"default" : nil }
40
- }
41
35
42
36
if service ["pull_policy" ] == types .PullPolicyIfNotPresent {
43
37
service ["pull_policy" ] = types .PullPolicyMissing
@@ -137,18 +131,51 @@ func Normalize(dict map[string]any, env types.Mapping) (map[string]any, error) {
137
131
return dict , nil
138
132
}
139
133
140
- func normalizeNetworks (dict map [string ]any ) map [ string ] any {
134
+ func normalizeNetworks (dict map [string ]any ) {
141
135
var networks map [string ]any
142
136
if n , ok := dict ["networks" ]; ok {
143
137
networks = n .(map [string ]any )
144
138
} else {
145
139
networks = map [string ]any {}
146
140
}
147
- if _ , ok := networks ["default" ]; ! ok {
141
+
142
+ // implicit `default` network must be introduced only if actually used by some service
143
+ usesDefaultNetwork := false
144
+
145
+ if s , ok := dict ["services" ]; ok {
146
+ services := s .(map [string ]any )
147
+ for name , se := range services {
148
+ service := se .(map [string ]any )
149
+ if _ , ok := service ["network_mode" ]; ok {
150
+ continue
151
+ }
152
+ if n , ok := service ["networks" ]; ! ok {
153
+ // If none explicitly declared, service is connected to default network
154
+ service ["networks" ] = map [string ]any {"default" : nil }
155
+ usesDefaultNetwork = true
156
+ } else {
157
+ net := n .(map [string ]any )
158
+ if len (net ) == 0 {
159
+ // networks section declared but empty (corner case)
160
+ service ["networks" ] = map [string ]any {"default" : nil }
161
+ usesDefaultNetwork = true
162
+ } else if _ , ok := net ["default" ]; ok {
163
+ usesDefaultNetwork = true
164
+ }
165
+ }
166
+ services [name ] = service
167
+ }
168
+ dict ["services" ] = services
169
+ }
170
+
171
+ if _ , ok := networks ["default" ]; ! ok && usesDefaultNetwork {
148
172
// If not declared explicitly, Compose model involves an implicit "default" network
149
173
networks ["default" ] = nil
150
174
}
151
- return networks
175
+
176
+ if len (networks ) > 0 {
177
+ dict ["networks" ] = networks
178
+ }
152
179
}
153
180
154
181
func resolve (a any , fn func (s string ) (string , bool )) (any , bool ) {
0 commit comments