diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index f69d993..40e061f 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -11,12 +11,12 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v6 - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v6 with: - go-version: 1.23.10 + go-version: '1.25.0' - name: Build run: go build -v ./... diff --git a/cmd/envite/docker.go b/cmd/envite/docker.go index 552c66e..ca6a77e 100644 --- a/cmd/envite/docker.go +++ b/cmd/envite/docker.go @@ -7,7 +7,7 @@ package main import ( "encoding/json" "fmt" - "github.com/docker/docker/client" + "github.com/moby/moby/client" "github.com/perimeterx/envite" "github.com/perimeterx/envite/docker" ) diff --git a/docker/component.go b/docker/component.go index 9f1fff6..d326bd2 100644 --- a/docker/component.go +++ b/docker/component.go @@ -15,14 +15,11 @@ import ( "sync/atomic" "time" - "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/filters" - "github.com/docker/docker/api/types/image" - "github.com/docker/docker/client" - "github.com/docker/docker/errdefs" - "github.com/docker/docker/pkg/jsonmessage" - "github.com/docker/docker/pkg/stdcopy" + cerrdefs "github.com/containerd/errdefs" + "github.com/moby/moby/api/pkg/stdcopy" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/client" + "github.com/moby/moby/api/types/jsonstream" "github.com/perimeterx/envite" ) @@ -64,6 +61,15 @@ func newComponent( containerName := fmt.Sprintf("%s_%s", envID, config.Name) network.configure(config, runConf, containerName) + // The container.Config.MacAddress field was removed from the Docker API. + // A MAC address is now set per network endpoint, so apply the configured + // value to the endpoints created by network.configure. + if runConf.macAddress != nil && runConf.networkingConfig != nil { + for _, endpoint := range runConf.networkingConfig.EndpointsConfig { + endpoint.MacAddress = runConf.macAddress + } + } + c := &Component{ cli: cli, runtimeInfo: runtimeInfo, @@ -121,7 +127,11 @@ func (c *Component) Prepare(ctx context.Context) error { // create a dedicated copy of the docker image to prevent // other environments running concurrently from removing our image. - return c.cli.ImageTag(ctx, c.config.Image, c.imageCloneTag) + _, err = c.cli.ImageTag(ctx, client.ImageTagOptions{ + Source: c.config.Image, + Target: c.imageCloneTag, + }) + return err } // pullImage pulls the Docker image specified in the configuration. @@ -144,7 +154,7 @@ func (c *Component) pullImage(ctx context.Context) error { scanner := bufio.NewScanner(reader) for scanner.Scan() { bytes := scanner.Bytes() - msg := jsonmessage.JSONMessage{} + msg := jsonstream.Message{} err = json.Unmarshal(bytes, &msg) if err != nil { return fmt.Errorf("failed to parse image pull output: %w", err) @@ -191,17 +201,16 @@ func (c *Component) startContainer(ctx context.Context) (string, error) { defer c.lock.Unlock() var id string - res, err := c.cli.ContainerCreate( - ctx, - c.runConfig.containerConfig, - c.runConfig.hostConfig, - c.runConfig.networkingConfig, - c.runConfig.platformConfig, - c.containerName, - ) + res, err := c.cli.ContainerCreate(ctx, client.ContainerCreateOptions{ + Config: c.runConfig.containerConfig, + HostConfig: c.runConfig.hostConfig, + NetworkingConfig: c.runConfig.networkingConfig, + Platform: c.runConfig.platformConfig, + Name: c.containerName, + }) if err == nil { id = res.ID - } else if !errdefs.IsConflict(err) { + } else if !cerrdefs.IsConflict(err) { return "", fmt.Errorf("failed to create container: %w", err) } else { cont, err := c.findContainer(ctx) @@ -212,7 +221,7 @@ func (c *Component) startContainer(ctx context.Context) (string, error) { id = cont.ID } - err = c.cli.ContainerStart(context.Background(), id, container.StartOptions{}) + _, err = c.cli.ContainerStart(context.Background(), id, client.ContainerStartOptions{}) if err != nil { return "", fmt.Errorf("failed to start container: %w", err) } @@ -234,13 +243,13 @@ func (c *Component) Stop(ctx context.Context) error { return nil } - err = c.cli.ContainerStop(ctx, cont.ID, container.StopOptions{}) + _, err = c.cli.ContainerStop(ctx, cont.ID, client.ContainerStopOptions{}) if err != nil { return err } - err = c.cli.ContainerRemove(ctx, cont.ID, container.RemoveOptions{Force: true}) - if err != nil && !errdefs.IsNotFound(err) && !errdefs.IsConflict(err) { + _, err = c.cli.ContainerRemove(ctx, cont.ID, client.ContainerRemoveOptions{Force: true}) + if err != nil && !cerrdefs.IsNotFound(err) && !cerrdefs.IsConflict(err) { return err } @@ -261,7 +270,7 @@ func (c *Component) Cleanup(ctx context.Context) error { } func (c *Component) removeImage(ctx context.Context) error { - _, err := c.cli.ImageRemove(ctx, c.imageCloneTag, image.RemoveOptions{}) + _, err := c.cli.ImageRemove(ctx, c.imageCloneTag, client.ImageRemoveOptions{}) if err != nil && !strings.Contains(err.Error(), "reference does not exist") && !strings.Contains(err.Error(), "No such image") { return err } @@ -271,8 +280,8 @@ func (c *Component) removeImage(ctx context.Context) error { return nil } - _, err = c.cli.ImageRemove(ctx, c.config.Image, image.RemoveOptions{}) - if err != nil && !errdefs.IsNotFound(err) { + _, err = c.cli.ImageRemove(ctx, c.config.Image, client.ImageRemoveOptions{}) + if err != nil && !cerrdefs.IsNotFound(err) { return err } @@ -289,7 +298,7 @@ func (c *Component) Status(context.Context) (envite.ComponentStatus, error) { return "", fmt.Errorf("failed to find container: %w", err) } - if cont == nil || cont.State != "running" { + if cont == nil || cont.State != container.StateRunning { status = envite.ComponentStatusStopped c.status.Store(envite.ComponentStatusStopped) } @@ -327,9 +336,8 @@ func (c *Component) Exec(ctx context.Context, cmd []string) (int, error) { } c.Writer().WriteString(c.Writer().Color.Cyan(fmt.Sprintf("executing: %s", strings.Join(cmd, " ")))) - response, err := c.cli.ContainerExecCreate(ctx, cont.ID, container.ExecOptions{ + response, err := c.cli.ExecCreate(ctx, cont.ID, client.ExecCreateOptions{ Cmd: cmd, - Detach: false, AttachStdout: true, AttachStderr: true, }) @@ -337,7 +345,7 @@ func (c *Component) Exec(ctx context.Context, cmd []string) (int, error) { return 0, fmt.Errorf("failed to create exec: %w", err) } - hijack, err := c.cli.ContainerExecAttach(ctx, response.ID, container.ExecStartOptions{}) + hijack, err := c.cli.ExecAttach(ctx, response.ID, client.ExecAttachOptions{}) if err != nil { return 0, fmt.Errorf("failed to attach exec: %w", err) } @@ -349,7 +357,7 @@ func (c *Component) Exec(ctx context.Context, cmd []string) (int, error) { hijack.Close() - execResp, err := c.cli.ContainerExecInspect(ctx, response.ID) + execResp, err := c.cli.ExecInspect(ctx, response.ID, client.ExecInspectOptions{}) if err != nil { return 0, fmt.Errorf("failed to inspect exec: %w", err) } @@ -358,18 +366,19 @@ func (c *Component) Exec(ctx context.Context, cmd []string) (int, error) { return execResp.ExitCode, nil } -func (c *Component) findContainer(ctx context.Context) (*types.Container, error) { - containers, err := c.cli.ContainerList(ctx, container.ListOptions{ +func (c *Component) findContainer(ctx context.Context) (*container.Summary, error) { + listResult, err := c.cli.ContainerList(ctx, client.ContainerListOptions{ All: true, - Filters: filters.NewArgs(filters.Arg("name", c.containerName)), + Filters: make(client.Filters).Add("name", c.containerName), }) if err != nil { return nil, fmt.Errorf("failed to list containers: %w", err) } - for _, co := range containers { + for i := range listResult.Items { + co := &listResult.Items[i] if len(co.Names) > 0 && co.Names[0][1:] == c.containerName { - return &co, nil + return co, nil } } diff --git a/docker/config.go b/docker/config.go index 7a8e6b7..0935adc 100644 --- a/docker/config.go +++ b/docker/config.go @@ -6,18 +6,22 @@ package docker import ( "fmt" - "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/blkiodev" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/image" - "github.com/docker/docker/api/types/mount" - "github.com/docker/docker/api/types/network" - "github.com/docker/docker/api/types/strslice" + "net" + "net/netip" + "os" + "strings" + "time" + "github.com/docker/go-units" + "github.com/moby/moby/api/types/blkiodev" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/mount" + "github.com/moby/moby/api/types/network" + "github.com/moby/moby/api/types/registry" + "github.com/moby/moby/api/types/strslice" + mobyclient "github.com/moby/moby/client" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "gopkg.in/yaml.v3" - "os" - "time" ) // Config represents Docker Component configuration @@ -287,7 +291,7 @@ type ImagePullOptions struct { // PrivilegeFunc - used for https://github.com/moby/moby/blob/v24.0.6/api/types/client.go#L281 // available only via code, not available in config files - PrivilegeFunc types.RequestPrivilegeFunc `json:"-"` + PrivilegeFunc registry.RequestAuthConfig `json:"-"` // Platform - used for https://github.com/moby/moby/blob/v24.0.6/api/types/client.go#L282 Platform string `json:"platform,omitempty"` @@ -393,7 +397,13 @@ type Resources struct { // DeviceRequests - used for https://github.com/moby/moby/blob/v24.0.6/api/types/container/hostconfig.go#L348 DeviceRequests []DeviceRequest `json:"device_requests,omitempty"` - // KernelMemoryTCP - used for https://github.com/moby/moby/blob/v24.0.6/api/types/container/hostconfig.go#L353 + // KernelMemoryTCP is deprecated and no longer has any effect. + // + // The Docker API removed support for the kernel memory TCP limit, so this + // field is not mapped onto container.Resources. Setting it results in a + // validation error to avoid silently ignoring the option. + // + // Deprecated: KernelMemoryTCP is unsupported and must not be set. KernelMemoryTCP int64 `json:"kernel_memory_tcp,omitempty"` // MemoryReservation - used for https://github.com/moby/moby/blob/v24.0.6/api/types/container/hostconfig.go#L354 @@ -606,6 +616,7 @@ type runConfig struct { hostConfig *container.HostConfig networkingConfig *network.NetworkingConfig platformConfig *ocispec.Platform + macAddress network.HardwareAddr waiters []waiterFunc } @@ -623,6 +634,13 @@ func (c Config) initialize(network *Network, imageCloneTag string) (*runConfig, return nil, ErrInvalidConfig{Property: "console_size", Msg: "must have exactly two elements"} } + if c.Resources != nil && c.Resources.KernelMemoryTCP != 0 { + return nil, ErrInvalidConfig{ + Property: "resources.kernel_memory_tcp", + Msg: "is no longer supported by the Docker API and has no effect; remove it from the configuration", + } + } + waiters := make([]waiterFunc, len(c.Waiters)) for i, waiter := range c.Waiters { f, err := validateWaiter(waiter) @@ -633,18 +651,45 @@ func (c Config) initialize(network *Network, imageCloneTag string) (*runConfig, waiters[i] = f } + hostConfig, err := c.hostConfig(network) + if err != nil { + return nil, err + } + + macAddress, err := parseMacAddress(c.MacAddress) + if err != nil { + return nil, err + } + result := &runConfig{ containerConfig: c.containerConfig(imageCloneTag), - hostConfig: c.hostConfig(network), + hostConfig: hostConfig, platformConfig: c.PlatformConfig.build(), + macAddress: macAddress, waiters: waiters, } return result, nil } -func (c Config) imagePullOptions() (image.PullOptions, error) { - result := image.PullOptions{} +// parseMacAddress validates and parses a MAC address string into the type +// expected by the Docker network endpoint config. An empty string is valid and +// results in no MAC address being set. +func parseMacAddress(macAddress string) (network.HardwareAddr, error) { + if macAddress == "" { + return nil, nil + } + + parsed, err := net.ParseMAC(macAddress) + if err != nil { + return nil, ErrInvalidConfig{Property: "mac_address", Msg: err.Error()} + } + + return network.HardwareAddr(parsed), nil +} + +func (c Config) imagePullOptions() (mobyclient.ImagePullOptions, error) { + result := mobyclient.ImagePullOptions{} if c.ImagePullOptions != nil { var auth string @@ -652,21 +697,60 @@ func (c Config) imagePullOptions() (image.PullOptions, error) { var err error auth, err = c.ImagePullOptions.RegistryAuthFunc() if err != nil { - return image.PullOptions{}, fmt.Errorf("failed to get registry auth: %w", err) + return mobyclient.ImagePullOptions{}, fmt.Errorf("failed to get registry auth: %w", err) } } else { auth = c.ImagePullOptions.RegistryAuth } + platforms, err := parsePlatforms(c.ImagePullOptions.Platform) + if err != nil { + return mobyclient.ImagePullOptions{}, err + } + result.All = c.ImagePullOptions.All result.RegistryAuth = auth result.PrivilegeFunc = c.ImagePullOptions.PrivilegeFunc - result.Platform = c.ImagePullOptions.Platform + result.Platforms = platforms } return result, nil } +func parseDNSAddrs(addrs []string) ([]netip.Addr, error) { + result := make([]netip.Addr, 0, len(addrs)) + for _, addr := range addrs { + parsed, err := netip.ParseAddr(addr) + if err != nil { + return nil, ErrInvalidConfig{Property: "dns", Msg: fmt.Sprintf("invalid DNS address %q: %s", addr, err)} + } + result = append(result, parsed) + } + return result, nil +} + +func parsePlatforms(platform string) ([]ocispec.Platform, error) { + if platform == "" { + return nil, nil + } + + parts := strings.Split(platform, "/") + for _, part := range parts { + if part == "" { + return nil, fmt.Errorf("invalid platform %q: segments must not be empty", platform) + } + } + + switch len(parts) { + case 2: + return []ocispec.Platform{{OS: parts[0], Architecture: parts[1]}}, nil + case 3: + return []ocispec.Platform{{OS: parts[0], Architecture: parts[1], Variant: parts[2]}}, nil + default: + return nil, fmt.Errorf("invalid platform %q: expected os/arch[/variant]", platform) + } +} + func (c Config) containerConfig(imageCloneTag string) *container.Config { env := make([]string, 0, len(c.Env)) for key, value := range c.Env { @@ -693,7 +777,6 @@ func (c Config) containerConfig(imageCloneTag string) *container.Config { WorkingDir: c.WorkingDir, Entrypoint: strslice.StrSlice(c.Entrypoint), NetworkDisabled: c.NetworkDisabled, - MacAddress: c.MacAddress, OnBuild: c.OnBuild, Labels: c.Labels, StopSignal: c.StopSignal, @@ -716,11 +799,17 @@ func (c *Healthcheck) build() *container.HealthConfig { } } -func (c Config) hostConfig(network *Network) *container.HostConfig { +func (c Config) hostConfig(network *Network) (*container.HostConfig, error) { var consoleSize [2]uint if len(c.ConsoleSize) > 0 { consoleSize = [2]uint{c.ConsoleSize[0], c.ConsoleSize[1]} } + + dns, err := parseDNSAddrs(c.DNS) + if err != nil { + return nil, err + } + return &container.HostConfig{ Binds: c.Binds, ContainerIDFile: c.ContainerIDFile, @@ -734,7 +823,7 @@ func (c Config) hostConfig(network *Network) *container.HostConfig { CapAdd: strslice.StrSlice(c.CapAdd), CapDrop: strslice.StrSlice(c.CapDrop), CgroupnsMode: c.CgroupnsMode, - DNS: c.DNS, + DNS: dns, DNSOptions: c.DNSOptions, DNSSearch: c.DNSSearch, ExtraHosts: c.ExtraHosts, @@ -761,7 +850,7 @@ func (c Config) hostConfig(network *Network) *container.HostConfig { MaskedPaths: c.MaskedPaths, ReadonlyPaths: c.ReadonlyPaths, Init: c.Init, - } + }, nil } func (c *LogConfig) build() container.LogConfig { @@ -811,7 +900,6 @@ func (c *Resources) build() container.Resources { Devices: mapSlice(c.Devices, DeviceMapping.build), DeviceCgroupRules: c.DeviceCgroupRules, DeviceRequests: mapSlice(c.DeviceRequests, DeviceRequest.build), - KernelMemoryTCP: c.KernelMemoryTCP, MemoryReservation: c.MemoryReservation, MemorySwap: c.MemorySwap, MemorySwappiness: c.MemorySwappiness, diff --git a/docker/config_test.go b/docker/config_test.go index 2664cb4..6192543 100644 --- a/docker/config_test.go +++ b/docker/config_test.go @@ -5,8 +5,11 @@ package docker import ( - "github.com/stretchr/testify/assert" + "net/netip" "testing" + + ocispec "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/stretchr/testify/assert" ) func TestContainerConfig(t *testing.T) { @@ -51,6 +54,13 @@ func TestContainerConfig(t *testing.T) { assert.Error(t, err) assert.EqualError(t, err, "invalid docker config - property console_size: must have exactly two elements") + // Test when Resources.KernelMemoryTCP is set + config = newSampleConfig() + config.Resources = &Resources{KernelMemoryTCP: 1} + _, err = config.initialize(network, imageCloneTag) + assert.Error(t, err) + assert.EqualError(t, err, "invalid docker config - property resources.kernel_memory_tcp: is no longer supported by the Docker API and has no effect; remove it from the configuration") + // Test when Waiters contain an invalid waiter type config = newSampleConfig() config.Waiters = []Waiter{ @@ -62,3 +72,116 @@ func TestContainerConfig(t *testing.T) { assert.Error(t, err) assert.EqualError(t, err, "invalid waiter type invalid") } + +func TestParsePlatforms(t *testing.T) { + tests := []struct { + name string + platform string + want []ocispec.Platform + wantErr bool + }{ + { + name: "empty string returns nil", + platform: "", + want: nil, + }, + { + name: "single part is invalid", + platform: "amd64", + wantErr: true, + }, + { + name: "two parts are os and architecture", + platform: "linux/amd64", + want: []ocispec.Platform{{OS: "linux", Architecture: "amd64"}}, + }, + { + name: "three parts are os, architecture and variant", + platform: "linux/arm/v7", + want: []ocispec.Platform{{OS: "linux", Architecture: "arm", Variant: "v7"}}, + }, + { + name: "four parts are invalid", + platform: "linux/arm/v7/extra", + wantErr: true, + }, + { + name: "trailing slash is invalid", + platform: "linux/", + wantErr: true, + }, + { + name: "leading slash is invalid", + platform: "/amd64", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := parsePlatforms(tt.platform) + if tt.wantErr { + assert.Error(t, err) + assert.Nil(t, got) + return + } + + assert.NoError(t, err) + assert.Equal(t, tt.want, got) + }) + } +} + +func TestParseDNSAddrs(t *testing.T) { + tests := []struct { + name string + addrs []string + want []netip.Addr + wantErr bool + }{ + { + name: "nil input yields empty result", + addrs: nil, + want: []netip.Addr{}, + }, + { + name: "valid IPv4 addresses", + addrs: []string{"8.8.8.8", "1.1.1.1"}, + want: []netip.Addr{netip.MustParseAddr("8.8.8.8"), netip.MustParseAddr("1.1.1.1")}, + }, + { + name: "valid IPv6 address", + addrs: []string{"2001:4860:4860::8888"}, + want: []netip.Addr{netip.MustParseAddr("2001:4860:4860::8888")}, + }, + { + name: "invalid address returns error", + addrs: []string{"8.8.8.8", "not-an-ip"}, + wantErr: true, + }, + { + name: "out of range octet returns error", + addrs: []string{"999.999.999.999"}, + wantErr: true, + }, + { + name: "empty address returns error", + addrs: []string{""}, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := parseDNSAddrs(tt.addrs) + if tt.wantErr { + assert.Error(t, err) + assert.Nil(t, got) + return + } + + assert.NoError(t, err) + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/docker/logs.go b/docker/logs.go index ccb5d15..2b9a45d 100644 --- a/docker/logs.go +++ b/docker/logs.go @@ -7,9 +7,8 @@ package docker import ( "bufio" "context" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/client" - "github.com/docker/docker/pkg/stdcopy" + "github.com/moby/moby/api/pkg/stdcopy" + "github.com/moby/moby/client" "strings" "time" ) @@ -18,7 +17,7 @@ type logHandler func(timestamp time.Time, text string, stream stdcopy.StdType) ( // followLogs attaches to container's output func followLogs(ctx context.Context, cli *client.Client, id string, handler logHandler) error { - containerReader, err := cli.ContainerLogs(ctx, id, container.LogsOptions{ + containerReader, err := cli.ContainerLogs(ctx, id, client.ContainerLogsOptions{ ShowStdout: true, ShowStderr: true, Timestamps: true, diff --git a/docker/network.go b/docker/network.go index b3ec88d..e157711 100644 --- a/docker/network.go +++ b/docker/network.go @@ -14,10 +14,9 @@ import ( "strings" "sync" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/network" - "github.com/docker/docker/client" - "github.com/docker/go-connections/nat" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/network" + "github.com/moby/moby/client" ) // Network represents a Docker network. @@ -68,12 +67,12 @@ func (n *Network) NewComponent(config Config) (*Component, error) { } func newClosedNetwork(cli *client.Client, envID, networkIdentifier string, runtimeInfo *RuntimeInfo) (*Network, error) { - networks, err := cli.NetworkList(context.Background(), network.ListOptions{}) + listResult, err := cli.NetworkList(context.Background(), client.NetworkListOptions{}) if err != nil { return nil, fmt.Errorf("failed to list networks: %w", err) } - nw, err := findNetwork(networks, networkIdentifier) + nw, err := findNetwork(listResult.Items, networkIdentifier) if err != nil { return nil, fmt.Errorf("failed to find network: %w", err) } @@ -139,16 +138,16 @@ func newOpenNetwork(cli *client.Client, envID string, runtimeInfo *RuntimeInfo) EndpointsConfig: map[string]*network.EndpointSettings{id: {NetworkID: id}}, } runConfig.hostname = runtimeInfo.InternalHostname - runConfig.containerConfig.ExposedPorts = nat.PortSet{} - runConfig.hostConfig.PortBindings = nat.PortMap{} + runConfig.containerConfig.ExposedPorts = network.PortSet{} + runConfig.hostConfig.PortBindings = network.PortMap{} for _, port := range config.Ports { protocol := port.Protocol if protocol == "" { protocol = "tcp" } - p := nat.Port(fmt.Sprintf("%s/%s", port.Port, protocol)) + p := network.MustParsePort(fmt.Sprintf("%s/%s", port.Port, protocol)) runConfig.containerConfig.ExposedPorts[p] = struct{}{} - runConfig.hostConfig.PortBindings[p] = append(runConfig.hostConfig.PortBindings[p], nat.PortBinding{ + runConfig.hostConfig.PortBindings[p] = append(runConfig.hostConfig.PortBindings[p], network.PortBinding{ HostPort: port.Port, }) } @@ -166,7 +165,7 @@ func (n *Network) delete(ctx context.Context, c *Component) error { n.lock.Lock() defer n.lock.Unlock() - err := c.cli.NetworkRemove(ctx, c.envID) + _, err := c.cli.NetworkRemove(ctx, c.envID, client.NetworkRemoveOptions{}) if err != nil && !strings.Contains(err.Error(), "has active endpoints") && !strings.Contains(err.Error(), "not found") { @@ -177,7 +176,7 @@ func (n *Network) delete(ctx context.Context, c *Component) error { } func createNetworkIfNotExist(cli *client.Client, name, driver string) (string, error) { - res, err := cli.NetworkCreate(context.Background(), name, network.CreateOptions{ + res, err := cli.NetworkCreate(context.Background(), name, client.NetworkCreateOptions{ Driver: driver, }) if err != nil { diff --git a/docker/runtime.go b/docker/runtime.go index 2039070..1dddee0 100644 --- a/docker/runtime.go +++ b/docker/runtime.go @@ -6,7 +6,7 @@ import ( "strings" "time" - "github.com/docker/docker/client" + "github.com/moby/moby/client" ) // RuntimeInfo contains information about a runtime type @@ -21,11 +21,12 @@ type RuntimeInfo struct { // ExtractRuntimeInfo detects the Docker daemon implementation for the given client func ExtractRuntimeInfo(ctx context.Context, cli *client.Client) (*RuntimeInfo, error) { - info, err := cli.Info(ctx) + infoResult, err := cli.Info(ctx, client.InfoOptions{}) if err != nil { return nil, fmt.Errorf("failed to get docker info: %w", err) } + info := infoResult.Info name := strings.ToLower(info.Name) serverVersion := strings.ToLower(info.ServerVersion) diff --git a/docker/waiter.go b/docker/waiter.go index def3ae6..f2cbb9b 100644 --- a/docker/waiter.go +++ b/docker/waiter.go @@ -7,8 +7,8 @@ package docker import ( "context" "fmt" - "github.com/docker/docker/client" - "github.com/docker/docker/pkg/stdcopy" + "github.com/moby/moby/api/pkg/stdcopy" + "github.com/moby/moby/client" "regexp" "strings" "time" diff --git a/go.mod b/go.mod index 5f9237e..57cee71 100644 --- a/go.mod +++ b/go.mod @@ -1,62 +1,48 @@ module github.com/perimeterx/envite -go 1.23.0 - -toolchain go1.23.10 +go 1.25.0 require ( - github.com/docker/docker v28.5.1+incompatible - github.com/docker/go-connections v0.4.0 + github.com/containerd/errdefs v1.0.0 github.com/docker/go-units v0.5.0 github.com/go-redis/redis/v8 v8.11.5 github.com/gorilla/mux v1.8.0 - github.com/opencontainers/image-spec v1.0.2 + github.com/moby/moby/api v1.54.2 + github.com/moby/moby/client v0.4.1 + github.com/opencontainers/image-spec v1.1.1 github.com/stretchr/testify v1.11.1 go.mongodb.org/mongo-driver v1.12.1 - golang.org/x/sync v0.7.0 + golang.org/x/sync v0.20.0 gopkg.in/yaml.v3 v3.0.1 ) require ( - github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/containerd/errdefs v1.0.0 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect - github.com/containerd/log v0.1.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/distribution/reference v0.5.0 // indirect + github.com/distribution/reference v0.6.0 // indirect + github.com/docker/go-connections v0.7.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/golang/snappy v0.0.1 // indirect github.com/klauspost/compress v1.13.6 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect - github.com/moby/sys/atomicwriter v0.1.0 // indirect - github.com/moby/term v0.5.0 // indirect github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect - github.com/morikuni/aec v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.23.1 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.23.1 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect - golang.org/x/crypto v0.22.0 // indirect - golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.24.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.20.0 // indirect - gotest.tools/v3 v3.5.1 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect + go.opentelemetry.io/otel v1.35.0 // indirect + go.opentelemetry.io/otel/metric v1.35.0 // indirect + go.opentelemetry.io/otel/trace v1.35.0 // indirect + golang.org/x/crypto v0.52.0 // indirect + golang.org/x/sys v0.45.0 // indirect + golang.org/x/text v0.37.0 // indirect ) diff --git a/go.sum b/go.sum index a461801..5bd3e2a 100644 --- a/go.sum +++ b/go.sum @@ -1,29 +1,19 @@ -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= -github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk= -github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= -github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= -github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= -github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= -github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/docker v28.5.1+incompatible h1:Bm8DchhSD2J6PsFzxC35TZo4TLGR2PdW/E69rU45NhM= -github.com/docker/docker v28.5.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/docker/go-connections v0.7.0 h1:6SsRfJddP22WMrCkj19x9WKjEDTB+ahsdiGYf0mN39c= +github.com/docker/go-connections v0.7.0/go.mod h1:no1qkHdjq7kLMGUXYAduOhYPSJxxvgWBh7ogVvptn3Q= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= @@ -31,8 +21,8 @@ github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= @@ -42,10 +32,10 @@ github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU= github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -54,16 +44,12 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw= -github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs= -github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= -github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko= -github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/moby/moby/api v1.54.2 h1:wiat9QAhnDQjA7wk1kh/TqHz2I1uUA7M7t9SAl/JNXg= +github.com/moby/moby/api v1.54.2/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs= +github.com/moby/moby/client v0.4.1 h1:DMQgisVoMkmMs7fp3ROSdiBnoAu8+vo3GggFl06M/wY= +github.com/moby/moby/client v0.4.1/go.mod h1:z52C9O2POPOsnxZAy//WtKcQ32P+jT/NGeXu/7nfjGQ= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= -github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= @@ -72,16 +58,12 @@ github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= -github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= +github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= @@ -97,49 +79,42 @@ go.mongodb.org/mongo-driver v1.12.1 h1:nLkghSU8fQNaK7oUmDhQFsnrtcoNy7Z6LVFKsEecq go.mongodb.org/mongo-driver v1.12.1/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0 h1:doUP+ExOpH3spVTLS0FcWGLnQrPct/hD/bCPbDRUEAU= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0/go.mod h1:rdENBZMT2OE6Ne/KLwpiXudnAsbdrdBaqBvTN8M8BgA= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.23.1 h1:o8iWeVFa1BcLtVEV0LzrCxV2/55tB3xLxADr6Kyoey4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.23.1/go.mod h1:SEVfdK4IoBnbT2FXNM/k8yC08MrfbhWk3U4ljM8B3HE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.23.1 h1:cfuy3bXmLJS7M1RZmAL6SuhGtKUp2KEsrm00OlAXkq4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.23.1/go.mod h1:22jr92C6KwlwItJmQzfixzQM3oyyuYLCfHiMY+rpsPU= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.23.1 h1:O7JmZw0h76if63LQdsBMKQDWNb5oEcOThG9IrxscV+E= -go.opentelemetry.io/otel/sdk v1.23.1/go.mod h1:LzdEVR5am1uKOOwfBWFef2DCi1nu3SA8XQxx2IerWFk= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= -go.opentelemetry.io/proto/otlp v1.1.0 h1:2Di21piLrCqJ3U3eXGCTPHE9R8Nh+0uglSnOyxikMeI= -go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= +go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= +go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= +go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= +go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= +go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY= +go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= +go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o= +go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= +go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= +go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= +golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= +golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -148,25 +123,13 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= -golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 h1:rcS6EyEaoCO52hQDupoSfrxI3R6C2Tq741is7X8OvnM= -google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917/go.mod h1:CmlNWB9lSezaYELKS5Ym1r44VrrbPUa7JTvw+6MbpJ0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -176,5 +139,7 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= -gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= +gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= +pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk= +pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=