Skip to content

Commit 5e2abb6

Browse files
committed
support additional_context reference to another service
Signed-off-by: Nicolas De Loof <[email protected]>
1 parent 4db5fcd commit 5e2abb6

File tree

9 files changed

+91
-35
lines changed

9 files changed

+91
-35
lines changed

cmd/compose/build.go

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,16 @@ func (opts buildOptions) toAPIBuildOptions(services []string) (api.BuildOptions,
6868
uiMode = "rawjson"
6969
}
7070
return api.BuildOptions{
71-
Pull: opts.pull,
72-
Push: opts.push,
73-
Progress: uiMode,
74-
Args: types.NewMappingWithEquals(opts.args),
75-
NoCache: opts.noCache,
76-
Quiet: opts.quiet,
77-
Services: services,
78-
Deps: opts.deps,
79-
SSHs: SSHKeys,
80-
Builder: builderName,
81-
Compatibility: opts.Compatibility,
71+
Pull: opts.pull,
72+
Push: opts.push,
73+
Progress: uiMode,
74+
Args: types.NewMappingWithEquals(opts.args),
75+
NoCache: opts.noCache,
76+
Quiet: opts.quiet,
77+
Services: services,
78+
Deps: opts.deps,
79+
SSHs: SSHKeys,
80+
Builder: builderName,
8281
}, nil
8382
}
8483

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ require (
99
github.com/Microsoft/go-winio v0.6.2
1010
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
1111
github.com/buger/goterm v1.0.4
12-
github.com/compose-spec/compose-go/v2 v2.4.7
12+
github.com/compose-spec/compose-go/v2 v2.4.8-0.20250130174723-77ab539e4f3f
1313
github.com/containerd/containerd/v2 v2.0.2
1414
github.com/containerd/platforms v1.0.0-rc.1
1515
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 h1:lkAMpLVBDaj17e
8181
github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
8282
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE=
8383
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4=
84-
github.com/compose-spec/compose-go/v2 v2.4.7 h1:WNpz5bIbKG+G+w9pfu72B1ZXr+Og9jez8TMEo8ecXPk=
85-
github.com/compose-spec/compose-go/v2 v2.4.7/go.mod h1:lFN0DrMxIncJGYAXTfWuajfwj5haBJqrBkarHcnjJKc=
84+
github.com/compose-spec/compose-go/v2 v2.4.8-0.20250130174723-77ab539e4f3f h1:turCjSVHj+0P+G6kuRsJfhhYzp1ULfTv7GVzv1dgIHQ=
85+
github.com/compose-spec/compose-go/v2 v2.4.8-0.20250130174723-77ab539e4f3f/go.mod h1:lFN0DrMxIncJGYAXTfWuajfwj5haBJqrBkarHcnjJKc=
8686
github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0=
8787
github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0=
8888
github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro=

pkg/api/api.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,6 @@ type BuildOptions struct {
155155
Memory int64
156156
// Builder name passed in the command line
157157
Builder string
158-
// Compatibility let compose run with best backward compatibility
159-
Compatibility bool
160158
}
161159

162160
// Apply mutates project according to build options

pkg/compose/build.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"errors"
2222
"fmt"
2323
"os"
24+
"strings"
2425

2526
"github.com/compose-spec/compose-go/v2/types"
2627
"github.com/containerd/platforms"
@@ -71,7 +72,33 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
7172
if options.Deps {
7273
policy = types.IncludeDependencies
7374
}
74-
err := project.ForEachService(options.Services, func(serviceName string, service *types.ServiceConfig) error {
75+
76+
serviceDeps := false
77+
project, err := project.WithServicesTransform(func(serviceName string, service types.ServiceConfig) (types.ServiceConfig, error) {
78+
if service.Build != nil {
79+
for _, c := range service.Build.AdditionalContexts {
80+
if t, found := strings.CutPrefix(c, types.ServicePrefix); found {
81+
serviceDeps = true
82+
if service.DependsOn == nil {
83+
service.DependsOn = map[string]types.ServiceDependency{}
84+
}
85+
service.DependsOn[t] = types.ServiceDependency{
86+
Condition: "build", // non-canonical, but will force dependency graph ordering
87+
}
88+
}
89+
}
90+
}
91+
return service, nil
92+
})
93+
if err != nil {
94+
return imageIDs, err
95+
}
96+
97+
if serviceDeps {
98+
logrus.Infof(`additional_context with "service:"" is better supported when delegating build go bake. Set COMPOSE_BAKE=true`)
99+
}
100+
101+
err = project.ForEachService(options.Services, func(serviceName string, service *types.ServiceConfig) error {
75102
if service.Build == nil {
76103
return nil
77104
}
@@ -536,6 +563,11 @@ func getImageBuildLabels(project *types.Project, service types.ServiceConfig) ty
536563
func toBuildContexts(additionalContexts types.Mapping) map[string]build.NamedContext {
537564
namedContexts := map[string]build.NamedContext{}
538565
for name, contextPath := range additionalContexts {
566+
if _, found := strings.CutPrefix(contextPath, types.ServicePrefix); found {
567+
// image we depend on has been build previously, as we run in dependency order.
568+
// this assumes use of docker engine builder, so that build can access local images
569+
continue
570+
}
539571
namedContexts[name] = build.NamedContext{Path: contextPath}
540572
}
541573
return namedContexts

pkg/compose/build_bake.go

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,17 @@ type bakeTarget struct {
105105
Tags []string `json:"tags,omitempty"`
106106
CacheFrom []string `json:"cache-from,omitempty"`
107107
CacheTo []string `json:"cache-to,omitempty"`
108+
Target string `json:"target,omitempty"`
108109
Secrets []string `json:"secret,omitempty"`
109110
SSH []string `json:"ssh,omitempty"`
110111
Platforms []string `json:"platforms,omitempty"`
111-
Target string `json:"target,omitempty"`
112112
Pull bool `json:"pull,omitempty"`
113113
NoCache bool `json:"no-cache,omitempty"`
114+
NetworkMode string `json:"network,omitempty"`
115+
NoCacheFilter []string `json:"no-cache-filter,omitempty"`
114116
ShmSize types.UnitBytes `json:"shm-size,omitempty"`
115117
Ulimits []string `json:"ulimits,omitempty"`
118+
Call string `json:"call,omitempty"`
116119
Entitlements []string `json:"entitlements,omitempty"`
117120
Outputs []string `json:"output,omitempty"`
118121
}
@@ -124,11 +127,6 @@ type buildStatus struct {
124127
}
125128

126129
func (s *composeService) doBuildBake(ctx context.Context, project *types.Project, serviceToBeBuild types.Services, options api.BuildOptions) (map[string]string, error) { //nolint:gocyclo
127-
cw := progress.ContextWriter(ctx)
128-
for name := range serviceToBeBuild {
129-
cw.Event(progress.BuildingEvent(name))
130-
}
131-
132130
eg := errgroup.Group{}
133131
ch := make(chan *client.SolveStatus)
134132
display, err := progressui.NewDisplay(os.Stdout, progressui.DisplayMode(options.Progress))
@@ -191,7 +189,7 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
191189

192190
cfg.Targets[serviceName] = bakeTarget{
193191
Context: build.Context,
194-
Contexts: additionalContexts(build.AdditionalContexts, service.DependsOn, options.Compatibility),
192+
Contexts: additionalContexts(build.AdditionalContexts),
195193
Dockerfile: dockerFilePath(build.Context, build.Dockerfile),
196194
DockerfileInline: build.DockerfileInline,
197195
Args: args,
@@ -221,7 +219,7 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
221219
return nil, err
222220
}
223221

224-
logrus.Debugf("bake config:\n%s", string(b))
222+
logrus.Debugf("bake build config:\n%s", string(b))
225223

226224
metadata, err := os.CreateTemp(os.TempDir(), "compose")
227225
if err != nil {
@@ -320,6 +318,7 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
320318
return nil, err
321319
}
322320

321+
cw := progress.ContextWriter(ctx)
323322
results := map[string]string{}
324323
for name, m := range md {
325324
results[name] = m.Digest
@@ -328,14 +327,12 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
328327
return results, nil
329328
}
330329

331-
func additionalContexts(contexts types.Mapping, dependencies types.DependsOnConfig, compatibility bool) map[string]string {
330+
func additionalContexts(contexts types.Mapping) map[string]string {
332331
ac := map[string]string{}
333-
if compatibility {
334-
for name := range dependencies {
335-
ac[name] = "target:" + name
336-
}
337-
}
338332
for k, v := range contexts {
333+
if target, found := strings.CutPrefix(v, types.ServicePrefix); found {
334+
v = "target:" + target
335+
}
339336
ac[k] = v
340337
}
341338
return ac

pkg/e2e/build_test.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,18 +271,34 @@ func TestBuildImageDependencies(t *testing.T) {
271271
t.Run("ClassicBuilder", func(t *testing.T) {
272272
cli := NewCLI(t, WithEnv(
273273
"DOCKER_BUILDKIT=0",
274-
"COMPOSE_FILE=./fixtures/build-dependencies/compose.yaml",
274+
"COMPOSE_FILE=./fixtures/build-dependencies/classic.yaml",
275+
))
276+
doTest(t, cli)
277+
})
278+
279+
t.Run("BuildKit by dependency order", func(t *testing.T) {
280+
cli := NewCLI(t, WithEnv(
281+
"DOCKER_BUILDKIT=1",
282+
"COMPOSE_FILE=./fixtures/build-dependencies/classic.yaml",
275283
))
276284
doTest(t, cli)
277285
})
278286

279-
t.Run("BuildKit", func(t *testing.T) {
287+
t.Run("BuildKit by additional contexts", func(t *testing.T) {
280288
cli := NewCLI(t, WithEnv(
281289
"DOCKER_BUILDKIT=1",
282290
"COMPOSE_FILE=./fixtures/build-dependencies/compose.yaml",
283291
))
284292
doTest(t, cli)
285293
})
294+
295+
t.Run("Bake by additional contexts", func(t *testing.T) {
296+
cli := NewCLI(t, WithEnv(
297+
"DOCKER_BUILDKIT=1", "COMPOSE_BAKE=1",
298+
"COMPOSE_FILE=./fixtures/build-dependencies/compose.yaml",
299+
))
300+
doTest(t, cli)
301+
})
286302
}
287303

288304
func TestBuildPlatformsWithCorrectBuildxConfig(t *testing.T) {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
services:
2+
base:
3+
image: base
4+
init: true
5+
build:
6+
context: .
7+
dockerfile: base.dockerfile
8+
service:
9+
init: true
10+
depends_on:
11+
- base
12+
build:
13+
context: .
14+
dockerfile: service.dockerfile

pkg/e2e/fixtures/build-dependencies/compose.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ services:
77
dockerfile: base.dockerfile
88
service:
99
init: true
10-
depends_on:
11-
- base
1210
build:
1311
context: .
12+
additional_contexts:
13+
base: "service:base"
1414
dockerfile: service.dockerfile

0 commit comments

Comments
 (0)