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