|
1 | 1 | package dap |
2 | 2 |
|
3 | 3 | import ( |
4 | | - "context" |
5 | 4 | "fmt" |
6 | | - "net" |
7 | | - "os" |
8 | | - "path/filepath" |
9 | 5 |
|
10 | | - "github.com/docker/buildx/build" |
11 | | - "github.com/docker/cli/cli-plugins/metadata" |
12 | 6 | "github.com/google/go-dap" |
13 | 7 | "github.com/google/shlex" |
14 | 8 | "github.com/pkg/errors" |
@@ -86,95 +80,3 @@ func replCmd[Flags any, RetVal any](ctx Context, name string, resp *dap.Evaluate |
86 | 80 | }, |
87 | 81 | }, flags |
88 | 82 | } |
89 | | - |
90 | | -func (t *thread) Exec(ctx Context, args []string) (message string, retErr error) { |
91 | | - if t.rCtx == nil { |
92 | | - return "", errors.New("no container context for exec") |
93 | | - } |
94 | | - |
95 | | - cfg := &build.InvokeConfig{Tty: true} |
96 | | - if len(cfg.Entrypoint) == 0 && len(cfg.Cmd) == 0 { |
97 | | - cfg.Entrypoint = []string{"/bin/sh"} // launch shell by default |
98 | | - cfg.Cmd = []string{} |
99 | | - cfg.NoCmd = false |
100 | | - } |
101 | | - |
102 | | - ctr, err := build.NewContainer(ctx, t.rCtx, cfg) |
103 | | - if err != nil { |
104 | | - return "", err |
105 | | - } |
106 | | - defer func() { |
107 | | - if retErr != nil { |
108 | | - ctr.Cancel() |
109 | | - } |
110 | | - }() |
111 | | - |
112 | | - dir, err := os.MkdirTemp("", "buildx-dap-exec") |
113 | | - if err != nil { |
114 | | - return "", err |
115 | | - } |
116 | | - defer func() { |
117 | | - if retErr != nil { |
118 | | - os.RemoveAll(dir) |
119 | | - } |
120 | | - }() |
121 | | - |
122 | | - socketPath := filepath.Join(dir, "s.sock") |
123 | | - lc := net.ListenConfig{} |
124 | | - l, err := lc.Listen(ctx, "unix", socketPath) |
125 | | - if err != nil { |
126 | | - return "", err |
127 | | - } |
128 | | - |
129 | | - go func() { |
130 | | - defer os.RemoveAll(dir) |
131 | | - t.runExec(l, ctr, cfg) |
132 | | - }() |
133 | | - |
134 | | - // TODO: this should work in standalone mode too. |
135 | | - docker := os.Getenv(metadata.ReexecEnvvar) |
136 | | - req := &dap.RunInTerminalRequest{ |
137 | | - Request: dap.Request{ |
138 | | - Command: "runInTerminal", |
139 | | - }, |
140 | | - Arguments: dap.RunInTerminalRequestArguments{ |
141 | | - Kind: "integrated", |
142 | | - Args: []string{docker, "buildx", "dap", "attach", socketPath}, |
143 | | - Env: map[string]any{ |
144 | | - "BUILDX_EXPERIMENTAL": "1", |
145 | | - }, |
146 | | - }, |
147 | | - } |
148 | | - |
149 | | - resp := ctx.Request(req) |
150 | | - if !resp.GetResponse().Success { |
151 | | - return "", errors.New(resp.GetResponse().Message) |
152 | | - } |
153 | | - |
154 | | - message = fmt.Sprintf("Started process attached to %s.", socketPath) |
155 | | - return message, nil |
156 | | -} |
157 | | - |
158 | | -func (t *thread) runExec(l net.Listener, ctr *build.Container, cfg *build.InvokeConfig) { |
159 | | - defer l.Close() |
160 | | - defer ctr.Cancel() |
161 | | - |
162 | | - conn, err := l.Accept() |
163 | | - if err != nil { |
164 | | - return |
165 | | - } |
166 | | - defer conn.Close() |
167 | | - |
168 | | - // start a background goroutine to politely refuse any subsequent connections. |
169 | | - go func() { |
170 | | - for { |
171 | | - conn, err := l.Accept() |
172 | | - if err != nil { |
173 | | - return |
174 | | - } |
175 | | - fmt.Fprint(conn, "Error: Already connected to exec instance.") |
176 | | - conn.Close() |
177 | | - } |
178 | | - }() |
179 | | - ctr.Exec(context.Background(), cfg, conn, conn, conn) |
180 | | -} |
0 commit comments