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/modules
Viewing File: /opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/upstart_service.py
""" Module for the management of upstart systems. The Upstart system only supports service starting, stopping and restarting. .. important:: If you feel that Salt should be using this module to manage services on a minion, and it is using a different module (or gives an error similar to *'service.start' is not available*), see :ref:`here <module-provider-override>`. Currently (as of Ubuntu 12.04) there is no tool available to disable Upstart services (like update-rc.d). This[1] is the recommended way to disable an Upstart service. So we assume that all Upstart services that have not been disabled in this manner are enabled. But this is broken because we do not check to see that the dependent services are enabled. Otherwise we would have to do something like parse the output of "initctl show-config" to determine if all service dependencies are enabled to start on boot. For example, see the "start on" condition for the lightdm service below[2]. And this would be too hard. So we wait until the upstart developers have solved this problem. :) This is to say that an Upstart service that is enabled may not really be enabled. Also, when an Upstart service is enabled, should the dependent services be enabled too? Probably not. But there should be a notice about this, at least. [1] http://upstart.ubuntu.com/cookbook/#disabling-a-job-from-automatically-starting [2] example upstart configuration file:: lightdm emits login-session-start emits desktop-session-start emits desktop-shutdown start on ((((filesystem and runlevel [!06]) and started dbus) and (drm-device-added card0 PRIMARY_DEVICE_FOR_DISPLAY=1 or stopped udev-fallback-graphics)) or runlevel PREVLEVEL=S) stop on runlevel [016] .. warning:: This module should not be used on Red Hat systems. For these, the :mod:`rh_service <salt.modules.rh_service>` module should be used, as it supports the hybrid upstart/sysvinit system used in RHEL/CentOS 6. """ import fnmatch import glob import os import re import salt.modules.cmdmod import salt.utils.files import salt.utils.path import salt.utils.systemd __func_alias__ = {"reload_": "reload"} # Define the module's virtual name __virtualname__ = "service" def __virtual__(): """ Only work on Ubuntu """ # Disable on these platforms, specific service modules exist: if salt.utils.systemd.booted(__context__): return ( False, "The upstart execution module failed to load: this system was booted with" " systemd.", ) elif __grains__["os"] in ("Ubuntu", "Linaro", "elementary OS", "Mint"): return __virtualname__ elif __grains__["os"] in ("Debian", "Raspbian"): debian_initctl = "/sbin/initctl" if os.path.isfile(debian_initctl): initctl_version = salt.modules.cmdmod._run_quiet( debian_initctl + " version" ) if "upstart" in initctl_version: return __virtualname__ return ( False, "The upstart execution module failed to load: " " the system must be Ubuntu-based, or Debian-based with upstart support.", ) def _find_utmp(): """ Figure out which utmp file to use when determining runlevel. Sometimes /var/run/utmp doesn't exist, /run/utmp is the new hotness. """ result = {} # These are the likely locations for the file on Ubuntu for utmp in "/var/run/utmp", "/run/utmp": try: result[os.stat(utmp).st_mtime] = utmp except Exception: # pylint: disable=broad-except pass if result: return result[sorted(result).pop()] else: return False def _default_runlevel(): """ Try to figure out the default runlevel. It is kept in /etc/init/rc-sysinit.conf, but can be overridden with entries in /etc/inittab, or via the kernel command-line at boot """ # Try to get the "main" default. If this fails, throw up our # hands and just guess "2", because things are horribly broken try: with salt.utils.files.fopen("/etc/init/rc-sysinit.conf") as fp_: for line in fp_: line = salt.utils.stringutils.to_unicode(line) if line.startswith("env DEFAULT_RUNLEVEL"): runlevel = line.split("=")[-1].strip() except Exception: # pylint: disable=broad-except return "2" # Look for an optional "legacy" override in /etc/inittab try: with salt.utils.files.fopen("/etc/inittab") as fp_: for line in fp_: line = salt.utils.stringutils.to_unicode(line) if not line.startswith("#") and "initdefault" in line: runlevel = line.split(":")[1] except Exception: # pylint: disable=broad-except pass # The default runlevel can also be set via the kernel command-line. # Kinky. try: valid_strings = {"0", "1", "2", "3", "4", "5", "6", "s", "S", "-s", "single"} with salt.utils.files.fopen("/proc/cmdline") as fp_: for line in fp_: line = salt.utils.stringutils.to_unicode(line) for arg in line.strip().split(): if arg in valid_strings: runlevel = arg break except Exception: # pylint: disable=broad-except pass return runlevel def _runlevel(): """ Return the current runlevel """ if "upstart._runlevel" in __context__: return __context__["upstart._runlevel"] ret = _default_runlevel() utmp = _find_utmp() if utmp: out = __salt__["cmd.run"](["runlevel", f"{utmp}"], python_shell=False) try: ret = out.split()[1] except IndexError: pass __context__["upstart._runlevel"] = ret return ret def _is_symlink(name): return os.path.abspath(name) != os.path.realpath(name) def _service_is_upstart(name): """ From "Writing Jobs" at http://upstart.ubuntu.com/getting-started.html: Jobs are defined in files placed in /etc/init, the name of the job is the filename under this directory without the .conf extension. """ return os.access(f"/etc/init/{name}.conf", os.R_OK) def _upstart_is_disabled(name): """ An Upstart service is assumed disabled if a manual stanza is placed in /etc/init/[name].override. NOTE: An Upstart service can also be disabled by placing "manual" in /etc/init/[name].conf. """ files = [f"/etc/init/{name}.conf", f"/etc/init/{name}.override"] for file_name in filter(os.path.isfile, files): with salt.utils.files.fopen(file_name) as fp_: if re.search( r"^\s*manual", salt.utils.stringutils.to_unicode(fp_.read()), re.MULTILINE, ): return True return False def _upstart_is_enabled(name): """ Assume that if an Upstart service is not disabled then it must be enabled. """ return not _upstart_is_disabled(name) def _service_is_sysv(name): """ A System-V style service will have a control script in /etc/init.d. We make sure to skip over symbolic links that point to Upstart's /lib/init/upstart-job, and anything that isn't an executable, like README or skeleton. """ script = f"/etc/init.d/{name}" return not _service_is_upstart(name) and os.access(script, os.X_OK) def _sysv_is_disabled(name): """ A System-V style service is assumed disabled if there is no start-up link (starts with "S") to its script in /etc/init.d in the current runlevel. """ return not bool(glob.glob(f"/etc/rc{_runlevel()}.d/S*{name}")) def _sysv_is_enabled(name): """ Assume that if a System-V style service is not disabled then it must be enabled. """ return not _sysv_is_disabled(name) def _iter_service_names(): """ Detect all of the service names available to upstart via init configuration files and via classic sysv init scripts """ found = set() for line in glob.glob("/etc/init.d/*"): name = os.path.basename(line) found.add(name) yield name # This walk method supports nested services as per the init man page # definition 'For example a configuration file /etc/init/rc-sysinit.conf # is named rc-sysinit, while a configuration file /etc/init/net/apache.conf # is named net/apache' init_root = "/etc/init/" for root, dirnames, filenames in salt.utils.path.os_walk(init_root): relpath = os.path.relpath(root, init_root) for filename in fnmatch.filter(filenames, "*.conf"): if relpath == ".": # service is defined in the root, no need to append prefix. name = filename[:-5] else: # service is nested, append its relative path prefix. name = os.path.join(relpath, filename[:-5]) if name in found: continue yield name def get_enabled(): """ Return the enabled services CLI Example: .. code-block:: bash salt '*' service.get_enabled """ ret = set() for name in _iter_service_names(): if _service_is_upstart(name): if _upstart_is_enabled(name): ret.add(name) else: if _service_is_sysv(name): if _sysv_is_enabled(name): ret.add(name) return sorted(ret) def get_disabled(): """ Return the disabled services CLI Example: .. code-block:: bash salt '*' service.get_disabled """ ret = set() for name in _iter_service_names(): if _service_is_upstart(name): if _upstart_is_disabled(name): ret.add(name) else: if _service_is_sysv(name): if _sysv_is_disabled(name): ret.add(name) return sorted(ret) def available(name): """ Returns ``True`` if the specified service is available, otherwise returns ``False``. CLI Example: .. code-block:: bash salt '*' service.available sshd """ return name in get_all() def missing(name): """ The inverse of service.available. Returns ``True`` if the specified service is not available, otherwise returns ``False``. CLI Example: .. code-block:: bash salt '*' service.missing sshd """ return name not in get_all() def get_all(): """ Return all installed services CLI Example: .. code-block:: bash salt '*' service.get_all """ return sorted(get_enabled() + get_disabled()) def start(name): """ Start the specified service CLI Example: .. code-block:: bash salt '*' service.start <service name> """ cmd = ["service", name, "start"] return not __salt__["cmd.retcode"](cmd, python_shell=False) def stop(name): """ Stop the specified service CLI Example: .. code-block:: bash salt '*' service.stop <service name> """ cmd = ["service", name, "stop"] return not __salt__["cmd.retcode"](cmd, python_shell=False) def restart(name): """ Restart the named service CLI Example: .. code-block:: bash salt '*' service.restart <service name> """ cmd = ["service", name, "restart"] return not __salt__["cmd.retcode"](cmd, python_shell=False) def full_restart(name): """ Do a full restart (stop/start) of the named service CLI Example: .. code-block:: bash salt '*' service.full_restart <service name> """ cmd = ["service", name, "--full-restart"] return not __salt__["cmd.retcode"](cmd, python_shell=False) def reload_(name): """ Reload the named service CLI Example: .. code-block:: bash salt '*' service.reload <service name> """ cmd = ["service", name, "reload"] return not __salt__["cmd.retcode"](cmd, python_shell=False) def force_reload(name): """ Force-reload the named service CLI Example: .. code-block:: bash salt '*' service.force_reload <service name> """ cmd = ["service", name, "force-reload"] return not __salt__["cmd.retcode"](cmd, python_shell=False) def status(name, sig=None): """ Return the status for a service. If the name contains globbing, a dict mapping service name to True/False values is returned. .. versionchanged:: 2018.3.0 The service name can now be a glob (e.g. ``salt*``) Args: name (str): The name of the service to check sig (str): Signature to use to find the service via ps Returns: bool: True if running, False otherwise dict: Maps service name to True if running, False otherwise CLI Example: .. code-block:: bash salt '*' service.status <service name> [service signature] """ if sig: return bool(__salt__["status.pid"](sig)) contains_globbing = bool(re.search(r"\*|\?|\[.+\]", name)) if contains_globbing: services = fnmatch.filter(get_all(), name) else: services = [name] results = {} for service in services: cmd = ["service", service, "status"] if _service_is_upstart(service): # decide result base on cmd output, thus ignore retcode, # which makes cmd output not at error lvl even when cmd fail. results[service] = "start/running" in __salt__["cmd.run"]( cmd, python_shell=False, ignore_retcode=True ) else: # decide result base on retcode, thus ignore output (set quite) # because there is no way to avoid logging at error lvl when # service is not running - retcode != 0 (which is totally relevant). results[service] = not bool( __salt__["cmd.retcode"]( cmd, python_shell=False, ignore_retcode=True, quite=True ) ) if contains_globbing: return results return results[name] def _get_service_exec(): """ Debian uses update-rc.d to manage System-V style services. http://www.debian.org/doc/debian-policy/ch-opersys.html#s9.3.3 """ executable = "update-rc.d" salt.utils.path.check_or_die(executable) return executable def _upstart_disable(name): """ Disable an Upstart service. """ if _upstart_is_disabled(name): return _upstart_is_disabled(name) override = f"/etc/init/{name}.override" with salt.utils.files.fopen(override, "a") as ofile: ofile.write(salt.utils.stringutils.to_str("manual\n")) return _upstart_is_disabled(name) def _upstart_enable(name): """ Enable an Upstart service. """ if _upstart_is_enabled(name): return _upstart_is_enabled(name) override = f"/etc/init/{name}.override" files = [f"/etc/init/{name}.conf", override] for file_name in filter(os.path.isfile, files): with salt.utils.files.fopen(file_name, "r+") as fp_: new_text = re.sub( r"^\s*manual\n?", "", salt.utils.stringutils.to_unicode(fp_.read()), 0, re.MULTILINE, ) fp_.seek(0) fp_.write(salt.utils.stringutils.to_str(new_text)) fp_.truncate() if os.access(override, os.R_OK) and os.path.getsize(override) == 0: os.unlink(override) return _upstart_is_enabled(name) def enable(name, **kwargs): """ Enable the named service to start at boot CLI Example: .. code-block:: bash salt '*' service.enable <service name> """ if _service_is_upstart(name): return _upstart_enable(name) executable = _get_service_exec() cmd = f"{executable} -f {name} defaults" return not __salt__["cmd.retcode"](cmd, python_shell=False) def disable(name, **kwargs): """ Disable the named service from starting on boot CLI Example: .. code-block:: bash salt '*' service.disable <service name> """ if _service_is_upstart(name): return _upstart_disable(name) executable = _get_service_exec() cmd = [executable, "-f", name, "remove"] return not __salt__["cmd.retcode"](cmd, python_shell=False) def enabled(name, **kwargs): """ Check to see if the named service is enabled to start on boot CLI Example: .. code-block:: bash salt '*' service.enabled <service name> """ if _service_is_upstart(name): return _upstart_is_enabled(name) else: if _service_is_sysv(name): return _sysv_is_enabled(name) return None def disabled(name): """ Check to see if the named service is disabled to start on boot CLI Example: .. code-block:: bash salt '*' service.disabled <service name> """ if _service_is_upstart(name): return _upstart_is_disabled(name) else: if _service_is_sysv(name): return _sysv_is_disabled(name) return None