Files
Docker-Manager/backend/internal/docker/connector.go
T

84 lines
2.5 KiB
Go

// Package docker define la abstracción HostConnector: la interfaz que el
// resto del backend usa para hablar con "un host Docker", sin importarle si
// es el socket local (LocalConnector, fase 1) o un agente remoto
// (AgentConnector, cuando se añada un segundo host más adelante).
package docker
import (
"context"
"fmt"
"io"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
)
// Container es la representación simplificada que expone la API HTTP,
// desacoplada del tipo interno del SDK de Docker.
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"`
}
// HostConnector es el contrato que debe cumplir cualquier forma de hablar con
// un host Docker (local o remoto vía agente).
type HostConnector interface {
ListContainers(ctx context.Context) ([]Container, error)
Close() error
}
// LocalConnector implementa HostConnector hablando directamente con el
// socket Docker del host donde corre el backend.
type LocalConnector struct {
cli *client.Client
}
// NewLocalConnector crea un conector contra el Docker Engine local.
// Si dockerHost está vacío, usa la configuración por defecto del SDK
// (respeta la variable de entorno DOCKER_HOST si está definida).
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
}
// ListContainers devuelve todos los contenedores del host, incluidos los
// detenidos (equivalente a `docker ps -a`).
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
}
// Close libera los recursos del cliente Docker subyacente.
func (l *LocalConnector) Close() error {
return l.cli.Close()
}
var _ io.Closer = (*LocalConnector)(nil)