From 95086cf64163314cff1a56bb25d9c09ed4086df2 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Wed, 27 Apr 2022 17:33:12 +0200 Subject: [PATCH] cli: fix standalone command behavior Signed-off-by: CrazyMax --- cmd/buildx/main.go | 98 +++++++++++++++++++------------------------ cmd/buildx/tracing.go | 19 +++++++++ commands/root.go | 9 ++++ 3 files changed, 70 insertions(+), 56 deletions(-) create mode 100644 cmd/buildx/tracing.go diff --git a/cmd/buildx/main.go b/cmd/buildx/main.go index 78aeb960..28476c8c 100644 --- a/cmd/buildx/main.go +++ b/cmd/buildx/main.go @@ -15,11 +15,6 @@ import ( cliflags "github.com/docker/cli/cli/flags" "github.com/moby/buildkit/solver/errdefs" "github.com/moby/buildkit/util/stack" - "github.com/moby/buildkit/util/tracing/detect" - "go.opentelemetry.io/otel" - - _ "github.com/moby/buildkit/util/tracing/detect/delegated" - _ "github.com/moby/buildkit/util/tracing/env" // FIXME: "k8s.io/client-go/plugin/pkg/client/auth/azure" is excluded because of compilation error _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" @@ -31,73 +26,64 @@ import ( _ "github.com/docker/buildx/driver/kubernetes" ) -var experimental string - func init() { seed.WithTimeAndRand() stack.SetVersionInfo(version.Version, version.Revision) - - detect.ServiceName = "buildx" - // do not log tracing errors to stdio - otel.SetErrorHandler(skipErrors{}) } -func main() { - if plugin.RunningStandalone() { - dockerCli, err := command.NewDockerCli() - if err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } - opts := cliflags.NewClientOptions() - dockerCli.Initialize(opts) - rootCmd := commands.NewRootCmd(os.Args[0], false, dockerCli) - if err := rootCmd.Execute(); err != nil { - os.Exit(1) - } - os.Exit(0) +func runStandalone(cmd *command.DockerCli) error { + if err := cmd.Initialize(cliflags.NewClientOptions()); err != nil { + return err } + rootCmd := commands.NewRootCmd(os.Args[0], false, cmd) + return rootCmd.Execute() +} + +func runPlugin(cmd *command.DockerCli) error { + rootCmd := commands.NewRootCmd("buildx", true, cmd) + return plugin.RunPlugin(cmd, rootCmd, manager.Metadata{ + SchemaVersion: "0.1.0", + Vendor: "Docker Inc.", + Version: version.Version, + }) +} - dockerCli, err := command.NewDockerCli() +func main() { + cmd, err := command.NewDockerCli() if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } - p := commands.NewRootCmd("buildx", true, dockerCli) - meta := manager.Metadata{ - SchemaVersion: "0.1.0", - Vendor: "Docker Inc.", - Version: version.Version, - Experimental: experimental != "", + if plugin.RunningStandalone() { + err = runStandalone(cmd) + } else { + err = runPlugin(cmd) + } + if err == nil { + return } - if err := plugin.RunPlugin(dockerCli, p, meta); err != nil { - if sterr, ok := err.(cli.StatusError); ok { - if sterr.Status != "" { - fmt.Fprintln(dockerCli.Err(), sterr.Status) - } - // StatusError should only be used for errors, and all errors should - // have a non-zero exit status, so never exit with 0 - if sterr.StatusCode == 0 { - os.Exit(1) - } - os.Exit(sterr.StatusCode) + if sterr, ok := err.(cli.StatusError); ok { + if sterr.Status != "" { + fmt.Fprintln(cmd.Err(), sterr.Status) } - for _, s := range errdefs.Sources(err) { - s.Print(dockerCli.Err()) - } - - if debug.IsEnabled() { - fmt.Fprintf(dockerCli.Err(), "error: %+v", stack.Formatter(err)) - } else { - fmt.Fprintf(dockerCli.Err(), "error: %v\n", err) + // StatusError should only be used for errors, and all errors should + // have a non-zero exit status, so never exit with 0 + if sterr.StatusCode == 0 { + os.Exit(1) } - - os.Exit(1) + os.Exit(sterr.StatusCode) } -} -type skipErrors struct{} + for _, s := range errdefs.Sources(err) { + s.Print(cmd.Err()) + } + if debug.IsEnabled() { + fmt.Fprintf(cmd.Err(), "error: %+v", stack.Formatter(err)) + } else { + fmt.Fprintf(cmd.Err(), "error: %v\n", err) + } -func (skipErrors) Handle(err error) {} + os.Exit(1) +} diff --git a/cmd/buildx/tracing.go b/cmd/buildx/tracing.go new file mode 100644 index 00000000..fb7338a0 --- /dev/null +++ b/cmd/buildx/tracing.go @@ -0,0 +1,19 @@ +package main + +import ( + "github.com/moby/buildkit/util/tracing/detect" + "go.opentelemetry.io/otel" + + _ "github.com/moby/buildkit/util/tracing/detect/delegated" + _ "github.com/moby/buildkit/util/tracing/env" +) + +func init() { + detect.ServiceName = "buildx" + // do not log tracing errors to stdio + otel.SetErrorHandler(skipErrors{}) +} + +type skipErrors struct{} + +func (skipErrors) Handle(err error) {} diff --git a/commands/root.go b/commands/root.go index 100e6790..19aaed87 100644 --- a/commands/root.go +++ b/commands/root.go @@ -6,6 +6,7 @@ import ( imagetoolscmd "github.com/docker/buildx/commands/imagetools" "github.com/docker/buildx/util/logutil" "github.com/docker/cli-docs-tool/annotation" + "github.com/docker/cli/cli" "github.com/docker/cli/cli-plugins/plugin" "github.com/docker/cli/cli/command" "github.com/sirupsen/logrus" @@ -26,6 +27,14 @@ func NewRootCmd(name string, isPlugin bool, dockerCli command.Cli) *cobra.Comman cmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error { return plugin.PersistentPreRunE(cmd, args) } + } else { + // match plugin behavior for standalone mode + // https://github.com/docker/cli/blob/6c9eb708fa6d17765d71965f90e1c59cea686ee9/cli-plugins/plugin/plugin.go#L117-L127 + cmd.SilenceUsage = true + cmd.SilenceErrors = true + cmd.TraverseChildren = true + cmd.DisableFlagsInUseLine = true + cli.DisableFlagsInUseLine(cmd) } logrus.SetFormatter(&logutil.Formatter{})