From 1253020b3dae52071751beae9b75e5b90d9cad80 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Wed, 30 Jun 2021 07:41:21 +0200 Subject: [PATCH] Add metadata-file flag Signed-off-by: CrazyMax --- commands/bake.go | 23 +++++++++++++++++++++-- commands/build.go | 33 ++++++++++++++++++++++++++------- docs/reference/buildx_bake.md | 1 + docs/reference/buildx_build.md | 1 + 4 files changed, 49 insertions(+), 9 deletions(-) diff --git a/commands/bake.go b/commands/bake.go index 0d37b100..e98fef12 100644 --- a/commands/bake.go +++ b/commands/bake.go @@ -10,6 +10,7 @@ import ( "github.com/docker/buildx/build" "github.com/docker/buildx/util/progress" "github.com/docker/cli/cli/command" + "github.com/docker/docker/pkg/ioutils" "github.com/moby/buildkit/util/appcontext" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -90,7 +91,7 @@ func runBake(dockerCli command.Cli, targets []string, in bakeOptions) (err error } if in.printOnly { - dt, err := json.MarshalIndent(map[string]map[string]*bake.Target{"target": m}, "", " ") + dt, err := json.MarshalIndent(map[string]map[string]*bake.Target{"target": m}, "", " ") if err != nil { return err } @@ -108,7 +109,25 @@ func runBake(dockerCli command.Cli, targets []string, in bakeOptions) (err error return err } - _, err = build.Build(ctx, dis, bo, dockerAPI(dockerCli), dockerCli.ConfigFile(), printer) + resp, err := build.Build(ctx, dis, bo, dockerAPI(dockerCli), dockerCli.ConfigFile(), printer) + if err != nil { + return err + } + + if len(in.metadataFile) > 0 && resp != nil { + mdata := map[string]map[string]string{} + for k, r := range resp { + mdata[k] = r.ExporterResponse + } + mdatab, err := json.MarshalIndent(mdata, "", " ") + if err != nil { + return err + } + if err := ioutils.AtomicWriteFile(in.metadataFile, mdatab, 0644); err != nil { + return err + } + } + return err } diff --git a/commands/build.go b/commands/build.go index 324c4e3d..39581bbe 100644 --- a/commands/build.go +++ b/commands/build.go @@ -2,6 +2,7 @@ package commands import ( "context" + "encoding/json" "os" "path/filepath" "strings" @@ -12,6 +13,7 @@ import ( "github.com/docker/buildx/util/progress" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" + "github.com/docker/docker/pkg/ioutils" "github.com/moby/buildkit/client" "github.com/moby/buildkit/session/auth/authprovider" "github.com/moby/buildkit/util/appcontext" @@ -21,6 +23,8 @@ import ( "github.com/spf13/pflag" ) +const defaultTargetName = "default" + type buildOptions struct { commonOptions contextPath string @@ -64,10 +68,11 @@ type buildOptions struct { } type commonOptions struct { - builder string - noCache *bool - progress string - pull *bool + builder string + noCache *bool + progress string + pull *bool + metadataFile string // golangci-lint#826 // nolint:structcheck exportPush bool @@ -200,10 +205,10 @@ func runBuild(dockerCli command.Cli, in buildOptions) error { contextPathHash = in.contextPath } - return buildTargets(ctx, dockerCli, map[string]build.Options{"default": opts}, in.progress, contextPathHash, in.builder) + return buildTargets(ctx, dockerCli, map[string]build.Options{defaultTargetName: opts}, in.progress, contextPathHash, in.builder, in.metadataFile) } -func buildTargets(ctx context.Context, dockerCli command.Cli, opts map[string]build.Options, progressMode, contextPathHash, instance string) error { +func buildTargets(ctx context.Context, dockerCli command.Cli, opts map[string]build.Options, progressMode, contextPathHash, instance string, metadataFile string) error { dis, err := getInstanceOrDefault(ctx, dockerCli, instance, contextPathHash) if err != nil { return err @@ -213,11 +218,24 @@ func buildTargets(ctx context.Context, dockerCli command.Cli, opts map[string]bu defer cancel() printer := progress.NewPrinter(ctx2, os.Stderr, progressMode) - _, err = build.Build(ctx, dis, opts, dockerAPI(dockerCli), dockerCli.ConfigFile(), printer) + resp, err := build.Build(ctx, dis, opts, dockerAPI(dockerCli), dockerCli.ConfigFile(), printer) err1 := printer.Wait() if err == nil { err = err1 } + if err != nil { + return err + } + + if len(metadataFile) > 0 && resp != nil { + mdatab, err := json.MarshalIndent(resp[defaultTargetName].ExporterResponse, "", " ") + if err != nil { + return err + } + if err := ioutils.AtomicWriteFile(metadataFile, mdatab, 0644); err != nil { + return err + } + } return err } @@ -333,6 +351,7 @@ func commonBuildFlags(options *commonOptions, flags *pflag.FlagSet) { flags.StringVar(&options.progress, "progress", defaultProgress, "Set type of progress output (auto, plain, tty). Use plain to show container output") options.pull = flags.Bool("pull", false, "Always attempt to pull a newer version of the image") + flags.StringVar(&options.metadataFile, "metadata-file", "", "Write build result metadata to the file") } func listToMap(values []string, defaultEnv bool) map[string]string { diff --git a/docs/reference/buildx_bake.md b/docs/reference/buildx_bake.md index 55821153..7a86812e 100644 --- a/docs/reference/buildx_bake.md +++ b/docs/reference/buildx_bake.md @@ -18,6 +18,7 @@ Build from a file | `--builder string` | Override the configured builder instance | | [`-f`](#file), [`--file stringArray`](#file) | Build definition file | | `--load` | Shorthand for --set=*.output=type=docker | +| `--metadata-file string` | Write build result metadata to the file | | [`--no-cache`](#no-cache) | Do not use cache when building the image | | [`--print`](#print) | Print the options without building | | [`--progress string`](#progress) | Set type of progress output (auto, plain, tty). Use plain to show container output | diff --git a/docs/reference/buildx_build.md b/docs/reference/buildx_build.md index d7711085..0bc1bab6 100644 --- a/docs/reference/buildx_build.md +++ b/docs/reference/buildx_build.md @@ -25,6 +25,7 @@ Start a build | `--iidfile string` | Write the image ID to the file | | `--label stringArray` | Set metadata for an image | | [`--load`](#load) | Shorthand for --output=type=docker | +| `--metadata-file string` | Write build result metadata to the file | | `--network string` | Set the networking mode for the RUN instructions during build | | `--no-cache` | Do not use cache when building the image | | [`-o`](#output), [`--output stringArray`](#output) | Output destination (format: type=local,dest=path) |