Skip to content

Commit 4b70ff0

Browse files
ndeloofglours
authored andcommitted
fix support for ssh key from CLI flags
Signed-off-by: Nicolas De Loof <[email protected]>
1 parent 23351ec commit 4b70ff0

File tree

4 files changed

+114
-42
lines changed

4 files changed

+114
-42
lines changed

cmd/compose/build.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,17 @@ 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,
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,
8182
}, nil
8283
}
8384

cmd/compose/create_test.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ func TestRunCreate(t *testing.T) {
4040
)
4141

4242
createOpts := createOptions{}
43-
buildOpts := buildOptions{}
43+
buildOpts := buildOptions{
44+
ProjectOptions: &ProjectOptions{},
45+
}
4446
project := sampleProject()
4547
err := runCreate(ctx, nil, backend, createOpts, buildOpts, project, nil)
4648
require.NoError(t, err)
@@ -58,7 +60,9 @@ func TestRunCreate_Build(t *testing.T) {
5860
createOpts := createOptions{
5961
Build: true,
6062
}
61-
buildOpts := buildOptions{}
63+
buildOpts := buildOptions{
64+
ProjectOptions: &ProjectOptions{},
65+
}
6266
project := sampleProject()
6367
err := runCreate(ctx, nil, backend, createOpts, buildOpts, project, nil)
6468
require.NoError(t, err)

pkg/api/api.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,8 @@ 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
158160
}
159161

160162
// Apply mutates project according to build options

pkg/compose/build_bake.go

Lines changed: 95 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"os"
2727
"os/exec"
2828
"path/filepath"
29+
"slices"
2930
"strconv"
3031
"strings"
3132

@@ -35,6 +36,7 @@ import (
3536
"github.com/docker/cli/cli/command"
3637
"github.com/docker/compose/v2/pkg/api"
3738
"github.com/docker/compose/v2/pkg/progress"
39+
"github.com/docker/docker/api/types/versions"
3840
"github.com/docker/docker/builder/remotecontext/urlutil"
3941
"github.com/moby/buildkit/client"
4042
"github.com/moby/buildkit/util/progress/progressui"
@@ -93,19 +95,25 @@ type bakeGroup struct {
9395
}
9496

9597
type bakeTarget struct {
96-
Context string `json:"context,omitempty"`
97-
Dockerfile string `json:"dockerfile,omitempty"`
98-
Args map[string]string `json:"args,omitempty"`
99-
Labels map[string]string `json:"labels,omitempty"`
100-
Tags []string `json:"tags,omitempty"`
101-
CacheFrom []string `json:"cache-from,omitempty"`
102-
CacheTo []string `json:"cache-to,omitempty"`
103-
Secrets []string `json:"secret,omitempty"`
104-
SSH []string `json:"ssh,omitempty"`
105-
Platforms []string `json:"platforms,omitempty"`
106-
Target string `json:"target,omitempty"`
107-
Pull bool `json:"pull,omitempty"`
108-
NoCache bool `json:"no-cache,omitempty"`
98+
Context string `json:"context,omitempty"`
99+
Contexts map[string]string `json:"contexts,omitempty"`
100+
Dockerfile string `json:"dockerfile,omitempty"`
101+
DockerfileInline string `json:"dockerfile-inline,omitempty"`
102+
Args map[string]string `json:"args,omitempty"`
103+
Labels map[string]string `json:"labels,omitempty"`
104+
Tags []string `json:"tags,omitempty"`
105+
CacheFrom []string `json:"cache-from,omitempty"`
106+
CacheTo []string `json:"cache-to,omitempty"`
107+
Secrets []string `json:"secret,omitempty"`
108+
SSH []string `json:"ssh,omitempty"`
109+
Platforms []string `json:"platforms,omitempty"`
110+
Target string `json:"target,omitempty"`
111+
Pull bool `json:"pull,omitempty"`
112+
NoCache bool `json:"no-cache,omitempty"`
113+
ShmSize types.UnitBytes `json:"shm-size,omitempty"`
114+
Ulimits []string `json:"ulimits,omitempty"`
115+
Entitlements []string `json:"entitlements,omitempty"`
116+
Outputs []string `json:"output,omitempty"`
109117
}
110118

111119
type bakeMetadata map[string]buildStatus
@@ -136,8 +144,9 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
136144
Targets: map[string]bakeTarget{},
137145
}
138146
var group bakeGroup
147+
var privileged bool
139148

