add size to inspect

Signed-off-by: Zhang Kun <zkazure@gmail.com>
This commit is contained in:
Zhang Kun 2015-09-25 20:49:02 +08:00
parent bf80adeee4
commit b4d6b23838
13 changed files with 108 additions and 8 deletions

View File

@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"io"
"net/url"
"strings"
"text/template"
@ -27,6 +28,7 @@ func (cli *DockerCli) CmdInspect(args ...string) error {
cmd := Cli.Subcmd("inspect", []string{"CONTAINER|IMAGE [CONTAINER|IMAGE...]"}, Cli.DockerCommands["inspect"].Description, true)
tmplStr := cmd.String([]string{"f", "#format", "-format"}, "", "Format the output using the given go template")
inspectType := cmd.String([]string{"-type"}, "", "Return JSON for specified type, (e.g image or container)")
size := cmd.Bool([]string{"s", "-size"}, false, "Display total file sizes if the type is container")
cmd.Require(flag.Min, 1)
cmd.ParseFlags(args, true)
@ -51,10 +53,15 @@ func (cli *DockerCli) CmdInspect(args ...string) error {
status := 0
isImage := false
v := url.Values{}
if *size {
v.Set("size", "1")
}
for _, name := range cmd.Args() {
if *inspectType == "" || *inspectType == "container" {
obj, _, err = readBody(cli.call("GET", "/containers/"+name+"/json", nil, nil))
obj, _, err = readBody(cli.call("GET", "/containers/"+name+"/json?"+v.Encode(), nil, nil))
if err != nil && *inspectType == "container" {
if strings.Contains(err.Error(), "No such") {
fmt.Fprintf(cli.err, "Error: No such container: %s\n", name)

View File

@ -10,6 +10,7 @@ import (
// getContainersByName inspects containers configuration and serializes it as json.
func (s *router) getContainersByName(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
displaySize := httputils.BoolValue(r, "size")
if vars == nil {
return fmt.Errorf("Missing parameter")
}
@ -25,7 +26,7 @@ func (s *router) getContainersByName(ctx context.Context, w http.ResponseWriter,
case version.Equal("1.20"):
json, err = s.daemon.ContainerInspect120(vars["name"])
default:
json, err = s.daemon.ContainerInspect(vars["name"])
json, err = s.daemon.ContainerInspect(vars["name"], displaySize)
}
if err != nil {

View File

@ -269,6 +269,8 @@ type ContainerJSONBase struct {
ExecIDs []string
HostConfig *runconfig.HostConfig
GraphDriver GraphDriverData
SizeRw *int64 `json:",omitempty"`
SizeRootFs *int64 `json:",omitempty"`
}
// ContainerJSON is newly used struct along with MountPoint

View File

@ -207,6 +207,7 @@ complete -c docker -f -n '__fish_docker_no_subcommand' -a info -d 'Display syste
complete -c docker -f -n '__fish_docker_no_subcommand' -a inspect -d 'Return low-level information on a container or image'
complete -c docker -A -f -n '__fish_seen_subcommand_from inspect' -s f -l format -d 'Format the output using the given go template.'
complete -c docker -A -f -n '__fish_seen_subcommand_from inspect' -l help -d 'Print usage'
complete -c docker -A -f -n '__fish_seen_subcommand_from inspect' -s s -l size -d 'Display total file sizes if the type is container.'
complete -c docker -A -f -n '__fish_seen_subcommand_from inspect' -a '(__fish_print_docker_images)' -d "Image"
complete -c docker -A -f -n '__fish_seen_subcommand_from inspect' -a '(__fish_print_docker_containers all)' -d "Container"

View File

@ -548,6 +548,7 @@ __docker_subcommand() {
_arguments \
$opts_help \
"($help -f --format=-)"{-f,--format=-}"[Format the output using the given go template]:template: " \
"($help -s --size)"{-s,--size}"[Display total file sizes if the type is container]" \
"($help)--type=-[Return JSON for specified type]:type:(image container)" \
"($help -)*: :->values" && ret=0

View File

@ -11,7 +11,7 @@ import (
// ContainerInspect returns low-level information about a
// container. Returns an error if the container cannot be found, or if
// there is an error getting the data.
func (daemon *Daemon) ContainerInspect(name string) (*types.ContainerJSON, error) {
func (daemon *Daemon) ContainerInspect(name string, size bool) (*types.ContainerJSON, error) {
container, err := daemon.Get(name)
if err != nil {
return nil, err
@ -20,7 +20,7 @@ func (daemon *Daemon) ContainerInspect(name string) (*types.ContainerJSON, error
container.Lock()
defer container.Unlock()
base, err := daemon.getInspectData(container)
base, err := daemon.getInspectData(container, size)
if err != nil {
return nil, err
}
@ -40,7 +40,7 @@ func (daemon *Daemon) ContainerInspect120(name string) (*v1p20.ContainerJSON, er
container.Lock()
defer container.Unlock()
base, err := daemon.getInspectData(container)
base, err := daemon.getInspectData(container, false)
if err != nil {
return nil, err
}
@ -54,7 +54,7 @@ func (daemon *Daemon) ContainerInspect120(name string) (*v1p20.ContainerJSON, er
return &v1p20.ContainerJSON{base, mountPoints, config}, nil
}
func (daemon *Daemon) getInspectData(container *Container) (*types.ContainerJSONBase, error) {
func (daemon *Daemon) getInspectData(container *Container, size bool) (*types.ContainerJSONBase, error) {
// make a copy to play with
hostConfig := *container.hostConfig
@ -106,6 +106,16 @@ func (daemon *Daemon) getInspectData(container *Container) (*types.ContainerJSON
HostConfig: &hostConfig,
}
var (
sizeRw int64
sizeRootFs int64
)
if size {
sizeRw, sizeRootFs = container.getSize()
contJSONBase.SizeRw = &sizeRw
contJSONBase.SizeRootFs = &sizeRootFs
}
// Now set any platform-specific fields
contJSONBase = setPlatformSpecificContainerFields(container, contJSONBase)

View File

@ -27,7 +27,7 @@ func (daemon *Daemon) ContainerInspectPre120(name string) (*v1p19.ContainerJSON,
container.Lock()
defer container.Unlock()
base, err := daemon.getInspectData(container)
base, err := daemon.getInspectData(container, false)
if err != nil {
return nil, err
}

View File

@ -13,5 +13,5 @@ func addMountPoints(container *Container) []types.MountPoint {
// ContainerInspectPre120 get containers for pre 1.20 APIs.
func (daemon *Daemon) ContainerInspectPre120(name string) (*types.ContainerJSON, error) {
return daemon.ContainerInspect(name)
return daemon.ContainerInspect(name, false)
}

View File

@ -92,6 +92,7 @@ list of DNS options to be used in the container.
* `GET /info` now lists engine version information.
* `GET /containers/json` will return `ImageID` of the image used by container.
* `POST /exec/(name)/start` will now return an HTTP 409 when the container is either stopped or paused.
* `GET /containers/(name)/json` now accepts a `size` parameter. Setting this parameter to '1' returns container size information in the `SizeRw` and `SizeRootFs` fields.
### v1.20 API changes

View File

@ -466,6 +466,26 @@ Return low-level information on the container `id`
]
}
**Example request, with size information**:
GET /containers/4fa6e0f0c678/json?size=1 HTTP/1.1
**Example response, with size information**:
HTTP/1.1 200 OK
Content-Type: application/json
{
....
"SizeRw": 0,
"SizeRootFs": 972,
....
}
Query Parameters:
- **size** 1/True/true or 0/False/false, return container size information. Default is `false`.
Status Codes:
- **200** no error

View File

@ -18,6 +18,7 @@ parent = "smn_cli"
--help=false Print usage
--type=container|image Return JSON for specified type, permissible
values are "image" or "container"
-s, --size=false Display total file sizes if the type is container
By default, this will render all results in a JSON array. If a format is
specified, the given template will be executed for each result.

View File

@ -345,3 +345,43 @@ func (s *DockerSuite) TestInspectLogConfigNoType(c *check.C) {
c.Assert(logConfig.Type, check.Equals, "json-file")
c.Assert(logConfig.Config["max-file"], check.Equals, "42", check.Commentf("%v", logConfig))
}
func (s *DockerSuite) TestInspectNoSizeFlagContainer(c *check.C) {
//Both the container and image are named busybox. docker inspect will fetch container
//JSON SizeRw and SizeRootFs field. If there is no flag --size/-s, there are no size fields.
dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "top")
formatStr := fmt.Sprintf("--format='{{.SizeRw}},{{.SizeRootFs}}'")
out, _ := dockerCmd(c, "inspect", "--type=container", formatStr, "busybox")
c.Assert(strings.TrimSpace(out), check.Equals, "<nil>,<nil>", check.Commentf("Exepcted not to display size info: %s", out))
}
func (s *DockerSuite) TestInspectSizeFlagContainer(c *check.C) {
//Both the container and image are named busybox. docker inspect will fetch container
//JSON SizeRw and SizeRootFs field. If there is a flag --size/-s, the fields are not <no value>.
dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "top")
formatStr := fmt.Sprintf("--format='{{.SizeRw}},{{.SizeRootFs}}'")
out, _ := dockerCmd(c, "inspect", "-s", "--type=container", formatStr, "busybox")
sz := strings.Split(out, ",")
c.Assert(strings.TrimSpace(sz[0]), check.Not(check.Equals), "<nil>")
c.Assert(strings.TrimSpace(sz[1]), check.Not(check.Equals), "<nil>")
}
func (s *DockerSuite) TestInspectSizeFlagImage(c *check.C) {
//Both the container and image are named busybox. docker inspect will fetch image
//JSON SizeRw and SizeRootFs field. There are no these fields since they are only in containers.
dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "top")
formatStr := fmt.Sprintf("--format='{{.SizeRw}},{{.SizeRootFs}}'")
out, _ := dockerCmd(c, "inspect", "-s", "--type=image", formatStr, "busybox")
c.Assert(strings.TrimSpace(out), check.Equals, "<no value>,<no value>", check.Commentf("Fields SizeRw and SizeRootFs are not exepcted to exist"))
}

View File

@ -8,6 +8,7 @@ docker-inspect - Return low-level information on a container or image
**docker inspect**
[**--help**]
[**-f**|**--format**[=*FORMAT*]]
[**-s**|**--size**[=*false*]]
[**--type**=*container*|*image*]
CONTAINER|IMAGE [CONTAINER|IMAGE...]
@ -25,6 +26,9 @@ each result.
**-f**, **--format**=""
Format the output using the given Go template.
**-s**, **--size**=false
Display total file sizes if the type is container.
**--type**=*container*|*image*
Return JSON for specified type, permissible values are "image" or "container"
@ -205,6 +209,18 @@ output:
You can get more information about how to write a Go template from:
https://golang.org/pkg/text/template/.
## Getting size information on an container
$ docker inspect -s d2cc496561d6
[
{
....
"SizeRw": 0,
"SizeRootFs": 972,
....
}
]
## Getting information on an image
Use an image's ID or name (e.g., repository/name[:tag]) to get information