PNG  IHDRQgAMA a cHRMz&u0`:pQ<bKGDgmIDATxwUﹻ& ^CX(J I@ "% (** BX +*i"]j(IH{~R)[~>h{}gy)I$Ij .I$I$ʊy@}x.: $I$Ii}VZPC)I$IF ^0ʐJ$I$Q^}{"r=OzI$gRZeC.IOvH eKX $IMpxsk.쒷/&r[޳<v| .I~)@$updYRa$I |M.e JaֶpSYR6j>h%IRز if&uJ)M$I vLi=H;7UJ,],X$I1AҒJ$ XY XzI@GNҥRT)E@;]K*Mw;#5_wOn~\ DC&$(A5 RRFkvIR}l!RytRl;~^ǷJj اy뷦BZJr&ӥ8Pjw~vnv X^(I;4R=P[3]J,]ȏ~:3?[ a&e)`e*P[4]T=Cq6R[ ~ޤrXR Հg(t_HZ-Hg M$ãmL5R uk*`%C-E6/%[t X.{8P9Z.vkXŐKjgKZHg(aK9ڦmKjѺm_ \#$5,)-  61eJ,5m| r'= &ڡd%-]J on Xm|{ RҞe $eڧY XYrԮ-a7RK6h>n$5AVڴi*ֆK)mѦtmr1p| q:흺,)Oi*ֺK)ܬ֦K-5r3>0ԔHjJئEZj,%re~/z%jVMڸmrt)3]J,T K֦OvԒgii*bKiNO~%PW0=dii2tJ9Jݕ{7"I P9JKTbu,%r"6RKU}Ij2HKZXJ,妝 XYrP ެ24c%i^IK|.H,%rb:XRl1X4Pe/`x&P8Pj28Mzsx2r\zRPz4J}yP[g=L) .Q[6RjWgp FIH*-`IMRaK9TXcq*I y[jE>cw%gLRԕiFCj-ďa`#e~I j,%r,)?[gp FI˨mnWX#>mʔ XA DZf9,nKҲzIZXJ,L#kiPz4JZF,I,`61%2s $,VOϚ2/UFJfy7K> X+6 STXIeJILzMfKm LRaK9%|4p9LwJI!`NsiazĔ)%- XMq>pk$-$Q2x#N ؎-QR}ᶦHZډ)J,l#i@yn3LN`;nڔ XuX5pF)m|^0(>BHF9(cզEerJI rg7 4I@z0\JIi䵙RR0s;$s6eJ,`n 䂦0a)S)A 1eJ,堌#635RIgpNHuTH_SԕqVe ` &S)>p;S$魁eKIuX`I4춒o}`m$1":PI<[v9^\pTJjriRŭ P{#{R2,`)e-`mgj~1ϣLKam7&U\j/3mJ,`F;M'䱀 .KR#)yhTq;pcK9(q!w?uRR,n.yw*UXj#\]ɱ(qv2=RqfB#iJmmL<]Y͙#$5 uTU7ӦXR+q,`I}qL'`6Kͷ6r,]0S$- [RKR3oiRE|nӦXR.(i:LDLTJjY%o:)6rxzҒqTJjh㞦I.$YR.ʼnGZ\ֿf:%55 I˼!6dKxm4E"mG_ s? .e*?LRfK9%q#uh$)i3ULRfK9yxm܌bj84$i1U^@Wbm4uJ,ҪA>_Ij?1v32[gLRD96oTaR׿N7%L2 NT,`)7&ƝL*꽙yp_$M2#AS,`)7$rkTA29_Iye"|/0t)$n XT2`YJ;6Jx".e<`$) PI$5V4]29SRI>~=@j]lp2`K9Jaai^" Ԋ29ORI%:XV5]JmN9]H;1UC39NI%Xe78t)a;Oi Ҙ>Xt"~G>_mn:%|~ޅ_+]$o)@ǀ{hgN;IK6G&rp)T2i୦KJuv*T=TOSV>(~D>dm,I*Ɛ:R#ۙNI%D>G.n$o;+#RR!.eU˽TRI28t)1LWϚ>IJa3oFbu&:tJ*(F7y0ZR ^p'Ii L24x| XRI%ۄ>S1]Jy[zL$adB7.eh4%%누>WETf+3IR:I3Xה)3אOۦSRO'ٺ)S}"qOr[B7ϙ.edG)^ETR"RtRݜh0}LFVӦDB^k_JDj\=LS(Iv─aTeZ%eUAM-0;~˃@i|l @S4y72>sX-vA}ϛBI!ݎߨWl*)3{'Y|iSlEڻ(5KtSI$Uv02,~ԩ~x;P4ցCrO%tyn425:KMlD ^4JRxSهF_}شJTS6uj+ﷸk$eZO%G*^V2u3EMj3k%)okI]dT)URKDS 7~m@TJR~荪fT"֛L \sM -0T KfJz+nإKr L&j()[E&I ߴ>e FW_kJR|!O:5/2跌3T-'|zX ryp0JS ~^F>-2< `*%ZFP)bSn"L :)+pʷf(pO3TMW$~>@~ū:TAIsV1}S2<%ޟM?@iT ,Eūoz%i~g|`wS(]oȤ8)$ ntu`өe`6yPl IzMI{ʣzʨ )IZ2= ld:5+請M$-ї;U>_gsY$ÁN5WzWfIZ)-yuXIfp~S*IZdt;t>KūKR|$#LcԀ+2\;kJ`]YǔM1B)UbG"IRߊ<xܾӔJ0Z='Y嵤 Leveg)$znV-º^3Ւof#0Tfk^Zs[*I꯳3{)ˬW4Ւ4 OdpbZRS|*I 55#"&-IvT&/윚Ye:i$ 9{LkuRe[I~_\ؠ%>GL$iY8 9ܕ"S`kS.IlC;Ҏ4x&>u_0JLr<J2(^$5L s=MgV ~,Iju> 7r2)^=G$1:3G< `J3~&IR% 6Tx/rIj3O< ʔ&#f_yXJiގNSz; Tx(i8%#4 ~AS+IjerIUrIj362v885+IjAhK__5X%nV%Iͳ-y|7XV2v4fzo_68"S/I-qbf; LkF)KSM$ Ms>K WNV}^`-큧32ŒVؙGdu,^^m%6~Nn&͓3ŒVZMsRpfEW%IwdǀLm[7W&bIRL@Q|)* i ImsIMmKmyV`i$G+R 0tV'!V)֏28vU7͒vHꦼtxꗞT ;S}7Mf+fIRHNZUkUx5SAJㄌ9MqμAIRi|j5)o*^'<$TwI1hEU^c_j?Е$%d`z cyf,XO IJnTgA UXRD }{H}^S,P5V2\Xx`pZ|Yk:$e ~ @nWL.j+ϝYb퇪bZ BVu)u/IJ_ 1[p.p60bC >|X91P:N\!5qUB}5a5ja `ubcVxYt1N0Zzl4]7­gKj]?4ϻ *[bg$)+À*x쳀ogO$~,5 زUS9 lq3+5mgw@np1sso Ӻ=|N6 /g(Wv7U;zωM=wk,0uTg_`_P`uz?2yI!b`kĸSo+Qx%!\οe|އԁKS-s6pu_(ֿ$i++T8=eY; צP+phxWQv*|p1. ά. XRkIQYP,drZ | B%wP|S5`~́@i޾ E;Չaw{o'Q?%iL{u D?N1BD!owPHReFZ* k_-~{E9b-~P`fE{AܶBJAFO wx6Rox5 K5=WwehS8 (JClJ~ p+Fi;ŗo+:bD#g(C"wA^ r.F8L;dzdIHUX݆ϞXg )IFqem%I4dj&ppT{'{HOx( Rk6^C٫O.)3:s(۳(Z?~ٻ89zmT"PLtw䥈5&b<8GZ-Y&K?e8,`I6e(֍xb83 `rzXj)F=l($Ij 2*(F?h(/9ik:I`m#p3MgLaKjc/U#n5S# m(^)=y=đx8ŬI[U]~SцA4p$-F i(R,7Cx;X=cI>{Km\ o(Tv2vx2qiiDJN,Ҏ!1f 5quBj1!8 rDFd(!WQl,gSkL1Bxg''՞^ǘ;pQ P(c_ IRujg(Wz bs#P­rz> k c&nB=q+ؔXn#r5)co*Ũ+G?7< |PQӣ'G`uOd>%Mctz# Ԫڞ&7CaQ~N'-P.W`Oedp03C!IZcIAMPUۀ5J<\u~+{9(FbbyAeBhOSܳ1 bÈT#ŠyDžs,`5}DC-`̞%r&ڙa87QWWp6e7 Rϫ/oY ꇅ Nܶըtc!LA T7V4Jsū I-0Pxz7QNF_iZgúWkG83 0eWr9 X]㾮݁#Jˢ C}0=3ݱtBi]_ &{{[/o[~ \q鯜00٩|cD3=4B_b RYb$óBRsf&lLX#M*C_L܄:gx)WΘsGSbuL rF$9';\4Ɍq'n[%p.Q`u hNb`eCQyQ|l_C>Lb꟟3hSb #xNxSs^ 88|Mz)}:](vbۢamŖ࿥ 0)Q7@0=?^k(*J}3ibkFn HjB׻NO z x}7p 0tfDX.lwgȔhԾŲ }6g E |LkLZteu+=q\Iv0쮑)QٵpH8/2?Σo>Jvppho~f>%bMM}\//":PTc(v9v!gոQ )UfVG+! 35{=x\2+ki,y$~A1iC6#)vC5^>+gǵ@1Hy٪7u;p psϰu/S <aʸGu'tD1ԝI<pg|6j'p:tպhX{o(7v],*}6a_ wXRk,O]Lܳ~Vo45rp"N5k;m{rZbΦ${#)`(Ŵg,;j%6j.pyYT?}-kBDc3qA`NWQū20/^AZW%NQ MI.X#P#,^Ebc&?XR tAV|Y.1!؅⨉ccww>ivl(JT~ u`ٵDm q)+Ri x/x8cyFO!/*!/&,7<.N,YDŽ&ܑQF1Bz)FPʛ?5d 6`kQձ λc؎%582Y&nD_$Je4>a?! ͨ|ȎWZSsv8 j(I&yj Jb5m?HWp=g}G3#|I,5v珿] H~R3@B[☉9Ox~oMy=J;xUVoj bUsl_35t-(ՃɼRB7U!qc+x4H_Qo֮$[GO<4`&č\GOc[.[*Af%mG/ ňM/r W/Nw~B1U3J?P&Y )`ѓZ1p]^l“W#)lWZilUQu`-m|xĐ,_ƪ|9i:_{*(3Gѧ}UoD+>m_?VPۅ15&}2|/pIOʵ> GZ9cmíتmnz)yߐbD >e}:) r|@R5qVSA10C%E_'^8cR7O;6[eKePGϦX7jb}OTGO^jn*媓7nGMC t,k31Rb (vyܴʭ!iTh8~ZYZp(qsRL ?b}cŨʊGO^!rPJO15MJ[c&~Z`"ѓޔH1C&^|Ш|rʼ,AwĴ?b5)tLU)F| &g٣O]oqSUjy(x<Ϳ3 .FSkoYg2 \_#wj{u'rQ>o;%n|F*O_L"e9umDds?.fuuQbIWz |4\0 sb;OvxOSs; G%T4gFRurj(֍ڑb uԖKDu1MK{1^ q; C=6\8FR艇!%\YÔU| 88m)֓NcLve C6z;o&X x59:q61Z(T7>C?gcļxѐ Z oo-08jہ x,`' ҔOcRlf~`jj".Nv+sM_]Zk g( UOPyεx%pUh2(@il0ݽQXxppx-NS( WO+轾 nFߢ3M<;z)FBZjciu/QoF 7R¥ ZFLF~#ȣߨ^<쩡ݛкvџ))ME>ώx4m#!-m!L;vv#~Y[đKmx9.[,UFS CVkZ +ߟrY٧IZd/ioi$%͝ب_ֶX3ܫhNU ZZgk=]=bbJS[wjU()*I =ώ:}-蹞lUj:1}MWm=̛ _ ¾,8{__m{_PVK^n3esw5ӫh#$-q=A̟> ,^I}P^J$qY~Q[ Xq9{#&T.^GVj__RKpn,b=`żY@^՝;z{paVKkQXj/)y TIc&F;FBG7wg ZZDG!x r_tƢ!}i/V=M/#nB8 XxЫ ^@CR<{䤭YCN)eKOSƟa $&g[i3.C6xrOc8TI;o hH6P&L{@q6[ Gzp^71j(l`J}]e6X☉#͕ ׈$AB1Vjh㭦IRsqFBjwQ_7Xk>y"N=MB0 ,C #o6MRc0|$)ف"1!ixY<B9mx `,tA>)5ػQ?jQ?cn>YZe Tisvh# GMމȇp:ԴVuږ8ɼH]C.5C!UV;F`mbBk LTMvPʍϤj?ԯ/Qr1NB`9s"s TYsz &9S%U԰> {<ؿSMxB|H\3@!U| k']$U+> |HHMLޢ?V9iD!-@x TIî%6Z*9X@HMW#?nN ,oe6?tQwڱ.]-y':mW0#!J82qFjH -`ѓ&M0u Uγmxϵ^-_\])@0Rt.8/?ٰCY]x}=sD3ojަЫNuS%U}ԤwHH>ڗjܷ_3gN q7[q2la*ArǓԖ+p8/RGM ]jacd(JhWko6ڎbj]i5Bj3+3!\j1UZLsLTv8HHmup<>gKMJj0@H%,W΃7R) ">c, xixј^ aܖ>H[i.UIHc U1=yW\=S*GR~)AF=`&2h`DzT󑓶J+?W+}C%P:|0H܆}-<;OC[~o.$~i}~HQ TvXΈr=b}$vizL4:ȰT|4~*!oXQR6Lk+#t/g lԁߖ[Jڶ_N$k*". xsxX7jRVbAAʯKҎU3)zSNN _'s?f)6X!%ssAkʱ>qƷb hg %n ~p1REGMHH=BJiy[<5 ǁJҖgKR*倳e~HUy)Ag,K)`Vw6bRR:qL#\rclK/$sh*$ 6덤 KԖc 3Z9=Ɣ=o>X Ώ"1 )a`SJJ6k(<c e{%kϊP+SL'TcMJWRm ŏ"w)qc ef꒵i?b7b('"2r%~HUS1\<(`1Wx9=8HY9m:X18bgD1u ~|H;K-Uep,, C1 RV.MR5άh,tWO8WC$ XRVsQS]3GJ|12 [vM :k#~tH30Rf-HYݺ-`I9%lIDTm\ S{]9gOڒMNCV\G*2JRŨ;Rҏ^ڽ̱mq1Eu?To3I)y^#jJw^Ńj^vvlB_⋌P4x>0$c>K†Aļ9s_VjTt0l#m>E-,,x,-W)سo&96RE XR.6bXw+)GAEvL)͞K4$p=Ũi_ѱOjb HY/+@θH9޼]Nԥ%n{ &zjT? Ty) s^ULlb,PiTf^<À] 62R^V7)S!nllS6~͝V}-=%* ʻ>G DnK<y&>LPy7'r=Hj 9V`[c"*^8HpcO8bnU`4JȪAƋ#1_\ XϘHPRgik(~G~0DAA_2p|J묭a2\NCr]M_0 ^T%e#vD^%xy-n}-E\3aS%yN!r_{ )sAw ڼp1pEAk~v<:`'ӭ^5 ArXOI驻T (dk)_\ PuA*BY]yB"l\ey hH*tbK)3 IKZ򹞋XjN n *n>k]X_d!ryBH ]*R 0(#'7 %es9??ښFC,ՁQPjARJ\Ρw K#jahgw;2$l*) %Xq5!U᢯6Re] |0[__64ch&_}iL8KEgҎ7 M/\`|.p,~`a=BR?xܐrQ8K XR2M8f ?`sgWS%" Ԉ 7R%$ N}?QL1|-эټwIZ%pvL3Hk>,ImgW7{E xPHx73RA @RS CC !\ȟ5IXR^ZxHл$Q[ŝ40 (>+ _C >BRt<,TrT {O/H+˟Pl6 I B)/VC<6a2~(XwV4gnXR ϱ5ǀHٻ?tw똤Eyxp{#WK qG%5],(0ӈH HZ])ג=K1j&G(FbM@)%I` XRg ʔ KZG(vP,<`[ Kn^ SJRsAʠ5xՅF`0&RbV tx:EaUE/{fi2;.IAwW8/tTxAGOoN?G}l L(n`Zv?pB8K_gI+ܗ #i?ޙ.) p$utc ~DžfՈEo3l/)I-U?aԅ^jxArA ΧX}DmZ@QLےbTXGd.^|xKHR{|ΕW_h] IJ`[G9{).y) 0X YA1]qp?p_k+J*Y@HI>^?gt.06Rn ,` ?);p pSF9ZXLBJPWjgQ|&)7! HjQt<| ؅W5 x W HIzYoVMGP Hjn`+\(dNW)F+IrS[|/a`K|ͻ0Hj{R,Q=\ (F}\WR)AgSG`IsnAR=|8$}G(vC$)s FBJ?]_u XRvύ6z ŨG[36-T9HzpW̞ú Xg큽=7CufzI$)ki^qk-) 0H*N` QZkk]/tnnsI^Gu't=7$ Z;{8^jB% IItRQS7[ϭ3 $_OQJ`7!]W"W,)Iy W AJA;KWG`IY{8k$I$^%9.^(`N|LJ%@$I}ֽp=FB*xN=gI?Q{٥4B)mw $Igc~dZ@G9K X?7)aK%݅K$IZ-`IpC U6$I\0>!9k} Xa IIS0H$I H ?1R.Чj:4~Rw@p$IrA*u}WjWFPJ$I➓/6#! LӾ+ X36x8J |+L;v$Io4301R20M I$-E}@,pS^ޟR[/s¹'0H$IKyfŸfVOπFT*a$I>He~VY/3R/)>d$I>28`Cjw,n@FU*9ttf$I~<;=/4RD~@ X-ѕzἱI$: ԍR a@b X{+Qxuq$IЛzo /~3\8ڒ4BN7$IҀj V]n18H$IYFBj3̵̚ja pp $Is/3R Ӻ-Yj+L;.0ŔI$Av? #!5"aʄj}UKmɽH$IjCYs?h$IDl843.v}m7UiI=&=0Lg0$I4: embe` eQbm0u? $IT!Sƍ'-sv)s#C0:XB2a w I$zbww{."pPzO =Ɔ\[ o($Iaw]`E).Kvi:L*#gР7[$IyGPI=@R 4yR~̮´cg I$I/<tPͽ hDgo 94Z^k盇΄8I56^W$I^0̜N?4*H`237}g+hxoq)SJ@p|` $I%>-hO0eO>\ԣNߌZD6R=K ~n($I$y3D>o4b#px2$yڪtzW~a $I~?x'BwwpH$IZݑnC㧄Pc_9sO gwJ=l1:mKB>Ab<4Lp$Ib o1ZQ@85b̍ S'F,Fe,^I$IjEdù{l4 8Ys_s Z8.x m"+{~?q,Z D!I$ϻ'|XhB)=…']M>5 rgotԎ 獽PH$IjIPhh)n#cÔqA'ug5qwU&rF|1E%I$%]!'3AFD/;Ck_`9 v!ٴtPV;x`'*bQa w I$Ix5 FC3D_~A_#O݆DvV?<qw+I$I{=Z8".#RIYyjǪ=fDl9%M,a8$I$Ywi[7ݍFe$s1ՋBVA?`]#!oz4zjLJo8$I$%@3jAa4(o ;p,,dya=F9ً[LSPH$IJYЉ+3> 5"39aZ<ñh!{TpBGkj}Sp $IlvF.F$I z< '\K*qq.f<2Y!S"-\I$IYwčjF$ w9 \ߪB.1v!Ʊ?+r:^!I$BϹB H"B;L'G[ 4U#5>੐)|#o0aڱ$I>}k&1`U#V?YsV x>{t1[I~D&(I$I/{H0fw"q"y%4 IXyE~M3 8XψL}qE$I[> nD?~sf ]o΁ cT6"?'_Ἣ $I>~.f|'!N?⟩0G KkXZE]ޡ;/&?k OۘH$IRۀwXӨ<7@PnS04aӶp.:@\IWQJ6sS%I$e5ڑv`3:x';wq_vpgHyXZ 3gЂ7{{EuԹn±}$I$8t;b|591nءQ"P6O5i }iR̈́%Q̄p!I䮢]O{H$IRϻ9s֧ a=`- aB\X0"+5"C1Hb?߮3x3&gşggl_hZ^,`5?ߎvĸ%̀M!OZC2#0x LJ0 Gw$I$I}<{Eb+y;iI,`ܚF:5ܛA8-O-|8K7s|#Z8a&><a&/VtbtLʌI$I$I$I$I$I$IRjDD%tEXtdate:create2022-05-31T04:40:26+00:00!Î%tEXtdate:modify2022-05-31T04:40:26+00:00|{2IENDB`Mini Shell

HOME


Mini Shell 1.0
DIR:/bin/
Upload File :
Current File : //bin/cloud-publish-image
#!/bin/bash
# This script uses bash arrays; do not switch to /bin/sh
#
#    cloud-publish-image - wrapper for cloud image publishing
#
#    Copyright (C) 2010 Canonical Ltd.
#
#    Authors: Scott Moser <smoser@canonical.com>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, version 3 of the License.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.


EC2PRE=${EC2PRE:-euca-}
TMPD=""
RENAME_D=""
VERBOSITY=0
IMAGE_TYPES=( auto image kernel ramdisk vmlinuz initrd )

error() { echo "$@" 1>&2; }
errorp() { printf "$@" 1>&2; }
fail() { [ $# -eq 0 ] || error "$@"; exit 1; }
failp() { [ $# -eq 0 ] || errorp "$@"; exit 1; }

Usage() {
	cat <<EOF
Usage: ${0##*/} [ options ] arch image bucket

   arch           : one of i386 or x86_64
   image          : the image to upload and register
   bucket         : bucket to publish image to

   options:
      -l|--add-launch ID          : ID can be "all", or "none", or numerical ID
         --dry-run                : only report what would be done
         --allow-existing         : if a image is already registered
                                    simply report as if work was done
         --hook-img EXE           : invoke executable 'EXE' with full path to
                                    downloaded disk image file
      -o|--output <file>          : write registered id and manifest to file
        |--rename <publish_path>  : publish to bucket/<publish_path>
                                    default: bucket/<basename(image)>
      -t|--type   <type>          : type is one of kernel/ramdisk/image
      -v|--verbose                : increase verbosity
         --name   <name>          : register with '--name'.
                                    default: publish_path

         --save-downloaded        : if the image is a url, save it to '.'

   if type is 'image', then:
      -k | --kernel  k        : use previously registered kernel with id 'k'
                                specify 'none' for no kernel
      -K | --kernel-file f    : bundle, upload, use file 'f' as kernel
      -r | --ramdisk r        : use previously registered ramdisk with id 'r'
                                specify 'none' for no ramdisk
      -R | --ramdisk-file f   : bundle, upload, use file 'f' as ramdisk
      -B | --block-device-mapping m : specify block device mapping in bundle
EOF
}

bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; exit 1; }
cleanup() {
	local x=""
	for x in "${RENAME_D}" "${TMPD}"; do
		[ -z "${x}" -o ! -d "${x}" ] || rm -Rf "${x}"
	done
	return 0
}

debug() {
	local level=${1}
	shift;
	[ "${level}" -ge "${VERBOSITY}" ] && return
	error "$(date):" "${@}"
}
run() {
	local dir="${1}" pre=${2} msg=${3};
	shift 3;
	[ -e "${dir}/stamp.${pre}" ] &&
		{ debug 1 "skipping ${pre}"; return 0; }
	debug 1 "${msg}"
	echo "$@" > "${dir}/${pre}.cmd"
	"$@" > "${dir}/${pre}.stdout" 2> "${dir}/${pre}.stderr" &&
		: > "${dir}/stamp.${pre}" && return 0
	local ret=$?
	echo "failed: ${*}"
	cat "${dir}/${pre}.stdout"
	cat "${dir}/${pre}.stderr" 1>&2
	return ${ret}
}

search_args() {
	local x="" i=0 needle="$1"
	shift;
	for x in "${@}"; do
		[ "${needle}" = "${x}" ] && { _RET=$i; return 0; }
		i=$(($i+1))
	done
	return 1
}

checkstatus() {
	local x="" i=0
	for x in "$@"; do
		[ "$x" = "0" ] || i=$(($i+1))
	done
	return $i
}

get_manifest_id() {
	local tmpf="" out="" ret=1 m1="${1}" m2="${2}"
	out=$(${EC2PRE}describe-images -o self |
		awk '$3 ~ m1 || $3 ~ m2 { printf("%s\t%s\n",$2,$3); }' \
				"m1=$m1" "m2=${m2:-^$}"
			checkstatus ${PIPESTATUS[@]}) || return 1
	_RET=${out}
	return
}
get_image_type() {
	local image=${1} file_out="" img_type=""
	file_out=$(file --uncompress "${image}") || return 1;
	case "${file_out}" in
		*[lL]inux\ kernel*) img_type="kernel";;
		*LSB\ executable*gzip*) img_type="kernel";;
		*cpio\ archive*) img_type="ramdisk";;
		*ext[234]\ file*|*boot\ sector*) img_type="image";;
		*) error "unable to determine image type. pass --type"; return 1;;
	esac
	_RET=${img_type}
	return 0
}

upload_register() {
	local out=""
	out=$(cloud-publish-image "${@}") || return
	set -- ${out}
	_RET=${1}
}

dl() {
	# dl url, target, quiet
	local url=${1} target=${2} quiet=${3:-1}
	if [ -f "${url}" ]; then
		[ "${target}" = "-" ] && { cat "$url"; return; }
		cp "$url" "$target"
		return
	fi
	local qflag="-q"
	[ "$quiet" = "0" ] && qflag=""

	wget $qflag --progress=dot:mega "$url" -O "$target" ||
		return 1
}

dl_input_image() {
	# this downloads an image if necessary and sets _RET to location of image
	local input="$1" save_dir="${2:-.}" ret="" quiet=1
	[ $VERBOSITY -ge 2 ] && quiet=0
	case "$input" in
		file://*)
			ret="$save_dir/${input##*/}"
			dl "${input#file://}" "$ret" $quiet || return $?;;
		http://*|ftp://*|https://*)
			ret="$save_dir/${input##*/}"
			dl "$input" "$ret" $quiet || return $?
			;;
		*) ret="$input";;
	esac
	_RET="$ret"
}


