Browse code

client: merge ContainerInspectWithRaw with ContainerInspect

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Sebastiaan van Stijn authored on 2025/10/25 04:35:38
Showing 47 changed files
... ...
@@ -63,8 +63,7 @@ type ContainerAPIClient interface {
63 63
 	ContainerDiff(ctx context.Context, container string, options ContainerDiffOptions) (ContainerDiffResult, error)
64 64
 	ExecAPIClient
65 65
 	ContainerExport(ctx context.Context, container string) (io.ReadCloser, error)
66
-	ContainerInspect(ctx context.Context, container string) (container.InspectResponse, error)
67
-	ContainerInspectWithRaw(ctx context.Context, container string, getSize bool) (container.InspectResponse, []byte, error)
66
+	ContainerInspect(ctx context.Context, container string, options ContainerInspectOptions) (ContainerInspectResult, error)
68 67
 	ContainerKill(ctx context.Context, container, signal string) error
69 68
 	ContainerList(ctx context.Context, options ContainerListOptions) ([]container.Summary, error)
70 69
 	ContainerLogs(ctx context.Context, container string, options ContainerLogsOptions) (io.ReadCloser, error)
... ...
@@ -1,57 +1,47 @@
1 1
 package client
2 2
 
3 3
 import (
4
-	"bytes"
5 4
 	"context"
6 5
 	"encoding/json"
7
-	"io"
8 6
 	"net/url"
9 7
 
10 8
 	"github.com/moby/moby/api/types/container"
11 9
 )
12 10
 
13
-// ContainerInspect returns the container information.
14
-func (cli *Client) ContainerInspect(ctx context.Context, containerID string) (container.InspectResponse, error) {
15
-	containerID, err := trimID("container", containerID)
16
-	if err != nil {
17
-		return container.InspectResponse{}, err
18
-	}
19
-
20
-	resp, err := cli.get(ctx, "/containers/"+containerID+"/json", nil, nil)
21
-	defer ensureReaderClosed(resp)
22
-	if err != nil {
23
-		return container.InspectResponse{}, err
24
-	}
11
+// ContainerInspectOptions holds options for inspecting a container using
12
+// the [Client.ConfigInspect] method.
13
+type ContainerInspectOptions struct {
14
+	// Size controls whether the container's filesystem size should be calculated.
15
+	// When set, the [container.InspectResponse.SizeRw] and [container.InspectResponse.SizeRootFs]
16
+	// fields in [ContainerInspectResult.Container] are populated with the result.
17
+	//
18
+	// Calculating the size can be a costly operation, and should not be used
19
+	// unless needed.
20
+	Size bool
21
+}
25 22
 
26
-	var response container.InspectResponse
27
-	err = json.NewDecoder(resp.Body).Decode(&response)
28
-	return response, err
23
+// ContainerInspectResult holds the result from the [Client.ConfigInspect] method.
24
+type ContainerInspectResult struct {
25
+	Container container.InspectResponse
26
+	Raw       json.RawMessage
29 27
 }
30 28
 
31
-// ContainerInspectWithRaw returns the container information and its raw representation.
32
-func (cli *Client) ContainerInspectWithRaw(ctx context.Context, containerID string, getSize bool) (container.InspectResponse, []byte, error) {
29
+// ContainerInspect returns the container information.
30
+func (cli *Client) ContainerInspect(ctx context.Context, containerID string, options ContainerInspectOptions) (ContainerInspectResult, error) {
33 31
 	containerID, err := trimID("container", containerID)
34 32
 	if err != nil {
35
-		return container.InspectResponse{}, nil, err
33
+		return ContainerInspectResult{}, err
36 34
 	}
37 35
 
38 36
 	query := url.Values{}
39
-	if getSize {
37
+	if options.Size {
40 38
 		query.Set("size", "1")
41 39
 	}
42 40
 	resp, err := cli.get(ctx, "/containers/"+containerID+"/json", query, nil)
43
-	defer ensureReaderClosed(resp)
44
-	if err != nil {
45
-		return container.InspectResponse{}, nil, err
46
-	}
47
-
48
-	body, err := io.ReadAll(resp.Body)
49 41
 	if err != nil {
50
-		return container.InspectResponse{}, nil, err
42
+		return ContainerInspectResult{}, err
51 43
 	}
52
-
53
-	var response container.InspectResponse
54
-	rdr := bytes.NewReader(body)
55
-	err = json.NewDecoder(rdr).Decode(&response)
56
-	return response, body, err
44
+	var out ContainerInspectResult
45
+	out.Raw, err = decodeWithRaw(resp, &out.Container)
46
+	return out, err
57 47
 }
... ...
@@ -1,7 +1,6 @@
1 1
 package client
2 2
 
3 3
 import (
4
-	"context"
5 4
 	"errors"
6 5
 	"net/http"
7 6
 	"testing"
... ...
@@ -18,14 +17,14 @@ func TestContainerInspectError(t *testing.T) {
18 18
 	)
19 19
 	assert.NilError(t, err)
20 20
 
21
-	_, err = client.ContainerInspect(context.Background(), "nothing")
21
+	_, err = client.ContainerInspect(t.Context(), "nothing", ContainerInspectOptions{})
22 22
 	assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal))
23 23
 
24
-	_, err = client.ContainerInspect(context.Background(), "")
24
+	_, err = client.ContainerInspect(t.Context(), "", ContainerInspectOptions{})
25 25
 	assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
26 26
 	assert.Check(t, is.ErrorContains(err, "value is empty"))
27 27
 
28
-	_, err = client.ContainerInspect(context.Background(), "    ")
28
+	_, err = client.ContainerInspect(t.Context(), "    ", ContainerInspectOptions{})
29 29
 	assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
30 30
 	assert.Check(t, is.ErrorContains(err, "value is empty"))
31 31
 }
... ...
@@ -36,7 +35,7 @@ func TestContainerInspectContainerNotFound(t *testing.T) {
36 36
 	)
37 37
 	assert.NilError(t, err)
38 38
 
39
-	_, err = client.ContainerInspect(context.Background(), "unknown")
39
+	_, err = client.ContainerInspect(t.Context(), "unknown", ContainerInspectOptions{})
40 40
 	assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound))
41 41
 }
42 42
 
... ...
@@ -48,19 +47,11 @@ func TestContainerInspectWithEmptyID(t *testing.T) {
48 48
 	)
49 49
 	assert.NilError(t, err)
50 50
 
51
-	_, err = client.ContainerInspect(context.Background(), "")
51
+	_, err = client.ContainerInspect(t.Context(), "", ContainerInspectOptions{})
52 52
 	assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
53 53
 	assert.Check(t, is.ErrorContains(err, "value is empty"))
54 54
 
55
-	_, err = client.ContainerInspect(context.Background(), "    ")
56
-	assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
57
-	assert.Check(t, is.ErrorContains(err, "value is empty"))
58
-
59
-	_, _, err = client.ContainerInspectWithRaw(context.Background(), "", false)
60
-	assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
61
-	assert.Check(t, is.ErrorContains(err, "value is empty"))
62
-
63
-	_, _, err = client.ContainerInspectWithRaw(context.Background(), "    ", false)
55
+	_, err = client.ContainerInspect(t.Context(), "    ", ContainerInspectOptions{})
64 56
 	assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
65 57
 	assert.Check(t, is.ErrorContains(err, "value is empty"))
66 58
 }
... ...
@@ -81,9 +72,9 @@ func TestContainerInspect(t *testing.T) {
81 81
 	)
82 82
 	assert.NilError(t, err)
83 83
 
84
-	r, err := client.ContainerInspect(context.Background(), "container_id")
84
+	res, err := client.ContainerInspect(t.Context(), "container_id", ContainerInspectOptions{})
85 85
 	assert.NilError(t, err)
86
-	assert.Check(t, is.Equal(r.ID, "container_id"))
87
-	assert.Check(t, is.Equal(r.Image, "image"))
88
-	assert.Check(t, is.Equal(r.Name, "name"))
86
+	assert.Check(t, is.Equal(res.Container.ID, "container_id"))
87
+	assert.Check(t, is.Equal(res.Container.Image, "image"))
88
+	assert.Check(t, is.Equal(res.Container.Name, "name"))
89 89
 }
... ...
@@ -593,10 +593,10 @@ func UtilCreateNetworkMode(t *testing.T, networkMode container.NetworkMode) {
593 593
 	})
594 594
 	assert.NilError(t, err)
595 595
 
596
-	containerJSON, err := apiClient.ContainerInspect(testutil.GetContext(t), ctr.ID)
596
+	res, err := apiClient.ContainerInspect(testutil.GetContext(t), ctr.ID, client.ContainerInspectOptions{})
597 597
 	assert.NilError(t, err)
598 598
 
599
-	assert.Equal(t, containerJSON.HostConfig.NetworkMode, networkMode, "Mismatched NetworkMode")
599
+	assert.Equal(t, res.Container.HostConfig.NetworkMode, networkMode, "Mismatched NetworkMode")
600 600
 }
601 601
 
602 602
 func (s *DockerAPISuite) TestContainerAPICreateWithCpuSharesCpuset(c *testing.T) {
... ...
@@ -624,13 +624,13 @@ func (s *DockerAPISuite) TestContainerAPICreateWithCpuSharesCpuset(c *testing.T)
624 624
 	})
625 625
 	assert.NilError(c, err)
626 626
 
627
-	containerJSON, err := apiClient.ContainerInspect(testutil.GetContext(c), ctr.ID)
627
+	res, err := apiClient.ContainerInspect(testutil.GetContext(c), ctr.ID, client.ContainerInspectOptions{})
628 628
 	assert.NilError(c, err)
629 629
 
630
-	out := inspectField(c, containerJSON.ID, "HostConfig.CpuShares")
630
+	out := inspectField(c, res.Container.ID, "HostConfig.CpuShares")
631 631
 	assert.Equal(c, out, "512")
632 632
 
633
-	outCpuset := inspectField(c, containerJSON.ID, "HostConfig.CpusetCpus")
633
+	outCpuset := inspectField(c, res.Container.ID, "HostConfig.CpusetCpus")
634 634
 	assert.Equal(c, outCpuset, "0")
635 635
 }
636 636
 
... ...
@@ -913,10 +913,10 @@ func (s *DockerAPISuite) TestContainerAPIDeleteRemoveVolume(c *testing.T) {
913 913
 	assert.NilError(c, err)
914 914
 	defer apiClient.Close()
915 915
 
916
-	ctrInspect, err := apiClient.ContainerInspect(testutil.GetContext(c), id)
916
+	res, err := apiClient.ContainerInspect(testutil.GetContext(c), id, client.ContainerInspectOptions{})
917 917
 	assert.NilError(c, err)
918
-	assert.Assert(c, is.Len(ctrInspect.Mounts, 1), "expected to have 1 mount")
919
-	mnt := ctrInspect.Mounts[0]
918
+	assert.Assert(c, is.Len(res.Container.Mounts, 1), "expected to have 1 mount")
919
+	mnt := res.Container.Mounts[0]
920 920
 	assert.Equal(c, mnt.Destination, testVol)
921 921
 
922 922
 	_, err = os.Stat(mnt.Source)
... ...
@@ -949,7 +949,7 @@ func (s *DockerAPISuite) TestContainerAPIChunkedEncoding(c *testing.T) {
949 949
 		req.ContentLength = -1
950 950
 		return nil
951 951
 	}))
952
-	assert.Assert(c, err == nil, "error creating container with chunked encoding")
952
+	assert.NilError(c, err, "error creating container with chunked encoding")
953 953
 	defer resp.Body.Close()
954 954
 	assert.Equal(c, resp.StatusCode, http.StatusCreated)
955 955
 }
... ...
@@ -1057,10 +1057,10 @@ func (s *DockerAPISuite) TestPostContainersCreateMemorySwappinessHostConfigOmitt
1057 1057
 	})
1058 1058
 	assert.NilError(c, err)
1059 1059
 
1060
-	containerJSON, err := apiClient.ContainerInspect(testutil.GetContext(c), ctr.ID)
1060
+	res, err := apiClient.ContainerInspect(testutil.GetContext(c), ctr.ID, client.ContainerInspectOptions{})
1061 1061
 	assert.NilError(c, err)
1062 1062
 
1063
-	assert.Assert(c, is.Nil(containerJSON.HostConfig.MemorySwappiness))
1063
+	assert.Assert(c, is.Nil(res.Container.HostConfig.MemorySwappiness))
1064 1064
 }
1065 1065
 
1066 1066
 // check validation is done daemon side and not only in cli
... ...
@@ -1660,9 +1660,9 @@ func (s *DockerAPISuite) TestContainersAPICreateMountsCreate(c *testing.T) {
1660 1660
 				})
1661 1661
 			assert.NilError(c, err)
1662 1662
 
1663
-			containerInspect, err := apiclient.ContainerInspect(ctx, ctr.ID)
1663
+			res, err := apiclient.ContainerInspect(ctx, ctr.ID, client.ContainerInspectOptions{})
1664 1664
 			assert.NilError(c, err)
1665
-			mps := containerInspect.Mounts
1665
+			mps := res.Container.Mounts
1666 1666
 			assert.Assert(c, is.Len(mps, 1))
1667 1667
 			mountPoint := mps[0]
1668 1668
 
