From 27c7ecb587c64ecf2057189f06b3d5ce365ed6e7 Mon Sep 17 00:00:00 2001 From: Solomon Hykes Date: Sat, 19 Jan 2013 17:43:42 -0800 Subject: [PATCH] CLI: more information in 'list' and 'layers' --- dockerd/.dockerd.go.swp | Bin 0 -> 28672 bytes dockerd/dockerd.go | 75 +++++++++++++++++++++++++++++++++------- 2 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 dockerd/.dockerd.go.swp diff --git a/dockerd/.dockerd.go.swp b/dockerd/.dockerd.go.swp new file mode 100644 index 0000000000000000000000000000000000000000..5bb84f54fd048b94e749ba04f63f70afc339e2ba GIT binary patch literal 28672 zcmeI4eQ+FSdB87$&>WCBq_lsu4ZObKcu$e{Bw2QhV&lk?Y>UXUV@b{sS(w$`N_X+y z?qzo`lJGb!Z5TQfI+;Sqq?8W*8bY0a%0LpJ=}b!?kSQezp-D@dG^82IOgd$tG)Uz1urk2AcfS$=>+q+kN-_eBQ5ppXWI(4jh|2q^`2J=lEQb%YFLV|2p!NQW2>sHS zU#WS^rDeYq2IbOnEvmK_?Xuq}Rs5)2_gfV%$|v0*{z`5u_OgG@g0qL21YYeDXhlog zc3qU)J~TKWqPV=US^fN_bFX%(WbMx+kVznuKqi4q0+|Fd31kw;B=D+|K-9b-_p7w{ z{J7Qci@(q7`F>q|e_{N6YtQr7#`kaB;Q0kT;UDQq|C;zdiT4X}1(JHikF&2#0+|Fd z31kw;B#=oUlRzecOahq%G6`f7$Rv z1Uw2~f_vd^_yf2Tej7dj0o({D;Cgr`yd4JME$}Pw%W(h2x!ej|2Uoz07v*vf!|l+5 z5x5kdMVW91Ou#R~o8YN8G&AAsB8-5}#(7%bQZc|LXDTXw@pu4_vwz8mxF z>K$swfI21NslYv|PKZQQBV4XRSP34jBqqjHQzq! zI+d}yAG$%mBG7L|5_)}5izLJemP2LRcBt!GRBjMZu~WI+>0CZ=qgLQaqMDba?N?rn zM)Ndz%)Jimm$W&N2H(<}a-(9;L{1P{2tdL%?~%mPnxB}w6V+5%XWq$FT5+V-bgkmg znwPYstA4cYEIA>YM!z!u>jvv8Z_wnV&7Df;P0F~SX0#Ry0+CQ-L`46&fm4oZH@nC~ z_hcxd8uJ?s$E#RGRDJHMTb6Ou-xYn)_v=MvC4HE5ZBI{Av>z0^JF>Uuh?DNG-P_83 zbL|A8Jx6z)Jx$H~>66H?xZbIqZB!tel!&=0mEtj|i_PniXzLbB&*#bNL~mHB#H=E^ z3>IWEMw3LECY~O}HIKBqsZ0=J9q=vb0IM_j^QTiaF-5P>G#Qw2=7=rHR;Jhn`F0wZ z7G!7Oq-xs9x80uJA=0mwoO#!5#h!IOmXrxEsy%y@><$~Q z$VXe=E4U!*dA!t!?EOtPm}p6|X3X`g0`)a@9Z_3C{m&j;I&|DC^qXLNlEp+<+MaeA zF5{=}JJI$b%Y@C;-s=`s$#kIk>I@juR@FOLOmLhlvGu)3c1pVM6w;S%Es?&GVn_6@ zqle~brP9-ps!;Qme8LOkwXlhNRJayK zZe!a@t>UufBF=`Ed*QUKBc}>Z6glOpBpB6KD)LoSb$LNzfIC5jG|g5-uX`26eAL(e zl5$kg@;u%IJ1=`lj_zvH4`88Q ze>s%A_PbHJs%s`8N>`!1=p~WE$ZtyI8NSa|#TB+{i6>jOk`WfSIC6V3mMWXtCq=aM zB$UKvI#P@tg~{`Zzv9U>l^EmkbrMG{1%5;7DY4p~em$Iy5>xuIAam7@7;mz2jc|3K)*)DY)U5qBDBgvxzxgh}_kv z)Sl!8LKbC{my2?+){JmfuR23Jc1i#fqFR#mTyA7Jl5cZ%&j|nFKNk zWD>|EkVznuKqi4q0+|Fd31kw;B#=qqCrbd8Tx_)w#oSD+qb_Wzs5RFKL_<}v5BjYj z#Ntv?mb~6;SuJhTSj%Z--0ZQG5#?hHt>fU>Xj=FTu0; z6MP;18g7Gk!*Q608{leq2}RC}@B(}pJ_ElFH-QIxVGrzv%i#z34SW}#g@1-;;2!t@ z)Zj2&4$r-Yy1{+$A()4K&9C_%0E1jq7k zW~G?O21V<>L8}@yuO&*yeidJJ)g}&8yVXwPg%RhH)F)2VRiPwJyGn;l5!xRkc__6? zH?X(+LKiJ@MXD8FbyX`4TVJgyH$;VxDqlHqLaN3Jl_Y4_X~yKQ>y$j)t*fLJzuo4a zim`nr=Aa^m2XQc={%LoOT7{x8^PMo}%?4%&7t5zH!fEp@rKwU$l^t&@Dt!lk4qcdu zAx6?v#v3i>t1@b^LNzR`k;VCuT?@tat|0{?C3f!h2K1`2F1uc|&Of9obvIgPZG(-? zN~p%;)`;$&go%HPi>m{=aFK>Cah>af)@Vys`&vs&ZeYzXNQl+l-O?rzf*7-r5hk^i zTw=*}O6(E4Xuj=zPUu=K`v}*Fqh(*$a)ULiI6r#yz=^q|Qzx#Sc-Ml-l)G7f%&FI{ zmg+;_Z4*En8g5keE3y1z@0|IC#5sqKrr}sQQu$$!E!-p;a^)`D*cC+OZAbM=Nh(xA zd2h1Zd()m}H#*V64d@Ck{h;D|l4y>tGpg1?b<$lE3y$lReXL)M+@nXv7$Wt0Y;N)t zHSEWWYpv;ulhGklQ<0DrJ0Ibv((P`P_^9A#)azo@&PVASeujiyo=MWWpj0vhEDx<+ogA2QZ#E zRkeGYT9WH!-*l-sALX$_GLsw5N!JqFpsWVWP16P9caual;o5#^;>3+ky%JKUZN=&H zz3y0SEG(}?k$r|0Ny^5H2Ok5O%*H6EE6V<(txxtbr`~c8FInO`qCH90Jux=B4WHpg zBxd1t$&6`FKa=`M^Yv7*_cK*&nesFBTG?d@>Z%GAj-{$61ckpG_r3JHw00LkI-A{9 zY@ynl(A0>f(u7dQq%N~eZ=@18!Zx#f-(Aj( z6j&Zl#eb)mdNSp&Bu{YINoJ!duj9qYT4jpXdBjsvPg5BfvINM;5W1}Y;)O9GLrnZ% zw9TIZLuF-faFy~v%*$=NZ>+%H=U3MH6&c8YNZbVU$wG#bsh>FG8M|vLemU{!GZIM+ zz&LO@^Pc3l_l*&poI@?L0canIK>lN#a8{F(3oSi*l ztthdq;v5<_*-_lY9W+pVarjLw{9qFYLa8XmR(rn_Idz$Y$TSuyh3gdJbn1GeUPYH- z6-I`KhKJZt@lvqHjc@9@ZC=d3Y?c9=CK>9jcgAI9qf=wQBvvZ!a0KjAV+Tj44@}Ic zz7kK@2X!4a#Q}%1Q@O-mx#{J+*V9SQW+~|C#OUnAxD?d={?+4t(_TgGc=_kG>Pog4 zoPG*PUNf_!vva!6g}v>-u|qoZjw3PNQ^xNYPvex!UD}5@$#7C9?G%ke7kwk|F}==U zQL`?O^c*oR5gp$xbDwqvlSy)R|DjG9v6&g2jP#qb~K1Vmr(LwE`vg9qUrI0K&s(Iwml?}s(G5pIA3FbtdFt?(B3 z5&D38;dAg=5M9D{7=j;j#(xMt1Ahjh3mAh@xCZuuf~Ps}KLt<1pTZrm498#w-UbEO z3>U)Voc%>F@DO|rz6u|QI!wbbTnLYF=D!y{0iqMQ2DZW`5Iw+y@NsxA=&@mjMfQIt zfwN0sL*+%LiBf6S(Z-1GR$LOo{JACpMrQf(2OPP`< zISwa>%1p__X*yH#WJ;d4f-F<=WJ;d1`~vv@hmt4#W2U*;F{^0Ld9~GP$MZ4081?fs)yhn*(?C;Wj`*Ue>DnX`?S^Op$V<-uHfQ%6LC*giIrZly?q7gsK=c5g zgFgoO&A-Hz-wb4*Oahq%G6`f7$Rv}wk0*il@!`*D z> longestCol { + longestCol = l + } + } + if longestCol > 50 { + longestCol = 50 + } else if longestCol < 5 { + longestCol = 8 + } + tpl := "%-16s %-*.*s %-6s %-25s %10s %-s\n" + fmt.Fprintf(stdout, tpl, "ID", longestCol, longestCol, "CMD", "STATUS", "CREATED", "CHANGES", "LAYERS") for _, container := range docker.containers { var layers []string for _, layer := range container.Layers { layers = append(layers, layer.Name) } - fmt.Fprintf(w, "%s\t%s %s\t?\t%s\n", - container.Id, - container.Cmd, - strings.Join(container.Args, " "), - strings.Join(layers, ", ")) + fmt.Fprintf(stdout, tpl, + /* ID */ container.Id, + /* CMD */ longestCol, longestCol, container.CmdString(), + /* STATUS */ "?", + /* CREATED */ humanDuration(time.Now().Sub(container.Created)) + " ago", + /* CHANGES */ fmt.Sprintf("%.1fM", float32(container.BytesChanged) / 1024 / 1024), + /* LAYERS */ strings.Join(layers, ", ")) } - w.Flush() return nil } @@ -147,6 +162,10 @@ func main() { func (docker *Docker) ServeHTTP(w http.ResponseWriter, r *http.Request) { cmd, args := URLToCall(r.URL) + if cmd == "" { + docker.CmdUsage(r.Body, w, "") + return + } method := docker.getMethod(cmd) if method == nil { docker.CmdUsage(r.Body, w, cmd) @@ -196,6 +215,7 @@ type Layer struct { Id string Name string Added time.Time + Size uint } type Container struct { @@ -203,6 +223,13 @@ type Container struct { Cmd string Args []string Layers []Layer + Created time.Time + FilesChanged uint + BytesChanged uint +} + +func (c *Container) CmdString() string { + return strings.Join(append([]string{c.Cmd}, c.Args...), " ") } type Cmd func(io.ReadCloser, io.Writer, ...string) error @@ -233,3 +260,27 @@ func randomId() string { id, _ := ComputeId(randomBytes()) // can't fail return id } + + +func humanDuration(d time.Duration) string { + if seconds := int(d.Seconds()); seconds < 1 { + return "Less than a second" + } else if seconds < 60 { + return fmt.Sprintf("%d seconds", seconds) + } else if minutes := int(d.Minutes()); minutes == 1 { + return "About a minute" + } else if minutes < 60 { + return fmt.Sprintf("%d minutes", minutes) + } else if hours := int(d.Hours()); hours == 1{ + return "About an hour" + } else if hours < 48 { + return fmt.Sprintf("%d hours", hours) + } else if hours < 24 * 7 * 2 { + return fmt.Sprintf("%d days", hours / 24) + } else if hours < 24 * 30 * 3 { + return fmt.Sprintf("%d weeks", hours / 24 / 7) + } else if hours < 24 * 365 * 2 { + return fmt.Sprintf("%d months", hours / 24 / 30) + } + return fmt.Sprintf("%d years", d.Hours() / 24 / 365) +}