github.com/ncdc/docker@v0.10.1-0.20160129113957-6c6729ef5b74/api/client/inspect.go (about)

     1  package client
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"text/template"
     7  
     8  	"github.com/docker/docker/api/client/inspect"
     9  	Cli "github.com/docker/docker/cli"
    10  	flag "github.com/docker/docker/pkg/mflag"
    11  	"github.com/docker/engine-api/client"
    12  )
    13  
    14  var funcMap = template.FuncMap{
    15  	"json": func(v interface{}) string {
    16  		a, _ := json.Marshal(v)
    17  		return string(a)
    18  	},
    19  }
    20  
    21  // CmdInspect displays low-level information on one or more containers or images.
    22  //
    23  // Usage: docker inspect [OPTIONS] CONTAINER|IMAGE [CONTAINER|IMAGE...]
    24  func (cli *DockerCli) CmdInspect(args ...string) error {
    25  	cmd := Cli.Subcmd("inspect", []string{"CONTAINER|IMAGE [CONTAINER|IMAGE...]"}, Cli.DockerCommands["inspect"].Description, true)
    26  	tmplStr := cmd.String([]string{"f", "-format"}, "", "Format the output using the given go template")
    27  	inspectType := cmd.String([]string{"-type"}, "", "Return JSON for specified type, (e.g image or container)")
    28  	size := cmd.Bool([]string{"s", "-size"}, false, "Display total file sizes if the type is container")
    29  	cmd.Require(flag.Min, 1)
    30  
    31  	cmd.ParseFlags(args, true)
    32  
    33  	if *inspectType != "" && *inspectType != "container" && *inspectType != "image" {
    34  		return fmt.Errorf("%q is not a valid value for --type", *inspectType)
    35  	}
    36  
    37  	var elementSearcher inspectSearcher
    38  	switch *inspectType {
    39  	case "container":
    40  		elementSearcher = cli.inspectContainers(*size)
    41  	case "image":
    42  		elementSearcher = cli.inspectImages(*size)
    43  	default:
    44  		elementSearcher = cli.inspectAll(*size)
    45  	}
    46  
    47  	return cli.inspectElements(*tmplStr, cmd.Args(), elementSearcher)
    48  }
    49  
    50  func (cli *DockerCli) inspectContainers(getSize bool) inspectSearcher {
    51  	return func(ref string) (interface{}, []byte, error) {
    52  		return cli.client.ContainerInspectWithRaw(ref, getSize)
    53  	}
    54  }
    55  
    56  func (cli *DockerCli) inspectImages(getSize bool) inspectSearcher {
    57  	return func(ref string) (interface{}, []byte, error) {
    58  		return cli.client.ImageInspectWithRaw(ref, getSize)
    59  	}
    60  }
    61  
    62  func (cli *DockerCli) inspectAll(getSize bool) inspectSearcher {
    63  	return func(ref string) (interface{}, []byte, error) {
    64  		c, rawContainer, err := cli.client.ContainerInspectWithRaw(ref, getSize)
    65  		if err != nil {
    66  			// Search for image with that id if a container doesn't exist.
    67  			if client.IsErrContainerNotFound(err) {
    68  				i, rawImage, err := cli.client.ImageInspectWithRaw(ref, getSize)
    69  				if err != nil {
    70  					if client.IsErrImageNotFound(err) {
    71  						return nil, nil, fmt.Errorf("Error: No such image or container: %s", ref)
    72  					}
    73  					return nil, nil, err
    74  				}
    75  				return i, rawImage, err
    76  			}
    77  			return nil, nil, err
    78  		}
    79  		return c, rawContainer, err
    80  	}
    81  }
    82  
    83  type inspectSearcher func(ref string) (interface{}, []byte, error)
    84  
    85  func (cli *DockerCli) inspectElements(tmplStr string, references []string, searchByReference inspectSearcher) error {
    86  	elementInspector, err := cli.newInspectorWithTemplate(tmplStr)
    87  	if err != nil {
    88  		return Cli.StatusError{StatusCode: 64, Status: err.Error()}
    89  	}
    90  
    91  	var inspectErr error
    92  	for _, ref := range references {
    93  		element, raw, err := searchByReference(ref)
    94  		if err != nil {
    95  			inspectErr = err
    96  			break
    97  		}
    98  
    99  		if err := elementInspector.Inspect(element, raw); err != nil {
   100  			inspectErr = err
   101  			break
   102  		}
   103  	}
   104  
   105  	if err := elementInspector.Flush(); err != nil {
   106  		cli.inspectErrorStatus(err)
   107  	}
   108  
   109  	if status := cli.inspectErrorStatus(inspectErr); status != 0 {
   110  		return Cli.StatusError{StatusCode: status}
   111  	}
   112  	return nil
   113  }
   114  
   115  func (cli *DockerCli) inspectErrorStatus(err error) (status int) {
   116  	if err != nil {
   117  		fmt.Fprintf(cli.err, "%s\n", err)
   118  		status = 1
   119  	}
   120  	return
   121  }
   122  
   123  func (cli *DockerCli) newInspectorWithTemplate(tmplStr string) (inspect.Inspector, error) {
   124  	elementInspector := inspect.NewIndentedInspector(cli.out)
   125  	if tmplStr != "" {
   126  		tmpl, err := template.New("").Funcs(funcMap).Parse(tmplStr)
   127  		if err != nil {
   128  			return nil, fmt.Errorf("Template parsing error: %s", err)
   129  		}
   130  		elementInspector = inspect.NewTemplateInspector(cli.out, tmpl)
   131  	}
   132  	return elementInspector, nil
   133  }