[ "${CLOUD_UTILS_WARN_UEC:-0}" = "0" ] && _n="${0##*/}" &&
	[ "${_n#uec}" != "${_n}" ] && export CLOUD_UTILS_WARN_UEC=1 &&
	error "WARNING: '${0##*/}' is now to 'cloud${_n#uec}'. Please update your tools or docs"

short_opts="B:h:k:K:l:no:r:R:t:vw:"
long_opts="add-launch:,allow-existing,block-device-mapping:,dry-run,help,hook-img:,kernel:,kernel-file:,name:,output:,image-to-raw,ramdisk:,ramdisk-file:,rename:,save-downloaded,type:,verbose,working-dir:"
getopt_out=$(getopt --name "${0##*/}" \
	--options "${short_opts}" --long "${long_opts}" -- "$@") &&
	eval set -- "${getopt_out}" ||
	bad_Usage

add_acl=""
allow_existing=0
arch=""
bucket=""
dry_run=0
image=""
img_type="image"
kernel=""
kernel_file=""
output=""
ramdisk=""
ramdisk_file=""
rename=""
save_dl=0
name=__unset__
wdir_in=""
dev_mapping=""
image2raw=0
raw_image=""
hook_img=""

while [ $# -ne 0 ]; do
	cur=${1}; next=${2};
	case "$cur" in
		-d|--working-dir) wdir_in=${next}; shift;;
		-h|--help) Usage; exit 0;;
		   --hook-img)
			[ -z "${hook_img}" ] || bad_Usage "only one --hook-img supported";
			[ -x "$next" ] || bad_Usage "--hook-img is not executable"
			hook_img=$(readlink -f "$next") ||
				bad_Usage "could not find full path to $next"
			hook_img="$next"
			shift;;
		-B|--block-device-mapping) dev_mapping=${next}; shift;;
		-k|--kernel) kernel=${next}; shift;;
		-K|--kernel-file) kernel_file=${next}; shift;;
		-l|--add-launch)
			if [ "${next}" = "none" ]; then
				add_acl=""
			else
				user=${next//-/}; # just be nice and remove '-'
				add_acl="${add_acl:+${add_acl} }${user}";
			fi
			shift;;
		   --name) name=${next}; shift;;
		-o|--output) output="${next}"; shift;;
		   --image-to-raw) image2raw=1;;
		-r|--ramdisk) ramdisk=${next}; shift;;
		-R|--ramdisk-file) ramdisk_file=${next}; shift;;
		-n|--dry-run) dry_run=1;;
		   --rename) rename=${next}; shift;;
		   --save-downloaded) save_dl=1;;
		-t|--type) 
			img_type=${next};
			search_args "${img_type}" "${IMAGE_TYPES[@]}" ||
				bad_Usage "image type (${next}) not in ${IMAGE_TYPES[*]}"
			shift;;
		-v|--verbose) VERBOSITY=$((${VERBOSITY}+1));;
		--allow-existing) allow_existing=1;;
		--) shift; break;;
		-*) bad_Usage "confused by ${cur}";;
	esac
	shift;
