Currently `docker inspect -f` use json.Unmarshal() unmarshal
to interface, it will store all JSON numbers in float64, so
we use `docker inspect 4f0d73b75a0d | grep Memory` and
`docker inspect -f {{.HostConfig.Memory}} 4f0d73b75a0d` will
get different values.
Signed-off-by: Qiang Huang <h.huangqiang@huawei.com>
... | ... |
@@ -57,9 +57,14 @@ func (cli *DockerCli) CmdInspect(args ...string) error { |
57 | 57 |
continue |
58 | 58 |
} |
59 | 59 |
} else { |
60 |
- // Has template, will render |
|
61 | 60 |
var value interface{} |
62 |
- if err := json.Unmarshal(obj, &value); err != nil { |
|
61 |
+ |
|
62 |
+ // Do not use `json.Unmarshal()` because unmarshal JSON into |
|
63 |
+ // an interface value, Unmarshal stores JSON numbers in |
|
64 |
+ // float64, which is different from `json.Indent()` does. |
|
65 |
+ dec := json.NewDecoder(bytes.NewReader(obj)) |
|
66 |
+ dec.UseNumber() |
|
67 |
+ if err := dec.Decode(&value); err != nil { |
|
63 | 68 |
fmt.Fprintf(cli.err, "%s\n", err) |
64 | 69 |
status = 1 |
65 | 70 |
continue |
... | ... |
@@ -5383,11 +5383,11 @@ func (s *DockerSuite) TestBuildResourceConstraintsAreUsed(c *check.C) { |
5383 | 5383 |
cID := strings.TrimSpace(out) |
5384 | 5384 |
|
5385 | 5385 |
type hostConfig struct { |
5386 |
- Memory float64 // Use float64 here since the json decoder sees it that way |
|
5387 |
- MemorySwap int |
|
5386 |
+ Memory int64 |
|
5387 |
+ MemorySwap int64 |
|
5388 | 5388 |
CpusetCpus string |
5389 | 5389 |
CpusetMems string |
5390 |
- CpuShares int |
|
5390 |
+ CpuShares int64 |
|
5391 | 5391 |
} |
5392 | 5392 |
|
5393 | 5393 |
cfg, err := inspectFieldJSON(cID, "HostConfig") |
... | ... |
@@ -5399,10 +5399,9 @@ func (s *DockerSuite) TestBuildResourceConstraintsAreUsed(c *check.C) { |
5399 | 5399 |
if err := json.Unmarshal([]byte(cfg), &c1); err != nil { |
5400 | 5400 |
c.Fatal(err, cfg) |
5401 | 5401 |
} |
5402 |
- mem := int64(c1.Memory) |
|
5403 |
- if mem != 67108864 || c1.MemorySwap != -1 || c1.CpusetCpus != "0" || c1.CpusetMems != "0" || c1.CpuShares != 100 { |
|
5402 |
+ if c1.Memory != 67108864 || c1.MemorySwap != -1 || c1.CpusetCpus != "0" || c1.CpusetMems != "0" || c1.CpuShares != 100 { |
|
5404 | 5403 |
c.Fatalf("resource constraints not set properly:\nMemory: %d, MemSwap: %d, CpusetCpus: %s, CpusetMems: %s, CpuShares: %d", |
5405 |
- mem, c1.MemorySwap, c1.CpusetCpus, c1.CpusetMems, c1.CpuShares) |
|
5404 |
+ c1.Memory, c1.MemorySwap, c1.CpusetCpus, c1.CpusetMems, c1.CpuShares) |
|
5406 | 5405 |
} |
5407 | 5406 |
|
5408 | 5407 |
// Make sure constraints aren't saved to image |
... | ... |
@@ -5416,10 +5415,9 @@ func (s *DockerSuite) TestBuildResourceConstraintsAreUsed(c *check.C) { |
5416 | 5416 |
if err := json.Unmarshal([]byte(cfg), &c2); err != nil { |
5417 | 5417 |
c.Fatal(err, cfg) |
5418 | 5418 |
} |
5419 |
- mem = int64(c2.Memory) |
|
5420 |
- if mem == 67108864 || c2.MemorySwap == -1 || c2.CpusetCpus == "0" || c2.CpusetMems == "0" || c2.CpuShares == 100 { |
|
5419 |
+ if c2.Memory == 67108864 || c2.MemorySwap == -1 || c2.CpusetCpus == "0" || c2.CpusetMems == "0" || c2.CpuShares == 100 { |
|
5421 | 5420 |
c.Fatalf("resource constraints leaked from build:\nMemory: %d, MemSwap: %d, CpusetCpus: %s, CpusetMems: %s, CpuShares: %d", |
5422 |
- mem, c2.MemorySwap, c2.CpusetCpus, c2.CpusetMems, c2.CpuShares) |
|
5421 |
+ c2.Memory, c2.MemorySwap, c2.CpusetCpus, c2.CpusetMems, c2.CpuShares) |
|
5423 | 5422 |
} |
5424 | 5423 |
|
5425 | 5424 |
} |
... | ... |
@@ -21,3 +21,23 @@ func (s *DockerSuite) TestInspectImage(c *check.C) { |
21 | 21 |
} |
22 | 22 |
|
23 | 23 |
} |
24 |
+ |
|
25 |
+func (s *DockerSuite) TestInspectInt64(c *check.C) { |
|
26 |
+ runCmd := exec.Command(dockerBinary, "run", "-d", "-m=300M", "busybox", "true") |
|
27 |
+ out, _, _, err := runCommandWithStdoutStderr(runCmd) |
|
28 |
+ if err != nil { |
|
29 |
+ c.Fatalf("failed to run container: %v, output: %q", err, out) |
|
30 |
+ } |
|
31 |
+ |
|
32 |
+ out = strings.TrimSpace(out) |
|
33 |
+ |
|
34 |
+ inspectCmd := exec.Command(dockerBinary, "inspect", "-f", "{{.HostConfig.Memory}}", out) |
|
35 |
+ inspectOut, _, err := runCommandWithOutput(inspectCmd) |
|
36 |
+ if err != nil { |
|
37 |
+ c.Fatalf("failed to inspect container: %v, output: %q", err, inspectOut) |
|
38 |
+ } |
|
39 |
+ |
|
40 |
+ if strings.TrimSpace(inspectOut) != "314572800" { |
|
41 |
+ c.Fatalf("inspect got wrong value, got: %q, expected: 314572800", inspectOut) |
|
42 |
+ } |
|
43 |
+} |