diff --git a/client/client_interfaces.go b/client/client_interfaces.go index d6e6e855f0..0e81639417 100644 --- a/client/client_interfaces.go +++ b/client/client_interfaces.go @@ -62,7 +62,7 @@ type ContainerAPIClient interface { ContainerExport(ctx context.Context, container string) (io.ReadCloser, error) ContainerInspect(ctx context.Context, container string, options ContainerInspectOptions) (ContainerInspectResult, error) ContainerKill(ctx context.Context, container string, options ContainerKillOptions) (ContainerKillResult, error) - ContainerList(ctx context.Context, options ContainerListOptions) ([]container.Summary, error) + ContainerList(ctx context.Context, options ContainerListOptions) (ContainerListResult, error) ContainerLogs(ctx context.Context, container string, options ContainerLogsOptions) (io.ReadCloser, error) ContainerPause(ctx context.Context, container string, options ContainerPauseOptions) (ContainerPauseResult, error) ContainerRemove(ctx context.Context, container string, options ContainerRemoveOptions) (ContainerRemoveResult, error) diff --git a/client/container_list.go b/client/container_list.go index 0b181aafaf..fcd39c4da5 100644 --- a/client/container_list.go +++ b/client/container_list.go @@ -20,8 +20,12 @@ type ContainerListOptions struct { Filters Filters } +type ContainerListResult struct { + Items []container.Summary +} + // ContainerList returns the list of containers in the docker host. -func (cli *Client) ContainerList(ctx context.Context, options ContainerListOptions) ([]container.Summary, error) { +func (cli *Client) ContainerList(ctx context.Context, options ContainerListOptions) (ContainerListResult, error) { query := url.Values{} if options.All { @@ -49,10 +53,10 @@ func (cli *Client) ContainerList(ctx context.Context, options ContainerListOptio resp, err := cli.get(ctx, "/containers/json", query, nil) defer ensureReaderClosed(resp) if err != nil { - return nil, err + return ContainerListResult{}, err } var containers []container.Summary err = json.NewDecoder(resp.Body).Decode(&containers) - return containers, err + return ContainerListResult{Items: containers}, err } diff --git a/client/container_list_test.go b/client/container_list_test.go index 58622f543f..912ae15358 100644 --- a/client/container_list_test.go +++ b/client/container_list_test.go @@ -65,7 +65,7 @@ func TestContainerList(t *testing.T) { ) assert.NilError(t, err) - containers, err := client.ContainerList(context.Background(), ContainerListOptions{ + list, err := client.ContainerList(context.Background(), ContainerListOptions{ Size: true, All: true, Since: "container", @@ -75,5 +75,5 @@ func TestContainerList(t *testing.T) { Add("before", "container"), }) assert.NilError(t, err) - assert.Check(t, is.Len(containers, 2)) + assert.Check(t, is.Len(list.Items, 2)) } diff --git a/integration-cli/daemon/daemon.go b/integration-cli/daemon/daemon.go index e045e4a18f..03661c205c 100644 --- a/integration-cli/daemon/daemon.go +++ b/integration-cli/daemon/daemon.go @@ -88,14 +88,14 @@ func (d *Daemon) CheckActiveContainerCount(ctx context.Context) func(t *testing. apiClient, err := client.NewClientWithOpts(client.FromEnv, client.WithHost(d.Sock())) assert.NilError(t, err) - ctrs, err := apiClient.ContainerList(ctx, client.ContainerListOptions{}) + list, err := apiClient.ContainerList(ctx, client.ContainerListOptions{}) _ = apiClient.Close() assert.NilError(t, err) var out strings.Builder - for _, ctr := range ctrs { + for _, ctr := range list.Items { out.WriteString(stringid.TruncateID(ctr.ID) + "\n") } - return len(ctrs), out.String() + return len(list.Items), out.String() } } diff --git a/integration-cli/docker_api_containers_test.go b/integration-cli/docker_api_containers_test.go index 5441e28e78..e9d5e70ebb 100644 --- a/integration-cli/docker_api_containers_test.go +++ b/integration-cli/docker_api_containers_test.go @@ -42,12 +42,12 @@ func (s *DockerAPISuite) TestContainerAPIGetAll(c *testing.T) { defer apiClient.Close() ctx := testutil.GetContext(c) - containers, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ + list, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ All: true, }) assert.NilError(c, err) - assert.Equal(c, len(containers), startCount+1) - actual := containers[0].Names[0] + assert.Equal(c, len(list.Items), startCount+1) + actual := list.Items[0].Names[0] assert.Equal(c, actual, "/"+name) } @@ -64,10 +64,10 @@ func (s *DockerAPISuite) TestContainerAPIGetJSONNoFieldsOmitted(c *testing.T) { All: true, } ctx := testutil.GetContext(c) - containers, err := apiClient.ContainerList(ctx, options) + list, err := apiClient.ContainerList(ctx, options) assert.NilError(c, err) - assert.Equal(c, len(containers), startCount+1) - actual := fmt.Sprintf("%+v", containers[0]) + assert.Equal(c, len(list.Items), startCount+1) + actual := fmt.Sprintf("%+v", list.Items[0]) // empty Labels field triggered this bug, make sense to check for everything // cause even Ports for instance can trigger this bug diff --git a/integration/build/build_test.go b/integration/build/build_test.go index e27b7de442..1e4f274943 100644 --- a/integration/build/build_test.go +++ b/integration/build/build_test.go @@ -116,7 +116,7 @@ func TestBuildWithRemoveAndForceRemove(t *testing.T) { assert.NilError(t, err) remainingContainers, err := apiClient.ContainerList(ctx, client.ContainerListOptions{Filters: filter, All: true}) assert.NilError(t, err) - assert.Equal(t, tc.numberOfIntermediateContainers, len(remainingContainers), "Expected %v remaining intermediate containers, got %v", tc.numberOfIntermediateContainers, len(remainingContainers)) + assert.Equal(t, tc.numberOfIntermediateContainers, len(remainingContainers.Items), "Expected %v remaining intermediate containers, got %v", tc.numberOfIntermediateContainers, len(remainingContainers.Items)) }) } } diff --git a/integration/container/links_linux_test.go b/integration/container/links_linux_test.go index 2c1f7fe2e6..909fb25d9f 100644 --- a/integration/container/links_linux_test.go +++ b/integration/container/links_linux_test.go @@ -42,10 +42,10 @@ func TestLinksContainerNames(t *testing.T) { container.Run(ctx, t, apiClient, container.WithName(containerA)) container.Run(ctx, t, apiClient, container.WithName(containerB), container.WithLinks(containerA+":"+containerA)) - containers, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ + list, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ Filters: make(client.Filters).Add("name", containerA), }) assert.NilError(t, err) - assert.Check(t, is.Equal(1, len(containers))) - assert.Check(t, is.DeepEqual([]string{"/" + containerA, "/" + containerB + "/" + containerA}, containers[0].Names)) + assert.Check(t, is.Equal(1, len(list.Items))) + assert.Check(t, is.DeepEqual([]string{"/" + containerA, "/" + containerB + "/" + containerA}, list.Items[0].Names)) } diff --git a/integration/container/list_test.go b/integration/container/list_test.go index 63253ef033..83e06d080e 100644 --- a/integration/container/list_test.go +++ b/integration/container/list_test.go @@ -35,12 +35,12 @@ func TestContainerList(t *testing.T) { } // list them and verify correctness - containerList, err := apiClient.ContainerList(ctx, client.ContainerListOptions{All: true}) + list, err := apiClient.ContainerList(ctx, client.ContainerListOptions{All: true}) assert.NilError(t, err) - assert.Assert(t, is.Len(containerList, num)) + assert.Assert(t, is.Len(list.Items, num)) for i := range num { // container list should be ordered in descending creation order - assert.Assert(t, is.Equal(containerList[i].ID, containers[num-1-i])) + assert.Assert(t, is.Equal(list.Items[i].ID, containers[num-1-i])) } } @@ -65,14 +65,14 @@ func TestContainerList_Annotations(t *testing.T) { id := container.Create(ctx, t, apiClient, container.WithAnnotations(annotations)) defer container.Remove(ctx, t, apiClient, id, client.ContainerRemoveOptions{Force: true}) - containers, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ + list, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ All: true, Filters: make(client.Filters).Add("id", id), }) assert.NilError(t, err) - assert.Assert(t, is.Len(containers, 1)) - assert.Equal(t, containers[0].ID, id) - assert.Check(t, is.DeepEqual(containers[0].HostConfig.Annotations, tc.expectedAnnotations)) + assert.Assert(t, is.Len(list.Items, 1)) + assert.Equal(t, list.Items[0].ID, id) + assert.Check(t, is.DeepEqual(list.Items[0].HostConfig.Annotations, tc.expectedAnnotations)) }) } } @@ -101,22 +101,22 @@ func TestContainerList_Filter(t *testing.T) { t.Run("since", func(t *testing.T) { ctx := testutil.StartSpan(ctx, t) - results, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ + list, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ All: true, Filters: make(client.Filters).Add("since", top), }) assert.NilError(t, err) - assert.Check(t, is.Contains(containerIDs(results), next)) + assert.Check(t, is.Contains(containerIDs(list.Items), next)) }) t.Run("before", func(t *testing.T) { ctx := testutil.StartSpan(ctx, t) - results, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ + list, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ All: true, Filters: make(client.Filters).Add("before", top), }) assert.NilError(t, err) - assert.Check(t, is.Contains(containerIDs(results), prev)) + assert.Check(t, is.Contains(containerIDs(list.Items), prev)) }) } @@ -132,13 +132,13 @@ func TestContainerList_ImageManifestPlatform(t *testing.T) { id := container.Create(ctx, t, apiClient) defer container.Remove(ctx, t, apiClient, id, client.ContainerRemoveOptions{Force: true}) - containers, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ + list, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ All: true, }) assert.NilError(t, err) - assert.Assert(t, len(containers) > 0) + assert.Assert(t, len(list.Items) > 0) - ctr := containers[0] + ctr := list.Items[0] if assert.Check(t, ctr.ImageManifestDescriptor != nil && ctr.ImageManifestDescriptor.Platform != nil) { // Check that at least OS and Architecture have a value. Other values // depend on the platform on which we're running the test. @@ -149,7 +149,7 @@ func TestContainerList_ImageManifestPlatform(t *testing.T) { func pollForHealthStatusSummary(ctx context.Context, apiClient client.APIClient, containerID string, healthStatus containertypes.HealthStatus) func(log poll.LogT) poll.Result { return func(log poll.LogT) poll.Result { - containers, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ + list, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ All: true, Filters: make(client.Filters).Add("id", containerID), }) @@ -158,7 +158,7 @@ func pollForHealthStatusSummary(ctx context.Context, apiClient client.APIClient, } total := 0 version := apiClient.ClientVersion() - for _, ctr := range containers { + for _, ctr := range list.Items { if ctr.Health == nil && versions.LessThan(version, "1.52") { total++ } else if ctr.Health != nil && ctr.Health.Status == healthStatus && versions.GreaterThanOrEqualTo(version, "1.52") { @@ -166,7 +166,7 @@ func pollForHealthStatusSummary(ctx context.Context, apiClient client.APIClient, } } - if total == len(containers) { + if total == len(list.Items) { return poll.Success() } diff --git a/integration/internal/container/container.go b/integration/internal/container/container.go index 6c5209fb0e..a82c9242d8 100644 --- a/integration/internal/container/container.go +++ b/integration/internal/container/container.go @@ -176,10 +176,10 @@ func Remove(ctx context.Context, t *testing.T, apiClient client.APIClient, conta func RemoveAll(ctx context.Context, t *testing.T, apiClient client.APIClient) { t.Helper() - containers, err := apiClient.ContainerList(ctx, client.ContainerListOptions{All: true}) + list, err := apiClient.ContainerList(ctx, client.ContainerListOptions{All: true}) assert.NilError(t, err) - for _, c := range containers { + for _, c := range list.Items { Remove(ctx, t, apiClient, c.ID, client.ContainerRemoveOptions{Force: true}) } } diff --git a/integration/network/bridge/iptablesdoc/iptablesdoc_linux_test.go b/integration/network/bridge/iptablesdoc/iptablesdoc_linux_test.go index fafff64427..62d5892898 100644 --- a/integration/network/bridge/iptablesdoc/iptablesdoc_linux_test.go +++ b/integration/network/bridge/iptablesdoc/iptablesdoc_linux_test.go @@ -382,12 +382,12 @@ func createServices(ctx context.Context, t *testing.T, d *daemon.Daemon, section } func pollService(ctx context.Context, t *testing.T, c *client.Client, host networking.Host) poll.Result { - cl, err := c.ContainerList(ctx, client.ContainerListOptions{}) + list, err := c.ContainerList(ctx, client.ContainerListOptions{}) if err != nil { return poll.Error(fmt.Errorf("failed to list containers: %w", err)) } - if len(cl) != 1 { - return poll.Continue("got %d containers, want 1", len(cl)) + if len(list.Items) != 1 { + return poll.Continue("got %d containers, want 1", len(list.Items)) } // The DOCKER-INGRESS chain seems to be created, then populated, a few // milliseconds after the container starts. So, also wait for a conntrack diff --git a/integration/network/overlay/overlay_test.go b/integration/network/overlay/overlay_test.go index b2b6bdb2d1..20d46ba23a 100644 --- a/integration/network/overlay/overlay_test.go +++ b/integration/network/overlay/overlay_test.go @@ -89,12 +89,12 @@ func TestHostPortMappings(t *testing.T) { poll.WaitOn(t, swarm.RunningTasksCount(ctx, apiClient, svcID, 1), swarm.ServicePoll) - ctrs, err := apiClient.ContainerList(ctx, client.ContainerListOptions{}) + list, err := apiClient.ContainerList(ctx, client.ContainerListOptions{}) assert.NilError(t, err) - assert.Equal(t, 1, len(ctrs)) + assert.Equal(t, 1, len(list.Items)) var addrs []string - for _, port := range ctrs[0].Ports { + for _, port := range list.Items[0].Ports { addrs = append(addrs, fmt.Sprintf("%s:%d/%s", net.JoinHostPort(port.IP.String(), strconv.Itoa(int(port.PublicPort))), port.PrivatePort, port.Type)) } diff --git a/integration/service/create_test.go b/integration/service/create_test.go index 9afc6519bb..feab7ad22f 100644 --- a/integration/service/create_test.go +++ b/integration/service/create_test.go @@ -64,13 +64,13 @@ func testServiceCreateInit(ctx context.Context, daemonEnabled bool) func(t *test func inspectServiceContainer(ctx context.Context, t *testing.T, apiClient client.APIClient, serviceID string) container.InspectResponse { t.Helper() - containers, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ + list, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ Filters: make(client.Filters).Add("label", "com.docker.swarm.service.id="+serviceID), }) assert.NilError(t, err) - assert.Check(t, is.Len(containers, 1)) + assert.Check(t, is.Len(list.Items, 1)) - inspect, err := apiClient.ContainerInspect(ctx, containers[0].ID, client.ContainerInspectOptions{}) + inspect, err := apiClient.ContainerInspect(ctx, list.Items[0].ID, client.ContainerInspectOptions{}) assert.NilError(t, err) return inspect.Container } diff --git a/internal/testutil/daemon/container.go b/internal/testutil/daemon/container.go index cbc00fd1d0..62f86b2a32 100644 --- a/internal/testutil/daemon/container.go +++ b/internal/testutil/daemon/container.go @@ -14,11 +14,11 @@ func (d *Daemon) ActiveContainers(ctx context.Context, t testing.TB) []string { cli := d.NewClientT(t) defer cli.Close() - containers, err := cli.ContainerList(context.Background(), client.ContainerListOptions{}) + list, err := cli.ContainerList(context.Background(), client.ContainerListOptions{}) assert.NilError(t, err) - ids := make([]string, len(containers)) - for i, c := range containers { + ids := make([]string, len(list.Items)) + for i, c := range list.Items { ids[i] = c.ID } return ids diff --git a/internal/testutil/environment/clean.go b/internal/testutil/environment/clean.go index 483ab79103..429ad22767 100644 --- a/internal/testutil/environment/clean.go +++ b/internal/testutil/environment/clean.go @@ -51,12 +51,12 @@ func unpauseAllContainers(ctx context.Context, t testing.TB, apiClient client.Co func getPausedContainers(ctx context.Context, t testing.TB, apiClient client.ContainerAPIClient) []container.Summary { t.Helper() - containers, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ + list, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ Filters: make(client.Filters).Add("status", "paused"), All: true, }) assert.Check(t, err, "failed to list containers") - return containers + return list.Items } func deleteAllContainers(ctx context.Context, t testing.TB, apiclient client.ContainerAPIClient, protectedContainers map[string]struct{}) { @@ -85,11 +85,11 @@ func deleteAllContainers(ctx context.Context, t testing.TB, apiclient client.Con func getAllContainers(ctx context.Context, t testing.TB, apiClient client.ContainerAPIClient) []container.Summary { t.Helper() - containers, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ + list, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ All: true, }) assert.Check(t, err, "failed to list containers") - return containers + return list.Items } func deleteAllImages(ctx context.Context, t testing.TB, apiclient client.ImageAPIClient, protectedImages map[string]struct{}) { diff --git a/internal/testutil/environment/protect.go b/internal/testutil/environment/protect.go index 784727ab9a..fbd1cc3727 100644 --- a/internal/testutil/environment/protect.go +++ b/internal/testutil/environment/protect.go @@ -79,13 +79,13 @@ func ProtectContainers(ctx context.Context, t testing.TB, testEnv *Execution) { func getExistingContainers(ctx context.Context, t testing.TB, testEnv *Execution) []string { t.Helper() - containerList, err := testEnv.APIClient().ContainerList(ctx, client.ContainerListOptions{ + list, err := testEnv.APIClient().ContainerList(ctx, client.ContainerListOptions{ All: true, }) assert.NilError(t, err, "failed to list containers") var containers []string - for _, container := range containerList { + for _, container := range list.Items { containers = append(containers, container.ID) } return containers diff --git a/vendor/github.com/moby/moby/client/client_interfaces.go b/vendor/github.com/moby/moby/client/client_interfaces.go index d6e6e855f0..0e81639417 100644 --- a/vendor/github.com/moby/moby/client/client_interfaces.go +++ b/vendor/github.com/moby/moby/client/client_interfaces.go @@ -62,7 +62,7 @@ type ContainerAPIClient interface { ContainerExport(ctx context.Context, container string) (io.ReadCloser, error) ContainerInspect(ctx context.Context, container string, options ContainerInspectOptions) (ContainerInspectResult, error) ContainerKill(ctx context.Context, container string, options ContainerKillOptions) (ContainerKillResult, error) - ContainerList(ctx context.Context, options ContainerListOptions) ([]container.Summary, error) + ContainerList(ctx context.Context, options ContainerListOptions) (ContainerListResult, error) ContainerLogs(ctx context.Context, container string, options ContainerLogsOptions) (io.ReadCloser, error) ContainerPause(ctx context.Context, container string, options ContainerPauseOptions) (ContainerPauseResult, error) ContainerRemove(ctx context.Context, container string, options ContainerRemoveOptions) (ContainerRemoveResult, error) diff --git a/vendor/github.com/moby/moby/client/container_list.go b/vendor/github.com/moby/moby/client/container_list.go index 0b181aafaf..fcd39c4da5 100644 --- a/vendor/github.com/moby/moby/client/container_list.go +++ b/vendor/github.com/moby/moby/client/container_list.go @@ -20,8 +20,12 @@ type ContainerListOptions struct { Filters Filters } +type ContainerListResult struct { + Items []container.Summary +} + // ContainerList returns the list of containers in the docker host. -func (cli *Client) ContainerList(ctx context.Context, options ContainerListOptions) ([]container.Summary, error) { +func (cli *Client) ContainerList(ctx context.Context, options ContainerListOptions) (ContainerListResult, error) { query := url.Values{} if options.All { @@ -49,10 +53,10 @@ func (cli *Client) ContainerList(ctx context.Context, options ContainerListOptio resp, err := cli.get(ctx, "/containers/json", query, nil) defer ensureReaderClosed(resp) if err != nil { - return nil, err + return ContainerListResult{}, err } var containers []container.Summary err = json.NewDecoder(resp.Body).Decode(&containers) - return containers, err + return ContainerListResult{Items: containers}, err }