mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
add size to inspect
Signed-off-by: Zhang Kun <zkazure@gmail.com>
This commit is contained in:
parent
bf80adeee4
commit
b4d6b23838
13 changed files with 108 additions and 8 deletions
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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"))
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue