package docker import ( "context" "fmt" "io" "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" ) type Container struct { ID string `json:"id"` Names []string `json:"names"` Image string `json:"image"` State string `json:"state"` Status string `json:"status"` Created int64 `json:"created"` } type HostConnector interface { ListContainers(ctx context.Context) ([]Container, error) Close() error } type LocalConnector struct { cli *client.Client } func NewLocalConnector(dockerHost string) (*LocalConnector, error) { opts := []client.Opt{client.FromEnv, client.WithAPIVersionNegotiation()} if dockerHost != "" { opts = append(opts, client.WithHost(dockerHost)) } cli, err := client.NewClientWithOpts(opts...) if err != nil { return nil, fmt.Errorf("creating docker client: %w", err) } return &LocalConnector{cli: cli}, nil } func (l *LocalConnector) ListContainers(ctx context.Context) ([]Container, error) { list, err := l.cli.ContainerList(ctx, container.ListOptions{All: true}) if err != nil { return nil, fmt.Errorf("listing containers: %w", err) } out := make([]Container, 0, len(list)) for _, c := range list { out = append(out, Container{ ID: c.ID, Names: c.Names, Image: c.Image, State: c.State, Status: c.Status, Created: c.Created, }) } return out, nil } func (l *LocalConnector) Close() error { return l.cli.Close() } var _ io.Closer = (*LocalConnector)(nil)