github.com/goern/docker@v1.9.0-rc1/api/client/inspect.go (about) 1 package client 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io" 8 "net/url" 9 "strings" 10 "text/template" 11 12 "github.com/docker/docker/api/types" 13 Cli "github.com/docker/docker/cli" 14 flag "github.com/docker/docker/pkg/mflag" 15 ) 16 17 var funcMap = template.FuncMap{ 18 "json": func(v interface{}) string { 19 a, _ := json.Marshal(v) 20 return string(a) 21 }, 22 } 23 24 // CmdInspect displays low-level information on one or more containers or images. 25 // 26 // Usage: docker inspect [OPTIONS] CONTAINER|IMAGE [CONTAINER|IMAGE...] 27 func (cli *DockerCli) CmdInspect(args ...string) error { 28 cmd := Cli.Subcmd("inspect", []string{"CONTAINER|IMAGE [CONTAINER|IMAGE...]"}, Cli.DockerCommands["inspect"].Description, true) 29 tmplStr := cmd.String([]string{"f", "#format", "-format"}, "", "Format the output using the given go template") 30 inspectType := cmd.String([]string{"-type"}, "", "Return JSON for specified type, (e.g image or container)") 31 size := cmd.Bool([]string{"s", "-size"}, false, "Display total file sizes if the type is container") 32 cmd.Require(flag.Min, 1) 33 34 cmd.ParseFlags(args, true) 35 36 var tmpl *template.Template 37 var err error 38 var obj []byte 39 40 if *tmplStr != "" { 41 if tmpl, err = template.New("").Funcs(funcMap).Parse(*tmplStr); err != nil { 42 return Cli.StatusError{StatusCode: 64, 43 Status: "Template parsing error: " + err.Error()} 44 } 45 } 46 47 if *inspectType != "" && *inspectType != "container" && *inspectType != "image" { 48 return fmt.Errorf("%q is not a valid value for --type", *inspectType) 49 } 50 51 indented := new(bytes.Buffer) 52 indented.WriteString("[\n") 53 status := 0 54 isImage := false 55 56 v := url.Values{} 57 if *size { 58 v.Set("size", "1") 59 } 60 61 for _, name := range cmd.Args() { 62 63 if *inspectType == "" || *inspectType == "container" { 64 obj, _, err = readBody(cli.call("GET", "/containers/"+name+"/json?"+v.Encode(), nil, nil)) 65 if err != nil && *inspectType == "container" { 66 if strings.Contains(err.Error(), "No such") { 67 fmt.Fprintf(cli.err, "Error: No such container: %s\n", name) 68 } else { 69 fmt.Fprintf(cli.err, "%s", err) 70 } 71 status = 1 72 continue 73 } 74 } 75 76 if obj == nil && (*inspectType == "" || *inspectType == "image") { 77 obj, _, err = readBody(cli.call("GET", "/images/"+name+"/json", nil, nil)) 78 isImage = true 79 if err != nil { 80 if strings.Contains(err.Error(), "No such") { 81 if *inspectType == "" { 82 fmt.Fprintf(cli.err, "Error: No such image or container: %s\n", name) 83 } else { 84 fmt.Fprintf(cli.err, "Error: No such image: %s\n", name) 85 } 86 } else { 87 fmt.Fprintf(cli.err, "%s", err) 88 } 89 status = 1 90 continue 91 } 92 93 } 94 95 if tmpl == nil { 96 if err := json.Indent(indented, obj, "", " "); err != nil { 97 fmt.Fprintf(cli.err, "%s\n", err) 98 status = 1 99 continue 100 } 101 } else { 102 rdr := bytes.NewReader(obj) 103 dec := json.NewDecoder(rdr) 104 105 if isImage { 106 inspPtr := types.ImageInspect{} 107 if err := dec.Decode(&inspPtr); err != nil { 108 fmt.Fprintf(cli.err, "%s\n", err) 109 status = 1 110 continue 111 } 112 if err := tmpl.Execute(cli.out, inspPtr); err != nil { 113 rdr.Seek(0, 0) 114 var raw interface{} 115 if err := dec.Decode(&raw); err != nil { 116 return err 117 } 118 if err = tmpl.Execute(cli.out, raw); err != nil { 119 return err 120 } 121 } 122 } else { 123 inspPtr := types.ContainerJSON{} 124 if err := dec.Decode(&inspPtr); err != nil { 125 fmt.Fprintf(cli.err, "%s\n", err) 126 status = 1 127 continue 128 } 129 if err := tmpl.Execute(cli.out, inspPtr); err != nil { 130 rdr.Seek(0, 0) 131 var raw interface{} 132 if err := dec.Decode(&raw); err != nil { 133 return err 134 } 135 if err = tmpl.Execute(cli.out, raw); err != nil { 136 return err 137 } 138 } 139 } 140 cli.out.Write([]byte{'\n'}) 141 } 142 indented.WriteString(",") 143 } 144 145 if indented.Len() > 1 { 146 // Remove trailing ',' 147 indented.Truncate(indented.Len() - 1) 148 } 149 indented.WriteString("]\n") 150 151 if tmpl == nil { 152 // Note that we will always write "[]" when "-f" isn't specified, 153 // to make sure the output would always be array, see 154 // https://github.com/docker/docker/pull/9500#issuecomment-65846734 155 if _, err := io.Copy(cli.out, indented); err != nil { 156 return err 157 } 158 } 159 160 if status != 0 { 161 return Cli.StatusError{StatusCode: status} 162 } 163 return nil 164 }