mydev/internal/checks/docker.go
Victor Abrell 7140397a13 Initial commit: MyDev dev-environment TUI
CLI + live dashboard wrapping aws/docker/git/awsmfa for local dev:
AWS MFA auth status + expiry, dev compose stack control, container
drift vs the dev repo, git repo status, prod-data and DB-access tools.
Config-driven (~/.config/mydev/config.yaml). Dashboard runs commands
via a command palette with captured/interactive modes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 14:31:58 +02:00

58 lines
1.4 KiB
Go

package checks
import (
"context"
"encoding/json"
"os/exec"
"strings"
"time"
)
// Container is one docker container's summary state.
type Container struct {
Name string
Image string
State string // running, exited, ...
Status string // human string, e.g. "Up 3 hours"
}
// Containers runs `docker ps -a` and parses the line-delimited JSON output.
// Returns ([], "") when docker works but no containers exist.
func Containers(ctx context.Context) ([]Container, string) {
ctx, cancel := context.WithTimeout(ctx, 8*time.Second)
defer cancel()
// docker emits one JSON object per line with --format json.
out, err := exec.CommandContext(ctx, "docker", "ps", "-a", "--format", "json").Output()
if err != nil {
msg := err.Error()
if ee, ok := err.(*exec.ExitError); ok && len(ee.Stderr) > 0 {
msg = strings.TrimSpace(string(ee.Stderr))
}
return nil, msg
}
var list []Container
for _, line := range strings.Split(strings.TrimSpace(string(out)), "\n") {
if line == "" {
continue
}
var row struct {
Names string `json:"Names"`
Image string `json:"Image"`
State string `json:"State"`
Status string `json:"Status"`
}
if err := json.Unmarshal([]byte(line), &row); err != nil {
continue
}
list = append(list, Container{
Name: row.Names,
Image: row.Image,
State: row.State,
Status: row.Status,
})
}
return list, ""
}