Skip to content

Commit f363523

Browse files
Merge pull request moby#51290 from thaJeztah/container_noraw
client: merge ContainerInspectWithRaw with ContainerInspect
2 parents be8d6e2 + 4259753 commit f363523

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+368
-394
lines changed

client/client_interfaces.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,7 @@ type ContainerAPIClient interface {
6363
ContainerDiff(ctx context.Context, container string, options ContainerDiffOptions) (ContainerDiffResult, error)
6464
ExecAPIClient
6565
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)
6867
ContainerKill(ctx context.Context, container, signal string) error
6968
ContainerList(ctx context.Context, options ContainerListOptions) ([]container.Summary, error)
7069
ContainerLogs(ctx context.Context, container string, options ContainerLogsOptions) (io.ReadCloser, error)

client/container_inspect.go

Lines changed: 23 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,47 @@
11
package client
22

33
import (
4-
"bytes"
54
"context"
65
"encoding/json"
7-
"io"
86
"net/url"
97

108
"github.com/moby/moby/api/types/container"
119
)
1210

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+
}
2522

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
2927
}
3028

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) {
3331
containerID, err := trimID("container", containerID)
3432
if err != nil {
35-
return container.InspectResponse{}, nil, err
33+
return ContainerInspectResult{}, err
3634
}
3735

3836
query := url.Values{}
39-
if getSize {
37+
if options.Size {
4038
query.Set("size", "1")
4139
}
4240
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)
4941
if err != nil {
50-
return container.InspectResponse{}, nil, err
42+
return ContainerInspectResult{}, err
5143
}
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
5747
}

client/container_inspect_test.go

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package client
22

33
import (
4-
"context"
54
"errors"
65
"net/http"
76
"testing"
@@ -18,14 +17,14 @@ func TestContainerInspectError(t *testing.T) {
1817
)
1918
assert.NilError(t, err)
2019

21-
_, err = client.ContainerInspect(context.Background(), "nothing")
20+
_, err = client.ContainerInspect(t.Context(), "nothing", ContainerInspectOptions{})
2221
assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal))
2322

24-
_, err = client.ContainerInspect(context.Background(), "")
23+
_, err = client.ContainerInspect(t.Context(), "", ContainerInspectOptions{})
2524
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
2625
assert.Check(t, is.ErrorContains(err, "value is empty"))
2726

28-
_, err = client.ContainerInspect(context.Background(), " ")
27+
_, err = client.ContainerInspect(t.Context(), " ", ContainerInspectOptions{})
2928
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
3029
assert.Check(t, is.ErrorContains(err, "value is empty"))
3130
}
@@ -36,7 +35,7 @@ func TestContainerInspectContainerNotFound(t *testing.T) {
3635
)
3736
assert.NilError(t, err)
3837

39-
_, err = client.ContainerInspect(context.Background(), "unknown")
38+
_, err = client.ContainerInspect(t.Context(), "unknown", ContainerInspectOptions{})
4039
assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound))
4140
}
4241

@@ -48,19 +47,11 @@ func TestContainerInspectWithEmptyID(t *testing.T) {
4847
)
4948
assert.NilError(t, err)
5049

51-
_, err = client.ContainerInspect(context.Background(), "")
50+
_, err = client.ContainerInspect(t.Context(), "", ContainerInspectOptions{})
5251
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
5352
assert.Check(t, is.ErrorContains(err, "value is empty"))
5453

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)
54+
_, err = client.ContainerInspect(t.Context(), " ", ContainerInspectOptions{})
6455
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
6556
assert.Check(t, is.ErrorContains(err, "value is empty"))
6657
}
@@ -81,9 +72,9 @@ func TestContainerInspect(t *testing.T) {
8172
)
8273
assert.NilError(t, err)
8374

84-
r, err := client.ContainerInspect(context.Background(), "container_id")
75+
res, err := client.ContainerInspect(t.Context(), "container_id", ContainerInspectOptions{})
8576
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"))
77+
assert.Check(t, is.Equal(res.Container.ID, "container_id"))
78+
assert.Check(t, is.Equal(res.Container.Image, "image"))
79+
assert.Check(t, is.Equal(res.Container.Name, "name"))
8980
}

