MCPcopy Index your code
hub / github.com/coder/coder / List

Method List

agent/agentcontainers/containers_dockercli.go:244–308  ·  view source on GitHub ↗
(ctx context.Context)

Source from the content-addressed store, hash-verified

242}
243
244func (dcli *dockerCLI) List(ctx context.Context) (codersdk.WorkspaceAgentListContainersResponse, error) {
245 var stdoutBuf, stderrBuf bytes.Buffer
246 // List all container IDs, one per line, with no truncation
247 cmd := dcli.execer.CommandContext(ctx, "docker", "ps", "--all", "--quiet", "--no-trunc")
248 cmd.Stdout = &stdoutBuf
249 cmd.Stderr = &stderrBuf
250 if err := cmd.Run(); err != nil {
251 // TODO(Cian): detect specific errors:
252 // - docker not installed
253 // - docker not running
254 // - no permissions to talk to docker
255 return codersdk.WorkspaceAgentListContainersResponse{}, xerrors.Errorf("run docker ps: %w: %q", err, strings.TrimSpace(stderrBuf.String()))
256 }
257
258 ids := make([]string, 0)
259 scanner := bufio.NewScanner(&stdoutBuf)
260 for scanner.Scan() {
261 tmp := strings.TrimSpace(scanner.Text())
262 if tmp == "" {
263 continue
264 }
265 ids = append(ids, tmp)
266 }
267 if err := scanner.Err(); err != nil {
268 return codersdk.WorkspaceAgentListContainersResponse{}, xerrors.Errorf("scan docker ps output: %w", err)
269 }
270
271 res := codersdk.WorkspaceAgentListContainersResponse{
272 Containers: make([]codersdk.WorkspaceAgentContainer, 0, len(ids)),
273 Warnings: make([]string, 0),
274 }
275 dockerPsStderr := strings.TrimSpace(stderrBuf.String())
276 if dockerPsStderr != "" {
277 res.Warnings = append(res.Warnings, dockerPsStderr)
278 }
279 if len(ids) == 0 {
280 return res, nil
281 }
282
283 // now we can get the detailed information for each container
284 // Run `docker inspect` on each container ID.
285 // NOTE: There is an unavoidable potential race condition where a
286 // container is removed between `docker ps` and `docker inspect`.
287 // In this case, stderr will contain an error message but stdout
288 // will still contain valid JSON. We will just end up missing
289 // information about the removed container. We could potentially
290 // log this error, but I'm not sure it's worth it.
291 dockerInspectStdout, dockerInspectStderr, err := runDockerInspect(ctx, dcli.execer, ids...)
292 if err != nil {
293 return codersdk.WorkspaceAgentListContainersResponse{}, xerrors.Errorf("run docker inspect: %w: %s", err, dockerInspectStderr)
294 }
295
296 if len(dockerInspectStderr) > 0 {
297 res.Warnings = append(res.Warnings, string(dockerInspectStderr))
298 }
299
300 outs, warns, err := convertDockerInspect(dockerInspectStdout)
301 if err != nil {

Callers

nothing calls this directly

Calls 9

runDockerInspectFunction · 0.85
convertDockerInspectFunction · 0.85
ErrMethod · 0.80
CommandContextMethod · 0.65
RunMethod · 0.65
ErrorfMethod · 0.45
StringMethod · 0.45
ScanMethod · 0.45
TextMethod · 0.45

Tested by

no test coverage detected