PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i WWWWWW
Current Directory: /opt/saltstack/salt/lib/python3.10/site-packages/salt/states
Viewing File: /opt/saltstack/salt/lib/python3.10/site-packages/salt/states/lxc.py
""" Manage Linux Containers ======================= """ from salt.exceptions import CommandExecutionError, SaltInvocationError __docformat__ = "restructuredtext en" # Container existence/non-existence def present( name, running=None, clone_from=None, snapshot=False, profile=None, network_profile=None, template=None, options=None, image=None, config=None, fstype=None, size=None, backing=None, vgname=None, lvname=None, thinpool=None, path=None, ): """ .. versionchanged:: 2015.8.0 The :mod:`lxc.created <salt.states.lxc.created>` state has been renamed to ``lxc.present``, and the :mod:`lxc.cloned <salt.states.lxc.cloned>` state has been merged into this state. Create the named container if it does not exist name The name of the container to be created path path to the container parent default: /var/lib/lxc (system default) .. versionadded:: 2015.8.0 running : False * If ``True``, ensure that the container is running * If ``False``, ensure that the container is stopped * If ``None``, do nothing with regards to the running state of the container .. versionadded:: 2015.8.0 clone_from Create named container as a clone of the specified container snapshot : False Use Copy On Write snapshots (LVM). Only supported with ``clone_from``. profile Profile to use in container creation (see the :ref:`LXC Tutorial <tutorial-lxc-profiles-container>` for more information). Values in a profile will be overridden by the parameters listed below. network_profile Network Profile to use in container creation (see the :ref:`LXC Tutorial <tutorial-lxc-profiles-container>` for more information). Values in a profile will be overridden by the parameters listed below. .. versionadded:: 2015.5.2 **Container Creation Arguments** template The template to use. For example, ``ubuntu`` or ``fedora``. For a full list of available templates, check out the :mod:`lxc.templates <salt.modules.lxc.templates>` function. Conflicts with the ``image`` argument. .. note:: The ``download`` template requires the following three parameters to be defined in ``options``: * **dist** - The name of the distribution * **release** - Release name/version * **arch** - Architecture of the container The available images can be listed using the :mod:`lxc.images <salt.modules.lxc.images>` function. options .. versionadded:: 2015.5.0 Template-specific options to pass to the lxc-create command. These correspond to the long options (ones beginning with two dashes) that the template script accepts. For example: .. code-block:: yaml web01: lxc.present: - template: download - options: dist: centos release: 6 arch: amd64 Remember to double-indent the options, due to :ref:`how PyYAML works <nested-dict-indentation>`. For available template options, refer to the lxc template scripts which are usually located under ``/usr/share/lxc/templates``, or run ``lxc-create -t <template> -h``. image A tar archive to use as the rootfs for the container. Conflicts with the ``template`` argument. backing The type of storage to use. Set to ``lvm`` to use an LVM group. Defaults to filesystem within /var/lib/lxc. fstype Filesystem type to use on LVM logical volume size Size of the volume to create. Only applicable if ``backing`` is set to ``lvm``. vgname : lxc Name of the LVM volume group in which to create the volume for this container. Only applicable if ``backing`` is set to ``lvm``. lvname Name of the LVM logical volume in which to create the volume for this container. Only applicable if ``backing`` is set to ``lvm``. thinpool Name of a pool volume that will be used for thin-provisioning this container. Only applicable if ``backing`` is set to ``lvm``. """ ret = { "name": name, "result": True, "comment": f"Container '{name}' already exists", "changes": {}, } if not any((template, image, clone_from)): # Take a peek into the profile to see if there is a clone source there. # Otherwise, we're assuming this is a template/image creation. Also # check to see if none of the create types are in the profile. If this # is the case, then bail out early. c_profile = __salt__["lxc.get_container_profile"](profile) if not any(x for x in c_profile if x in ("template", "image", "clone_from")): ret["result"] = False ret["comment"] = ( "No template, image, or clone_from parameter " "was found in either the state's arguments or " "the LXC profile" ) else: try: # Assign the profile's clone_from param to the state, so that # we know to invoke lxc.clone to create the container. clone_from = c_profile["clone_from"] except KeyError: pass # Sanity check(s) if clone_from and not __salt__["lxc.exists"](clone_from, path=path): ret["result"] = False ret["comment"] = f"Clone source '{clone_from}' does not exist" if not ret["result"]: return ret action = f"cloned from {clone_from}" if clone_from else "created" state = {"old": __salt__["lxc.state"](name, path=path)} if __opts__["test"]: if state["old"] is None: ret["comment"] = "Container '{}' will be {}".format( name, f"cloned from {clone_from}" if clone_from else "created" ) ret["result"] = None return ret else: if running is None: # Container exists and we're not managing whether or not it's # running. Set the result back to True and return return ret elif running: if state["old"] in ("frozen", "stopped"): ret["comment"] = "Container '{}' would be {}".format( name, "unfrozen" if state["old"] == "frozen" else "started" ) ret["result"] = None return ret else: ret["comment"] += " and is running" return ret else: if state["old"] in ("frozen", "running"): ret["comment"] = f"Container '{name}' would be stopped" ret["result"] = None return ret else: ret["comment"] += " and is stopped" return ret if state["old"] is None: # Container does not exist try: if clone_from: result = __salt__["lxc.clone"]( name, clone_from, profile=profile, network_profile=network_profile, snapshot=snapshot, size=size, path=path, backing=backing, ) else: result = __salt__["lxc.create"]( name, profile=profile, network_profile=network_profile, template=template, options=options, image=image, config=config, fstype=fstype, size=size, backing=backing, vgname=vgname, path=path, lvname=lvname, thinpool=thinpool, ) except (CommandExecutionError, SaltInvocationError) as exc: ret["result"] = False ret["comment"] = exc.strerror else: if clone_from: ret["comment"] = "Cloned container '{}' as '{}'".format( clone_from, name ) else: ret["comment"] = f"Created container '{name}'" state["new"] = result["state"]["new"] if ret["result"] is True: # Enforce the "running" parameter if running is None: # Don't do anything pass elif running: c_state = __salt__["lxc.state"](name, path=path) if c_state == "running": ret["comment"] += " and is running" else: error = ", but it could not be started" try: start_func = "lxc.unfreeze" if c_state == "frozen" else "lxc.start" state["new"] = __salt__[start_func](name, path=path)["state"]["new"] if state["new"] != "running": ret["result"] = False ret["comment"] += error except (SaltInvocationError, CommandExecutionError) as exc: ret["result"] = False ret["comment"] += f"{error}: {exc}" else: if state["old"] is None: ret["comment"] += ", and the container was started" else: ret["comment"] = "Container '{}' was {}".format( name, "unfrozen" if state["old"] == "frozen" else "started" ) else: c_state = __salt__["lxc.state"](name, path=path) if c_state == "stopped": if state["old"] is not None: ret["comment"] += " and is stopped" else: error = ", but it could not be stopped" try: state["new"] = __salt__["lxc.stop"](name, path=path)["state"]["new"] if state["new"] != "stopped": ret["result"] = False ret["comment"] += error except (SaltInvocationError, CommandExecutionError) as exc: ret["result"] = False ret["comment"] += f"{error}: {exc}" else: if state["old"] is None: ret["comment"] += ", and the container was stopped" else: ret["comment"] = f"Container '{name}' was stopped" if "new" not in state: # Make sure we know the final state of the container before we return state["new"] = __salt__["lxc.state"](name, path=path) if state["old"] != state["new"]: ret["changes"]["state"] = state return ret def absent(name, stop=False, path=None): """ Ensure a container is not present, destroying it if present name Name of the container to destroy stop stop before destroying default: false .. versionadded:: 2015.5.2 path path to the container parent default: /var/lib/lxc (system default) .. versionadded:: 2015.8.0 .. code-block:: yaml web01: lxc.absent """ ret = { "name": name, "changes": {}, "result": True, "comment": f"Container '{name}' does not exist", } if not __salt__["lxc.exists"](name, path=path): return ret if __opts__["test"]: ret["result"] = None ret["comment"] = f"Container '{name}' would be destroyed" return ret try: result = __salt__["lxc.destroy"](name, stop=stop, path=path) except (SaltInvocationError, CommandExecutionError) as exc: ret["result"] = False ret["comment"] = f"Failed to destroy container: {exc}" else: ret["changes"]["state"] = result["state"] ret["comment"] = f"Container '{name}' was destroyed" return ret # Container state (running/frozen/stopped) def running(name, restart=False, path=None): """ .. versionchanged:: 2015.5.0 The :mod:`lxc.started <salt.states.lxc.started>` state has been renamed to ``lxc.running`` Ensure that a container is running .. note:: This state does not enforce the existence of the named container, it just starts the container if it is not running. To ensure that the named container exists, use :mod:`lxc.present <salt.states.lxc.present>`. name The name of the container path path to the container parent default: /var/lib/lxc (system default) .. versionadded:: 2015.8.0 restart : False Restart container if it is already running .. code-block:: yaml web01: lxc.running web02: lxc.running: - restart: True """ ret = { "name": name, "result": True, "comment": f"Container '{name}' is already running", "changes": {}, } state = {"old": __salt__["lxc.state"](name, path=path)} if state["old"] is None: ret["result"] = False ret["comment"] = f"Container '{name}' does not exist" return ret elif state["old"] == "running" and not restart: return ret elif state["old"] == "stopped" and restart: # No need to restart since container is not running restart = False if restart: if state["old"] != "stopped": action = ("restart", "restarted") else: action = ("start", "started") else: if state["old"] == "frozen": action = ("unfreeze", "unfrozen") else: action = ("start", "started") if __opts__["test"]: ret["result"] = None ret["comment"] = f"Container '{name}' would be {action[1]}" return ret try: if state["old"] == "frozen" and not restart: result = __salt__["lxc.unfreeze"](name, path=path) else: if restart: result = __salt__["lxc.restart"](name, path=path) else: result = __salt__["lxc.start"](name, path=path) except (CommandExecutionError, SaltInvocationError) as exc: ret["result"] = False ret["comment"] = exc.strerror state["new"] = __salt__["lxc.state"](name, path=path) else: state["new"] = result["state"]["new"] if state["new"] != "running": ret["result"] = False ret["comment"] = f"Unable to {action[0]} container '{name}'" else: ret["comment"] = "Container '{}' was successfully {}".format( name, action[1] ) try: ret["changes"]["restarted"] = result["restarted"] except KeyError: pass if state["old"] != state["new"]: ret["changes"]["state"] = state return ret def frozen(name, start=True, path=None): """ .. versionadded:: 2015.5.0 Ensure that a container is frozen .. note:: This state does not enforce the existence of the named container, it just freezes the container if it is running. To ensure that the named container exists, use :mod:`lxc.present <salt.states.lxc.present>`. name The name of the container path path to the container parent default: /var/lib/lxc (system default) .. versionadded:: 2015.8.0 start : True Start container first, if necessary. If ``False``, then this state will fail if the container is not running. .. code-block:: yaml web01: lxc.frozen web02: lxc.frozen: - start: False """ ret = { "name": name, "result": True, "comment": f"Container '{name}' is already frozen", "changes": {}, } state = {"old": __salt__["lxc.state"](name, path=path)} if state["old"] is None: ret["result"] = False ret["comment"] = f"Container '{name}' does not exist" elif state["old"] == "stopped" and not start: ret["result"] = False ret["comment"] = f"Container '{name}' is stopped" if ret["result"] is False or state["old"] == "frozen": return ret if state["old"] == "stopped": action = ("start and freeze", "started and frozen") else: action = ("freeze", "frozen") if __opts__["test"]: ret["result"] = None ret["comment"] = f"Container '{name}' would be {action[1]}" return ret try: result = __salt__["lxc.freeze"](name, start=start, path=path) except (CommandExecutionError, SaltInvocationError) as exc: ret["result"] = False ret["comment"] = exc.strerror state["new"] = __salt__["lxc.state"](name, path=path) else: state["new"] = result["state"]["new"] if state["new"] != "frozen": ret["result"] = False ret["comment"] = f"Unable to {action[0]} container '{name}'" else: ret["comment"] = "Container '{}' was successfully {}".format( name, action[1] ) try: ret["changes"]["started"] = result["started"] except KeyError: pass if state["old"] != state["new"]: ret["changes"]["state"] = state return ret def stopped(name, kill=False, path=None): """ Ensure that a container is stopped .. note:: This state does not enforce the existence of the named container, it just stops the container if it running or frozen. To ensure that the named container exists, use :mod:`lxc.present <salt.states.lxc.present>`, or use the :mod:`lxc.absent <salt.states.lxc.absent>` state to ensure that the container does not exist. name The name of the container path path to the container parent default: /var/lib/lxc (system default) .. versionadded:: 2015.8.0 kill : False Do not wait for the container to stop, kill all tasks in the container. Older LXC versions will stop containers like this irrespective of this argument. .. versionadded:: 2015.5.0 .. code-block:: yaml web01: lxc.stopped """ ret = { "name": name, "result": True, "comment": f"Container '{name}' is already stopped", "changes": {}, } state = {"old": __salt__["lxc.state"](name, path=path)} if state["old"] is None: ret["result"] = False ret["comment"] = f"Container '{name}' does not exist" return ret elif state["old"] == "stopped": return ret if kill: action = ("force-stop", "force-stopped") else: action = ("stop", "stopped") if __opts__["test"]: ret["result"] = None ret["comment"] = f"Container '{name}' would be {action[1]}" return ret try: result = __salt__["lxc.stop"](name, kill=kill, path=path) except (CommandExecutionError, SaltInvocationError) as exc: ret["result"] = False ret["comment"] = exc.strerror state["new"] = __salt__["lxc.state"](name, path=path) else: state["new"] = result["state"]["new"] if state["new"] != "stopped": ret["result"] = False ret["comment"] = f"Unable to {action[0]} container '{name}'" else: ret["comment"] = "Container '{}' was successfully {}".format( name, action[1] ) if state["old"] != state["new"]: ret["changes"]["state"] = state return ret def set_pass(name, **kwargs): # pylint: disable=W0613 """ .. deprecated:: 2015.5.0 This state function has been disabled, as it did not conform to design guidelines. Specifically, due to the fact that :mod:`lxc.set_password <salt.modules.lxc.set_password>` uses ``chpasswd(8)`` to set the password, there was no method to make this action idempotent (in other words, the password would be changed every time). This makes this state redundant, since the following state will do the same thing: .. code-block:: yaml setpass: module.run: - name: set_pass - m_name: root - password: secret """ return { "name": name, "comment": ( "The lxc.set_pass state is no longer supported. Please " "see the LXC states documentation for further " "information." ), "result": False, "changes": {}, } def edited_conf(name, lxc_conf=None, lxc_conf_unset=None): """ .. warning:: This state is unsuitable for setting parameters that appear more than once in an LXC config file, or parameters which must appear in a certain order (such as when configuring more than one network interface). `Issue #35523`_ was opened to track the addition of a suitable replacement or fix. Edit LXC configuration options .. deprecated:: 2015.5.0 path path to the container parent default: /var/lib/lxc (system default) .. versionadded:: 2015.8.0 .. code-block:: bash setconf: lxc.edited_conf: - name: ubuntu - lxc_conf: - network.ipv4.ip: 10.0.3.6 - lxc_conf_unset: - lxc.utsname .. _`Issue #35523`: https://github.com/saltstack/salt/issues/35523 """ if __opts__["test"]: return { "name": name, "comment": f"{name} lxc.conf will be edited", "result": True, "changes": {}, } if not lxc_conf_unset: lxc_conf_unset = {} if not lxc_conf: lxc_conf = {} cret = __salt__["lxc.update_lxc_conf"]( name, lxc_conf=lxc_conf, lxc_conf_unset=lxc_conf_unset ) cret["name"] = name return cret