From 208b042129e3503c37af0274a651924e662d7d66 Mon Sep 17 00:00:00 2001 From: Cameron Adams Date: Sat, 12 Aug 2023 17:42:14 +0200 Subject: [PATCH] command(bake): Specify local and remote bake files This adds the ability to source additional local build definition files when sourcing Bake files via a remote url. Prefixing a file with 'cwd://' will source a bake file on the local machine, instead of the remote location. Local files will be read/have precedence before remote files. Usage: ``` docker buildx bake https://github.com/example/upstream.git --file cwd://docker-bake.override.hcl --print ``` This will source a default file from the example/upstream repository, and also source a build definition from the local machine. Also moves remote and local files reading logic to a func Signed-off-by: CrazyMax Signed-off-by: Cameron Adams Co-authored-by: CrazyMax --- commands/bake.go | 50 +++++++++++++++++++++++++++++++++--------- tests/bake.go | 56 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 91 insertions(+), 15 deletions(-) diff --git a/commands/bake.go b/commands/bake.go index f81d64fe88c..9d11b5e79b8 100644 --- a/commands/bake.go +++ b/commands/bake.go @@ -4,7 +4,9 @@ import ( "context" "encoding/json" "fmt" + "io" "os" + "strings" "github.com/containerd/console" "github.com/containerd/containerd/platforms" @@ -98,8 +100,6 @@ func runBake(dockerCli command.Cli, targets []string, in bakeOptions, cFlags com defer cancel() var nodes []builder.Node - var files []bake.File - var inp *bake.Input var progressConsoleDesc, progressTextDesc string // instance only needed for reading remote bake files or building @@ -147,14 +147,7 @@ func runBake(dockerCli command.Cli, targets []string, in bakeOptions, cFlags com } }() - if url != "" { - files, inp, err = bake.ReadRemoteFiles(ctx, nodes, url, in.files, printer) - } else { - progress.Wrap("[internal] load local bake definitions", printer.Write, func(sub progress.SubLogger) error { - files, err = bake.ReadLocalFiles(in.files, dockerCli.In(), sub) - return nil - }) - } + files, inp, err := readBakeFiles(ctx, nodes, url, in.files, dockerCli.In(), printer) if err != nil { return err } @@ -296,3 +289,40 @@ func saveLocalStateGroup(dockerCli command.Cli, ref string, lsg localstate.State } return l.SaveGroup(ref, lsg) } + +func readBakeFiles(ctx context.Context, nodes []builder.Node, url string, names []string, stdin io.Reader, pw progress.Writer) (files []bake.File, inp *bake.Input, err error) { + var lnames []string + var rnames []string + for _, v := range names { + if strings.HasPrefix(v, "cwd://") { + lnames = append(lnames, strings.TrimPrefix(v, "cwd://")) + } else { + rnames = append(rnames, v) + } + } + + if len(lnames) > 0 || url == "" { + progress.Wrap("[internal] load local bake definitions", pw.Write, func(sub progress.SubLogger) error { + if url != "" { + files, err = bake.ReadLocalFiles(lnames, stdin, sub) + } else { + files, err = bake.ReadLocalFiles(append(lnames, rnames...), stdin, sub) + } + return nil + }) + if err != nil { + return nil, nil, err + } + } + + if url != "" { + var rfiles []bake.File + rfiles, inp, err = bake.ReadRemoteFiles(ctx, nodes, url, rnames, pw) + if err != nil { + return nil, nil, err + } + files = append(files, rfiles...) + } + + return +} diff --git a/tests/bake.go b/tests/bake.go index 83a171ea573..35017a36092 100644 --- a/tests/bake.go +++ b/tests/bake.go @@ -23,6 +23,7 @@ var bakeTests = []func(t *testing.T, sb integration.Sandbox){ testBakeLocalMulti, testBakeRemote, testBakeRemoteCmdContext, + testBakeRemoteLocalOverride, testBakeRemoteCmdContextOverride, testBakeRemoteContextSubdir, testBakeRemoteCmdContextEscapeRoot, @@ -82,12 +83,15 @@ services: dirDest := t.TempDir() cmd := buildxCmd(sb, withDir(dir), withArgs("bake", "--progress=plain", "--set", "*.output=type=local,dest="+dirDest)) - out, err := cmd.CombinedOutput() - require.NoError(t, err, out) - require.Contains(t, string(out), `#1 [internal] load local bake definitions`) - require.Contains(t, string(out), `#1 reading compose.yaml`) - require.Contains(t, string(out), `#1 reading docker-bake.hcl`) + dt, err := cmd.CombinedOutput() + require.NoError(t, err, string(dt)) + require.Contains(t, string(dt), `#1 [internal] load local bake definitions`) + require.Contains(t, string(dt), `#1 reading compose.yaml`) + require.Contains(t, string(dt), `#1 reading docker-bake.hcl`) + require.FileExists(t, filepath.Join(dirDest, "foo")) + out, err := bakeCmd(sb, withDir(dir), withArgs("--file", "cwd://docker-bake.hcl", "--set", "*.output=type=local,dest="+dirDest)) + require.NoError(t, err, out) require.FileExists(t, filepath.Join(dirDest, "foo")) } @@ -121,6 +125,48 @@ EOT require.FileExists(t, filepath.Join(dirDest, "foo")) } +func testBakeRemoteLocalOverride(t *testing.T, sb integration.Sandbox) { + remoteBakefile := []byte(` +target "default" { + dockerfile-inline = <