done

[ $# -lt 3 ] && bad_Usage "must provide arch, image, bucket"
[ $# -gt 3 ] && bad_Usage "unexpected arguments: ${4}"
arch="${1}"
image="${2}"
bucket="${3}"

# remove any trailing slashes on bucket
while [ "${bucket%/}" != "${bucket}" ]; do bucket=${bucket%/}; done

[ "${arch}" = "amd64" ] && arch=x86_64

[ "${img_type}" = "vmlinuz" ] && img_type="kernel"
[ "${img_type}" = "initrd" ] && img_type="ramdisk"

[ -n "${kernel_file}" -a -n "${kernel}" ] &&
	bad_Usage "--kernel-file is incompatible with --kernel"
[ -n "${ramdisk_file}" -a -n "${ramdisk}" ] &&
	bad_Usage "--ramdisk-file is incompatible with --ramdisk"

if [ -n "${wdir_in}" ]; then
	[ -d "${wdir_in}" ] || fail "input working directory not a directory";
	wdir=$(readlink -f "${wdir_in}") ||
		fail "failed to realize ${wdir_in}"
else
	TMPD=$(mktemp -d ${TMPDIR:-/tmp}/${0##*/}.XXXXXX) ||
		fail "failed to make tmpdir"
	wdir="${TMPD}"
fi
trap cleanup EXIT

if [ -n "$kernel" -a "$kernel" != "none" ]; then
	aki_arch=""; ari_arch="";
	# if kernel is given, check that its arch matches the register arch
	aki_arch=""; ari_arch="";
	
	[ "$ramdisk" = "none" ] && _ramdisk="" || _ramdisk="$ramdisk"

	${EC2PRE}describe-images "$kernel" $_ramdisk > "${TMPD}/kernel.info" ||
		fail "failed to describe kernel ${kernel}"
	aki_arch=$(awk '-F\t' '$1 == "IMAGE" && $2 == id { print $8 }' \
		"id=$kernel" "$TMPD/kernel.info") && [ -n "$aki_arch" ] ||
		fail "failed to get arch of $kernel"
	if [ -n "$ramdisk" -a "$ramdisk" != "none" ]; then
		ari_arch=$(awk '-F\t' '$1 == "IMAGE" && $2 == id { print $8 }' \
			"id=$ramdisk" "$TMPD/kernel.info") && [ -n "$ari_arch" ] ||
			fail "failed to get arch of $ramdisk"
	fi

	# if kernel and ramdisk are given, and arch=i386 kernel/ramdisk=x86_64,
	# then assume loader kernel.
	case "$arch:$aki_arch:$ari_arch" in
		$arch:$arch:$arch|$arch:$arch:) : ;;
		i386:x86_64:x86_64)
			error "WARNING: assuming loader kernel ($kernel/$ramdisk arch=$aki_arch, provided arch=$arch)"
			arch="x86_64";;
		*) fail "arch $arch != kernel/ramdisk arch [$aki_arch/$ari_arch]";;
	esac
fi

save_dir="${wdir}"
[ $save_dl -eq 1 ] && save_dir=.

dl_input_image "$image" "$save_dir" && image="$_RET" ||
	fail "failed to download image $image to $save_dir"

[ -z "$kernel_file" ] ||
	{ dl_input_image "$kernel_file" "$save_dir" && kernel_file="$_RET"; } ||
	fail "failed to download kernel $kernel_file to $save_dir"

[ -z "$ramdisk_file" ] ||
	{ dl_input_image "$ramdisk_file" "$save_dir" && ramdisk_file="$_RET"; } ||
	fail "failed to download ramdisk $ramdisk_file to $save_dir"

[ -f "${image}" ] || bad_Usage "${image}: image is not a file"

[ -z "${kernel_file}" -o -f "${kernel_file}" ] ||
	fail "${kernel_file} is not a file"
[ -z "${ramdisk_file}" -o -f "${ramdisk_file}" ] ||
	fail "${ramdisk_file} is not a file"

if [ "${img_type}" = "auto" ]; then
	get_image_type "${image}" ||
		fail "failed to determine file type of ${image}"
	img_type=${_RET}
fi

[ -n "${dev_mapping}" -a "${img_type}" != "image" ] &&
	fail "-B/--block-device-mapping can only be specified for --type=image"

[ -n "${rename}" ] || rename=${image##*/}

if [ "${name}" = "__unset__" ]; then

	# if user did not pass --name, try to figure out if register supports it
	# we unfortunately can't assume that '--help' exits 0
	${EC2PRE}register --help > "${TMPD}/register-help.out" 2>&1
	if grep -q -- "--name" "${TMPD}/register-help.out"; then
		name="${bucket}/${rename}"
		debug 1 "using ${name} for --name"
	else
		debug 1 "${EC2PRE}register seems not to support --name, not passing"
		name=""
	fi
	
elif [ -z "${name}" -o "${name}" == "none" ]; then
	# if user passed in '--name=""' or '--name=none", do not pass --name
	name=""
fi

image_full=$(readlink -f "${image}") ||
	fail "failed to get full path to ${image}"

if [ -e "${wdir}/${rename}" ]; then
	[ "${wdir}/${rename}" -ef "${image}" ] ||
		fail "${wdir} already contains file named ${rename}"
fi

# bundle-kernel doesn't like for file to exist in destination-dir
# so, create it one dir under there
RENAME_D=$(mktemp -d "${wdir}/.rename.XXXXXX") &&
	ln -s "${image_full}" "${RENAME_D}/${rename}" &&
	rename_full="${RENAME_D}/${rename}" ||
	fail "link failed: working-dir/rename/${rename} -> ${image_full}"

reg_id=""

manifest="${rename}.manifest.xml"

# set up "pass through" args to go through to kernel/ramdisk publishing
pthr=( )
[ $VERBOSITY -eq 0 ] || pthr[${#pthr[@]}]="--verbose"
[ ${allow_existing} -eq 0 ] || pthr[${#pthr[@]}]="--allow-existing"
[ -z "${add_acl}" ] ||
	{ pthr[${#pthr[@]}]="--add-launch"; pthr[${#pthr[@]}]="${add_acl}"; }
[ ${dry_run} -eq 0 ] || pthr[${#pthr[@]}]="--dry-run"

if [ -n "${kernel_file}" ]; then
	debug 1 "publishing kernel ${kernel_file}"
	upload_register --type kernel "${pthr[@]}" \
		"${arch}" "${kernel_file}" "${bucket}" ||
		fail "failed to register ${kernel_file}"
	kernel=${_RET}
	debug 1 "kernel registered as ${kernel}"
fi

if [ -n "${ramdisk_file}" ]; then
	debug 1 "publishing ramdisk ${ramdisk_file}"
	upload_register --type ramdisk "${pthr[@]}" \
		"${arch}" "${ramdisk_file}" "${bucket}" ||
		fail "failed to register ${ramdisk_file}"
	ramdisk=${_RET}
	debug 1 "ramdisk registered as ${ramdisk}"
fi

if [ ${VERBOSITY} -ge 1 -o ${dry_run} -ne 0 ]; then
	[ -n "${kernel}" ] && krd_fmt=" %s/%s" &&
		krd_args=( "${kernel}" "${ramdisk:-none}" )
	errorp "[%-6s] %s => %s/%s ${krd_fmt}\n" "${img_type}" \
		"${image##*/}" "${bucket}" "${rename}" "${krd_args[@]}"
	if [ ${dry_run} -ne 0 ]; then
		case "${img_type}" in
			kernel) pre="eki";;
			ramdisk) pre="eri";;
			image) pre="emi";;
		esac
		printf "%s\t%s\n" "${pre}-xxxxxxxx" "${bucket}/${rename##*/}"
		exit
	fi
fi

krd_args=( );
[ -n "${kernel}" -a "${kernel}" != "none" ] &&
	krd_args=( "${krd_args[@]}" "--kernel" "${kernel}" )
[ -n "${ramdisk}" -a "${ramdisk}" != "none" ] &&
	krd_args=( "${krd_args[@]}" "--ramdisk" "${ramdisk}" )

if [ "${EC2PRE%ec2-}" != "${EC2PRE}" ]; then
	req="EC2_CERT EC2_PRIVATE_KEY EC2_USER_ID EC2_ACCESS_KEY EC2_SECRET_KEY"
	for env_name in ${req}; do
		[ -n "${!env_name}" ] ||
			fail "when using ec2- tools, you must set env: ${req}"
	done
	ex_bundle_args=( --cert "${EC2_CERT}" 
	                 --privatekey "${EC2_PRIVATE_KEY}" 
	                 --user "${EC2_USER_ID}" )
	ex_upload_args=( --access-key "${EC2_ACCESS_KEY}" 
	                 --secret-key "${EC2_SECRET_KEY}" )

fi

debug 1 "checking for existing registered image at ${bucket}/${manifest}"
get_manifest_id "^${bucket}/${manifest}" "/$name$" ||
	fail "failed to check for existing manifest"
if [ -n "${_RET}" ]; then
	set -- ${_RET}
	img_id=${1}; path=${2}
	[ ${allow_existing} -eq 1 ] ||
		fail "${path} already registered as ${img_id}"
	debug 1 "using existing ${img_id} for ${bucket}/${manifest}"
else
	if [ $image2raw -eq 1 -a "$img_type" = "image" ]; then
		# this is really here because of LP: #836759 
		# but could be useful elsewhere
		qemu-img info "$image" > "${TMPD}/disk-info.out" ||
			fail "failed to qemu-img info $image"
		imgfmt=$(awk '-F:' '$1 == "file format" { sub(/ /,"",$2); print $2 }' \
			"${TMPD}/disk-info.out")
		if [ "$imgfmt" != "raw" ]; then
			debug 1 "converting image to raw"
			raw_image="${TMPD}/image.raw"
			qemu-img convert -O raw "$image" "$raw_image" ||
				fail "failed to convert image to raw"
			image="$raw_image"
			ln -sf "$raw_image" "$rename_full" ||
				fail "symlink to raw image $raw_image failed"
		else
			debug 1 "disk is already raw format, not converting"
		fi
	fi

	if [ -n "$hook_img" ]; then
		debug 1 "image hook: $hook_img $rename_full"
		"$hook_img" "$rename_full" ||
			fail "image hook failed: $hook_img ${rename_full} failed"
	fi

	bundle_args=( "--image" "${rename_full}" )
	[ -n "${dev_mapping}" ] &&
		bundle_args[${#bundle_args[@]}]="--block-device-mapping=${dev_mapping}"

	case "${img_type}" in
		kernel|ramdisk)
			bundle_args[${#bundle_args[@]}]="--${img_type}"
			bundle_args[${#bundle_args[@]}]="true"
	esac
	run "${wdir}" "bundle" "bundling ${img_type} ${image}" \
		${EC2PRE}bundle-image --destination "${wdir}" --arch "${arch}" \
			"${ex_bundle_args[@]}" \
			"${bundle_args[@]}" "${krd_args[@]}" ||
		fail "failed to bundle ${img_type} ${image}"

	run "${wdir}" "upload" "upload ${bucket}/${manifest}" \
		${EC2PRE}upload-bundle --bucket "${bucket}" \
				"${ex_upload_args[@]}" \
				--manifest "${wdir}/${manifest}" ||
			fail "failed to upload bundle to ${bucket}/${manifest}"

	junk="" img_id="";
	run "${wdir}" "register" "register ${bucket}/${manifest}" \
		${EC2PRE}register ${name:+--name "${name}"} \
			"${ex_register_args[@]}" "${bucket}/${manifest}" &&
		read junk img_id < "${wdir}/register.stdout" &&
		[ "${img_id#???-}" != "${img_id}" ] || {
			if bad=$(get_manifest_id "${bucket}/${manifest}" "/${name}") &&
			   [ -n "${bad}" ]; then
				set -- ${bad}
				bad_id=${1}
				error "un-registering invalid $bad" >/dev/null
				${EC2PRE}deregister "${bad_id}"
			fi
			fail "failed to register ${manifest}"
		}

	debug 1 "registered at ${bucket}/${manifest} as ${img_id}"

fi
debug 1 "${img_id} ${bucket}/${manifest}"

if [ -z "${output}" -o "${output}" = "-" ]; then
	printf "%s\t%s\n" "${img_id}" "${bucket}/${manifest}"
else
	printf "%s\t%s\n" "${img_id}" "${bucket}/${manifest}" >> "${output}"
fi

for user in ${add_acl}; do
	run "${wdir}" "add_user.${user}" \
		"add ${user} to ${manifest}" \
		${EC2PRE}modify-image-attribute \
			--launch-permission --add "${user}" "${img_id}" ||
		fail "failed to add launch permission for ${user} to ${img_id}"
done

exit 0

# vi: ts=4 noexpandtab