From a8d359a9caedbd2998ca5ce1be42c7a2f66e4d6f Mon Sep 17 00:00:00 2001 From: "Jonathan A. Sternberg" Date: Thu, 19 Mar 2026 14:09:39 -0500 Subject: [PATCH] dap: make dap generally available Removes the experimental flags and bits for dap and deletes some dead code that somehow made its way this far without anyone noticing. Signed-off-by: Jonathan A. Sternberg --- commands/dap.go | 2 - commands/root.go | 2 +- dap/debug_shell.go | 3 -- dap/eval.go | 98 ------------------------------------ docs/reference/buildx.md | 38 +++++++------- docs/reference/buildx_dap.md | 2 +- tests/dap_build.go | 4 -- 7 files changed, 21 insertions(+), 128 deletions(-) diff --git a/commands/dap.go b/commands/dap.go index 6114870b1633..b6bbbcfe17ac 100644 --- a/commands/dap.go +++ b/commands/dap.go @@ -8,7 +8,6 @@ import ( "github.com/containerd/console" "github.com/docker/buildx/dap" "github.com/docker/buildx/dap/common" - "github.com/docker/buildx/util/cobrautil" "github.com/docker/buildx/util/ioset" "github.com/docker/buildx/util/progress" "github.com/docker/cli/cli" @@ -29,7 +28,6 @@ func dapCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { DisableFlagsInUseLine: true, } - cobrautil.MarkCommandExperimental(cmd) dapBuildCmd := buildCmd(dockerCli, rootOpts, &options) dapBuildCmd.Args = cobra.RangeArgs(0, 1) diff --git a/commands/root.go b/commands/root.go index ee658bbcbf74..9082d5aa1107 100644 --- a/commands/root.go +++ b/commands/root.go @@ -127,10 +127,10 @@ func addCommands(cmd *cobra.Command, opts *rootOptions, dockerCli command.Cli) { duCmd(dockerCli, opts), imagetoolscmd.RootCmd(cmd, dockerCli, imagetoolscmd.RootOptions{Builder: &opts.builder}), historycmd.RootCmd(cmd, dockerCli, historycmd.RootOptions{Builder: &opts.builder}), + dapCmd(dockerCli, opts), ) if confutil.IsExperimental() { cmd.AddCommand(debugCmd(dockerCli, opts)) - cmd.AddCommand(dapCmd(dockerCli, opts)) } cmd.RegisterFlagCompletionFunc( //nolint:errcheck diff --git a/dap/debug_shell.go b/dap/debug_shell.go index 2bfe84635da7..9679b1a18963 100644 --- a/dap/debug_shell.go +++ b/dap/debug_shell.go @@ -251,9 +251,6 @@ func (s *shell) SendRunInTerminalRequest(ctx Context) error { Arguments: dap.RunInTerminalRequestArguments{ Kind: "integrated", Args: args, - Env: map[string]any{ - "BUILDX_EXPERIMENTAL": "1", - }, }, } diff --git a/dap/eval.go b/dap/eval.go index 10d13b3bd13c..b95eb73f9b31 100644 --- a/dap/eval.go +++ b/dap/eval.go @@ -1,14 +1,8 @@ package dap import ( - "context" "fmt" - "net" - "os" - "path/filepath" - "github.com/docker/buildx/build" - "github.com/docker/cli/cli-plugins/metadata" "github.com/google/go-dap" "github.com/google/shlex" "github.com/pkg/errors" @@ -86,95 +80,3 @@ func replCmd[Flags any, RetVal any](ctx Context, name string, resp *dap.Evaluate }, }, flags } - -func (t *thread) Exec(ctx Context, args []string) (message string, retErr error) { - if t.rCtx == nil { - return "", errors.New("no container context for exec") - } - - cfg := &build.InvokeConfig{Tty: true} - if len(cfg.Entrypoint) == 0 && len(cfg.Cmd) == 0 { - cfg.Entrypoint = []string{"/bin/sh"} // launch shell by default - cfg.Cmd = []string{} - cfg.NoCmd = false - } - - ctr, err := build.NewContainer(ctx, t.rCtx, cfg) - if err != nil { - return "", err - } - defer func() { - if retErr != nil { - ctr.Cancel() - } - }() - - dir, err := os.MkdirTemp("", "buildx-dap-exec") - if err != nil { - return "", err - } - defer func() { - if retErr != nil { - os.RemoveAll(dir) - } - }() - - socketPath := filepath.Join(dir, "s.sock") - lc := net.ListenConfig{} - l, err := lc.Listen(ctx, "unix", socketPath) - if err != nil { - return "", err - } - - go func() { - defer os.RemoveAll(dir) - t.runExec(l, ctr, cfg) - }() - - // TODO: this should work in standalone mode too. - docker := os.Getenv(metadata.ReexecEnvvar) - req := &dap.RunInTerminalRequest{ - Request: dap.Request{ - Command: "runInTerminal", - }, - Arguments: dap.RunInTerminalRequestArguments{ - Kind: "integrated", - Args: []string{docker, "buildx", "dap", "attach", socketPath}, - Env: map[string]any{ - "BUILDX_EXPERIMENTAL": "1", - }, - }, - } - - resp := ctx.Request(req) - if !resp.GetResponse().Success { - return "", errors.New(resp.GetResponse().Message) - } - - message = fmt.Sprintf("Started process attached to %s.", socketPath) - return message, nil -} - -func (t *thread) runExec(l net.Listener, ctr *build.Container, cfg *build.InvokeConfig) { - defer l.Close() - defer ctr.Cancel() - - conn, err := l.Accept() - if err != nil { - return - } - defer conn.Close() - - // start a background goroutine to politely refuse any subsequent connections. - go func() { - for { - conn, err := l.Accept() - if err != nil { - return - } - fmt.Fprint(conn, "Error: Already connected to exec instance.") - conn.Close() - } - }() - ctr.Exec(context.Background(), cfg, conn, conn, conn) -} diff --git a/docs/reference/buildx.md b/docs/reference/buildx.md index a4f02ee30dd6..0541572d0589 100644 --- a/docs/reference/buildx.md +++ b/docs/reference/buildx.md @@ -9,25 +9,25 @@ Extended build capabilities with BuildKit ### Subcommands -| Name | Description | -|:-------------------------------------|:----------------------------------------------------------------| -| [`bake`](buildx_bake.md) | Build from a file | -| [`build`](buildx_build.md) | Start a build | -| [`create`](buildx_create.md) | Create a new builder instance | -| [`dap`](buildx_dap.md) | Start debug adapter protocol compatible debugger (EXPERIMENTAL) | -| [`debug`](buildx_debug.md) | Start debugger (EXPERIMENTAL) | -| [`dial-stdio`](buildx_dial-stdio.md) | Proxy current stdio streams to builder instance | -| [`du`](buildx_du.md) | Disk usage | -| [`history`](buildx_history.md) | Commands to work on build records | -| [`imagetools`](buildx_imagetools.md) | Commands to work on images in registry | -| [`inspect`](buildx_inspect.md) | Inspect current builder instance | -| [`ls`](buildx_ls.md) | List builder instances | -| [`policy`](buildx_policy.md) | Commands for working with build policies | -| [`prune`](buildx_prune.md) | Remove build cache | -| [`rm`](buildx_rm.md) | Remove one or more builder instances | -| [`stop`](buildx_stop.md) | Stop builder instance | -| [`use`](buildx_use.md) | Set the current builder instance | -| [`version`](buildx_version.md) | Show buildx version information | +| Name | Description | +|:-------------------------------------|:-------------------------------------------------| +| [`bake`](buildx_bake.md) | Build from a file | +| [`build`](buildx_build.md) | Start a build | +| [`create`](buildx_create.md) | Create a new builder instance | +| [`dap`](buildx_dap.md) | Start debug adapter protocol compatible debugger | +| [`debug`](buildx_debug.md) | Start debugger (EXPERIMENTAL) | +| [`dial-stdio`](buildx_dial-stdio.md) | Proxy current stdio streams to builder instance | +| [`du`](buildx_du.md) | Disk usage | +| [`history`](buildx_history.md) | Commands to work on build records | +| [`imagetools`](buildx_imagetools.md) | Commands to work on images in registry | +| [`inspect`](buildx_inspect.md) | Inspect current builder instance | +| [`ls`](buildx_ls.md) | List builder instances | +| [`policy`](buildx_policy.md) | Commands for working with build policies | +| [`prune`](buildx_prune.md) | Remove build cache | +| [`rm`](buildx_rm.md) | Remove one or more builder instances | +| [`stop`](buildx_stop.md) | Stop builder instance | +| [`use`](buildx_use.md) | Set the current builder instance | +| [`version`](buildx_version.md) | Show buildx version information | ### Options diff --git a/docs/reference/buildx_dap.md b/docs/reference/buildx_dap.md index 3eebe3a4f1bb..09f0e2b20383 100644 --- a/docs/reference/buildx_dap.md +++ b/docs/reference/buildx_dap.md @@ -1,7 +1,7 @@ # docker buildx dap -Start debug adapter protocol compatible debugger (EXPERIMENTAL) +Start debug adapter protocol compatible debugger ### Subcommands diff --git a/tests/dap_build.go b/tests/dap_build.go index 5e132e2a6866..8075c7699346 100644 --- a/tests/dap_build.go +++ b/tests/dap_build.go @@ -25,10 +25,6 @@ import ( ) func dapBuildCmd(t *testing.T, sb integration.Sandbox, opts ...cmdOpt) (*daptest.Client, func(interrupt bool) error, error) { - if !isExperimental() { - t.Skip("only testing when experimental is enabled") - } - opts = append([]cmdOpt{withArgs("dap", "build")}, opts...) cmd := buildxCmd(sb, opts...)