... ...
@@ -1713,13 +1713,13 @@ func (s *DockerAPISuite) TestContainersAPICreateMountsCreate(c *testing.T) {
1713 1713
 
1714 1714
 func containerExit(ctx context.Context, apiclient client.APIClient, name string) func(poll.LogT) poll.Result {
1715 1715
 	return func(logT poll.LogT) poll.Result {
1716
-		ctr, err := apiclient.ContainerInspect(ctx, name)
1716
+		res, err := apiclient.ContainerInspect(ctx, name, client.ContainerInspectOptions{})
1717 1717
 		if err != nil {
1718 1718
 			return poll.Error(err)
1719 1719
 		}
1720
-		switch ctr.State.Status {
1720
+		switch s := res.Container.State.Status; s {
1721 1721
 		case container.StateCreated, container.StateRunning:
1722
-			return poll.Continue("container %s is %s, waiting for exit", name, ctr.State.Status)
1722
+			return poll.Continue("container %s is %s, waiting for exit", name, s)
1723 1723
 		case container.StatePaused, container.StateRestarting, container.StateRemoving, container.StateExited, container.StateDead:
1724 1724
 			// done
1725 1725
 		}
... ...
@@ -10,6 +10,7 @@ import (
10 10
 	"strings"
11 11
 	"testing"
12 12
 
13
+	"github.com/moby/moby/client"
13 14
 	"github.com/moby/moby/v2/integration-cli/cli"
14 15
 	"github.com/moby/moby/v2/internal/testutil"
15 16
 	"gotest.tools/v3/assert"
... ...
@@ -190,14 +191,14 @@ func assertPortList(t *testing.T, out string, expected []string) {
190 190
 }
191 191
 
192 192
 func assertPortRange(ctx context.Context, id string, expectedTCP, expectedUDP []int) error {
193
-	client := testEnv.APIClient()
194
-	inspect, err := client.ContainerInspect(ctx, id)
193
+	apiClient := testEnv.APIClient()
194
+	res, err := apiClient.ContainerInspect(ctx, id, client.ContainerInspectOptions{})
195 195
 	if err != nil {
196 196
 		return err
197 197
 	}
198 198
 
199 199
 	var validTCP, validUDP bool
200
-	for port, binding := range inspect.NetworkSettings.Ports {
200
+	for port, binding := range res.Container.NetworkSettings.Ports {
201 201
 		if port.Proto() == "tcp" && len(expectedTCP) == 0 {
202 202
 			continue
203 203
 		}
... ...
@@ -3689,10 +3689,10 @@ func (s *DockerCLIRunSuite) TestRunNamedVolumesFromNotRemoved(c *testing.T) {
3689 3689
 	assert.NilError(c, err)
3690 3690
 	defer apiClient.Close()
3691 3691
 
3692
-	container, err := apiClient.ContainerInspect(testutil.GetContext(c), strings.TrimSpace(cid))
3692
+	inspect, err := apiClient.ContainerInspect(testutil.GetContext(c), strings.TrimSpace(cid), client.ContainerInspectOptions{})
3693 3693
 	assert.NilError(c, err)
3694 3694
 	var vname string
3695
-	for _, v := range container.Mounts {
3695
+	for _, v := range inspect.Container.Mounts {
3696 3696
 		if v.Name != "test" {
3697 3697
 			vname = v.Name
3698 3698
 		}
... ...
@@ -1560,9 +1560,9 @@ func (s *DockerCLIRunSuite) TestRunWithNanoCPUs(c *testing.T) {
1560 1560
 
1561 1561
 	clt, err := client.NewClientWithOpts(client.FromEnv)
1562 1562
 	assert.NilError(c, err)
1563
-	inspect, err := clt.ContainerInspect(testutil.GetContext(c), "test")
1563
+	res, err := clt.ContainerInspect(testutil.GetContext(c), "test", client.ContainerInspectOptions{})
1564 1564
 	assert.NilError(c, err)
1565
-	assert.Equal(c, inspect.HostConfig.NanoCPUs, int64(500000000))
1565
+	assert.Equal(c, res.Container.HostConfig.NanoCPUs, int64(500000000))
1566 1566
 
1567 1567
 	out = inspectField(c, "test", "HostConfig.CpuQuota")
1568 1568
 	assert.Equal(c, out, "0", "CPU CFS quota should be 0")
... ...
@@ -266,9 +266,9 @@ func (s *DockerCLIUpdateSuite) TestUpdateWithNanoCPUs(c *testing.T) {
266 266
 
267 267
 	clt, err := client.NewClientWithOpts(client.FromEnv)
268 268
 	assert.NilError(c, err)
269
-	inspect, err := clt.ContainerInspect(testutil.GetContext(c), "top")
269
+	res, err := clt.ContainerInspect(testutil.GetContext(c), "top", client.ContainerInspectOptions{})
270 270
 	assert.NilError(c, err)
271
-	assert.Equal(c, inspect.HostConfig.NanoCPUs, int64(500000000))
271
+	assert.Equal(c, res.Container.HostConfig.NanoCPUs, int64(500000000))
272 272
 
273 273
 	out = inspectField(c, "top", "HostConfig.CpuQuota")
274 274
 	assert.Equal(c, out, "0", "CPU CFS quota should be 0")
... ...
@@ -280,9 +280,9 @@ func (s *DockerCLIUpdateSuite) TestUpdateWithNanoCPUs(c *testing.T) {
280 280
 	assert.Assert(c, is.Contains(out, "Conflicting options: CPU Quota cannot be updated as NanoCPUs has already been set"))
281 281
 
282 282
 	cli.DockerCmd(c, "update", "--cpus", "0.8", "top")
283
-	inspect, err = clt.ContainerInspect(testutil.GetContext(c), "top")
283
+	res, err = clt.ContainerInspect(testutil.GetContext(c), "top", client.ContainerInspectOptions{})
284 284
 	assert.NilError(c, err)
285
-	assert.Equal(c, inspect.HostConfig.NanoCPUs, int64(800000000))
285
+	assert.Equal(c, res.Container.HostConfig.NanoCPUs, int64(800000000))
286 286
 
287 287
 	out = inspectField(c, "top", "HostConfig.CpuQuota")
288 288
 	assert.Equal(c, out, "0", "CPU CFS quota should be 0")
... ...
@@ -251,14 +251,14 @@ func waitInspect(name, expr, expected string, timeout time.Duration) error {
251 251
 	return daemon.WaitInspectWithArgs(dockerBinary, name, expr, expected, timeout)
252 252
 }
253 253
 
254
-func getInspectBody(t *testing.T, version, id string) []byte {
254
+func getInspectBody(t *testing.T, version, id string) json.RawMessage {
255 255
 	t.Helper()
256 256
 	apiClient, err := client.NewClientWithOpts(client.FromEnv, client.WithVersion(version))
257 257
 	assert.NilError(t, err)
258 258
 	defer apiClient.Close()
259
-	_, body, err := apiClient.ContainerInspectWithRaw(testutil.GetContext(t), id, false)
259
+	inspect, err := apiClient.ContainerInspect(testutil.GetContext(t), id, client.ContainerInspectOptions{})
260 260
 	assert.NilError(t, err)
261
-	return body
261
+	return inspect.Raw
262 262
 }
263 263
 
264 264
 // Run a long running idle task in a background container using the
... ...
@@ -42,7 +42,7 @@ func TestCreateWithCDIDevices(t *testing.T) {
42 42
 	)
43 43
 	defer apiClient.ContainerRemove(ctx, id, client.ContainerRemoveOptions{Force: true})
44 44
 
45
-	inspect, err := apiClient.ContainerInspect(ctx, id)
45
+	res, err := apiClient.ContainerInspect(ctx, id, client.ContainerInspectOptions{})
46 46
 	assert.NilError(t, err)
47 47
 
48 48
 	expectedRequests := []containertypes.DeviceRequest{
... ...
@@ -51,7 +51,7 @@ func TestCreateWithCDIDevices(t *testing.T) {
51 51
 			DeviceIDs: []string{"vendor1.com/device=foo"},
52 52
 		},
53 53
 	}
54
-	assert.Check(t, is.DeepEqual(inspect.HostConfig.DeviceRequests, expectedRequests))
54
+	assert.Check(t, is.DeepEqual(res.Container.HostConfig.DeviceRequests, expectedRequests))
55 55
 
56 56
 	poll.WaitOn(t, container.IsStopped(ctx, apiClient, id))
57 57
 	reader, err := apiClient.ContainerLogs(ctx, id, client.ContainerLogsOptions{
... ...
@@ -73,9 +73,9 @@ func TestCheckpoint(t *testing.T) {
73 73
 	}
74 74
 	assert.NilError(t, err)
75 75
 
76
-	inspect, err := apiClient.ContainerInspect(ctx, cID)
76
+	inspect, err := apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
77 77
 	assert.NilError(t, err)
78
-	assert.Check(t, is.Equal(true, inspect.State.Running))
78
+	assert.Check(t, is.Equal(true, inspect.Container.State.Running))
79 79
 
80 80
 	res, err := apiClient.CheckpointList(ctx, cID, client.CheckpointListOptions{})
81 81
 	assert.NilError(t, err)
... ...
@@ -98,9 +98,9 @@ func TestCheckpoint(t *testing.T) {
98 98
 
99 99
 	poll.WaitOn(t, container.IsInState(ctx, apiClient, cID, containertypes.StateExited))
100 100
 
101
-	inspect, err = apiClient.ContainerInspect(ctx, cID)
101
+	inspect, err = apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
102 102
 	assert.NilError(t, err)
103
-	assert.Check(t, is.Equal(false, inspect.State.Running))
103
+	assert.Check(t, is.Equal(false, inspect.Container.State.Running))
104 104
 
105 105
 	// Check that both checkpoints are listed.
106 106
 	res, err = apiClient.CheckpointList(ctx, cID, client.CheckpointListOptions{})
... ...
@@ -121,9 +121,9 @@ func TestCheckpoint(t *testing.T) {
121 121
 	})
122 122
 	assert.NilError(t, err)
123 123
 
124
-	inspect, err = apiClient.ContainerInspect(ctx, cID)
124
+	inspect, err = apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
125 125
 	assert.NilError(t, err)
126
-	assert.Check(t, is.Equal(true, inspect.State.Running))
126
+	assert.Check(t, is.Equal(true, inspect.Container.State.Running))
127 127
 
128 128
 	// Check that the test file has been restored.
129 129
 	cmd = []string{"test", "-f", "/tmp/test-file"}
... ...
@@ -295,9 +295,9 @@ func TestCreateWithCustomMaskedPaths(t *testing.T) {
295 295
 			})
296 296
 			assert.NilError(t, err)
297 297
 
298
-			ctrInspect, err := apiClient.ContainerInspect(ctx, ctr.ID)
298
+			inspect, err := apiClient.ContainerInspect(ctx, ctr.ID, client.ContainerInspectOptions{})
299 299
 			assert.NilError(t, err)
300
-			assert.DeepEqual(t, ctrInspect.HostConfig.MaskedPaths, tc.expected)
300
+			assert.DeepEqual(t, inspect.Container.HostConfig.MaskedPaths, tc.expected)
301 301
 
302 302
 			// Start the container.
303 303
 			err = apiClient.ContainerStart(ctx, ctr.ID, client.ContainerStartOptions{})
... ...
@@ -307,9 +307,9 @@ func TestCreateWithCustomMaskedPaths(t *testing.T) {
307 307
 			err = apiClient.ContainerStop(ctx, ctr.ID, client.ContainerStopOptions{})
308 308
 			assert.NilError(t, err)
309 309
 
310
-			ctrInspect, err = apiClient.ContainerInspect(ctx, ctr.ID)
310
+			inspect, err = apiClient.ContainerInspect(ctx, ctr.ID, client.ContainerInspectOptions{})
311 311
 			assert.NilError(t, err)
312
-			assert.DeepEqual(t, ctrInspect.HostConfig.MaskedPaths, tc.expected)
312
+			assert.DeepEqual(t, inspect.Container.HostConfig.MaskedPaths, tc.expected)
313 313
 		})
314 314
 	}
315 315
 }
... ...
@@ -366,9 +366,9 @@ func TestCreateWithCustomReadonlyPaths(t *testing.T) {
366 366
 			})
367 367
 			assert.NilError(t, err)
368 368
 
369
-			ctrInspect, err := apiClient.ContainerInspect(ctx, ctr.ID)
369
+			ctrInspect, err := apiClient.ContainerInspect(ctx, ctr.ID, client.ContainerInspectOptions{})
370 370
 			assert.NilError(t, err)
371
-			assert.DeepEqual(t, ctrInspect.HostConfig.ReadonlyPaths, tc.expected)
371
+			assert.DeepEqual(t, ctrInspect.Container.HostConfig.ReadonlyPaths, tc.expected)
372 372
 
373 373
 			// Start the container.
374 374
 			err = apiClient.ContainerStart(ctx, ctr.ID, client.ContainerStartOptions{})
... ...
@@ -378,9 +378,9 @@ func TestCreateWithCustomReadonlyPaths(t *testing.T) {
378 378
 			err = apiClient.ContainerStop(ctx, ctr.ID, client.ContainerStopOptions{})
379 379
 			assert.NilError(t, err)
380 380
 
381
-			ctrInspect, err = apiClient.ContainerInspect(ctx, ctr.ID)
381
+			ctrInspect, err = apiClient.ContainerInspect(ctx, ctr.ID, client.ContainerInspectOptions{})
382 382
 			assert.NilError(t, err)
383
-			assert.DeepEqual(t, ctrInspect.HostConfig.ReadonlyPaths, tc.expected)
383
+			assert.DeepEqual(t, ctrInspect.Container.HostConfig.ReadonlyPaths, tc.expected)
384 384
 		})
385 385
 	}
386 386
 }
... ...
@@ -492,11 +492,11 @@ func TestCreateTmpfsOverrideAnonymousVolume(t *testing.T) {
492 492
 		assert.NilError(t, err)
493 493
 	}()
494 494
 
495
-	inspect, err := apiClient.ContainerInspect(ctx, id)
495
+	inspect, err := apiClient.ContainerInspect(ctx, id, client.ContainerInspectOptions{})
496 496
 	assert.NilError(t, err)
497 497
 	// tmpfs do not currently get added to inspect.Mounts
498 498
 	// Normally an anonymous volume would, except now tmpfs should prevent that.
499
-	assert.Assert(t, is.Len(inspect.Mounts, 0))
499
+	assert.Assert(t, is.Len(inspect.Container.Mounts, 0))
500 500
 
501 501
 	chWait, chErr := apiClient.ContainerWait(ctx, id, container.WaitConditionNextExit)
502 502
 	assert.NilError(t, apiClient.ContainerStart(ctx, id, client.ContainerStartOptions{}))
... ...
@@ -52,15 +52,15 @@ func TestContainerStartOnDaemonRestart(t *testing.T) {
52 52
 	err := c.ContainerStart(ctx, cID, client.ContainerStartOptions{})
53 53
 	assert.Check(t, err, "error starting test container")
54 54
 
55
-	inspect, err := c.ContainerInspect(ctx, cID)
55
+	inspect, err := c.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
56 56
 	assert.Check(t, err, "error getting inspect data")
57 57
 
58
-	ppid := getContainerdShimPid(t, inspect)
58
+	ppid := getContainerdShimPid(t, inspect.Container)
59 59
 
60 60
 	err = d.Kill()
61 61
 	assert.Check(t, err, "failed to kill test daemon")
62 62
 
63
-	err = unix.Kill(inspect.State.Pid, unix.SIGKILL)
63
+	err = unix.Kill(inspect.Container.State.Pid, unix.SIGKILL)
64 64
 	assert.Check(t, err, "failed to kill container process")
65 65
 
66 66
 	err = unix.Kill(ppid, unix.SIGKILL)
... ...
@@ -107,25 +107,25 @@ func TestDaemonRestartIpcMode(t *testing.T) {
107 107
 	)
108 108
 	defer c.ContainerRemove(ctx, cID, client.ContainerRemoveOptions{Force: true})
109 109
 
110
-	inspect, err := c.ContainerInspect(ctx, cID)
110
+	inspect, err := c.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
111 111
 	assert.NilError(t, err)
112
-	assert.Check(t, is.Equal(string(inspect.HostConfig.IpcMode), "private"))
112
+	assert.Check(t, is.Equal(string(inspect.Container.HostConfig.IpcMode), "private"))
113 113
 
114 114
 	// restart the daemon with shareable default ipc mode
115 115
 	d.Restart(t, "--iptables=false", "--ip6tables=false", "--default-ipc-mode=shareable")
116 116
 
117 117
 	// check the container is still having private ipc mode
118
-	inspect, err = c.ContainerInspect(ctx, cID)
118
+	inspect, err = c.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
119 119
 	assert.NilError(t, err)
120
-	assert.Check(t, is.Equal(string(inspect.HostConfig.IpcMode), "private"))
120
+	assert.Check(t, is.Equal(string(inspect.Container.HostConfig.IpcMode), "private"))
121 121
 
122 122
 	// check a new container is created with shareable ipc mode as per new daemon default
123 123
 	cID = container.Run(ctx, t, c)
124 124
 	defer c.ContainerRemove(ctx, cID, client.ContainerRemoveOptions{Force: true})
125 125
 
126
-	inspect, err = c.ContainerInspect(ctx, cID)
126
+	inspect, err = c.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
127 127
 	assert.NilError(t, err)
128
-	assert.Check(t, is.Equal(string(inspect.HostConfig.IpcMode), "shareable"))
128
+	assert.Check(t, is.Equal(string(inspect.Container.HostConfig.IpcMode), "shareable"))
129 129
 }
130 130
 
131 131
 // TestDaemonHostGatewayIP verifies that when a magic string "host-gateway" is passed
... ...
@@ -267,11 +267,11 @@ func TestHardRestartWhenContainerIsRunning(t *testing.T) {
267 267
 		ctx := testutil.StartSpan(ctx, t)
268 268
 		ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
269 269
 		defer cancel()
270
-		inspect, err := apiClient.ContainerInspect(ctx, noPolicy)
270
+		inspect, err := apiClient.ContainerInspect(ctx, noPolicy, client.ContainerInspectOptions{})
271 271
 		assert.NilError(t, err)
272
-		assert.Check(t, is.Equal(inspect.State.Status, containertypes.StateExited))
273
-		assert.Check(t, is.Equal(inspect.State.ExitCode, 255))
274
-		finishedAt, err := time.Parse(time.RFC3339Nano, inspect.State.FinishedAt)
272
+		assert.Check(t, is.Equal(inspect.Container.State.Status, containertypes.StateExited))
273
+		assert.Check(t, is.Equal(inspect.Container.State.ExitCode, 255))
274
+		finishedAt, err := time.Parse(time.RFC3339Nano, inspect.Container.State.FinishedAt)
275 275
 		if assert.Check(t, err) {
276 276
 			assert.Check(t, is.DeepEqual(finishedAt, time.Now(), opt.TimeWithThreshold(time.Minute)))
277 277
 		}
... ...
@@ -281,11 +281,11 @@ func TestHardRestartWhenContainerIsRunning(t *testing.T) {
281 281
 		ctx := testutil.StartSpan(ctx, t)
282 282
 		ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
283 283
 		defer cancel()
284
-		inspect, err := apiClient.ContainerInspect(ctx, onFailure)
284
+		inspect, err := apiClient.ContainerInspect(ctx, onFailure, client.ContainerInspectOptions{})
285 285
 		assert.NilError(t, err)
286
-		assert.Check(t, is.Equal(inspect.State.Status, containertypes.StateRunning))
287
-		assert.Check(t, is.Equal(inspect.State.ExitCode, 0))
288
-		finishedAt, err := time.Parse(time.RFC3339Nano, inspect.State.FinishedAt)
286
+		assert.Check(t, is.Equal(inspect.Container.State.Status, containertypes.StateRunning))
287
+		assert.Check(t, is.Equal(inspect.Container.State.ExitCode, 0))
288
+		finishedAt, err := time.Parse(time.RFC3339Nano, inspect.Container.State.FinishedAt)
289 289
 		if assert.Check(t, err) {
290 290
 			assert.Check(t, is.DeepEqual(finishedAt, time.Now(), opt.TimeWithThreshold(time.Minute)))
291 291
 		}
... ...
@@ -40,16 +40,16 @@ func TestContainerKillOnDaemonStart(t *testing.T) {
40 40
 		assert.NilError(t, err)
41 41
 	}()
42 42
 
43
-	inspect, err := apiClient.ContainerInspect(ctx, id)
43
+	inspect, err := apiClient.ContainerInspect(ctx, id, client.ContainerInspectOptions{})
44 44
 	assert.NilError(t, err)
45
-	assert.Assert(t, inspect.State.Running)
45
+	assert.Assert(t, inspect.Container.State.Running)
46 46
 
47 47
 	assert.NilError(t, d.Kill())
48 48
 	d.Start(t, "--iptables=false", "--ip6tables=false")
49 49
 
50
-	inspect, err = apiClient.ContainerInspect(ctx, id)
50
+	inspect, err = apiClient.ContainerInspect(ctx, id, client.ContainerInspectOptions{})
51 51
 	assert.Check(t, is.Nil(err))
52
-	assert.Assert(t, !inspect.State.Running)
52
+	assert.Assert(t, !inspect.Container.State.Running)
53 53
 }
54 54
 
55 55
 // When the daemon doesn't stop in a clean way (eg. it crashes, the host has a power failure, etc..), or if it's started
... ...
@@ -84,18 +84,18 @@ func TestNetworkStateCleanupOnDaemonStart(t *testing.T) {
84 84
 		assert.NilError(t, err)
85 85
 	}()
86 86
 
87
-	inspect, err := apiClient.ContainerInspect(ctx, cid)
87
+	inspect, err := apiClient.ContainerInspect(ctx, cid, client.ContainerInspectOptions{})
88 88
 	assert.NilError(t, err)
89
-	assert.Assert(t, inspect.NetworkSettings.SandboxID != "")
90
-	assert.Assert(t, inspect.NetworkSettings.SandboxKey != "")
91
-	assert.Assert(t, inspect.NetworkSettings.Ports[mappedPort] != nil)
89
+	assert.Assert(t, inspect.Container.NetworkSettings.SandboxID != "")
90
+	assert.Assert(t, inspect.Container.NetworkSettings.SandboxKey != "")
91
+	assert.Assert(t, inspect.Container.NetworkSettings.Ports[mappedPort] != nil)
92 92
 
93 93
 	assert.NilError(t, d.Kill())
94 94
 	d.Start(t)
95 95
 
96
-	inspect, err = apiClient.ContainerInspect(ctx, cid)
96
+	inspect, err = apiClient.ContainerInspect(ctx, cid, client.ContainerInspectOptions{})
97 97
 	assert.NilError(t, err)
98
-	assert.Assert(t, inspect.NetworkSettings.SandboxID == "")
99
-	assert.Assert(t, inspect.NetworkSettings.SandboxKey == "")
100
-	assert.Assert(t, is.Nil(inspect.NetworkSettings.Ports[mappedPort]))
98
+	assert.Assert(t, inspect.Container.NetworkSettings.SandboxID == "")
99
+	assert.Assert(t, inspect.Container.NetworkSettings.SandboxKey == "")
100
+	assert.Assert(t, is.Nil(inspect.Container.NetworkSettings.Ports[mappedPort]))
101 101
 }
... ...
@@ -131,13 +131,13 @@ func TestHealthStartInterval(t *testing.T) {
131 131
 		if ctxPoll.Err() != nil {
132 132
 			return poll.Error(ctxPoll.Err())
133 133
 		}
134
-		inspect, err := apiClient.ContainerInspect(ctxPoll, id)
134
+		inspect, err := apiClient.ContainerInspect(ctxPoll, id, client.ContainerInspectOptions{})
135 135
 		if err != nil {
136 136
 			return poll.Error(err)
137 137
 		}
138
-		if inspect.State.Health.Status != containertypes.Healthy {
139
-			if len(inspect.State.Health.Log) > 0 {
140
-				t.Log(inspect.State.Health.Log[len(inspect.State.Health.Log)-1])
138
+		if inspect.Container.State.Health.Status != containertypes.Healthy {
139
+			if len(inspect.Container.State.Health.Log) > 0 {
140
+				t.Log(inspect.Container.State.Health.Log[len(inspect.Container.State.Health.Log)-1])
141 141
 			}
142 142
 			return poll.Continue("waiting on container to be ready")
143 143
 		}
... ...
@@ -150,19 +150,19 @@ func TestHealthStartInterval(t *testing.T) {
150 150
 	dl, _ = ctxPoll.Deadline()
151 151
 
152 152
 	poll.WaitOn(t, func(log poll.LogT) poll.Result {
153
-		inspect, err := apiClient.ContainerInspect(ctxPoll, id)
153
+		inspect, err := apiClient.ContainerInspect(ctxPoll, id, client.ContainerInspectOptions{})
154 154
 		if err != nil {
155 155
 			return poll.Error(err)
156 156
 		}
157 157
 
158
-		hLen := len(inspect.State.Health.Log)
158
+		hLen := len(inspect.Container.State.Health.Log)
159 159
 		if hLen < 2 {
160 160
 			return poll.Continue("waiting for more healthcheck results")
161 161
 		}
162 162
 
163
-		h1 := inspect.State.Health.Log[hLen-1]
164
-		h2 := inspect.State.Health.Log[hLen-2]
165
-		if h1.Start.Sub(h2.Start) >= inspect.Config.Healthcheck.Interval {
163
+		h1 := inspect.Container.State.Health.Log[hLen-1]
164
+		h2 := inspect.Container.State.Health.Log[hLen-2]
165
+		if h1.Start.Sub(h2.Start) >= inspect.Container.Config.Healthcheck.Interval {
166 166
 			return poll.Success()
167 167
 		}
168 168
 		t.Log(h1.Start.Sub(h2.Start))
... ...
@@ -170,15 +170,15 @@ func TestHealthStartInterval(t *testing.T) {
170 170
 	}, poll.WithDelay(time.Second), poll.WithTimeout(time.Until(dl)))
171 171
 }
172 172
 
173
-func pollForHealthCheckLog(ctx context.Context, client client.APIClient, containerID string, expected string) func(log poll.LogT) poll.Result {
173
+func pollForHealthCheckLog(ctx context.Context, apiClient client.APIClient, containerID string, expected string) func(log poll.LogT) poll.Result {
174 174
 	return func(log poll.LogT) poll.Result {
175
-		inspect, err := client.ContainerInspect(ctx, containerID)
175
+		inspect, err := apiClient.ContainerInspect(ctx, containerID, client.ContainerInspectOptions{})
176 176
 		if err != nil {
177 177
 			return poll.Error(err)
178 178
 		}
179
-		healthChecksTotal := len(inspect.State.Health.Log)
179
+		healthChecksTotal := len(inspect.Container.State.Health.Log)
180 180
 		if healthChecksTotal > 0 {
181
-			output := inspect.State.Health.Log[healthChecksTotal-1].Output
181
+			output := inspect.Container.State.Health.Log[healthChecksTotal-1].Output
182 182
 			if output == expected {
183 183
 				return poll.Success()
184 184
 			}
... ...
@@ -188,14 +188,14 @@ func pollForHealthCheckLog(ctx context.Context, client client.APIClient, contain
188 188
 	}
189 189
 }
190 190
 
191
-func pollForHealthStatus(ctx context.Context, client client.APIClient, containerID string, healthStatus containertypes.HealthStatus) func(log poll.LogT) poll.Result {
191
+func pollForHealthStatus(ctx context.Context, apiClient client.APIClient, containerID string, healthStatus containertypes.HealthStatus) func(log poll.LogT) poll.Result {
192 192
 	return func(log poll.LogT) poll.Result {
193
-		inspect, err := client.ContainerInspect(ctx, containerID)
193
+		inspect, err := apiClient.ContainerInspect(ctx, containerID, client.ContainerInspectOptions{})
194 194
 
195 195
 		switch {
196 196
 		case err != nil:
197 197
 			return poll.Error(err)
198
-		case inspect.State.Health.Status == healthStatus:
198
+		case inspect.Container.State.Health.Status == healthStatus:
199 199
 			return poll.Success()
200 200
 		default:
201 201
 			return poll.Continue("waiting for container to become %s", healthStatus)
... ...
@@ -33,9 +33,9 @@ func TestInspectAnnotations(t *testing.T) {
33 33
 		},
34 34
 	)
35 35
 
36
-	inspect, err := apiClient.ContainerInspect(ctx, id)
36
+	inspect, err := apiClient.ContainerInspect(ctx, id, client.ContainerInspectOptions{})
37 37
 	assert.NilError(t, err)
38
-	assert.Check(t, is.DeepEqual(inspect.HostConfig.Annotations, annotations))
38
+	assert.Check(t, is.DeepEqual(inspect.Container.HostConfig.Annotations, annotations))
39 39
 }
40 40
 
41 41
 // TestNetworkAliasesAreEmpty verifies that network-scoped aliases are not set
... ...
@@ -165,12 +165,14 @@ func TestContainerInspectWithRaw(t *testing.T) {
165 165
 	}
166 166
 	for _, tc := range tests {
167 167
 		t.Run(tc.doc, func(t *testing.T) {
168
-			ctrInspect, raw, err := apiClient.ContainerInspectWithRaw(ctx, ctrID, tc.withSize)
168
+			inspect, err := apiClient.ContainerInspect(ctx, ctrID, client.ContainerInspectOptions{
169
+				Size: tc.withSize,
170
+			})
169 171
 			assert.NilError(t, err)
170
-			assert.Check(t, is.Equal(ctrInspect.ID, ctrID))
172
+			assert.Check(t, is.Equal(inspect.Container.ID, ctrID))
171 173
 
172 174
 			var rawInspect map[string]any
173
-			err = json.Unmarshal(raw, &rawInspect)
175
+			err = json.Unmarshal(inspect.Raw, &rawInspect)
174 176
 			assert.NilError(t, err, "Should produce valid JSON")
175 177
 
176 178
 			if tc.withSize {
... ...
@@ -179,12 +181,12 @@ func TestContainerInspectWithRaw(t *testing.T) {
179 179
 					// See https://github.com/moby/moby/blob/2837112c8ead55cdad36eaac61bafc713b4f669a/daemon/images/image_windows.go#L12-L16
180 180
 					t.Log("skip checking SizeRw, SizeRootFs on windows as it's not yet implemented")
181 181
 				} else {
182
-					if assert.Check(t, ctrInspect.SizeRw != nil) {
182
+					if assert.Check(t, inspect.Container.SizeRw != nil) {
183 183
 						// RW-layer size can be zero.
184
-						assert.Check(t, *ctrInspect.SizeRw >= 0, "Should have a size: %d", *ctrInspect.SizeRw)
184
+						assert.Check(t, *inspect.Container.SizeRw >= 0, "Should have a size: %d", *inspect.Container.SizeRw)
185 185
 					}
186
-					if assert.Check(t, ctrInspect.SizeRootFs != nil) {
187
-						assert.Check(t, *ctrInspect.SizeRootFs > 0, "Should have a size: %d", *ctrInspect.SizeRootFs)
186
+					if assert.Check(t, inspect.Container.SizeRootFs != nil) {
187
+						assert.Check(t, *inspect.Container.SizeRootFs > 0, "Should have a size: %d", *inspect.Container.SizeRootFs)
188 188
 					}
189 189
 				}
190 190
 
... ...
@@ -193,12 +195,12 @@ func TestContainerInspectWithRaw(t *testing.T) {
193 193
 				_, ok = rawInspect["SizeRootFs"]
194 194
 				assert.Check(t, ok)
195 195
 			} else {
196
-				assert.Check(t, is.Nil(ctrInspect.SizeRw))
197
-				assert.Check(t, is.Nil(ctrInspect.SizeRootFs))
196
+				assert.Check(t, is.Nil(inspect.Container.SizeRw))
197
+				assert.Check(t, is.Nil(inspect.Container.SizeRootFs))
198 198
 				_, ok := rawInspect["SizeRw"]
199
-				assert.Check(t, !ok, "Should not contain SizeRw:\n%s", string(raw))
199
+				assert.Check(t, !ok, "Should not contain SizeRw:\n%s", string(inspect.Raw))
200 200
 				_, ok = rawInspect["SizeRootFs"]
201
-				assert.Check(t, !ok, "Should not contain SizeRootFs:\n%s", string(raw))
201
+				assert.Check(t, !ok, "Should not contain SizeRootFs:\n%s", string(inspect.Raw))
202 202
 			}
203 203
 		})
204 204
 	}
... ...
@@ -323,15 +323,15 @@ func TestIpcModeOlderClient(t *testing.T) {
323 323
 	// pre-check: default ipc mode in daemon is private
324 324
 	cID := container.Create(ctx, t, apiClient, container.WithAutoRemove)
325 325
 
326
-	inspect, err := apiClient.ContainerInspect(ctx, cID)
326
+	inspect, err := apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
327 327
 	assert.NilError(t, err)
328
-	assert.Check(t, is.Equal(string(inspect.HostConfig.IpcMode), "private"))
328
+	assert.Check(t, is.Equal(string(inspect.Container.HostConfig.IpcMode), "private"))
329 329
 
330 330
 	// main check: using older client creates "shareable" container
331 331
 	apiClient = request.NewAPIClient(t, client.WithVersion("1.39"))
332 332
 	cID = container.Create(ctx, t, apiClient, container.WithAutoRemove)
333 333
 
334
-	inspect, err = apiClient.ContainerInspect(ctx, cID)
334
+	inspect, err = apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
335 335
 	assert.NilError(t, err)
336
-	assert.Check(t, is.Equal(string(inspect.HostConfig.IpcMode), "shareable"))
336
+	assert.Check(t, is.Equal(string(inspect.Container.HostConfig.IpcMode), "shareable"))
337 337
 }
... ...
@@ -5,6 +5,7 @@ import (
5 5
 	"testing"
6 6
 
7 7
 	containertypes "github.com/moby/moby/api/types/container"
8
+	"github.com/moby/moby/client"
8 9
 	"github.com/moby/moby/v2/integration/internal/container"
9 10
 	"github.com/moby/moby/v2/internal/testutil"
10 11
 	"github.com/moby/moby/v2/internal/testutil/request"
... ...
@@ -160,9 +161,9 @@ func TestInspectOomKilledTrue(t *testing.T) {
160 160
 
161 161
 	poll.WaitOn(t, container.IsInState(ctx, apiClient, cID, containertypes.StateExited))
162 162
 
163
-	inspect, err := apiClient.ContainerInspect(ctx, cID)
163
+	inspect, err := apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
164 164
 	assert.NilError(t, err)
165
-	assert.Check(t, is.Equal(true, inspect.State.OOMKilled))
165
+	assert.Check(t, is.Equal(true, inspect.Container.State.OOMKilled))
166 166
 }
167 167
 
168 168
 func TestInspectOomKilledFalse(t *testing.T) {
... ...
@@ -175,7 +176,7 @@ func TestInspectOomKilledFalse(t *testing.T) {
175 175
 
176 176
 	poll.WaitOn(t, container.IsInState(ctx, apiClient, cID, containertypes.StateExited))
177 177
 
178
-	inspect, err := apiClient.ContainerInspect(ctx, cID)
178
+	inspect, err := apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
179 179
 	assert.NilError(t, err)
180
-	assert.Check(t, is.Equal(false, inspect.State.OOMKilled))
180
+	assert.Check(t, is.Equal(false, inspect.Container.State.OOMKilled))
181 181
 }
... ...
@@ -207,15 +207,15 @@ func TestMountDaemonRoot(t *testing.T) {
207 207
 						}
208 208
 					}()
209 209
 
210
-					inspect, err := apiClient.ContainerInspect(ctx, c.ID)
210
+					inspect, err := apiClient.ContainerInspect(ctx, c.ID, client.ContainerInspectOptions{})
211 211
 					if err != nil {
212 212
 						t.Fatal(err)
213 213
 					}
214
-					if len(inspect.Mounts) != 1 {
215
-						t.Fatalf("unexpected number of mounts: %+v", inspect.Mounts)
214
+					if len(inspect.Container.Mounts) != 1 {
215
+						t.Fatalf("unexpected number of mounts: %+v", inspect.Container.Mounts)
216 216
 					}
217 217
 
218
-					m := inspect.Mounts[0]
218
+					m := inspect.Container.Mounts[0]
219 219
 					if m.Propagation != test.expected {
220 220
 						t.Fatalf("got unexpected propagation mode, expected %q, got: %v", test.expected, m.Propagation)
221 221
 					}
... ...
@@ -30,9 +30,9 @@ func TestPause(t *testing.T) {
30 30
 	err := apiClient.ContainerPause(ctx, cID)
31 31
 	assert.NilError(t, err)
32 32
 
33
-	inspect, err := apiClient.ContainerInspect(ctx, cID)
33
+	inspect, err := apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
34 34
 	assert.NilError(t, err)
35
-	assert.Check(t, is.Equal(true, inspect.State.Paused))
35
+	assert.Check(t, is.Equal(true, inspect.Container.State.Paused))
36 36
 
37 37
 	err = apiClient.ContainerUnpause(ctx, cID)
38 38
 	assert.NilError(t, err)
... ...
@@ -44,7 +44,7 @@ func TestRemoveContainerWithRemovedVolume(t *testing.T) {
44 44
 	})
45 45
 	assert.NilError(t, err)
46 46
 
47
-	_, err = apiClient.ContainerInspect(ctx, cID)
47
+	_, err = apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
48 48
 	assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound))
49 49
 	assert.Check(t, is.ErrorContains(err, "No such container"))
50 50
 }
... ...
@@ -58,10 +58,10 @@ func TestRemoveContainerWithVolume(t *testing.T) {
58 58
 
59 59
 	cID := container.Run(ctx, t, apiClient, container.WithVolume(prefix+slash+"srv"))
60 60
 
61
-	ctrInspect, err := apiClient.ContainerInspect(ctx, cID)
61
+	inspect, err := apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
62 62
 	assert.NilError(t, err)
63
-	assert.Check(t, is.Equal(1, len(ctrInspect.Mounts)))
64
-	volName := ctrInspect.Mounts[0].Name
63
+	assert.Check(t, is.Equal(1, len(inspect.Container.Mounts)))
64
+	volName := inspect.Container.Mounts[0].Name
65 65
 
66 66
 	_, err = apiClient.VolumeInspect(ctx, volName, client.VolumeInspectOptions{})
67 67
 	assert.NilError(t, err)
... ...
@@ -37,9 +37,9 @@ func TestRenameLinkedContainer(t *testing.T) {
37 37
 
38 38
 	bID = container.Run(ctx, t, apiClient, container.WithName(bName), container.WithLinks(aName))
39 39
 
40
-	inspect, err := apiClient.ContainerInspect(ctx, bID)
40
+	inspect, err := apiClient.ContainerInspect(ctx, bID, client.ContainerInspectOptions{})
41 41
 	assert.NilError(t, err)
42
-	assert.Check(t, is.DeepEqual([]string{"/" + aName + ":/" + bName + "/" + aName}, inspect.HostConfig.Links))
42
+	assert.Check(t, is.DeepEqual([]string{"/" + aName + ":/" + bName + "/" + aName}, inspect.Container.HostConfig.Links))
43 43
 }
44 44
 
45 45
 func TestRenameStoppedContainer(t *testing.T) {
... ...
@@ -49,17 +49,17 @@ func TestRenameStoppedContainer(t *testing.T) {
49 49
 	oldName := "first_name" + t.Name()
50 50
 	cID := container.Run(ctx, t, apiClient, container.WithName(oldName), container.WithCmd("sh"))
51 51
 
52
-	inspect, err := apiClient.ContainerInspect(ctx, cID)
52
+	inspect, err := apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
53 53
 	assert.NilError(t, err)
54
-	assert.Check(t, is.Equal("/"+oldName, inspect.Name))
54
+	assert.Check(t, is.Equal("/"+oldName, inspect.Container.Name))
55 55
 
56 56
 	newName := "new_name" + cID // using cID as random suffix
57 57
 	err = apiClient.ContainerRename(ctx, oldName, newName)
58 58
 	assert.NilError(t, err)
59 59
 
60
-	inspect, err = apiClient.ContainerInspect(ctx, cID)
60
+	inspect, err = apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
61 61
 	assert.NilError(t, err)
62
-	assert.Check(t, is.Equal("/"+newName, inspect.Name))
62
+	assert.Check(t, is.Equal("/"+newName, inspect.Container.Name))
63 63
 }
64 64
 
65 65
 func TestRenameRunningContainerAndReuse(t *testing.T) {
... ...
@@ -73,18 +73,18 @@ func TestRenameRunningContainerAndReuse(t *testing.T) {
73 73
 	err := apiClient.ContainerRename(ctx, oldName, newName)
74 74
 	assert.NilError(t, err)
75 75
 
76
-	inspect, err := apiClient.ContainerInspect(ctx, cID)
76
+	inspect, err := apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
77 77
 	assert.NilError(t, err)
78
-	assert.Check(t, is.Equal("/"+newName, inspect.Name))
78
+	assert.Check(t, is.Equal("/"+newName, inspect.Container.Name))
79 79
 
80
-	_, err = apiClient.ContainerInspect(ctx, oldName)
80
+	_, err = apiClient.ContainerInspect(ctx, oldName, client.ContainerInspectOptions{})
81 81
 	assert.Check(t, is.ErrorContains(err, "No such container: "+oldName))
82 82
 
83 83
 	cID = container.Run(ctx, t, apiClient, container.WithName(oldName))
84 84
 
85
-	inspect, err = apiClient.ContainerInspect(ctx, cID)
85
+	inspect, err = apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
86 86
 	assert.NilError(t, err)
87
-	assert.Check(t, is.Equal("/"+oldName, inspect.Name))
87
+	assert.Check(t, is.Equal("/"+oldName, inspect.Container.Name))
88 88
 }
89 89
 
90 90
 func TestRenameInvalidName(t *testing.T) {
... ...
@@ -97,9 +97,9 @@ func TestRenameInvalidName(t *testing.T) {
97 97
 	err := apiClient.ContainerRename(ctx, oldName, "new:invalid")
98 98
 	assert.Check(t, is.ErrorContains(err, "Invalid container name"))
99 99
 
100
-	inspect, err := apiClient.ContainerInspect(ctx, oldName)
100
+	inspect, err := apiClient.ContainerInspect(ctx, oldName, client.ContainerInspectOptions{})
101 101
 	assert.NilError(t, err)
102
-	assert.Check(t, is.Equal(cID, inspect.ID))
102
+	assert.Check(t, is.Equal(cID, inspect.Container.ID))
103 103
 }
104 104
 
105 105
 // Test case for GitHub issue 22466
... ...
@@ -146,9 +146,9 @@ func TestRenameAnonymousContainer(t *testing.T) {
146 146
 	}, container.WithCmd("ping", count, "1", container1Name))
147 147
 	poll.WaitOn(t, container.IsInState(ctx, apiClient, cID, containertypes.StateExited))
148 148
 
149
-	inspect, err := apiClient.ContainerInspect(ctx, cID)
149
+	inspect, err := apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
150 150
 	assert.NilError(t, err)
151
-	assert.Check(t, is.Equal(0, inspect.State.ExitCode), "container %s exited with the wrong exitcode: %s", cID, inspect.State.Error)
151
+	assert.Check(t, is.Equal(0, inspect.Container.State.ExitCode), "container %s exited with the wrong exitcode: %s", cID, inspect.Container.State.Error)
152 152
 }
153 153
 
154 154
 // TODO: should be a unit test
... ...
@@ -186,9 +186,9 @@ func TestRenameContainerWithLinkedContainer(t *testing.T) {
186 186
 	err := apiClient.ContainerRename(ctx, app1Name, app2Name)
187 187
 	assert.NilError(t, err)
188 188
 
189
-	inspect, err := apiClient.ContainerInspect(ctx, app2Name+"/mysql")
189
+	inspect, err := apiClient.ContainerInspect(ctx, app2Name+"/mysql", client.ContainerInspectOptions{})
190 190
 	assert.NilError(t, err)
191
-	assert.Check(t, is.Equal(db1ID, inspect.ID))
191
+	assert.Check(t, is.Equal(db1ID, inspect.Container.ID))
192 192
 }
193 193
 
194 194
 // Regression test for https://github.com/moby/moby/issues/47186
... ...
@@ -145,15 +145,15 @@ func TestDaemonRestartKillContainers(t *testing.T) {
145 145
 	}
146 146
 }
147 147
 
148
-func pollForNewHealthCheck(ctx context.Context, client *client.Client, startTime time.Time, containerID string) func(log poll.LogT) poll.Result {
148
+func pollForNewHealthCheck(ctx context.Context, apiClient *client.Client, startTime time.Time, containerID string) func(log poll.LogT) poll.Result {
149 149
 	return func(log poll.LogT) poll.Result {
150
-		inspect, err := client.ContainerInspect(ctx, containerID)
150
+		inspect, err := apiClient.ContainerInspect(ctx, containerID, client.ContainerInspectOptions{})
151 151
 		if err != nil {
152 152
 			return poll.Error(err)
153 153
 		}
154
-		healthChecksTotal := len(inspect.State.Health.Log)
154
+		healthChecksTotal := len(inspect.Container.State.Health.Log)
155 155
 		if healthChecksTotal > 0 {
156
-			if inspect.State.Health.Log[healthChecksTotal-1].Start.After(startTime) {
156
+			if inspect.Container.State.Health.Log[healthChecksTotal-1].Start.After(startTime) {
157 157
 				return poll.Success()
158 158
 			}
159 159
 		}
... ...
@@ -202,9 +202,9 @@ func TestContainerWithAutoRemoveCanBeRestarted(t *testing.T) {
202 202
 			err := apiClient.ContainerRestart(ctx, cID, client.ContainerStopOptions{Timeout: &noWaitTimeout})
203 203
 			assert.NilError(t, err)
204 204
 
205
-			inspect, err := apiClient.ContainerInspect(ctx, cID)
205
+			inspect, err := apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
206 206
 			assert.NilError(t, err)
207
-			assert.Assert(t, inspect.State.Status != container.StateRemoving, "Container should not be removing yet")
207
+			assert.Assert(t, inspect.Container.State.Status != container.StateRemoving, "Container should not be removing yet")
208 208
 
209 209
 			poll.WaitOn(t, testContainer.IsInState(ctx, apiClient, cID, container.StateRunning))
210 210
 
... ...
@@ -278,7 +278,7 @@ func TestContainerRestartWithCancelledRequest(t *testing.T) {
278 278
 	}
279 279
 
280 280
 	// Container should be restarted (running).
281
-	inspect, err := apiClient.ContainerInspect(ctx, cID)
281
+	inspect, err := apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
282 282
 	assert.NilError(t, err)
283
-	assert.Check(t, is.Equal(inspect.State.Status, container.StateRunning))
283
+	assert.Check(t, is.Equal(inspect.Container.State.Status, container.StateRunning))
284 284
 }
... ...
@@ -49,10 +49,10 @@ func TestNISDomainname(t *testing.T) {
49 49
 		c.Config.Hostname = hostname
50 50
 		c.Config.Domainname = domainname
51 51
 	})
52
-	inspect, err := apiClient.ContainerInspect(ctx, cID)
52
+	inspect, err := apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
53 53
 	assert.NilError(t, err)
54
-	assert.Check(t, is.Equal(hostname, inspect.Config.Hostname))
55
-	assert.Check(t, is.Equal(domainname, inspect.Config.Domainname))
54
+	assert.Check(t, is.Equal(hostname, inspect.Container.Config.Hostname))
55
+	assert.Check(t, is.Equal(domainname, inspect.Container.Config.Domainname))
56 56
 
57 57
 	// Check hostname.
58 58
 	res, err := container.Exec(ctx, apiClient, cID,
... ...
@@ -89,9 +89,9 @@ func TestHostnameDnsResolution(t *testing.T) {
89 89
 		c.Config.Hostname = hostname
90 90
 		c.HostConfig.NetworkMode = containertypes.NetworkMode(netName)
91 91
 	})
92
-	inspect, err := apiClient.ContainerInspect(ctx, cID)
92
+	inspect, err := apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
93 93
 	assert.NilError(t, err)
94
-	assert.Check(t, is.Equal(hostname, inspect.Config.Hostname))
94
+	assert.Check(t, is.Equal(hostname, inspect.Container.Config.Hostname))
95 95
 
96 96
 	// Clear hosts file so ping will use DNS for hostname resolution
97 97
 	res, err := container.Exec(ctx, apiClient, cID,
... ...
@@ -53,9 +53,9 @@ func TestStopContainerWithTimeoutCancel(t *testing.T) {
53 53
 	case <-time.After(5 * time.Second):
54 54
 		t.Fatal("timeout waiting for stop request to be cancelled")
55 55
 	}
56
-	inspect, err := apiClient.ContainerInspect(ctx, id)
56
+	inspect, err := apiClient.ContainerInspect(ctx, id, client.ContainerInspectOptions{})
57 57
 	assert.Check(t, err)
58
-	assert.Check(t, inspect.State.Running)
58
+	assert.Check(t, inspect.Container.State.Running)
59 59
 
60 60
 	// container should be stopped after stopTimeout is reached. The daemon.containerStop
61 61
 	// code is rather convoluted, and waits another 2 seconds for the container to
... ...
@@ -105,9 +105,9 @@ func TestStopContainerWithTimeout(t *testing.T) {
105 105
 
106 106
 			poll.WaitOn(t, container.IsStopped(ctx, apiClient, id), pollOpts...)
107 107
 
108
-			inspect, err := apiClient.ContainerInspect(ctx, id)
108
+			inspect, err := apiClient.ContainerInspect(ctx, id, client.ContainerInspectOptions{})
109 109
 			assert.NilError(t, err)
110
-			assert.Check(t, is.Equal(inspect.State.ExitCode, tc.expectedExitCode))
110
+			assert.Check(t, is.Equal(inspect.Container.State.ExitCode, tc.expectedExitCode))
111 111
 		})
112 112
 	}
113 113
 }
... ...
@@ -45,10 +45,10 @@ func TestUpdateMemory(t *testing.T) {
45 45
 	})
46 46
 	assert.NilError(t, err)
47 47
 
48
-	inspect, err := apiClient.ContainerInspect(ctx, cID)
48
+	inspect, err := apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
49 49
 	assert.NilError(t, err)
50
-	assert.Check(t, is.Equal(setMemory, inspect.HostConfig.Memory))
51
-	assert.Check(t, is.Equal(setMemorySwap, inspect.HostConfig.MemorySwap))
50
+	assert.Check(t, is.Equal(setMemory, inspect.Container.HostConfig.Memory))
51
+	assert.Check(t, is.Equal(setMemorySwap, inspect.Container.HostConfig.MemorySwap))
52 52
 
53 53
 	memoryFile := "/sys/fs/cgroup/memory/memory.limit_in_bytes"
54 54
 	if testEnv.DaemonInfo.CgroupVersion == "2" {
... ...
@@ -116,9 +116,9 @@ func TestUpdateCPUQuota(t *testing.T) {
116 116
 			assert.NilError(t, err)
117 117
 		}
118 118
 
119
-		inspect, err := apiClient.ContainerInspect(ctx, cID)
119
+		inspect, err := apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
120 120
 		assert.NilError(t, err)
121
-		assert.Check(t, is.Equal(test.update, inspect.HostConfig.CPUQuota))
121
+		assert.Check(t, is.Equal(test.update, inspect.Container.HostConfig.CPUQuota))
122 122
 
123 123
 		if testEnv.DaemonInfo.CgroupVersion == "2" {
124 124
 			res, err := container.Exec(ctx, apiClient, cID,
... ...
@@ -192,10 +192,10 @@ func TestUpdatePidsLimit(t *testing.T) {
192 192
 			})
193 193
 			assert.NilError(t, err)
194 194
 
195
-			inspect, err := c.ContainerInspect(ctx, cID)
195
+			inspect, err := c.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
196 196
 			assert.NilError(t, err)
197
-			assert.Assert(t, inspect.HostConfig.Resources.PidsLimit != nil)
198
-			assert.Equal(t, *inspect.HostConfig.Resources.PidsLimit, test.expect)
197
+			assert.Assert(t, inspect.Container.HostConfig.Resources.PidsLimit != nil)
198
+			assert.Equal(t, *inspect.Container.HostConfig.Resources.PidsLimit, test.expect)
199 199
 
200 200
 			ctx, cancel := context.WithTimeout(ctx, 60*time.Second)
201 201
 			defer cancel()
... ...
@@ -6,6 +6,7 @@ import (
6 6
 
7 7
 	cerrdefs "github.com/containerd/errdefs"
8 8
 	containertypes "github.com/moby/moby/api/types/container"
9
+	"github.com/moby/moby/client"
9 10
 	"github.com/moby/moby/v2/integration/internal/container"
10 11
 	"gotest.tools/v3/assert"
11 12
 	is "gotest.tools/v3/assert/cmp"
... ...
@@ -38,10 +39,10 @@ func TestUpdateRestartPolicy(t *testing.T) {
38 38
 
39 39
 	poll.WaitOn(t, container.IsInState(ctx, apiClient, cID, containertypes.StateExited), poll.WithTimeout(timeout))
40 40
 
41
-	inspect, err := apiClient.ContainerInspect(ctx, cID)
41
+	inspect, err := apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
42 42
 	assert.NilError(t, err)
43
-	assert.Check(t, is.Equal(inspect.RestartCount, 5))
44
-	assert.Check(t, is.Equal(inspect.HostConfig.RestartPolicy.MaximumRetryCount, 5))
43
+	assert.Check(t, is.Equal(inspect.Container.RestartCount, 5))
44
+	assert.Check(t, is.Equal(inspect.Container.HostConfig.RestartPolicy.MaximumRetryCount, 5))
45 45
 }
46 46
 
47 47
 func TestUpdateRestartWithAutoRemove(t *testing.T) {
... ...
@@ -158,8 +158,8 @@ func TestWaitConditions(t *testing.T) {
158 158
 			default:
159 159
 			}
160 160
 
161
-			info, _ := cli.ContainerInspect(ctx, containerID)
162
-			assert.Equal(t, info.State.Status, containertypes.StateRunning)
161
+			inspect, _ := cli.ContainerInspect(ctx, containerID, client.ContainerInspectOptions{})
162
+			assert.Equal(t, inspect.Container.State.Status, containertypes.StateRunning)
163 163
 
164 164
 			_, err = streams.Conn.Write([]byte("\n"))
165 165
 			assert.NilError(t, err)
... ...
@@ -170,8 +170,8 @@ func TestWaitConditions(t *testing.T) {
170 170
 			case waitRes := <-waitResC:
171 171
 				assert.Check(t, is.Equal(int64(99), waitRes.StatusCode))
172 172
 			case <-time.After(StopContainerWindowsPollTimeout):
173
-				ctr, _ := cli.ContainerInspect(ctx, containerID)
174
-				t.Fatalf("Timed out waiting for container exit code (status = %q)", ctr.State.Status)
173
+				ctr, _ := cli.ContainerInspect(ctx, containerID, client.ContainerInspectOptions{})
174
+				t.Fatalf("Timed out waiting for container exit code (status = %q)", ctr.Container.State.Status)
175 175
 			}
176 176
 		})
177 177
 	}
... ...
@@ -505,7 +505,7 @@ func testLiveRestoreAutoRemove(t *testing.T) {
505 505
 		d.Restart(t, "--live-restore", "--iptables=false", "--ip6tables=false")
506 506
 
507 507
 		apiClient := d.NewClientT(t)
508
-		_, err := apiClient.ContainerInspect(ctx, cID)
508
+		_, err := apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
509 509
 		assert.NilError(t, err, "Container shouldn't be removed after engine restart")
510 510
 
511 511
 		finishContainer()
... ...
@@ -518,9 +518,9 @@ func testLiveRestoreAutoRemove(t *testing.T) {
518 518
 		apiClient := d.NewClientT(t)
519 519
 
520 520
 		// Get PID of the container process.
521
-		inspect, err := apiClient.ContainerInspect(ctx, cID)
521
+		inspect, err := apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
522 522
 		assert.NilError(t, err)
523
-		pid := inspect.State.Pid
523
+		pid := inspect.Container.State.Pid
524 524
 
525 525
 		d.Stop(t)
526 526
 
... ...
@@ -639,9 +639,9 @@ func testLiveRestoreVolumeReferences(t *testing.T) {
639 639
 
640 640
 			poll.WaitOn(t, container.IsStopped(ctx, c, cID2))
641 641
 
642
-			inspect, err := c.ContainerInspect(ctx, cID2)
642
+			inspect, err := c.ContainerInspect(ctx, cID2, client.ContainerInspectOptions{})
643 643
 			if assert.Check(t, err) {
644
-				assert.Check(t, is.Equal(inspect.State.ExitCode, 0), "volume doesn't have the same file")
644
+				assert.Check(t, is.Equal(inspect.Container.State.ExitCode, 0), "volume doesn't have the same file")
645 645
 			}
646 646
 
647 647
 			logs, err := c.ContainerLogs(ctx, cID2, client.ContainerLogsOptions{ShowStdout: true})
... ...
@@ -84,10 +84,10 @@ func TestGraphDriverPersistence(t *testing.T) {
84 84
 	assert.Check(t, is.Equal(imageInspect.GraphDriver.Name, prevDriver), "Image graphdriver data should match")
85 85
 
86 86
 	// Verify our container is still there
87
-	containerInspect, err := c.ContainerInspect(ctx, containerID)
87
+	inspect, err := c.ContainerInspect(ctx, containerID, client.ContainerInspectOptions{})
88 88
 	assert.NilError(t, err, "Test container should still exist after daemon restart")
89
-	assert.Check(t, containerInspect.GraphDriver != nil, "GraphDriver should be set for graphdriver backend")
90
-	assert.Check(t, is.Equal(containerInspect.GraphDriver.Name, prevDriver), "Container graphdriver data should match")
89
+	assert.Check(t, inspect.Container.GraphDriver != nil, "GraphDriver should be set for graphdriver backend")
90
+	assert.Check(t, is.Equal(inspect.Container.GraphDriver.Name, prevDriver), "Container graphdriver data should match")
91 91
 }
92 92
 
93 93
 // TestInspectGraphDriverAPIBC checks API backward compatibility of the GraphDriver field in image/container inspect.
... ...
@@ -158,20 +158,20 @@ func TestInspectGraphDriverAPIBC(t *testing.T) {
158 158
 				}
159 159
 			}
160 160
 
161
-			if containerInspect, err := c.ContainerInspect(ctx, ctr.ID); assert.Check(t, err) {
161
+			if inspect, err := c.ContainerInspect(ctx, ctr.ID, client.ContainerInspectOptions{}); assert.Check(t, err) {
162 162
 				if tc.expGraphDriver != "" {
163
-					if assert.Check(t, containerInspect.GraphDriver != nil) {
164
-						assert.Check(t, is.Equal(containerInspect.GraphDriver.Name, tc.expGraphDriver))
163
+					if assert.Check(t, inspect.Container.GraphDriver != nil) {
164
+						assert.Check(t, is.Equal(inspect.Container.GraphDriver.Name, tc.expGraphDriver))
165 165
 					}
166 166
 				} else {
167
-					assert.Check(t, is.Nil(containerInspect.GraphDriver))
167
+					assert.Check(t, is.Nil(inspect.Container.GraphDriver))
168 168
 				}
169 169
 				if tc.expRootFSStorage {
170
-					assert.DeepEqual(t, containerInspect.Storage, &storage.Storage{
170
+					assert.DeepEqual(t, inspect.Container.Storage, &storage.Storage{
171 171
 						RootFS: &storage.RootFSStorage{Snapshot: &storage.RootFSStorageSnapshot{Name: "overlayfs"}},
172 172
 					})
173 173
 				} else {
174
-					assert.Check(t, is.Nil(containerInspect.Storage))
174
+					assert.Check(t, is.Nil(inspect.Container.Storage))
175 175
 				}
176 176
 			}
177 177
 		})
... ...
@@ -127,10 +127,10 @@ func RunAttach(ctx context.Context, t *testing.T, apiClient client.APIClient, op
127 127
 
128 128
 	// Inspect to get the exit code. A new context is used here to make sure that if the context passed as argument as
129 129
 	// reached timeout during the demultiplexStream call, we still return a RunResult.
130
-	resp, err := apiClient.ContainerInspect(context.Background(), id)
130
+	inspect, err := apiClient.ContainerInspect(context.Background(), id, client.ContainerInspectOptions{})
131 131
 	assert.NilError(t, err)
132 132
 
133
-	return RunResult{ContainerID: id, ExitCode: resp.State.ExitCode, Stdout: &s.stdout, Stderr: &s.stderr}
133
+	return RunResult{ContainerID: id, ExitCode: inspect.Container.State.ExitCode, Stdout: &s.stdout, Stderr: &s.stderr}
134 134
 }
135 135
 
136 136
 type streams struct {
... ...
@@ -187,10 +187,10 @@ func RemoveAll(ctx context.Context, t *testing.T, apiClient client.APIClient) {
187 187
 func Inspect(ctx context.Context, t *testing.T, apiClient client.APIClient, containerRef string) container.InspectResponse {
188 188
 	t.Helper()
189 189
 
190
-	c, err := apiClient.ContainerInspect(ctx, containerRef)
190
+	inspect, err := apiClient.ContainerInspect(ctx, containerRef, client.ContainerInspectOptions{})
191 191
 	assert.NilError(t, err)
192 192
 
193
-	return c
193
+	return inspect.Container
194 194
 }
195 195
 
196 196
 type ContainerOutput struct {
... ...
@@ -14,12 +14,12 @@ import (
14 14
 // RunningStateFlagIs polls for the container's Running state flag to be equal to running.
15 15
 func RunningStateFlagIs(ctx context.Context, apiClient client.APIClient, containerID string, running bool) func(log poll.LogT) poll.Result {
16 16
 	return func(log poll.LogT) poll.Result {
17
-		inspect, err := apiClient.ContainerInspect(ctx, containerID)
17
+		inspect, err := apiClient.ContainerInspect(ctx, containerID, client.ContainerInspectOptions{})
18 18
 
19 19
 		switch {
20 20
 		case err != nil:
21 21
 			return poll.Error(err)
22
-		case inspect.State.Running == running:
22
+		case inspect.Container.State.Running == running:
23 23
 			return poll.Success()
24 24
 		default:
25 25
 			return poll.Continue("waiting for container to be %s", map[bool]string{true: "running", false: "stopped"}[running])
... ...
@@ -35,19 +35,19 @@ func IsStopped(ctx context.Context, apiClient client.APIClient, containerID stri
35 35
 // IsInState verifies the container is in one of the specified state, e.g., "running", "exited", etc.
36 36
 func IsInState(ctx context.Context, apiClient client.APIClient, containerID string, state ...container.ContainerState) func(log poll.LogT) poll.Result {
37 37
 	return func(log poll.LogT) poll.Result {
38
-		inspect, err := apiClient.ContainerInspect(ctx, containerID)
38
+		inspect, err := apiClient.ContainerInspect(ctx, containerID, client.ContainerInspectOptions{})
39 39
 		if err != nil {
40 40
 			return poll.Error(err)
41 41
 		}
42 42
 		for _, v := range state {
43
-			if inspect.State.Status == v {
43
+			if inspect.Container.State.Status == v {
44 44
 				return poll.Success()
45 45
 			}
46 46
 		}
47 47
 		if len(state) == 1 {
48
-			return poll.Continue("waiting for container State.Status to be '%s', currently '%s'", state[0], inspect.State.Status)
48
+			return poll.Continue("waiting for container State.Status to be '%s', currently '%s'", state[0], inspect.Container.State.Status)
49 49
 		} else {
50
-			return poll.Continue("waiting for container State.Status to be one of (%s), currently '%s'", strings.Join(state, ", "), inspect.State.Status)
50
+			return poll.Continue("waiting for container State.Status to be one of (%s), currently '%s'", strings.Join(state, ", "), inspect.Container.State.Status)
51 51
 		}
52 52
 	}
53 53
 }
... ...
@@ -55,30 +55,30 @@ func IsInState(ctx context.Context, apiClient client.APIClient, containerID stri
55 55
 // IsSuccessful verifies state.Status == "exited" && state.ExitCode == 0
56 56
 func IsSuccessful(ctx context.Context, apiClient client.APIClient, containerID string) func(log poll.LogT) poll.Result {
57 57
 	return func(log poll.LogT) poll.Result {
58
-		inspect, err := apiClient.ContainerInspect(ctx, containerID)
58
+		inspect, err := apiClient.ContainerInspect(ctx, containerID, client.ContainerInspectOptions{})
59 59
 		if err != nil {
60 60
 			return poll.Error(err)
61 61
 		}
62
-		if inspect.State.Status == container.StateExited {
63
-			if inspect.State.ExitCode == 0 {
62
+		if inspect.Container.State.Status == container.StateExited {
63
+			if inspect.Container.State.ExitCode == 0 {
64 64
 				return poll.Success()
65 65
 			}
66
-			return poll.Error(errors.Errorf("expected exit code 0, got %d", inspect.State.ExitCode))
66
+			return poll.Error(errors.Errorf("expected exit code 0, got %d", inspect.Container.State.ExitCode))
67 67
 		}
68
-		return poll.Continue("waiting for container to be %q, currently %s", container.StateExited, inspect.State.Status)
68
+		return poll.Continue("waiting for container to be %q, currently %s", container.StateExited, inspect.Container.State.Status)
69 69
 	}
70 70
 }
71 71
 
72 72
 // IsRemoved verifies the container has been removed
73 73
 func IsRemoved(ctx context.Context, apiClient client.APIClient, containerID string) func(log poll.LogT) poll.Result {
74 74
 	return func(log poll.LogT) poll.Result {
75
-		inspect, err := apiClient.ContainerInspect(ctx, containerID)
75
+		inspect, err := apiClient.ContainerInspect(ctx, containerID, client.ContainerInspectOptions{})
76 76
 		if err != nil {
77 77
 			if cerrdefs.IsNotFound(err) {
78 78
 				return poll.Success()
79 79
 			}
80 80
 			return poll.Error(err)
81 81
 		}
82
-		return poll.Continue("waiting for container to be removed, currently %s", inspect.State.Status)
82
+		return poll.Continue("waiting for container to be removed, currently %s", inspect.Container.State.Status)
83 83
 	}
84 84
 }
... ...
@@ -531,9 +531,9 @@ func TestPublishedPortAlreadyInUse(t *testing.T) {
531 531
 	err := apiClient.ContainerStart(ctx, ctr2, client.ContainerStartOptions{})
532 532
 	assert.Assert(t, is.ErrorContains(err, "failed to set up container networking"))
533 533
 
534
-	inspect, err := apiClient.ContainerInspect(ctx, ctr2)
534
+	inspect, err := apiClient.ContainerInspect(ctx, ctr2, client.ContainerInspectOptions{})
535 535
 	assert.NilError(t, err)
536
-	assert.Check(t, is.Equal(inspect.State.Status, containertypes.StateCreated))
536
+	assert.Check(t, is.Equal(inspect.Container.State.Status, containertypes.StateCreated))
537 537
 }
538 538
 
539 539
 // TestAllPortMappingsAreReturned check that dual-stack ports mapped through
... ...
@@ -975,9 +975,9 @@ func TestEmptyPortBindingsBC(t *testing.T) {
975 975
 
976 976
 		// Inspect the container and return its port bindings, along with
977 977
 		// warnings returns on container create.
978
-		inspect, err := apiClient.ContainerInspect(ctx, c.ID)
978
+		inspect, err := apiClient.ContainerInspect(ctx, c.ID, client.ContainerInspectOptions{})
979 979
 		assert.NilError(t, err)
980
-		return inspect.HostConfig.PortBindings, c.Warnings
980
+		return inspect.Container.HostConfig.PortBindings, c.Warnings
981 981
 	}
982 982
 
983 983
 	t.Run("backfilling on old client version", func(t *testing.T) {
... ...
@@ -245,9 +245,9 @@ func testIpvlanL2MultiSubnetNoParent(t *testing.T, ctx context.Context, client d
245 245
 	testIpvlanL2MultiSubnet(t, ctx, client, "")
246 246
 }
247 247
 
248
-func testIpvlanL2MultiSubnet(t *testing.T, ctx context.Context, client dclient.APIClient, parent string) {
248
+func testIpvlanL2MultiSubnet(t *testing.T, ctx context.Context, apiClient dclient.APIClient, parent string) {
249 249
 	netName := "dualstackl2"
250
-	net.CreateNoError(ctx, t, client, netName,
250
+	net.CreateNoError(ctx, t, apiClient, netName,
251 251
 		net.WithIPvlan(parent, ""),
252 252
 		net.WithIPv6(),
253 253
 		net.WithIPAM("172.28.200.0/24", ""),
... ...
@@ -255,63 +255,63 @@ func testIpvlanL2MultiSubnet(t *testing.T, ctx context.Context, client dclient.A
255 255
 		net.WithIPAM("2001:db8:abc8::/64", ""),
256 256
 		net.WithIPAM("2001:db8:abc6::/64", "2001:db8:abc6::254"),
257 257
 	)
258
-	assert.Check(t, n.IsNetworkAvailable(ctx, client, netName))
258
+	assert.Check(t, n.IsNetworkAvailable(ctx, apiClient, netName))
259 259
 
260 260
 	// start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.100.0/24 and 2001:db8:abc2::/64
261
-	id1 := container.Run(ctx, t, client,
261
+	id1 := container.Run(ctx, t, apiClient,
262 262
 		container.WithNetworkMode(netName),
263 263
 		container.WithIPv4(netName, "172.28.200.20"),
264 264
 		container.WithIPv6(netName, "2001:db8:abc8::20"),
265 265
 	)
266
-	id2 := container.Run(ctx, t, client,
266
+	id2 := container.Run(ctx, t, apiClient,
267 267
 		container.WithNetworkMode(netName),
268 268
 		container.WithIPv4(netName, "172.28.200.21"),
269 269
 		container.WithIPv6(netName, "2001:db8:abc8::21"),
270 270
 	)
271
-	c1, err := client.ContainerInspect(ctx, id1)
271
+	c1, err := apiClient.ContainerInspect(ctx, id1, dclient.ContainerInspectOptions{})
272 272
 	assert.NilError(t, err)
273 273
 	// Inspect the v4 gateway to ensure no default GW was assigned
274
-	assert.Check(t, !c1.NetworkSettings.Networks[netName].Gateway.IsValid())
274
+	assert.Check(t, !c1.Container.NetworkSettings.Networks[netName].Gateway.IsValid())
275 275
 	// Inspect the v6 gateway to ensure no default GW was assigned
276
-	assert.Check(t, !c1.NetworkSettings.Networks[netName].IPv6Gateway.IsValid())
276
+	assert.Check(t, !c1.Container.NetworkSettings.Networks[netName].IPv6Gateway.IsValid())
277 277
 
278 278
 	// verify ipv4 connectivity to the explicit --ip address second to first
279
-	_, err = container.Exec(ctx, client, id2, []string{"ping", "-c", "1", c1.NetworkSettings.Networks[netName].IPAddress.String()})
279
+	_, err = container.Exec(ctx, apiClient, id2, []string{"ping", "-c", "1", c1.Container.NetworkSettings.Networks[netName].IPAddress.String()})
280 280
 	assert.NilError(t, err)
281 281
 	// verify ipv6 connectivity to the explicit --ip6 address second to first
282
-	_, err = container.Exec(ctx, client, id2, []string{"ping6", "-c", "1", c1.NetworkSettings.Networks[netName].GlobalIPv6Address.String()})
282
+	_, err = container.Exec(ctx, apiClient, id2, []string{"ping6", "-c", "1", c1.Container.NetworkSettings.Networks[netName].GlobalIPv6Address.String()})
283 283
 	assert.NilError(t, err)
284 284
 
285 285
 	// start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.102.0/24 and 2001:db8:abc4::/64
286
-	id3 := container.Run(ctx, t, client,
286
+	id3 := container.Run(ctx, t, apiClient,
287 287
 		container.WithNetworkMode(netName),
288 288
 		container.WithIPv4(netName, "172.28.202.20"),
289 289
 		container.WithIPv6(netName, "2001:db8:abc6::20"),
290 290
 	)
291
-	id4 := container.Run(ctx, t, client,
291
+	id4 := container.Run(ctx, t, apiClient,
292 292
 		container.WithNetworkMode(netName),
293 293
 		container.WithIPv4(netName, "172.28.202.21"),
294 294
 		container.WithIPv6(netName, "2001:db8:abc6::21"),
295 295
 	)
296
-	c3, err := client.ContainerInspect(ctx, id3)
296
+	c3, err := apiClient.ContainerInspect(ctx, id3, dclient.ContainerInspectOptions{})
297 297
 	assert.NilError(t, err)
298 298
 	if parent == "" {
299 299
 		// Inspect the v4 gateway to ensure no default GW was assigned
300
-		assert.Check(t, !c3.NetworkSettings.Networks[netName].Gateway.IsValid())
300
+		assert.Check(t, !c3.Container.NetworkSettings.Networks[netName].Gateway.IsValid())
301 301
 		// Inspect the v6 gateway to ensure no default GW was assigned
302
-		assert.Check(t, !c3.NetworkSettings.Networks[netName].IPv6Gateway.IsValid())
302
+		assert.Check(t, !c3.Container.NetworkSettings.Networks[netName].IPv6Gateway.IsValid())
303 303
 	} else {
304 304
 		// Inspect the v4 gateway to ensure the proper explicitly assigned default GW was assigned
305
-		assert.Check(t, is.Equal(c3.NetworkSettings.Networks[netName].Gateway, netip.MustParseAddr("172.28.202.254")))
305
+		assert.Check(t, is.Equal(c3.Container.NetworkSettings.Networks[netName].Gateway, netip.MustParseAddr("172.28.202.254")))
306 306
 		// Inspect the v6 gateway to ensure the proper explicitly assigned default GW was assigned
307
-		assert.Check(t, is.Equal(c3.NetworkSettings.Networks[netName].IPv6Gateway, netip.MustParseAddr("2001:db8:abc6::254")))
307
+		assert.Check(t, is.Equal(c3.Container.NetworkSettings.Networks[netName].IPv6Gateway, netip.MustParseAddr("2001:db8:abc6::254")))
308 308
 	}
309 309
 
310 310
 	// verify ipv4 connectivity to the explicit --ip address from third to fourth
311
-	_, err = container.Exec(ctx, client, id4, []string{"ping", "-c", "1", c3.NetworkSettings.Networks[netName].IPAddress.String()})
311
+	_, err = container.Exec(ctx, apiClient, id4, []string{"ping", "-c", "1", c3.Container.NetworkSettings.Networks[netName].IPAddress.String()})
312 312
 	assert.NilError(t, err)
313 313
 	// verify ipv6 connectivity to the explicit --ip6 address from third to fourth
314
-	_, err = container.Exec(ctx, client, id4, []string{"ping6", "-c", "1", c3.NetworkSettings.Networks[netName].GlobalIPv6Address.String()})
314
+	_, err = container.Exec(ctx, apiClient, id4, []string{"ping6", "-c", "1", c3.Container.NetworkSettings.Networks[netName].GlobalIPv6Address.String()})
315 315
 	assert.NilError(t, err)
316 316
 }
317 317
 
... ...
@@ -338,14 +338,14 @@ func testIpvlanL3MultiSubnet(t *testing.T, ctx context.Context, client dclient.A
338 338
 		container.WithIPv4(netName, "172.28.10.21"),
339 339
 		container.WithIPv6(netName, "2001:db8:abc9::21"),
340 340
 	)
341
-	c1, err := client.ContainerInspect(ctx, id1)
341
+	c1, err := client.ContainerInspect(ctx, id1, dclient.ContainerInspectOptions{})
342 342
 	assert.NilError(t, err)
343 343
 
344 344
 	// verify ipv4 connectivity to the explicit --ipv address second to first
345
-	_, err = container.Exec(ctx, client, id2, []string{"ping", "-c", "1", c1.NetworkSettings.Networks[netName].IPAddress.String()})
345
+	_, err = container.Exec(ctx, client, id2, []string{"ping", "-c", "1", c1.Container.NetworkSettings.Networks[netName].IPAddress.String()})
346 346
 	assert.NilError(t, err)
347 347
 	// verify ipv6 connectivity to the explicit --ipv6 address second to first
348
-	_, err = container.Exec(ctx, client, id2, []string{"ping6", "-c", "1", c1.NetworkSettings.Networks[netName].GlobalIPv6Address.String()})
348
+	_, err = container.Exec(ctx, client, id2, []string{"ping6", "-c", "1", c1.Container.NetworkSettings.Networks[netName].GlobalIPv6Address.String()})
349 349
 	assert.NilError(t, err)
350 350
 
351 351
 	// start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.102.0/24 and 2001:db8:abc4::/64
... ...
@@ -359,24 +359,24 @@ func testIpvlanL3MultiSubnet(t *testing.T, ctx context.Context, client dclient.A
359 359
 		container.WithIPv4(netName, "172.28.12.21"),
360 360
 		container.WithIPv6(netName, "2001:db8:abc7::21"),
361 361
 	)
362
-	c3, err := client.ContainerInspect(ctx, id3)
362
+	c3, err := client.ContainerInspect(ctx, id3, dclient.ContainerInspectOptions{})
363 363
 	assert.NilError(t, err)
364 364
 
365 365
 	// verify ipv4 connectivity to the explicit --ipv address from third to fourth
366
-	_, err = container.Exec(ctx, client, id4, []string{"ping", "-c", "1", c3.NetworkSettings.Networks[netName].IPAddress.String()})
366
+	_, err = container.Exec(ctx, client, id4, []string{"ping", "-c", "1", c3.Container.NetworkSettings.Networks[netName].IPAddress.String()})
367 367
 	assert.NilError(t, err)
368 368
 	// verify ipv6 connectivity to the explicit --ipv6 address from third to fourth
369
-	_, err = container.Exec(ctx, client, id4, []string{"ping6", "-c", "1", c3.NetworkSettings.Networks[netName].GlobalIPv6Address.String()})
369
+	_, err = container.Exec(ctx, client, id4, []string{"ping6", "-c", "1", c3.Container.NetworkSettings.Networks[netName].GlobalIPv6Address.String()})
370 370
 	assert.NilError(t, err)
371 371
 
372 372
 	// Inspect the v4 gateway to ensure no next hop is assigned in L3 mode
373
-	assert.Check(t, !c1.NetworkSettings.Networks[netName].Gateway.IsValid())
373
+	assert.Check(t, !c1.Container.NetworkSettings.Networks[netName].Gateway.IsValid())
374 374
 	// Inspect the v6 gateway to ensure the explicitly specified default GW is ignored per L3 mode enabled
375
-	assert.Check(t, !c1.NetworkSettings.Networks[netName].IPv6Gateway.IsValid())
375
+	assert.Check(t, !c1.Container.NetworkSettings.Networks[netName].IPv6Gateway.IsValid())
376 376
 	// Inspect the v4 gateway to ensure no next hop is assigned in L3 mode
377
-	assert.Check(t, !c3.NetworkSettings.Networks[netName].Gateway.IsValid())
377
+	assert.Check(t, !c3.Container.NetworkSettings.Networks[netName].Gateway.IsValid())
378 378
 	// Inspect the v6 gateway to ensure the explicitly specified default GW is ignored per L3 mode enabled
379
-	assert.Check(t, !c3.NetworkSettings.Networks[netName].IPv6Gateway.IsValid())
379
+	assert.Check(t, !c3.Container.NetworkSettings.Networks[netName].IPv6Gateway.IsValid())
380 380
 }
381 381
 
382 382
 // Verify ipvlan l2 mode sets the proper default gateway routes via netlink
... ...
@@ -332,9 +332,9 @@ func testMacvlanMultiSubnetNoParent(t *testing.T, ctx context.Context, client cl
332 332
 	testMacvlanMultiSubnet(t, ctx, client, "")
333 333
 }
334 334
 
335
-func testMacvlanMultiSubnet(t *testing.T, ctx context.Context, client client.APIClient, parent string) {
335
+func testMacvlanMultiSubnet(t *testing.T, ctx context.Context, apiClient client.APIClient, parent string) {
336 336
 	netName := "dualstackbridge"
337
-	net.CreateNoError(ctx, t, client, netName,
337
+	net.CreateNoError(ctx, t, apiClient, netName,
338 338
 		net.WithMacvlan(parent),
339 339
 		net.WithIPv6(),
340 340
 		net.WithIPAM("172.28.100.0/24", ""),
... ...
@@ -343,63 +343,63 @@ func testMacvlanMultiSubnet(t *testing.T, ctx context.Context, client client.API
343 343
 		net.WithIPAM("2001:db8:abc4::/64", "2001:db8:abc4::254"),
344 344
 	)
345 345
 
346
-	assert.Check(t, n.IsNetworkAvailable(ctx, client, netName))
346
+	assert.Check(t, n.IsNetworkAvailable(ctx, apiClient, netName))
347 347
 
348 348
 	// start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.100.0/24 and 2001:db8:abc2::/64
349
-	id1 := container.Run(ctx, t, client,
349
+	id1 := container.Run(ctx, t, apiClient,
350 350
 		container.WithNetworkMode("dualstackbridge"),
351 351
 		container.WithIPv4("dualstackbridge", "172.28.100.20"),
352 352
 		container.WithIPv6("dualstackbridge", "2001:db8:abc2::20"),
353 353
 	)
354
-	id2 := container.Run(ctx, t, client,
354
+	id2 := container.Run(ctx, t, apiClient,
355 355
 		container.WithNetworkMode("dualstackbridge"),
356 356
 		container.WithIPv4("dualstackbridge", "172.28.100.21"),
357 357
 		container.WithIPv6("dualstackbridge", "2001:db8:abc2::21"),
358 358
 	)
359
-	c1, err := client.ContainerInspect(ctx, id1)
359
+	c1, err := apiClient.ContainerInspect(ctx, id1, client.ContainerInspectOptions{})
360 360
 	assert.NilError(t, err)
361 361
 	// Inspect the v4 gateway to ensure no default GW was assigned
362
-	assert.Check(t, !c1.NetworkSettings.Networks["dualstackbridge"].Gateway.IsValid())
362
+	assert.Check(t, !c1.Container.NetworkSettings.Networks["dualstackbridge"].Gateway.IsValid())
363 363
 	// Inspect the v6 gateway to ensure no default GW was assigned
364
-	assert.Check(t, !c1.NetworkSettings.Networks["dualstackbridge"].IPv6Gateway.IsValid())
364
+	assert.Check(t, !c1.Container.NetworkSettings.Networks["dualstackbridge"].IPv6Gateway.IsValid())
365 365
 
366 366
 	// verify ipv4 connectivity to the explicit --ip address second to first
367
-	_, err = container.Exec(ctx, client, id2, []string{"ping", "-c", "1", c1.NetworkSettings.Networks["dualstackbridge"].IPAddress.String()})
367
+	_, err = container.Exec(ctx, apiClient, id2, []string{"ping", "-c", "1", c1.Container.NetworkSettings.Networks["dualstackbridge"].IPAddress.String()})
368 368
 	assert.NilError(t, err)
369 369
 	// verify ipv6 connectivity to the explicit --ip6 address second to first
370
-	_, err = container.Exec(ctx, client, id2, []string{"ping6", "-c", "1", c1.NetworkSettings.Networks["dualstackbridge"].GlobalIPv6Address.String()})
370
+	_, err = container.Exec(ctx, apiClient, id2, []string{"ping6", "-c", "1", c1.Container.NetworkSettings.Networks["dualstackbridge"].GlobalIPv6Address.String()})
371 371
 	assert.NilError(t, err)
372 372
 
373 373
 	// start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.102.0/24 and 2001:db8:abc4::/64
374
-	id3 := container.Run(ctx, t, client,
374
+	id3 := container.Run(ctx, t, apiClient,
375 375
 		container.WithNetworkMode("dualstackbridge"),
376 376
 		container.WithIPv4("dualstackbridge", "172.28.102.20"),
377 377
 		container.WithIPv6("dualstackbridge", "2001:db8:abc4::20"),
378 378
 	)
379
-	id4 := container.Run(ctx, t, client,
379
+	id4 := container.Run(ctx, t, apiClient,
380 380
 		container.WithNetworkMode("dualstackbridge"),
381 381
 		container.WithIPv4("dualstackbridge", "172.28.102.21"),
382 382
 		container.WithIPv6("dualstackbridge", "2001:db8:abc4::21"),
383 383
 	)
384
-	c3, err := client.ContainerInspect(ctx, id3)
384
+	c3, err := apiClient.ContainerInspect(ctx, id3, client.ContainerInspectOptions{})
385 385
 	assert.NilError(t, err)
386 386
 	if parent == "" {
387 387
 		// Inspect the v4 gateway to ensure no default GW was assigned
388
-		assert.Check(t, !c3.NetworkSettings.Networks["dualstackbridge"].Gateway.IsValid())
388
+		assert.Check(t, !c3.Container.NetworkSettings.Networks["dualstackbridge"].Gateway.IsValid())
389 389
 		// Inspect the v6 gateway to ensure no default GW was assigned
390
-		assert.Check(t, !c3.NetworkSettings.Networks["dualstackbridge"].IPv6Gateway.IsValid())
390
+		assert.Check(t, !c3.Container.NetworkSettings.Networks["dualstackbridge"].IPv6Gateway.IsValid())
391 391
 	} else {
392 392
 		// Inspect the v4 gateway to ensure the proper explicitly assigned default GW was assigned
393
-		assert.Check(t, is.Equal(c3.NetworkSettings.Networks["dualstackbridge"].Gateway, netip.MustParseAddr("172.28.102.254")))
393
+		assert.Check(t, is.Equal(c3.Container.NetworkSettings.Networks["dualstackbridge"].Gateway, netip.MustParseAddr("172.28.102.254")))
394 394
 		// Inspect the v6 gateway to ensure the proper explicitly assigned default GW was assigned
395
-		assert.Check(t, is.Equal(c3.NetworkSettings.Networks["dualstackbridge"].IPv6Gateway, netip.MustParseAddr("2001:db8:abc4::254")))
395
+		assert.Check(t, is.Equal(c3.Container.NetworkSettings.Networks["dualstackbridge"].IPv6Gateway, netip.MustParseAddr("2001:db8:abc4::254")))
396 396
 	}
397 397
 
398 398
 	// verify ipv4 connectivity to the explicit --ip address from third to fourth
399
-	_, err = container.Exec(ctx, client, id4, []string{"ping", "-c", "1", c3.NetworkSettings.Networks["dualstackbridge"].IPAddress.String()})
399
+	_, err = container.Exec(ctx, apiClient, id4, []string{"ping", "-c", "1", c3.Container.NetworkSettings.Networks["dualstackbridge"].IPAddress.String()})
400 400
 	assert.NilError(t, err)
401 401
 	// verify ipv6 connectivity to the explicit --ip6 address from third to fourth
402
-	_, err = container.Exec(ctx, client, id4, []string{"ping6", "-c", "1", c3.NetworkSettings.Networks["dualstackbridge"].GlobalIPv6Address.String()})
402
+	_, err = container.Exec(ctx, apiClient, id4, []string{"ping6", "-c", "1", c3.Container.NetworkSettings.Networks["dualstackbridge"].GlobalIPv6Address.String()})
403 403
 	assert.NilError(t, err)
404 404
 }
405 405
 
... ...
@@ -235,9 +235,9 @@ func TestInspectCfgdMAC(t *testing.T) {
235 235
 				Force: true,
236 236
 			})
237 237
 
238
-			_, raw, err := c.ContainerInspectWithRaw(ctx, id, false)
238
+			inspect, err := c.ContainerInspect(ctx, id, client.ContainerInspectOptions{})
239 239
 			assert.NilError(t, err)
240
-			var inspect struct {
240
+			var resp struct {
241 241
 				Config struct {
242 242
 					// Mac Address of the container.
243 243
 					//
... ...
@@ -245,10 +245,10 @@ func TestInspectCfgdMAC(t *testing.T) {
245 245
 					MacAddress string `json:",omitempty"`
246 246
 				}
247 247
 			}
248
-			err = json.Unmarshal(raw, &inspect)
249
-			assert.NilError(t, err, string(raw))
250
-			configMAC := inspect.Config.MacAddress
251
-			assert.Check(t, is.DeepEqual(configMAC, tc.desiredMAC), string(raw))
248
+			err = json.Unmarshal(inspect.Raw, &resp)
249
+			assert.NilError(t, err, string(inspect.Raw))
250
+			configMAC := resp.Config.MacAddress
251
+			assert.Check(t, is.DeepEqual(configMAC, tc.desiredMAC), string(inspect.Raw))
252 252
 		})
253 253
 	}
254 254
 }
... ...
@@ -49,7 +49,7 @@ func TestAuthZPluginV2AllowNonVolumeRequest(t *testing.T) {
49 49
 	// Ensure docker run command and accompanying docker ps are successful
50 50
 	cID := container.Run(ctx, t, c)
51 51
 
52
-	_, err = c.ContainerInspect(ctx, cID)
52
+	_, err = c.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
53 53
 	assert.NilError(t, err)
54 54
 }
55 55
 
... ...
@@ -70,9 +70,9 @@ func inspectServiceContainer(ctx context.Context, t *testing.T, apiClient client
70 70
 	assert.NilError(t, err)
71 71
 	assert.Check(t, is.Len(containers, 1))
72 72
 
73
-	i, err := apiClient.ContainerInspect(ctx, containers[0].ID)
73
+	inspect, err := apiClient.ContainerInspect(ctx, containers[0].ID, client.ContainerInspectOptions{})
74 74
 	assert.NilError(t, err)
75
-	return i
75
+	return inspect.Container
76 76
 }
77 77
 
78 78
 func TestCreateServiceMultipleTimes(t *testing.T) {
... ...
@@ -380,9 +380,9 @@ func TestCreateServiceSysctls(t *testing.T) {
380 380
 		assert.Check(t, is.Equal(len(taskList.Items), 1))
381 381
 
382 382
 		// verify that the container has the sysctl option set
383
-		ctnr, err := apiClient.ContainerInspect(ctx, taskList.Items[0].Status.ContainerStatus.ContainerID)
383
+		inspect, err := apiClient.ContainerInspect(ctx, taskList.Items[0].Status.ContainerStatus.ContainerID, client.ContainerInspectOptions{})
384 384
 		assert.NilError(t, err)
385
-		assert.DeepEqual(t, ctnr.HostConfig.Sysctls, expectedSysctls)
385
+		assert.DeepEqual(t, inspect.Container.HostConfig.Sysctls, expectedSysctls)
386 386
 
387 387
 		// verify that the task has the sysctl option set in the task object
388 388
 		assert.DeepEqual(t, taskList.Items[0].Spec.ContainerSpec.Sysctls, expectedSysctls)
... ...
@@ -450,10 +450,10 @@ func TestCreateServiceCapabilities(t *testing.T) {
450 450
 	assert.Check(t, is.Equal(len(taskList.Items), 1))
451 451
 
452 452
 	// verify that the container has the capabilities option set
453
-	ctnr, err := apiClient.ContainerInspect(ctx, taskList.Items[0].Status.ContainerStatus.ContainerID)
453
+	inspect, err := apiClient.ContainerInspect(ctx, taskList.Items[0].Status.ContainerStatus.ContainerID, client.ContainerInspectOptions{})
454 454
 	assert.NilError(t, err)
455
-	assert.DeepEqual(t, ctnr.HostConfig.CapAdd, capAdd)
456
-	assert.DeepEqual(t, ctnr.HostConfig.CapDrop, capDrop)
455
+	assert.DeepEqual(t, inspect.Container.HostConfig.CapAdd, capAdd)
456
+	assert.DeepEqual(t, inspect.Container.HostConfig.CapDrop, capDrop)
457 457
 
458 458
 	// verify that the task has the capabilities option set in the task object
459 459
 	assert.DeepEqual(t, taskList.Items[0].Spec.ContainerSpec.CapabilityAdd, capAdd)
... ...
@@ -541,9 +541,9 @@ func TestCreateServiceMemorySwap(t *testing.T) {
541 541
 			// if the host supports it (see https://github.com/moby/moby/blob/v17.03.2-ce/daemon/daemon_unix.go#L290-L294)
542 542
 			// then check that the swap option is set on the container, and properly reported by the group FS as well
543 543
 			if testEnv.DaemonInfo.SwapLimit {
544
-				ctnr, err := apiClient.ContainerInspect(ctx, task.Status.ContainerStatus.ContainerID)
544
+				ctr, err := apiClient.ContainerInspect(ctx, task.Status.ContainerStatus.ContainerID, client.ContainerInspectOptions{})
545 545
 				assert.NilError(t, err)
546
-				assert.Equal(t, testCase.expectedDockerSwap, ctnr.HostConfig.Resources.MemorySwap)
546
+				assert.Equal(t, testCase.expectedDockerSwap, ctr.Container.HostConfig.Resources.MemorySwap)
547 547
 			}
548 548
 		})
549 549
 	}
... ...
@@ -57,10 +57,10 @@ func TestDockerNetworkConnectAliasPreV144(t *testing.T) {
57 57
 	err = apiClient.ContainerStart(ctx, cID1, client.ContainerStartOptions{})
58 58
 	assert.NilError(t, err)
59 59
 
60
-	ng1, err := apiClient.ContainerInspect(ctx, cID1)
60
+	ng1, err := apiClient.ContainerInspect(ctx, cID1, client.ContainerInspectOptions{})
61 61
 	assert.NilError(t, err)
62
-	assert.Check(t, is.Equal(len(ng1.NetworkSettings.Networks[name].Aliases), 2))
63
-	assert.Check(t, is.Equal(ng1.NetworkSettings.Networks[name].Aliases[0], "aaa"))
62
+	assert.Check(t, is.Equal(len(ng1.Container.NetworkSettings.Networks[name].Aliases), 2))
63
+	assert.Check(t, is.Equal(ng1.Container.NetworkSettings.Networks[name].Aliases[0], "aaa"))
64 64
 
65 65
 	cID2 := container.Create(ctx, t, apiClient, func(c *container.TestContainerConfig) {
66 66
 		c.NetworkingConfig = &network.NetworkingConfig{
... ...
@@ -80,10 +80,10 @@ func TestDockerNetworkConnectAliasPreV144(t *testing.T) {
80 80
 	err = apiClient.ContainerStart(ctx, cID2, client.ContainerStartOptions{})
81 81
 	assert.NilError(t, err)
82 82
 
83
-	ng2, err := apiClient.ContainerInspect(ctx, cID2)
83
+	ng2, err := apiClient.ContainerInspect(ctx, cID2, client.ContainerInspectOptions{})
84 84
 	assert.NilError(t, err)
85
-	assert.Check(t, is.Equal(len(ng2.NetworkSettings.Networks[name].Aliases), 2))
86
-	assert.Check(t, is.Equal(ng2.NetworkSettings.Networks[name].Aliases[0], "bbb"))
85
+	assert.Check(t, is.Equal(len(ng2.Container.NetworkSettings.Networks[name].Aliases), 2))
86
+	assert.Check(t, is.Equal(ng2.Container.NetworkSettings.Networks[name].Aliases[0], "bbb"))
87 87
 }
88 88
 
89 89
 func TestDockerNetworkReConnect(t *testing.T) {
... ...
@@ -114,15 +114,15 @@ func TestDockerNetworkReConnect(t *testing.T) {
114 114
 	err = apiClient.ContainerStart(ctx, c1, client.ContainerStartOptions{})
115 115
 	assert.NilError(t, err)
116 116
 
117
-	n1, err := apiClient.ContainerInspect(ctx, c1)
117
+	n1, err := apiClient.ContainerInspect(ctx, c1, client.ContainerInspectOptions{})
118 118
 	assert.NilError(t, err)
119 119
 
120 120
 	err = apiClient.NetworkConnect(ctx, name, c1, &network.EndpointSettings{})
121 121
 	assert.ErrorContains(t, err, "is already attached to network")
122 122
 
123
-	n2, err := apiClient.ContainerInspect(ctx, c1)
123
+	n2, err := apiClient.ContainerInspect(ctx, c1, client.ContainerInspectOptions{})
124 124
 	assert.NilError(t, err)
125
-	assert.Check(t, is.DeepEqual(n1, n2, cmpopts.EquateComparable(netip.Addr{}, netip.Prefix{})))
125
+	assert.Check(t, is.DeepEqual(n1.Container, n2.Container, cmpopts.EquateComparable(netip.Addr{}, netip.Prefix{})))
126 126
 }
127 127
 
128 128
 // Check that a swarm-scoped network can't have EnableIPv4=false.
... ...
@@ -366,10 +366,10 @@ func getServiceTaskContainer(ctx context.Context, t *testing.T, cli client.APICl
366 366
 	assert.NilError(t, err)
367 367
 	assert.Assert(t, len(taskList.Items) > 0)
368 368
 
369
-	ctr, err := cli.ContainerInspect(ctx, taskList.Items[0].Status.ContainerStatus.ContainerID)
369
+	inspect, err := cli.ContainerInspect(ctx, taskList.Items[0].Status.ContainerStatus.ContainerID, client.ContainerInspectOptions{})
370 370
 	assert.NilError(t, err)
371
-	assert.Equal(t, ctr.State.Running, true)
372
-	return ctr
371
+	assert.Equal(t, inspect.Container.State.Running, true)
372
+	return inspect.Container
373 373
 }
374 374
 
375 375
 func getService(ctx context.Context, t *testing.T, apiClient client.ServiceAPIClient, serviceID string) swarmtypes.Service {
... ...
@@ -49,7 +49,7 @@ func TestCgroupDriverSystemdMemoryLimit(t *testing.T) {
49 49
 	err := c.ContainerStart(ctx, ctrID, client.ContainerStartOptions{})
50 50
 	assert.NilError(t, err)
51 51
 
52
-	s, err := c.ContainerInspect(ctx, ctrID)
52
+	s, err := c.ContainerInspect(ctx, ctrID, client.ContainerInspectOptions{})
53 53
 	assert.NilError(t, err)
54
-	assert.Equal(t, s.HostConfig.Memory, mem)
54
+	assert.Equal(t, s.Container.HostConfig.Memory, mem)
55 55
 }
... ...
@@ -107,9 +107,9 @@ func TestRunMountVolumeSubdir(t *testing.T) {
107 107
 			output, err := container.Output(ctx, apiClient, id)
108 108
 			assert.Check(t, err)
109 109
 
110
-			inspect, err := apiClient.ContainerInspect(ctx, id)
110
+			inspect, err := apiClient.ContainerInspect(ctx, id, client.ContainerInspectOptions{})
111 111
 			if assert.Check(t, err) {
112
-				assert.Check(t, is.Equal(inspect.State.ExitCode, 0))
112
+				assert.Check(t, is.Equal(inspect.Container.State.ExitCode, 0))
113 113
 			}
114 114
 
115 115
 			assert.Check(t, is.Equal(strings.TrimSpace(output.Stderr), ""))
... ...
@@ -222,9 +222,9 @@ func TestRunMountImage(t *testing.T) {
222 222
 			output, err := container.Output(ctx, apiClient, id)
223 223
 			assert.Check(t, err)
224 224
 
225
-			inspect, err := apiClient.ContainerInspect(ctx, id)
225
+			inspect, err := apiClient.ContainerInspect(ctx, id, client.ContainerInspectOptions{})
226 226
 			if tc.startErr == "" && assert.Check(t, err) {
227
-				assert.Check(t, is.Equal(inspect.State.ExitCode, 0))
227
+				assert.Check(t, is.Equal(inspect.Container.State.ExitCode, 0))
228 228
 			}
229 229
 
230 230
 			assert.Check(t, is.Equal(strings.TrimSpace(output.Stderr), ""))
... ...
@@ -294,9 +294,9 @@ func setupTestVolume(t *testing.T, apiClient client.APIClient) string {
294 294
 	assert.NilError(t, err)
295 295
 	assert.Assert(t, is.Equal(output.Stderr, ""))
296 296
 
297
-	inspect, err := apiClient.ContainerInspect(ctx, cid)
297
+	inspect, err := apiClient.ContainerInspect(ctx, cid, client.ContainerInspectOptions{})
298 298
 	assert.NilError(t, err)
299
-	assert.Assert(t, is.Equal(inspect.State.ExitCode, 0))
299
+	assert.Assert(t, is.Equal(inspect.Container.State.ExitCode, 0))
300 300
 
301 301
 	return volumeName
302 302
 }
... ...
@@ -384,12 +384,12 @@ func TestRunMountImageMultipleTimes(t *testing.T) {
384 384
 
385 385
 	defer apiClient.ContainerRemove(ctx, id, client.ContainerRemoveOptions{Force: true})
386 386
 
387
-	inspect, err := apiClient.ContainerInspect(ctx, id)
387
+	inspect, err := apiClient.ContainerInspect(ctx, id, client.ContainerInspectOptions{})
388 388
 	assert.NilError(t, err)
389 389
 
390
-	assert.Equal(t, len(inspect.Mounts), 2)
390
+	assert.Equal(t, len(inspect.Container.Mounts), 2)
391 391
 	var hasFoo, hasBar bool
392
-	for _, mnt := range inspect.Mounts {
392
+	for _, mnt := range inspect.Container.Mounts {
393 393
 		if mnt.Destination == "/etc/foo" {
394 394
 			hasFoo = true
395 395
 		}
... ...
@@ -71,9 +71,9 @@ func TestVolumesRemove(t *testing.T) {
71 71
 
72 72
 	id := container.Create(ctx, t, apiClient, container.WithVolume(prefix+slash+"foo"))
73 73
 
74
-	c, err := apiClient.ContainerInspect(ctx, id)
74
+	inspect, err := apiClient.ContainerInspect(ctx, id, client.ContainerInspectOptions{})
75 75
 	assert.NilError(t, err)
76
-	vname := c.Mounts[0].Name
76
+	vname := inspect.Container.Mounts[0].Name
77 77
 
78 78
 	t.Run("volume in use", func(t *testing.T) {
79 79
 		err = apiClient.VolumeRemove(ctx, vname, client.VolumeRemoveOptions{})
... ...
@@ -123,9 +123,9 @@ func TestVolumesRemoveSwarmEnabled(t *testing.T) {
123 123
 	prefix, slash := getPrefixAndSlashFromDaemonPlatform()
124 124
 	id := container.Create(ctx, t, apiClient, container.WithVolume(prefix+slash+"foo"))
125 125
 
126
-	c, err := apiClient.ContainerInspect(ctx, id)
126
+	inspect, err := apiClient.ContainerInspect(ctx, id, client.ContainerInspectOptions{})
127 127
 	assert.NilError(t, err)
128
-	vname := c.Mounts[0].Name
128
+	vname := inspect.Container.Mounts[0].Name
129 129
 
130 130
 	t.Run("volume in use", func(t *testing.T) {
131 131
 		err = apiClient.VolumeRemove(ctx, vname, client.VolumeRemoveOptions{})
... ...
@@ -343,12 +343,12 @@ VOLUME ` + volDest
343 343
 	id := container.Create(ctx, t, apiClient, container.WithImage(img))
344 344
 	defer apiClient.ContainerRemove(ctx, id, client.ContainerRemoveOptions{})
345 345
 
346
-	inspect, err := apiClient.ContainerInspect(ctx, id)
346
+	inspect, err := apiClient.ContainerInspect(ctx, id, client.ContainerInspectOptions{})
347 347
 	assert.NilError(t, err)
348 348
 
349
-	assert.Assert(t, is.Len(inspect.Mounts, 1))
349
+	assert.Assert(t, is.Len(inspect.Container.Mounts, 1))
350 350
 
351
-	volumeName := inspect.Mounts[0].Name
351
+	volumeName := inspect.Container.Mounts[0].Name
352 352
 	assert.Assert(t, volumeName != "")
353 353
 
354 354
 	err = apiClient.ContainerRemove(ctx, id, client.ContainerRemoveOptions{})
... ...
@@ -164,12 +164,12 @@ COPY . /static`); err != nil {
164 164
 	assert.NilError(t, err)
165 165
 
166 166
 	// Find out the system assigned port
167
-	i, err := c.ContainerInspect(context.Background(), b.ID)
167
+	inspect, err := c.ContainerInspect(context.Background(), b.ID, client.ContainerInspectOptions{})
168 168
 	assert.NilError(t, err)
169
-	ports, exists := i.NetworkSettings.Ports[network.MustParsePort("80/tcp")]
169
+	ports, exists := inspect.Container.NetworkSettings.Ports[network.MustParsePort("80/tcp")]
170 170
 	assert.Assert(t, exists, "unable to find port 80/tcp for %s", ctrName)
171 171
 	if len(ports) == 0 {
172
-		t.Fatalf("no ports mapped for 80/tcp for %s: %#v", ctrName, i.NetworkSettings.Ports)
172
+		t.Fatalf("no ports mapped for 80/tcp for %s: %#v", ctrName, inspect.Container.NetworkSettings.Ports)
173 173
 	}
174 174
 	// TODO(thaJeztah): this will be "0.0.0.0" or "::", is that expected, should this use the IP of the testEnv.Server?
175 175
 	host := ports[0].HostIP
... ...
@@ -63,8 +63,7 @@ type ContainerAPIClient interface {
63 63
 	ContainerDiff(ctx context.Context, container string, options ContainerDiffOptions) (ContainerDiffResult, error)
64 64
 	ExecAPIClient
65 65
 	ContainerExport(ctx context.Context, container string) (io.ReadCloser, error)
66
-	ContainerInspect(ctx context.Context, container string) (container.InspectResponse, error)
67
-	ContainerInspectWithRaw(ctx context.Context, container string, getSize bool) (container.InspectResponse, []byte, error)
66
+	ContainerInspect(ctx context.Context, container string, options ContainerInspectOptions) (ContainerInspectResult, error)
68 67
 	ContainerKill(ctx context.Context, container, signal string) error
69 68
 	ContainerList(ctx context.Context, options ContainerListOptions) ([]container.Summary, error)
70 69
 	ContainerLogs(ctx context.Context, container string, options ContainerLogsOptions) (io.ReadCloser, error)
... ...
@@ -1,57 +1,47 @@
1 1
 package client
2 2
 
3 3
 import (
4
-	"bytes"
5 4
 	"context"
6 5
 	"encoding/json"
7
-	"io"
8 6
 	"net/url"
9 7
 
10 8
 	"github.com/moby/moby/api/types/container"
11 9
 )
12 10
 
13
-// ContainerInspect returns the container information.
14
-func (cli *Client) ContainerInspect(ctx context.Context, containerID string) (container.InspectResponse, error) {
15
-	containerID, err := trimID("container", containerID)
16
-	if err != nil {
17
-		return container.InspectResponse{}, err
18
-	}
19
-
20
-	resp, err := cli.get(ctx, "/containers/"+containerID+"/json", nil, nil)
21
-	defer ensureReaderClosed(resp)
22
-	if err != nil {
23
-		return container.InspectResponse{}, err
24
-	}
11
+// ContainerInspectOptions holds options for inspecting a container using
12
+// the [Client.ConfigInspect] method.
13
+type ContainerInspectOptions struct {
14
+	// Size controls whether the container's filesystem size should be calculated.
15
+	// When set, the [container.InspectResponse.SizeRw] and [container.InspectResponse.SizeRootFs]
16
+	// fields in [ContainerInspectResult.Container] are populated with the result.
17
+	//
18
+	// Calculating the size can be a costly operation, and should not be used
19
+	// unless needed.
20
+	Size bool
21
+}
25 22
 
26
-	var response container.InspectResponse
27
-	err = json.NewDecoder(resp.Body).Decode(&response)
28
-	return response, err
23
+// ContainerInspectResult holds the result from the [Client.ConfigInspect] method.
24
+type ContainerInspectResult struct {
25
+	Container container.InspectResponse
26
+	Raw       json.RawMessage
29 27
 }
30 28
 
31
-// ContainerInspectWithRaw returns the container information and its raw representation.
32
-func (cli *Client) ContainerInspectWithRaw(ctx context.Context, containerID string, getSize bool) (container.InspectResponse, []byte, error) {
29
+// ContainerInspect returns the container information.
30
+func (cli *Client) ContainerInspect(ctx context.Context, containerID string, options ContainerInspectOptions) (ContainerInspectResult, error) {
33 31
 	containerID, err := trimID("container", containerID)
34 32
 	if err != nil {
35
-		return container.InspectResponse{}, nil, err
33
+		return ContainerInspectResult{}, err
36 34
 	}
37 35
 
38 36
 	query := url.Values{}
39
-	if getSize {
37
+	if options.Size {
40 38
 		query.Set("size", "1")
41 39
 	}
42 40
 	resp, err := cli.get(ctx, "/containers/"+containerID+"/json", query, nil)
43
-	defer ensureReaderClosed(resp)
44
-	if err != nil {
45
-		return container.InspectResponse{}, nil, err
46
-	}
47
-
48
-	body, err := io.ReadAll(resp.Body)
49 41
 	if err != nil {
50
-		return container.InspectResponse{}, nil, err
42
+		return ContainerInspectResult{}, err
51 43
 	}
52
-
53
-	var response container.InspectResponse
54
-	rdr := bytes.NewReader(body)
55
-	err = json.NewDecoder(rdr).Decode(&response)
56
-	return response, body, err
44
+	var out ContainerInspectResult
45
+	out.Raw, err = decodeWithRaw(resp, &out.Container)
46
+	return out, err
57 47
 }