140-
for _, service := range serviceToBeBuild {
149+
for serviceName, service := range serviceToBeBuild {
141150
if service.Build == nil {
142151
continue
143152
}
@@ -153,23 +162,43 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
153162

154163
image := api.GetImageNameOrDefault(service, project.Name)
155164

156-
cfg.Targets[image] = bakeTarget{
157-
Context: build.Context,
158-
Dockerfile: dockerFilePath(build.Context, build.Dockerfile),
159-
Args: args,
160-
Labels: build.Labels,
161-
Tags: append(build.Tags, image),
165+
entitlements := build.Entitlements
166+
if slices.Contains(build.Entitlements, "security.insecure") {
167+
privileged = true
168+
}
169+
if build.Privileged {
170+
entitlements = append(entitlements, "security.insecure")
171+
privileged = true
172+
}
173+
174+
outputs := []string{"type=docker"}
175+
if options.Push && service.Image != "" {
176+
outputs = append(outputs, "type=image,push=true")
177+
}
178+
179+
cfg.Targets[serviceName] = bakeTarget{
180+
Context: build.Context,
181+
Contexts: additionalContexts(build.AdditionalContexts, service.DependsOn, options.Compatibility),
182+
Dockerfile: dockerFilePath(build.Context, build.Dockerfile),
183+
DockerfileInline: build.DockerfileInline,
184+
Args: args,
185+
Labels: build.Labels,
186+
Tags: append(build.Tags, image),
162187

163188
CacheFrom: build.CacheFrom,
164189
// CacheTo: TODO
165-
Platforms: build.Platforms,
166-
Target: build.Target,
167-
Secrets: toBakeSecrets(project, build.Secrets),
168-
SSH: toBakeSSH(build.SSH),
169-
Pull: options.Pull,
170-
NoCache: options.NoCache,
190+
Platforms: build.Platforms,
191+
Target: build.Target,
192+
Secrets: toBakeSecrets(project, build.Secrets),
193+
SSH: toBakeSSH(append(build.SSH, options.SSHs...)),
194+
Pull: options.Pull,
195+
NoCache: options.NoCache,
196+
ShmSize: build.ShmSize,
197+
Ulimits: toBakeUlimits(build.Ulimits),
198+
Entitlements: entitlements,
199+
Outputs: outputs,
171200
}
172-
group.Targets = append(group.Targets, image)
201+
group.Targets = append(group.Targets, serviceName)
173202
}
174203

175204
cfg.Groups["default"] = group
@@ -188,7 +217,14 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
188217
if err != nil {
189218
return nil, err
190219
}
191-
cmd := exec.CommandContext(ctx, buildx.Path, "bake", "--file", "-", "--progress", "rawjson", "--metadata-file", metadata.Name())
220+
221+
args := []string{"bake", "--file", "-", "--progress", "rawjson", "--metadata-file", metadata.Name()}
222+
mustAllow := buildx.Version != "" && versions.GreaterThanOrEqualTo(buildx.Version[1:], "0.17.0")
223+
if privileged && mustAllow {
224+
args = append(args, "--allow", "security.insecure")
225+
}
226+
227+
cmd := exec.CommandContext(ctx, buildx.Path, args...)
192228
// Remove DOCKER_CLI_PLUGIN... variable so buildx can detect it run standalone
193229
cmd.Env = filter(os.Environ(), manager.ReexecEnvvar)
194230

@@ -258,6 +294,31 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
258294
return results, nil
259295
}
260296

297+
func additionalContexts(contexts types.Mapping, dependencies types.DependsOnConfig, compatibility bool) map[string]string {
298+
ac := map[string]string{}
299+
if compatibility {
300+
for name := range dependencies {
301+
ac[name] = "target:" + name
302+
}
303+
}
304+
for k, v := range contexts {
305+
ac[k] = v
306+
}
307+
return ac
308+
}
309+
310+
func toBakeUlimits(ulimits map[string]*types.UlimitsConfig) []string {
311+
s := []string{}
312+
for u, l := range ulimits {
313+
if l.Single > 0 {
314+
s = append(s, fmt.Sprintf("%s=%d", u, l.Single))
315+
} else {
316+
s = append(s, fmt.Sprintf("%s=%d:%d", u, l.Soft, l.Hard))
317+
}
318+
}
319+
return s
320+
}
321+
261322
func toBakeSSH(ssh types.SSHConfig) []string {
262323
var s []string
263324
for _, key := range ssh {
@@ -270,11 +331,15 @@ func toBakeSecrets(project *types.Project, secrets []types.ServiceSecretConfig)
270331
var s []string
271332
for _, ref := range secrets {
272333
def := project.Secrets[ref.Source]
334+
target := ref.Target
335+
if target == "" {
336+
target = ref.Source
337+
}
273338
switch {
274339
case def.Environment != "":
275-
s = append(s, fmt.Sprintf("id=%s,type=env,env=%s", ref.Source, def.Environment))
340+
s = append(s, fmt.Sprintf("id=%s,type=env,env=%s", target, def.Environment))
276341
case def.File != "":
277-
s = append(s, fmt.Sprintf("id=%s,type=file,src=%s", ref.Source, def.File))
342+
s = append(s, fmt.Sprintf("id=%s,type=file,src=%s", target, def.File))
278343
}
279344
}
280345
return s

0 commit comments

Comments
 (0)