From c86bbee38a3dda50fa511bc48820398669dc0682 Mon Sep 17 00:00:00 2001 From: Dustin Sallings Date: Wed, 27 Nov 2013 15:07:15 -0800 Subject: [PATCH 1/3] Add -format to 'docker inspect' This makes it a lot easier to script with docker instances as one can ask for details about running instances more easily without having to have additional JSON processing tools installed. dotcloud/docker#734 Upstream-commit: 9837ad8e9b96b118e8d004e773a05ff9dd208b48 Component: engine --- components/engine/commands.go | 50 ++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/components/engine/commands.go b/components/engine/commands.go index e24b7aeece..ec51983ca0 100644 --- a/components/engine/commands.go +++ b/components/engine/commands.go @@ -31,6 +31,7 @@ import ( "strings" "syscall" "text/tabwriter" + "text/template" "time" ) @@ -632,6 +633,7 @@ func (cli *DockerCli) CmdStart(args ...string) error { func (cli *DockerCli) CmdInspect(args ...string) error { cmd := cli.Subcmd("inspect", "CONTAINER|IMAGE [CONTAINER|IMAGE...]", "Return low-level information on a container/image") + tmplStr := cmd.String("format", "", "Format the output using the given go template.") if err := cmd.Parse(args); err != nil { return nil } @@ -640,10 +642,21 @@ func (cli *DockerCli) CmdInspect(args ...string) error { return nil } + var tmpl *template.Template + if *tmplStr != "" { + var err error + if tmpl, err = template.New("").Parse(*tmplStr); err != nil { + fmt.Fprintf(cli.err, "Template parsing error: %v\n", err) + return &utils.StatusError{StatusCode: 64, + Status: "Template parsing error: " + err.Error()} + } + } + indented := new(bytes.Buffer) + indented.WriteByte('[') status := 0 - for _, name := range args { + for _, name := range cmd.Args() { obj, _, err := cli.call("GET", "/containers/"+name+"/json", nil) if err != nil { obj, _, err = cli.call("GET", "/images/"+name+"/json", nil) @@ -658,23 +671,40 @@ func (cli *DockerCli) CmdInspect(args ...string) error { } } - if err = json.Indent(indented, obj, "", " "); err != nil { - fmt.Fprintf(cli.err, "%s\n", err) - status = 1 - continue + if tmpl == nil { + if err = json.Indent(indented, obj, "", " "); err != nil { + fmt.Fprintf(cli.err, "%s\n", err) + status = 1 + continue + } + } else { + // Has template, will render + var value interface{} + if err := json.Unmarshal(obj, &value); err != nil { + fmt.Fprintf(cli.err, "%s\n", err) + status = 1 + continue + } + if err := tmpl.Execute(cli.out, value); err != nil { + return err + } + cli.out.Write([]byte{'\n'}) } indented.WriteString(",") } - if indented.Len() > 0 { + if indented.Len() > 1 { // Remove trailing ',' indented.Truncate(indented.Len() - 1) } - fmt.Fprintf(cli.out, "[") - if _, err := io.Copy(cli.out, indented); err != nil { - return err + indented.WriteByte(']') + + if tmpl == nil { + if _, err := io.Copy(cli.out, indented); err != nil { + return err + } } - fmt.Fprintf(cli.out, "]") + if status != 0 { return &utils.StatusError{StatusCode: status} } From b0a3ce1eefe6ab88af1e8b75966333b0d3621747 Mon Sep 17 00:00:00 2001 From: Dustin Sallings Date: Fri, 29 Nov 2013 16:12:10 -0800 Subject: [PATCH 2/3] Use inspect format to get IP address for psql example Upstream-commit: 1d503be4660667a27b42f7bf0c089404cabd2c9c Component: engine --- components/engine/docs/sources/examples/postgresql_service.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/engine/docs/sources/examples/postgresql_service.rst b/components/engine/docs/sources/examples/postgresql_service.rst index 82ca8b59ca..e142f65899 100644 --- a/components/engine/docs/sources/examples/postgresql_service.rst +++ b/components/engine/docs/sources/examples/postgresql_service.rst @@ -127,7 +127,7 @@ on the machine. For ubuntu, use something like .. code-block:: bash - CONTAINER_IP=$(sudo docker inspect $CONTAINER | grep IPAddress | awk '{ print $2 }' | tr -d ',"') + CONTAINER_IP=$(sudo docker inspect -format='{{.NetworkSettings.IPAddress}}' $CONTAINER) psql -h $CONTAINER_IP -p 5432 -d docker -U docker -W As before, create roles or databases if needed. From 56e5aafa16b024624b87e338cd77b4745e01d9eb Mon Sep 17 00:00:00 2001 From: Dustin Sallings Date: Fri, 29 Nov 2013 16:36:50 -0800 Subject: [PATCH 3/3] CLI docs and examples of format Upstream-commit: 4ad3dfb05f1932793cae5c8047a89660747b95b4 Component: engine --- .../engine/docs/sources/commandline/cli.rst | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/components/engine/docs/sources/commandline/cli.rst b/components/engine/docs/sources/commandline/cli.rst index a6f15df8a6..d7bb03b954 100644 --- a/components/engine/docs/sources/commandline/cli.rst +++ b/components/engine/docs/sources/commandline/cli.rst @@ -659,6 +659,54 @@ Insert file from github Return low-level information on a container + -format="": template to output results + +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. + +Go's `text/template ` package +describes all the details of the format. + +Examples +~~~~~~~~ + +Get an instance's IP Address +............................ + +For the most part, you can pick out any field from the JSON in a +fairly straightforward manner. + +.. code-block:: bash + + docker inspect -format='{{.NetworkSettings.IPAddress}}' $INSTANCE_ID + +List All Port Bindings +...................... + +One can loop over arrays and maps in the results to produce simple +text output: + +.. code-block:: bash + + docker inspect -format='{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}' $INSTANCE_ID + +Find a Specific Port Mapping +............................ + +.. code-block:: bash + +The ``.Field`` syntax doesn't work when the field name begins with a +number, but the template language's ``index`` function does. The +``.NetworkSettings.Ports`` section contains a map of the internal port +mappings to a list of external address/port objects, so to grab just +the numeric public port, you use ``index`` to find the specific port +map, and then ``index`` 0 contains first object inside of that. Then +we ask for the ``HostPort`` field to get the public address. + +.. code-block:: bash + + docker inspect -format='{{(index (index .NetworkSettings.Ports "8787/tcp") 0).HostPort}}' $INSTANCE_ID + .. _cli_kill: ``kill``