integration-cli/docker_api_containers_test.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -593,10 +593,10 @@ func UtilCreateNetworkMode(t *testing.T, networkMode container.NetworkMode) {
593593
})
594594
assert.NilError(t, err)
595595

596-
containerJSON, err := apiClient.ContainerInspect(testutil.GetContext(t), ctr.ID)
596+
res, err := apiClient.ContainerInspect(testutil.GetContext(t), ctr.ID, client.ContainerInspectOptions{})
597597
assert.NilError(t, err)
598598

599-
assert.Equal(t, containerJSON.HostConfig.NetworkMode, networkMode, "Mismatched NetworkMode")
599+
assert.Equal(t, res.Container.HostConfig.NetworkMode, networkMode, "Mismatched NetworkMode")
600600
}
601601

602602
func (s *DockerAPISuite) TestContainerAPICreateWithCpuSharesCpuset(c *testing.T) {
@@ -624,13 +624,13 @@ func (s *DockerAPISuite) TestContainerAPICreateWithCpuSharesCpuset(c *testing.T)
624624
})
625625
assert.NilError(c, err)
626626

627-
containerJSON, err := apiClient.ContainerInspect(testutil.GetContext(c), ctr.ID)
627+
res, err := apiClient.ContainerInspect(testutil.GetContext(c), ctr.ID, client.ContainerInspectOptions{})
628628
assert.NilError(c, err)
629629

630-
out := inspectField(c, containerJSON.ID, "HostConfig.CpuShares")
630+
out := inspectField(c, res.Container.ID, "HostConfig.CpuShares")
631631
assert.Equal(c, out, "512")
632632

633-
outCpuset := inspectField(c, containerJSON.ID, "HostConfig.CpusetCpus")
633+
outCpuset := inspectField(c, res.Container.ID, "HostConfig.CpusetCpus")
634634
assert.Equal(c, outCpuset, "0")
635635
}
636636

@@ -913,10 +913,10 @@ func (s *DockerAPISuite) TestContainerAPIDeleteRemoveVolume(c *testing.T) {
913913
assert.NilError(c, err)
914914
defer apiClient.Close()
915915

916-
ctrInspect, err := apiClient.ContainerInspect(testutil.GetContext(c), id)
916+
res, err := apiClient.ContainerInspect(testutil.GetContext(c), id, client.ContainerInspectOptions{})
917917
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]
920920
assert.Equal(c, mnt.Destination, testVol)
921921

922922
_, err = os.Stat(mnt.Source)
@@ -949,7 +949,7 @@ func (s *DockerAPISuite) TestContainerAPIChunkedEncoding(c *testing.T) {
949949
req.ContentLength = -1
950950
return nil
951951
}))
952-
assert.Assert(c, err == nil, "error creating container with chunked encoding")
952+
assert.NilError(c, err, "error creating container with chunked encoding")
953953
defer resp.Body.Close()
954954
assert.Equal(c, resp.StatusCode, http.StatusCreated)
955955
}
@@ -1057,10 +1057,10 @@ func (s *DockerAPISuite) TestPostContainersCreateMemorySwappinessHostConfigOmitt
10571057
})
10581058
assert.NilError(c, err)
10591059

1060-
containerJSON, err := apiClient.ContainerInspect(testutil.GetContext(c), ctr.ID)
1060+
res, err := apiClient.ContainerInspect(testutil.GetContext(c), ctr.ID, client.ContainerInspectOptions{})
10611061
assert.NilError(c, err)
10621062

1063-
assert.Assert(c, is.Nil(containerJSON.HostConfig.MemorySwappiness))
1063+
assert.Assert(c, is.Nil(res.Container.HostConfig.MemorySwappiness))
10641064
}
10651065

