small fix, don't worry about it

This commit is contained in:
Tomas Dvorak
2026-04-10 12:02:36 +02:00
parent 08bd0c6e5c
commit 08cb5754f3
638 changed files with 57332 additions and 34706 deletions
+364
View File
@@ -0,0 +1,364 @@
package docker
import (
"context"
"fmt"
"io"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/system"
"github.com/docker/docker/api/types/volume"
"github.com/docker/docker/client"
)
// Client wraps the Docker client with additional functionality
type Client struct {
cli *client.Client
}
// NewClient creates a new Docker client
func NewClient() (*Client, error) {
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
return nil, fmt.Errorf("failed to create Docker client: %w", err)
}
// Test connection
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
_, err = cli.Ping(ctx)
if err != nil {
return nil, fmt.Errorf("failed to connect to Docker daemon: %w", err)
}
return &Client{cli: cli}, nil
}
// ListContainers returns all containers
func (c *Client) ListContainers(ctx context.Context, all bool) ([]types.Container, error) {
return c.cli.ContainerList(ctx, container.ListOptions{
All: all,
})
}
// GetContainer returns detailed information about a specific container
func (c *Client) GetContainer(ctx context.Context, containerID string) (types.ContainerJSON, error) {
return c.cli.ContainerInspect(ctx, containerID)
}
// CreateContainer creates a new container
func (c *Client) CreateContainer(ctx context.Context, config ContainerConfig) (string, error) {
containerConfig := &container.Config{
Image: config.Image,
Cmd: config.Cmd,
Env: config.Env,
Labels: config.Labels,
ExposedPorts: config.ExposedPorts,
}
hostConfig := &container.HostConfig{
RestartPolicy: container.RestartPolicy{
Name: container.RestartPolicyMode(config.RestartPolicy),
},
PortBindings: config.PortBindings,
Mounts: config.Mounts,
Resources: container.Resources{
Memory: config.Memory,
NanoCPUs: config.NanoCPUs,
},
NetworkMode: container.NetworkMode(config.NetworkMode),
}
networkingConfig := &network.NetworkingConfig{
EndpointsConfig: config.Networks,
}
resp, err := c.cli.ContainerCreate(
ctx,
containerConfig,
hostConfig,
networkingConfig,
nil,
config.Name,
)
if err != nil {
return "", fmt.Errorf("failed to create container: %w", err)
}
return resp.ID, nil
}
// StartContainer starts a container
func (c *Client) StartContainer(ctx context.Context, containerID string) error {
return c.cli.ContainerStart(ctx, containerID, container.StartOptions{})
}
// StopContainer stops a container
func (c *Client) StopContainer(ctx context.Context, containerID string, timeout *time.Duration) error {
var timeoutInt *int
if timeout != nil {
t := int(timeout.Seconds())
timeoutInt = &t
}
return c.cli.ContainerStop(ctx, containerID, container.StopOptions{
Timeout: timeoutInt,
})
}
// RestartContainer restarts a container
func (c *Client) RestartContainer(ctx context.Context, containerID string, timeout *time.Duration) error {
var timeoutInt *int
if timeout != nil {
t := int(timeout.Seconds())
timeoutInt = &t
}
return c.cli.ContainerRestart(ctx, containerID, container.StopOptions{
Timeout: timeoutInt,
})
}
// RemoveContainer removes a container
func (c *Client) RemoveContainer(ctx context.Context, containerID string, force bool) error {
return c.cli.ContainerRemove(ctx, containerID, container.RemoveOptions{
Force: force,
})
}
// GetContainerLogs returns logs for a container
func (c *Client) GetContainerLogs(ctx context.Context, containerID string, options LogOptions) (io.ReadCloser, error) {
return c.cli.ContainerLogs(ctx, containerID, container.LogsOptions{
ShowStdout: options.Stdout,
ShowStderr: options.Stderr,
Follow: options.Follow,
Tail: options.Tail,
Timestamps: options.Timestamps,
})
}
// GetContainerStats returns real-time resource usage statistics for a container
func (c *Client) GetContainerStats(ctx context.Context, containerID string, stream bool) (*container.StatsResponseReader, error) {
resp, err := c.cli.ContainerStats(ctx, containerID, stream)
if err != nil {
return nil, err
}
return &resp, nil
}
// ListImages returns all images
func (c *Client) ListImages(ctx context.Context, all bool) ([]image.Summary, error) {
return c.cli.ImageList(ctx, image.ListOptions{
All: all,
})
}
// PullImage pulls an image from a registry
func (c *Client) PullImage(ctx context.Context, ref string, auth registry.AuthConfig) (io.ReadCloser, error) {
authStr, _ := registry.EncodeAuthConfig(auth)
return c.cli.ImagePull(ctx, ref, image.PullOptions{
RegistryAuth: authStr,
})
}
// BuildImage builds an image from a Dockerfile
func (c *Client) BuildImage(ctx context.Context, buildContext io.Reader, options BuildOptions) (types.ImageBuildResponse, error) {
return c.cli.ImageBuild(ctx, buildContext, types.ImageBuildOptions{
Dockerfile: options.Dockerfile,
Tags: options.Tags,
BuildArgs: options.BuildArgs,
Labels: options.Labels,
Remove: options.Remove,
})
}
// RemoveImage removes an image
func (c *Client) RemoveImage(ctx context.Context, imageID string, force bool) ([]image.DeleteResponse, error) {
return c.cli.ImageRemove(ctx, imageID, image.RemoveOptions{
Force: force,
})
}
// TagImage tags an image
func (c *Client) TagImage(ctx context.Context, imageID, ref string) error {
return c.cli.ImageTag(ctx, imageID, ref)
}
// ListNetworks returns all networks
func (c *Client) ListNetworks(ctx context.Context) ([]network.Summary, error) {
return c.cli.NetworkList(ctx, network.ListOptions{})
}
// CreateNetwork creates a new network
func (c *Client) CreateNetwork(ctx context.Context, config NetworkConfig) (string, error) {
resp, err := c.cli.NetworkCreate(ctx, config.Name, network.CreateOptions{
Driver: config.Driver,
Internal: config.Internal,
Labels: config.Labels,
})
if err != nil {
return "", err
}
return resp.ID, nil
}
// RemoveNetwork removes a network
func (c *Client) RemoveNetwork(ctx context.Context, networkID string) error {
return c.cli.NetworkRemove(ctx, networkID)
}
// ConnectNetwork connects a container to a network
func (c *Client) ConnectNetwork(ctx context.Context, networkID, containerID string, config network.EndpointSettings) error {
return c.cli.NetworkConnect(ctx, networkID, containerID, &config)
}
// DisconnectNetwork disconnects a container from a network
func (c *Client) DisconnectNetwork(ctx context.Context, networkID, containerID string, force bool) error {
return c.cli.NetworkDisconnect(ctx, networkID, containerID, force)
}
// ListVolumes returns all volumes
func (c *Client) ListVolumes(ctx context.Context) (volume.ListResponse, error) {
return c.cli.VolumeList(ctx, volume.ListOptions{})
}
// CreateVolume creates a new volume
func (c *Client) CreateVolume(ctx context.Context, config VolumeConfig) (volume.Volume, error) {
return c.cli.VolumeCreate(ctx, volume.CreateOptions{
Name: config.Name,
Driver: config.Driver,
Labels: config.Labels,
DriverOpts: config.DriverOpts,
})
}
// RemoveVolume removes a volume
func (c *Client) RemoveVolume(ctx context.Context, volumeID string, force bool) error {
return c.cli.VolumeRemove(ctx, volumeID, force)
}
// GetSystemInfo returns system-wide information
func (c *Client) GetSystemInfo(ctx context.Context) (system.Info, error) {
return c.cli.Info(ctx)
}
// GetDiskUsage returns Docker disk usage information
func (c *Client) GetDiskUsage(ctx context.Context) (types.DiskUsage, error) {
return c.cli.DiskUsage(ctx, types.DiskUsageOptions{})
}
// GetEvents returns Docker events
func (c *Client) GetEvents(ctx context.Context, options EventOptions) (io.ReadCloser, error) {
resp, errChan := c.cli.Events(ctx, events.ListOptions{
Since: options.Since,
Until: options.Until,
Filters: options.Filters,
})
// Convert the channel to a reader
r, w := io.Pipe()
go func() {
defer w.Close()
for {
select {
case event, ok := <-resp:
if !ok {
return
}
// Write event data to pipe
w.Write([]byte(fmt.Sprintf("%v\n", event)))
case err := <-errChan:
if err != nil {
w.CloseWithError(err)
return
}
case <-ctx.Done():
return
}
}
}()
return r, nil
}
// ExecCreate creates an exec instance in a container
func (c *Client) ExecCreate(ctx context.Context, containerID string, config ExecConfig) (types.IDResponse, error) {
return c.cli.ContainerExecCreate(ctx, containerID, container.ExecOptions{
Cmd: config.Cmd,
Env: config.Env,
WorkingDir: config.WorkingDir,
User: config.User,
AttachStdin: config.AttachStdin,
AttachStdout: config.AttachStdout,
AttachStderr: config.AttachStderr,
Tty: config.Tty,
})
}
// ExecStart starts an exec instance
func (c *Client) ExecStart(ctx context.Context, execID string, config ExecStartConfig) error {
return c.cli.ContainerExecStart(ctx, execID, container.ExecStartOptions{
Detach: config.Detach,
Tty: config.Tty,
})
}
// ExecInspect returns information about an exec instance
func (c *Client) ExecInspect(ctx context.Context, execID string) (container.ExecInspect, error) {
return c.cli.ContainerExecInspect(ctx, execID)
}
// GetImageInfo returns information about a Docker image
func (c *Client) GetImageInfo(ctx context.Context, imageName string) (*ImageInfo, error) {
images, err := c.cli.ImageList(ctx, image.ListOptions{})
if err != nil {
return nil, err
}
for _, img := range images {
for _, tag := range img.RepoTags {
if tag == imageName || tag == imageName+":latest" {
return &ImageInfo{
ID: img.ID,
RepoTags: img.RepoTags,
Size: img.Size,
Created: img.Created,
Labels: img.Labels,
RepoDigests: img.RepoDigests,
Digest: getDigestFromRepoTags(img.RepoDigests),
}, nil
}
}
}
return nil, fmt.Errorf("image not found: %s", imageName)
}
// PushImage pushes an image to a registry
func (c *Client) PushImage(ctx context.Context, imageName, registryURL string) error {
auth := registry.AuthConfig{}
authStr, _ := registry.EncodeAuthConfig(auth)
_, err := c.cli.ImagePush(ctx, imageName, image.PushOptions{
RegistryAuth: authStr,
})
return err
}
// Close closes the Docker client connection
func (c *Client) Close() error {
return c.cli.Close()
}
// Helper function to extract digest from repo digests
func getDigestFromRepoTags(digests []string) string {
if len(digests) > 0 {
return digests[0]
}
return ""
}
+282
View File
@@ -0,0 +1,282 @@
package docker
import (
"time"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/mount"
"github.com/docker/docker/api/types/network"
"github.com/docker/go-connections/nat"
)
// ContainerConfig represents the configuration for creating a container
type ContainerConfig struct {
Name string
Image string
Cmd []string
Env []string
Labels map[string]string
RestartPolicy string
ExposedPorts nat.PortSet
PortBindings nat.PortMap
Mounts []mount.Mount
Memory int64
NanoCPUs int64
NetworkMode string
Networks map[string]*network.EndpointSettings
}
// LogOptions represents options for retrieving container logs
type LogOptions struct {
Stdout bool
Stderr bool
Follow bool
Tail string
Timestamps bool
}
// BuildOptions represents options for building an image
type BuildOptions struct {
Dockerfile string
Tags []string
BuildArgs map[string]*string
Labels map[string]string
Remove bool
}
// NetworkConfig represents the configuration for creating a network
type NetworkConfig struct {
Name string
CheckDuplicate bool
Driver string
Internal bool
Labels map[string]string
}
// VolumeConfig represents the configuration for creating a volume
type VolumeConfig struct {
Name string
Driver string
Labels map[string]string
DriverOpts map[string]string
}
// EventOptions represents options for filtering Docker events
type EventOptions struct {
Since string
Until string
Filters filters.Args
}
// ExecConfig represents the configuration for creating an exec instance
type ExecConfig struct {
Cmd []string
Env []string
WorkingDir string
User string
AttachStdin bool
AttachStdout bool
AttachStderr bool
Tty bool
}
// ExecStartConfig represents the configuration for starting an exec instance
type ExecStartConfig struct {
Detach bool
Tty bool
}
// ServiceConfig represents a service configuration for deployment
type ServiceConfig struct {
Name string `json:"name"`
Image string `json:"image"`
Command []string `json:"command,omitempty"`
Environment map[string]string `json:"environment,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
RestartPolicy string `json:"restart_policy"`
PortMappings []PortMapping `json:"port_mappings,omitempty"`
VolumeMounts []VolumeMount `json:"volume_mounts,omitempty"`
Networks []string `json:"networks,omitempty"`
Resources ResourceLimits `json:"resources,omitempty"`
HealthCheck *HealthCheck `json:"health_check,omitempty"`
}
// PortMapping represents a port mapping configuration
type PortMapping struct {
ContainerPort int32 `json:"container_port"`
HostPort int32 `json:"host_port,omitempty"`
Protocol string `json:"protocol"` // tcp or udp
HostIP string `json:"host_ip,omitempty"`
}
// VolumeMount represents a volume mount configuration
type VolumeMount struct {
Type string `json:"type"` // bind, volume, tmpfs
Source string `json:"source"`
Destination string `json:"destination"`
ReadOnly bool `json:"read_only,omitempty"`
Consistency string `json:"consistency,omitempty"`
}
// ResourceLimits represents resource limits for a container
type ResourceLimits struct {
MemoryBytes int64 `json:"memory_bytes,omitempty"`
CPUQuota int64 `json:"cpu_quota,omitempty"`
CPUPeriod int64 `json:"cpu_period,omitempty"`
CPUShares int64 `json:"cpu_shares,omitempty"`
}
// HealthCheck represents a health check configuration
type HealthCheck struct {
Test []string `json:"test"`
Interval time.Duration `json:"interval"`
Timeout time.Duration `json:"timeout"`
Retries int `json:"retries"`
StartPeriod time.Duration `json:"start_period"`
}
// ServiceStatus represents the status of a service
type ServiceStatus struct {
ID string `json:"id"`
Name string `json:"name"`
Image string `json:"image"`
Status string `json:"status"`
CreatedAt time.Time `json:"created_at"`
StartedAt *time.Time `json:"started_at,omitempty"`
Ports []PortInfo `json:"ports,omitempty"`
Networks []NetworkInfo `json:"networks,omitempty"`
Mounts []MountInfo `json:"mounts,omitempty"`
Resources ResourceUsage `json:"resources"`
Health *HealthStatus `json:"health,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
}
// PortInfo represents port information for a running container
type PortInfo struct {
ContainerPort int32 `json:"container_port"`
HostPort int32 `json:"host_port,omitempty"`
HostIP string `json:"host_ip"`
Protocol string `json:"protocol"`
}
// NetworkInfo represents network information for a container
type NetworkInfo struct {
Name string `json:"name"`
NetworkID string `json:"network_id"`
IPAddress string `json:"ip_address"`
Gateway string `json:"gateway,omitempty"`
MACAddress string `json:"mac_address,omitempty"`
}
// MountInfo represents mount information for a container
type MountInfo struct {
Type string `json:"type"`
Source string `json:"source"`
Destination string `json:"destination"`
ReadOnly bool `json:"read_only"`
}
// ResourceUsage represents resource usage for a container
type ResourceUsage struct {
CPUPercent float64 `json:"cpu_percent"`
MemoryUsage int64 `json:"memory_usage"`
MemoryLimit int64 `json:"memory_limit"`
NetworkRx int64 `json:"network_rx"`
NetworkTx int64 `json:"network_tx"`
BlockRead int64 `json:"block_read"`
BlockWrite int64 `json:"block_write"`
PidsCurrent uint64 `json:"pids_current"`
PidsLimit uint64 `json:"pids_limit"`
}
// HealthStatus represents the health status of a container
type HealthStatus struct {
Status string `json:"status"`
FailingStreak int `json:"failing_streak"`
LastCheck time.Time `json:"last_check"`
}
// RegistryConfig represents Docker registry configuration
type RegistryConfig struct {
URL string `json:"url"`
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
Auth string `json:"auth,omitempty"`
Email string `json:"email,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
}
// ImageInfo represents information about a Docker image
type ImageInfo struct {
ID string `json:"id"`
RepoTags []string `json:"repo_tags"`
Size int64 `json:"size"`
Created int64 `json:"created"`
Labels map[string]string `json:"labels"`
RepoDigests []string `json:"repo_digests"`
Digest string `json:"digest"`
}
// BuildContext represents a build context for Docker images
type BuildContext struct {
Dockerfile string `json:"dockerfile"`
Context string `json:"context"`
Tags []string `json:"tags"`
BuildArgs map[string]string `json:"build_args,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
Target string `json:"target,omitempty"`
NoCache bool `json:"no_cache,omitempty"`
Remove bool `json:"remove,omitempty"`
ForceRm bool `json:"force_rm,omitempty"`
Pull bool `json:"pull,omitempty"`
}
// DeploymentConfig represents a deployment configuration
type DeploymentConfig struct {
Service ServiceConfig `json:"service"`
Replicas int `json:"replicas"`
Update UpdateConfig `json:"update,omitempty"`
Rollback RollbackConfig `json:"rollback,omitempty"`
Networks []NetworkConfig `json:"networks,omitempty"`
Volumes []VolumeConfig `json:"volumes,omitempty"`
Secrets []SecretConfig `json:"secrets,omitempty"`
Configs []ConfigFile `json:"configs,omitempty"`
}
// UpdateConfig represents update configuration for deployments
type UpdateConfig struct {
Parallelism uint `json:"parallelism"`
Delay time.Duration `json:"delay"`
FailureAction string `json:"failure_action"`
Monitor time.Duration `json:"monitor"`
MaxFailureRatio float64 `json:"max_failure_ratio"`
Order string `json:"order"`
}
// RollbackConfig represents rollback configuration
type RollbackConfig struct {
Parallelism uint `json:"parallelism"`
Delay time.Duration `json:"delay"`
FailureAction string `json:"failure_action"`
Monitor time.Duration `json:"monitor"`
MaxFailureRatio float64 `json:"max_failure_ratio"`
Order string `json:"order"`
}
// SecretConfig represents a secret configuration
type SecretConfig struct {
Name string `json:"name"`
Data string `json:"data"`
Labels map[string]string `json:"labels,omitempty"`
Driver string `json:"driver,omitempty"`
Template string `json:"template,omitempty"`
}
// ConfigFile represents a configuration file
type ConfigFile struct {
Name string `json:"name"`
File string `json:"file"`
Content string `json:"content"`
Labels map[string]string `json:"labels,omitempty"`
Template string `json:"template,omitempty"`
}