From b2ec1d331cb0865adb96714a12c954a60bfc5486 Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Mon, 27 Apr 2020 14:37:17 -0700 Subject: [PATCH] Add builder as a global flag. This allows all subcommands to use this flag. Additionally reads the default value for the flag from the `BUILDX_BUILDER` env var. Precedence is: CLI ARG > flag > env var > config file Signed-off-by: Brian Goff --- commands/bake.go | 2 +- commands/build.go | 7 +++---- commands/builder.go | 11 ----------- commands/diskusage.go | 6 +++--- commands/inspect.go | 15 ++++++++++----- commands/prune.go | 5 +++-- commands/rm.go | 15 ++++++++++----- commands/root.go | 30 ++++++++++++++++++++++-------- commands/stop.go | 15 ++++++++++----- commands/use.go | 27 ++++++++++++++++----------- 10 files changed, 78 insertions(+), 55 deletions(-) delete mode 100644 commands/builder.go diff --git a/commands/bake.go b/commands/bake.go index f1408d96..e60735c0 100644 --- a/commands/bake.go +++ b/commands/bake.go @@ -99,7 +99,7 @@ func defaultFiles() ([]string, error) { return out, nil } -func bakeCmd(dockerCli command.Cli) *cobra.Command { +func bakeCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { var options bakeOptions cmd := &cobra.Command{ diff --git a/commands/build.go b/commands/build.go index 26eb81cd..ff9eb47d 100644 --- a/commands/build.go +++ b/commands/build.go @@ -63,13 +63,12 @@ type buildOptions struct { } type commonOptions struct { - builderOptions + builder string noCache *bool progress string pull *bool exportPush bool exportLoad bool - builder string } func runBuild(dockerCli command.Cli, in buildOptions) error { @@ -210,7 +209,7 @@ func buildTargets(ctx context.Context, dockerCli command.Cli, opts map[string]bu return err } -func buildCmd(dockerCli command.Cli) *cobra.Command { +func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { var options buildOptions cmd := &cobra.Command{ @@ -220,6 +219,7 @@ func buildCmd(dockerCli command.Cli) *cobra.Command { Args: cli.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { options.contextPath = args[0] + options.builder = rootOpts.builder return runBuild(dockerCli, options) }, } @@ -305,7 +305,6 @@ func buildCmd(dockerCli command.Cli) *cobra.Command { } func commonBuildFlags(options *commonOptions, flags *pflag.FlagSet) { - builderFlags(&options.builderOptions, flags) flags.Var(flagutil.Tristate(options.noCache), "no-cache", "Do not use cache when building the image") flags.StringVar(&options.progress, "progress", "auto", "Set type of progress output (auto, plain, tty). Use plain to show container output") flags.Var(flagutil.Tristate(options.pull), "pull", "Always attempt to pull a newer version of the image") diff --git a/commands/builder.go b/commands/builder.go deleted file mode 100644 index 22a4b29b..00000000 --- a/commands/builder.go +++ /dev/null @@ -1,11 +0,0 @@ -package commands - -import "github.com/spf13/pflag" - -type builderOptions struct { - builder string -} - -func builderFlags(options *builderOptions, flags *pflag.FlagSet) { - flags.StringVar(&options.builder, "builder", "", "Override the configured builder instance") -} diff --git a/commands/diskusage.go b/commands/diskusage.go index 7fe5a02b..79a3e2b5 100644 --- a/commands/diskusage.go +++ b/commands/diskusage.go @@ -18,7 +18,7 @@ import ( ) type duOptions struct { - builderOptions + builder string filter opts.FilterOpt verbose bool } @@ -98,7 +98,7 @@ func runDiskUsage(dockerCli command.Cli, opts duOptions) error { return nil } -func duCmd(dockerCli command.Cli) *cobra.Command { +func duCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { options := duOptions{filter: opts.NewFilterOpt()} cmd := &cobra.Command{ @@ -106,13 +106,13 @@ func duCmd(dockerCli command.Cli) *cobra.Command { Short: "Disk usage", Args: cli.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { + options.builder = rootOpts.builder return runDiskUsage(dockerCli, options) }, Annotations: map[string]string{"version": "1.00"}, } flags := cmd.Flags() - builderFlags(&options.builderOptions, flags) flags.Var(&options.filter, "filter", "Provide filter values") flags.BoolVar(&options.verbose, "verbose", false, "Provide a more verbose output") diff --git a/commands/inspect.go b/commands/inspect.go index ccf53961..ce25970e 100644 --- a/commands/inspect.go +++ b/commands/inspect.go @@ -23,6 +23,7 @@ import ( type inspectOptions struct { bootstrap bool + builder string } type dinfo struct { @@ -38,7 +39,7 @@ type nginfo struct { err error } -func runInspect(dockerCli command.Cli, in inspectOptions, args []string) error { +func runInspect(dockerCli command.Cli, in inspectOptions) error { ctx := appcontext.Context() txn, release, err := getStore(dockerCli) @@ -49,8 +50,8 @@ func runInspect(dockerCli command.Cli, in inspectOptions, args []string) error { var ng *store.NodeGroup - if len(args) > 0 { - ng, err = getNodeGroup(txn, dockerCli, args[0]) + if in.builder != "" { + ng, err = getNodeGroup(txn, dockerCli, in.builder) if err != nil { return err } @@ -127,7 +128,7 @@ func runInspect(dockerCli command.Cli, in inspectOptions, args []string) error { return nil } -func inspectCmd(dockerCli command.Cli) *cobra.Command { +func inspectCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { var options inspectOptions cmd := &cobra.Command{ @@ -135,7 +136,11 @@ func inspectCmd(dockerCli command.Cli) *cobra.Command { Short: "Inspect current builder instance", Args: cli.RequiresMaxArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - return runInspect(dockerCli, options, args) + options.builder = rootOpts.builder + if len(args) > 0 { + options.builder = args[0] + } + return runInspect(dockerCli, options) }, } diff --git a/commands/prune.go b/commands/prune.go index 6ce54c88..2c2138ab 100644 --- a/commands/prune.go +++ b/commands/prune.go @@ -21,7 +21,7 @@ import ( ) type pruneOptions struct { - builderOptions + builder string all bool filter opts.FilterOpt keepStorage opts.MemBytes @@ -124,7 +124,7 @@ func runPrune(dockerCli command.Cli, opts pruneOptions) error { return nil } -func pruneCmd(dockerCli command.Cli) *cobra.Command { +func pruneCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { options := pruneOptions{filter: opts.NewFilterOpt()} cmd := &cobra.Command{ @@ -132,6 +132,7 @@ func pruneCmd(dockerCli command.Cli) *cobra.Command { Short: "Remove build cache ", Args: cli.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { + options.builder = rootOpts.builder return runPrune(dockerCli, options) }, Annotations: map[string]string{"version": "1.00"}, diff --git a/commands/rm.go b/commands/rm.go index 1687e49f..f5916373 100644 --- a/commands/rm.go +++ b/commands/rm.go @@ -11,9 +11,10 @@ import ( ) type rmOptions struct { + builder string } -func runRm(dockerCli command.Cli, in rmOptions, args []string) error { +func runRm(dockerCli command.Cli, in rmOptions) error { ctx := appcontext.Context() txn, release, err := getStore(dockerCli) @@ -22,8 +23,8 @@ func runRm(dockerCli command.Cli, in rmOptions, args []string) error { } defer release() - if len(args) > 0 { - ng, err := getNodeGroup(txn, dockerCli, args[0]) + if in.builder != "" { + ng, err := getNodeGroup(txn, dockerCli, in.builder) if err != nil { return err } @@ -49,7 +50,7 @@ func runRm(dockerCli command.Cli, in rmOptions, args []string) error { return nil } -func rmCmd(dockerCli command.Cli) *cobra.Command { +func rmCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { var options rmOptions cmd := &cobra.Command{ @@ -57,7 +58,11 @@ func rmCmd(dockerCli command.Cli) *cobra.Command { Short: "Remove a builder instance", Args: cli.RequiresMaxArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - return runRm(dockerCli, options, args) + options.builder = rootOpts.builder + if len(args) > 0 { + options.builder = args[0] + } + return runRm(dockerCli, options) }, } diff --git a/commands/root.go b/commands/root.go index 0f141e0e..761d4b7b 100644 --- a/commands/root.go +++ b/commands/root.go @@ -1,10 +1,13 @@ package commands import ( + "os" + imagetoolscmd "github.com/docker/buildx/commands/imagetools" "github.com/docker/cli/cli-plugins/plugin" "github.com/docker/cli/cli/command" "github.com/spf13/cobra" + "github.com/spf13/pflag" ) func NewRootCmd(name string, isPlugin bool, dockerCli command.Cli) *cobra.Command { @@ -22,21 +25,32 @@ func NewRootCmd(name string, isPlugin bool, dockerCli command.Cli) *cobra.Comman return cmd } +type rootOptions struct { + builder string +} + func addCommands(cmd *cobra.Command, dockerCli command.Cli) { + opts := &rootOptions{} + rootFlags(opts, cmd.PersistentFlags()) + cmd.AddCommand( - buildCmd(dockerCli), - bakeCmd(dockerCli), + buildCmd(dockerCli, opts), + bakeCmd(dockerCli, opts), createCmd(dockerCli), - rmCmd(dockerCli), + rmCmd(dockerCli, opts), lsCmd(dockerCli), - useCmd(dockerCli), - inspectCmd(dockerCli), - stopCmd(dockerCli), + useCmd(dockerCli, opts), + inspectCmd(dockerCli, opts), + stopCmd(dockerCli, opts), installCmd(dockerCli), uninstallCmd(dockerCli), versionCmd(dockerCli), - pruneCmd(dockerCli), - duCmd(dockerCli), + pruneCmd(dockerCli, opts), + duCmd(dockerCli, opts), imagetoolscmd.RootCmd(dockerCli), ) } + +func rootFlags(options *rootOptions, flags *pflag.FlagSet) { + flags.StringVar(&options.builder, "builder", os.Getenv("BUILDX_BUILDER"), "Override the configured builder instance") +} diff --git a/commands/stop.go b/commands/stop.go index f3dc73f9..71268696 100644 --- a/commands/stop.go +++ b/commands/stop.go @@ -8,9 +8,10 @@ import ( ) type stopOptions struct { + builder string } -func runStop(dockerCli command.Cli, in stopOptions, args []string) error { +func runStop(dockerCli command.Cli, in stopOptions) error { ctx := appcontext.Context() txn, release, err := getStore(dockerCli) @@ -19,8 +20,8 @@ func runStop(dockerCli command.Cli, in stopOptions, args []string) error { } defer release() - if len(args) > 0 { - ng, err := getNodeGroup(txn, dockerCli, args[0]) + if in.builder != "" { + ng, err := getNodeGroup(txn, dockerCli, in.builder) if err != nil { return err } @@ -41,7 +42,7 @@ func runStop(dockerCli command.Cli, in stopOptions, args []string) error { return stopCurrent(ctx, dockerCli, false) } -func stopCmd(dockerCli command.Cli) *cobra.Command { +func stopCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { var options stopOptions cmd := &cobra.Command{ @@ -49,7 +50,11 @@ func stopCmd(dockerCli command.Cli) *cobra.Command { Short: "Stop builder instance", Args: cli.RequiresMaxArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - return runStop(dockerCli, options, args) + options.builder = rootOpts.builder + if len(args) > 0 { + options.builder = args[0] + } + return runStop(dockerCli, options) }, } diff --git a/commands/use.go b/commands/use.go index ea4c09e1..530d7552 100644 --- a/commands/use.go +++ b/commands/use.go @@ -12,21 +12,22 @@ import ( type useOptions struct { isGlobal bool isDefault bool + builder string } -func runUse(dockerCli command.Cli, in useOptions, name string) error { +func runUse(dockerCli command.Cli, in useOptions) error { txn, release, err := getStore(dockerCli) if err != nil { return err } defer release() - if _, err := txn.NodeGroupByName(name); err != nil { + if _, err := txn.NodeGroupByName(in.builder); err != nil { if os.IsNotExist(errors.Cause(err)) { - if name == "default" && name != dockerCli.CurrentContext() { + if in.builder == "default" && in.builder != dockerCli.CurrentContext() { return errors.Errorf("run `docker context use default` to switch to default context") } - if name == "default" || name == dockerCli.CurrentContext() { + if in.builder == "default" || in.builder == dockerCli.CurrentContext() { ep, err := getCurrentEndpoint(dockerCli) if err != nil { return err @@ -41,35 +42,39 @@ func runUse(dockerCli command.Cli, in useOptions, name string) error { return err } for _, l := range list { - if l.Name == name { - return errors.Errorf("run `docker context use %s` to switch to context %s", name, name) + if l.Name == in.builder { + return errors.Errorf("run `docker context use %s` to switch to context %s", in.builder, in.builder) } } } - return errors.Wrapf(err, "failed to find instance %q", name) + return errors.Wrapf(err, "failed to find instance %q", in.builder) } ep, err := getCurrentEndpoint(dockerCli) if err != nil { return err } - if err := txn.SetCurrent(ep, name, in.isGlobal, in.isDefault); err != nil { + if err := txn.SetCurrent(ep, in.builder, in.isGlobal, in.isDefault); err != nil { return err } return nil } -func useCmd(dockerCli command.Cli) *cobra.Command { +func useCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { var options useOptions cmd := &cobra.Command{ Use: "use [OPTIONS] NAME", Short: "Set the current builder instance", - Args: cli.ExactArgs(1), + Args: cli.RequiresMaxArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - return runUse(dockerCli, options, args[0]) + options.builder = rootOpts.builder + if len(args) > 0 { + options.builder = args[0] + } + return runUse(dockerCli, options) }, }