Files
resticontainer/pkg/dockerclient/client.go
T
deytenit 10982e9c94 fix: propagate Docker hook failures
Disclosure: I'm an AI assistant helping Vladimir Eremin; I'm not Vladimir Eremin.
2026-10-11 15:54:33 +03:00

79 lines
2.3 KiB
Go

package dockerclient
import (
"context"
"fmt"
"io"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
)
type DockerClient interface {
ListContainers(ctx context.Context) ([]types.Container, error)
InspectContainer(ctx context.Context, id string) (types.ContainerJSON, error)
ExecCommand(ctx context.Context, containerID string, cmd []string) error
StopContainer(ctx context.Context, id string) error
StartContainer(ctx context.Context, id string) error
}
type DefaultClient struct {
cli *client.Client
}
func NewClient() (*DefaultClient, error) {
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
return nil, err
}
return &DefaultClient{cli: cli}, nil
}
func (c *DefaultClient) ListContainers(ctx context.Context) ([]types.Container, error) {
return c.cli.ContainerList(ctx, container.ListOptions{})
}
func (c *DefaultClient) InspectContainer(ctx context.Context, id string) (types.ContainerJSON, error) {
return c.cli.ContainerInspect(ctx, id)
}
func (c *DefaultClient) ExecCommand(ctx context.Context, containerID string, cmd []string) error {
execOpts := container.ExecOptions{
Cmd: cmd,
AttachStdout: true,
AttachStderr: true,
}
resp, err := c.cli.ContainerExecCreate(ctx, containerID, execOpts)
if err != nil {
return err
}
attach, err := c.cli.ContainerExecAttach(ctx, resp.ID, container.ExecStartOptions{})
if err != nil {
return err
}
defer attach.Close()
if _, err := io.Copy(io.Discard, attach.Reader); err != nil {
return fmt.Errorf("read exec output: %w", err)
}
inspect, err := c.cli.ContainerExecInspect(ctx, resp.ID)
if err != nil {
return fmt.Errorf("inspect exec: %w", err)
}
if inspect.Running {
return fmt.Errorf("exec %s is still running after its output stream closed", resp.ID)
}
if inspect.ExitCode != 0 {
return fmt.Errorf("exec %s failed with exit code %d", resp.ID, inspect.ExitCode)
}
return nil
}
func (c *DefaultClient) StopContainer(ctx context.Context, id string) error {
return c.cli.ContainerStop(ctx, id, container.StopOptions{})
}
func (c *DefaultClient) StartContainer(ctx context.Context, id string) error {
return c.cli.ContainerStart(ctx, id, container.StartOptions{})
}