10661066
// check validation is done daemon side and not only in cli
@@ -1660,9 +1660,9 @@ func (s *DockerAPISuite) TestContainersAPICreateMountsCreate(c *testing.T) {
16601660
})
16611661
assert.NilError(c, err)
16621662

1663-
containerInspect, err := apiclient.ContainerInspect(ctx, ctr.ID)
1663+
res, err := apiclient.ContainerInspect(ctx, ctr.ID, client.ContainerInspectOptions{})
16641664
assert.NilError(c, err)
1665-
mps := containerInspect.Mounts
1665+
mps := res.Container.Mounts
16661666
assert.Assert(c, is.Len(mps, 1))
16671667
mountPoint := mps[0]
16681668

@@ -1713,13 +1713,13 @@ func (s *DockerAPISuite) TestContainersAPICreateMountsCreate(c *testing.T) {
17131713

17141714
func containerExit(ctx context.Context, apiclient client.APIClient, name string) func(poll.LogT) poll.Result {
17151715
return func(logT poll.LogT) poll.Result {
1716-
ctr, err := apiclient.ContainerInspect(ctx, name)
1716+
res, err := apiclient.ContainerInspect(ctx, name, client.ContainerInspectOptions{})
17171717
if err != nil {
17181718
return poll.Error(err)
17191719
}
1720-
switch ctr.State.Status {
1720+
switch s := res.Container.State.Status; s {
17211721
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)
17231723
case container.StatePaused, container.StateRestarting, container.StateRemoving, container.StateExited, container.StateDead:
17241724
// done
17251725
}

integration-cli/docker_cli_port_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"strings"
1111
"testing"
1212

13+
"github.com/moby/moby/client"
1314
"github.com/moby/moby/v2/integration-cli/cli"
1415
"github.com/moby/moby/v2/internal/testutil"
1516
"gotest.tools/v3/assert"
@@ -190,14 +191,14 @@ func assertPortList(t *testing.T, out string, expected []string) {
190191
}
191192

192193
func assertPortRange(ctx context.Context, id string, expectedTCP, expectedUDP []int) error {
193-
client := testEnv.APIClient()
194-
inspect, err := client.ContainerInspect(ctx, id)
194+
apiClient := testEnv.APIClient()
195+
res, err := apiClient.ContainerInspect(ctx, id, client.ContainerInspectOptions{})
195196
if err != nil {
196197
return err
197198
}
198199

199200
var validTCP, validUDP bool
200-
for port, binding := range inspect.NetworkSettings.Ports {
201+
for port, binding := range res.Container.NetworkSettings.Ports {
201202
if port.Proto() == "tcp" && len(expectedTCP) == 0 {
202203
continue
203204
}

integration-cli/docker_cli_run_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3689,10 +3689,10 @@ func (s *DockerCLIRunSuite) TestRunNamedVolumesFromNotRemoved(c *testing.T) {
36893689
assert.NilError(c, err)
36903690
defer apiClient.Close()
36913691

3692-
container, err := apiClient.ContainerInspect(testutil.GetContext(c), strings.TrimSpace(cid))
3692+
inspect, err := apiClient.ContainerInspect(testutil.GetContext(c), strings.TrimSpace(cid), client.ContainerInspectOptions{})
36933693
assert.NilError(c, err)
36943694
var vname string
3695-
for _, v := range container.Mounts {
3695+
for _, v := range inspect.Container.Mounts {
36963696
if v.Name != "test" {
36973697
vname = v.Name
36983698
}

integration-cli/docker_cli_run_unix_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,9 +1560,9 @@ func (s *DockerCLIRunSuite) TestRunWithNanoCPUs(c *testing.T) {
15601560

15611561
clt, err := client.NewClientWithOpts(client.FromEnv)
15621562
assert.NilError(c, err)
1563-
inspect, err := clt.ContainerInspect(testutil.GetContext(c), "test")
1563+
res, err := clt.ContainerInspect(testutil.GetContext(c), "test", client.ContainerInspectOptions{})
15641564
assert.NilError(c, err)
1565-
assert.Equal(c, inspect.HostConfig.NanoCPUs, int64(500000000))
1565+
assert.Equal(c, res.Container.HostConfig.NanoCPUs, int64(500000000))
15661566

15671567
out = inspectField(c, "test", "HostConfig.CpuQuota")
15681568
assert.Equal(c, out, "0", "CPU CFS quota should be 0")

integration-cli/docker_cli_update_unix_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,9 @@ func (s *DockerCLIUpdateSuite) TestUpdateWithNanoCPUs(c *testing.T) {
266266

267267
clt, err := client.NewClientWithOpts(client.FromEnv)
268268
assert.NilError(c, err)
269-
inspect, err := clt.ContainerInspect(testutil.GetContext(c), "top")
269+
res, err := clt.ContainerInspect(testutil.GetContext(c), "top", client.ContainerInspectOptions{})
270270
assert.NilError(c, err)
271-
assert.Equal(c, inspect.HostConfig.NanoCPUs, int64(500000000))
271+
assert.Equal(c, res.Container.HostConfig.NanoCPUs, int64(500000000))
272272

273273
out = inspectField(c, "top", "HostConfig.CpuQuota")
274274
assert.Equal(c, out, "0", "CPU CFS quota should be 0")
@@ -280,9 +280,9 @@ func (s *DockerCLIUpdateSuite) TestUpdateWithNanoCPUs(c *testing.T) {
280280
assert.Assert(c, is.Contains(out, "Conflicting options: CPU Quota cannot be updated as NanoCPUs has already been set"))
281281

282282
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{})
284284
assert.NilError(c, err)
285-
assert.Equal(c, inspect.HostConfig.NanoCPUs, int64(800000000))
285+
assert.Equal(c, res.Container.HostConfig.NanoCPUs, int64(800000000))
286286

287287
out = inspectField(c, "top", "HostConfig.CpuQuota")
288288
assert.Equal(c, out, "0", "CPU CFS quota should be 0")

integration-cli/docker_utils_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,14 +251,14 @@ func waitInspect(name, expr, expected string, timeout time.Duration) error {
251251
return daemon.WaitInspectWithArgs(dockerBinary, name, expr, expected, timeout)
252252
}
253253

254-
func getInspectBody(t *testing.T, version, id string) []byte {
254+
func getInspectBody(t *testing.T, version, id string) json.RawMessage {
255255
t.Helper()
256256
apiClient, err := client.NewClientWithOpts(client.FromEnv, client.WithVersion(version))
257257
assert.NilError(t, err)
258258
defer apiClient.Close()
259-
_, body, err := apiClient.ContainerInspectWithRaw(testutil.GetContext(t), id, false)
259+
inspect, err := apiClient.ContainerInspect(testutil.GetContext(t), id, client.ContainerInspectOptions{})
260260
assert.NilError(t, err)
261-
return body
261+
return inspect.Raw
262262
}
263263

264264
// Run a long running idle task in a background container using the

integration/container/cdi_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func TestCreateWithCDIDevices(t *testing.T) {
4242
)
4343
defer apiClient.ContainerRemove(ctx, id, client.ContainerRemoveOptions{Force: true})
4444

45-
inspect, err := apiClient.ContainerInspect(ctx, id)
45+
res, err := apiClient.ContainerInspect(ctx, id, client.ContainerInspectOptions{})
4646
assert.NilError(t, err)
4747

4848
expectedRequests := []containertypes.DeviceRequest{
@@ -51,7 +51,7 @@ func TestCreateWithCDIDevices(t *testing.T) {
5151
DeviceIDs: []string{"vendor1.com/device=foo"},
5252
},
5353
}
54-
assert.Check(t, is.DeepEqual(inspect.HostConfig.DeviceRequests, expectedRequests))
54+
assert.Check(t, is.DeepEqual(res.Container.HostConfig.DeviceRequests, expectedRequests))
5555

5656
poll.WaitOn(t, container.IsStopped(ctx, apiClient, id))
5757
reader, err := apiClient.ContainerLogs(ctx, id, client.ContainerLogsOptions{

0 commit comments

Comments
 (0)