github.com/pdmccormick/importable-docker-buildx@v0.0.0-20240426161518-e47091289030/commands/debug/root.go (about) 1 package debug 2 3 import ( 4 "context" 5 "os" 6 "runtime" 7 8 "github.com/containerd/console" 9 "github.com/docker/buildx/controller" 10 "github.com/docker/buildx/controller/control" 11 controllerapi "github.com/docker/buildx/controller/pb" 12 "github.com/docker/buildx/monitor" 13 "github.com/docker/buildx/util/cobrautil" 14 "github.com/docker/buildx/util/progress" 15 "github.com/docker/cli/cli/command" 16 "github.com/moby/buildkit/util/progress/progressui" 17 "github.com/pkg/errors" 18 "github.com/sirupsen/logrus" 19 "github.com/spf13/cobra" 20 ) 21 22 // DebugConfig is a user-specified configuration for the debugger. 23 type DebugConfig struct { 24 // InvokeFlag is a flag to configure the launched debugger and the commaned executed on the debugger. 25 InvokeFlag string 26 27 // OnFlag is a flag to configure the timing of launching the debugger. 28 OnFlag string 29 } 30 31 // DebuggableCmd is a command that supports debugger with recognizing the user-specified DebugConfig. 32 type DebuggableCmd interface { 33 // NewDebugger returns the new *cobra.Command with support for the debugger with recognizing DebugConfig. 34 NewDebugger(*DebugConfig) *cobra.Command 35 } 36 37 func RootCmd(dockerCli command.Cli, children ...DebuggableCmd) *cobra.Command { 38 var controlOptions control.ControlOptions 39 var progressMode string 40 var options DebugConfig 41 42 cmd := &cobra.Command{ 43 Use: "debug", 44 Short: "Start debugger", 45 Args: cobra.NoArgs, 46 RunE: func(cmd *cobra.Command, args []string) error { 47 printer, err := progress.NewPrinter(context.TODO(), os.Stderr, progressui.DisplayMode(progressMode)) 48 if err != nil { 49 return err 50 } 51 52 ctx := context.TODO() 53 c, err := controller.NewController(ctx, controlOptions, dockerCli, printer) 54 if err != nil { 55 return err 56 } 57 defer func() { 58 if err := c.Close(); err != nil { 59 logrus.Warnf("failed to close server connection %v", err) 60 } 61 }() 62 con := console.Current() 63 if err := con.SetRaw(); err != nil { 64 return errors.Errorf("failed to configure terminal: %v", err) 65 } 66 67 _, err = monitor.RunMonitor(ctx, "", nil, controllerapi.InvokeConfig{ 68 Tty: true, 69 }, c, dockerCli.In(), os.Stdout, os.Stderr, printer) 70 con.Reset() 71 return err 72 }, 73 } 74 cobrautil.MarkCommandExperimental(cmd) 75 76 flags := cmd.Flags() 77 flags.StringVar(&options.InvokeFlag, "invoke", "", "Launch a monitor with executing specified command") 78 flags.StringVar(&options.OnFlag, "on", "error", "When to launch the monitor ([always, error])") 79 80 flags.StringVar(&controlOptions.Root, "root", "", "Specify root directory of server to connect for the monitor") 81 flags.BoolVar(&controlOptions.Detach, "detach", runtime.GOOS == "linux", "Detach buildx server for the monitor (supported only on linux)") 82 flags.StringVar(&controlOptions.ServerConfig, "server-config", "", "Specify buildx server config file for the monitor (used only when launching new server)") 83 flags.StringVar(&progressMode, "progress", "auto", `Set type of progress output ("auto", "plain", "tty") for the monitor. Use plain to show container output`) 84 85 cobrautil.MarkFlagsExperimental(flags, "invoke", "on", "root", "detach", "server-config") 86 87 for _, c := range children { 88 cmd.AddCommand(c.NewDebugger(&options)) 89 } 90 91 return cmd 92 }