github.com/brahmaroutu/docker@v1.2.1-0.20160809185609-eb28dde01f16/api/client/formatter/container.go (about) 1 package formatter 2 3 import ( 4 "bytes" 5 "fmt" 6 "strconv" 7 "strings" 8 "time" 9 10 "github.com/docker/docker/api" 11 "github.com/docker/docker/pkg/stringid" 12 "github.com/docker/docker/pkg/stringutils" 13 "github.com/docker/engine-api/types" 14 "github.com/docker/go-units" 15 ) 16 17 const ( 18 defaultContainerTableFormat = "table {{.ID}}\t{{.Image}}\t{{.Command}}\t{{.RunningFor}} ago\t{{.Status}}\t{{.Ports}}\t{{.Names}}" 19 20 containerIDHeader = "CONTAINER ID" 21 namesHeader = "NAMES" 22 commandHeader = "COMMAND" 23 runningForHeader = "CREATED" 24 statusHeader = "STATUS" 25 portsHeader = "PORTS" 26 mountsHeader = "MOUNTS" 27 ) 28 29 // ContainerContext contains container specific information required by the formater, encapsulate a Context struct. 30 type ContainerContext struct { 31 Context 32 // Size when set to true will display the size of the output. 33 Size bool 34 // Containers 35 Containers []types.Container 36 } 37 38 func (ctx ContainerContext) Write() { 39 switch ctx.Format { 40 case tableFormatKey: 41 if ctx.Quiet { 42 ctx.Format = defaultQuietFormat 43 } else { 44 ctx.Format = defaultContainerTableFormat 45 if ctx.Size { 46 ctx.Format += `\t{{.Size}}` 47 } 48 } 49 case rawFormatKey: 50 if ctx.Quiet { 51 ctx.Format = `container_id: {{.ID}}` 52 } else { 53 ctx.Format = `container_id: {{.ID}}\nimage: {{.Image}}\ncommand: {{.Command}}\ncreated_at: {{.CreatedAt}}\nstatus: {{.Status}}\nnames: {{.Names}}\nlabels: {{.Labels}}\nports: {{.Ports}}\n` 54 if ctx.Size { 55 ctx.Format += `size: {{.Size}}\n` 56 } 57 } 58 } 59 60 ctx.buffer = bytes.NewBufferString("") 61 ctx.preformat() 62 63 tmpl, err := ctx.parseFormat() 64 if err != nil { 65 return 66 } 67 68 for _, container := range ctx.Containers { 69 containerCtx := &containerContext{ 70 trunc: ctx.Trunc, 71 c: container, 72 } 73 err = ctx.contextFormat(tmpl, containerCtx) 74 if err != nil { 75 return 76 } 77 } 78 79 ctx.postformat(tmpl, &containerContext{}) 80 } 81 82 type containerContext struct { 83 baseSubContext 84 trunc bool 85 c types.Container 86 } 87 88 func (c *containerContext) ID() string { 89 c.addHeader(containerIDHeader) 90 if c.trunc { 91 return stringid.TruncateID(c.c.ID) 92 } 93 return c.c.ID 94 } 95 96 func (c *containerContext) Names() string { 97 c.addHeader(namesHeader) 98 names := stripNamePrefix(c.c.Names) 99 if c.trunc { 100 for _, name := range names { 101 if len(strings.Split(name, "/")) == 1 { 102 names = []string{name} 103 break 104 } 105 } 106 } 107 return strings.Join(names, ",") 108 } 109 110 func (c *containerContext) Image() string { 111 c.addHeader(imageHeader) 112 if c.c.Image == "" { 113 return "<no image>" 114 } 115 if c.trunc { 116 if trunc := stringid.TruncateID(c.c.ImageID); trunc == stringid.TruncateID(c.c.Image) { 117 return trunc 118 } 119 } 120 return c.c.Image 121 } 122 123 func (c *containerContext) Command() string { 124 c.addHeader(commandHeader) 125 command := c.c.Command 126 if c.trunc { 127 command = stringutils.Truncate(command, 20) 128 } 129 return strconv.Quote(command) 130 } 131 132 func (c *containerContext) CreatedAt() string { 133 c.addHeader(createdAtHeader) 134 return time.Unix(int64(c.c.Created), 0).String() 135 } 136 137 func (c *containerContext) RunningFor() string { 138 c.addHeader(runningForHeader) 139 createdAt := time.Unix(int64(c.c.Created), 0) 140 return units.HumanDuration(time.Now().UTC().Sub(createdAt)) 141 } 142 143 func (c *containerContext) Ports() string { 144 c.addHeader(portsHeader) 145 return api.DisplayablePorts(c.c.Ports) 146 } 147 148 func (c *containerContext) Status() string { 149 c.addHeader(statusHeader) 150 return c.c.Status 151 } 152 153 func (c *containerContext) Size() string { 154 c.addHeader(sizeHeader) 155 srw := units.HumanSize(float64(c.c.SizeRw)) 156 sv := units.HumanSize(float64(c.c.SizeRootFs)) 157 158 sf := srw 159 if c.c.SizeRootFs > 0 { 160 sf = fmt.Sprintf("%s (virtual %s)", srw, sv) 161 } 162 return sf 163 } 164 165 func (c *containerContext) Labels() string { 166 c.addHeader(labelsHeader) 167 if c.c.Labels == nil { 168 return "" 169 } 170 171 var joinLabels []string 172 for k, v := range c.c.Labels { 173 joinLabels = append(joinLabels, fmt.Sprintf("%s=%s", k, v)) 174 } 175 return strings.Join(joinLabels, ",") 176 } 177 178 func (c *containerContext) Label(name string) string { 179 n := strings.Split(name, ".") 180 r := strings.NewReplacer("-", " ", "_", " ") 181 h := r.Replace(n[len(n)-1]) 182 183 c.addHeader(h) 184 185 if c.c.Labels == nil { 186 return "" 187 } 188 return c.c.Labels[name] 189 } 190 191 func (c *containerContext) Mounts() string { 192 c.addHeader(mountsHeader) 193 194 var name string 195 var mounts []string 196 for _, m := range c.c.Mounts { 197 if m.Name == "" { 198 name = m.Source 199 } else { 200 name = m.Name 201 } 202 if c.trunc { 203 name = stringutils.Truncate(name, 15) 204 } 205 mounts = append(mounts, name) 206 } 207 return strings.Join(mounts, ",") 208 }