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/parted_partition.py
""" Module for managing partitions on POSIX-like systems. :depends: - parted, partprobe, lsblk (usually parted and util-linux packages) Some functions may not be available, depending on your version of parted. Check the manpage for ``parted(8)`` for more information, or the online docs at: http://www.gnu.org/software/parted/manual/html_chapter/parted_2.html In light of parted not directly supporting partition IDs, some of this module has been written to utilize sfdisk instead. For further information, please reference the man page for ``sfdisk(8)``. """ import logging import os import re import stat import string import salt.utils.path import salt.utils.platform from salt.exceptions import CommandExecutionError log = logging.getLogger(__name__) # Define the module's virtual name __virtualname__ = "partition" # Define a function alias in order not to shadow built-in's __func_alias__ = { "set_": "set", "list_": "list", } VALID_UNITS = { "s", "B", "kB", "MB", "MiB", "GB", "GiB", "TB", "TiB", "%", "cyl", "chs", "compact", } VALID_DISK_FLAGS = {"cylinder_alignment", "pmbr_boot", "implicit_partition_table"} VALID_PARTITION_FLAGS = { "boot", "root", "swap", "hidden", "raid", "lvm", "lba", "hp-service", "palo", "prep", "msftres", "bios_grub", "atvrecv", "diag", "legacy_boot", "msftdata", "irst", "esp", "type", } def __virtual__(): """ Only work on POSIX-like systems, which have parted and lsblk installed. These are usually provided by the ``parted`` and ``util-linux`` packages. """ if salt.utils.platform.is_windows(): return ( False, "The parted execution module failed to load " "Windows systems are not supported.", ) if not salt.utils.path.which("parted"): return ( False, "The parted execution module failed to load " "parted binary is not in the path.", ) if not salt.utils.path.which("lsblk"): return ( False, "The parted execution module failed to load " "lsblk binary is not in the path.", ) if not salt.utils.path.which("partprobe"): return ( False, "The parted execution module failed to load " "partprobe binary is not in the path.", ) return __virtualname__ # TODO: all the other inputs to the functions in this module are repetitively # validated within each function; collect them into validation functions here, # similar to _validate_device and _validate_partition_boundary def _validate_device(device): """ Ensure the device name supplied is valid in a manner similar to the `exists` function, but raise errors on invalid input rather than return False. This function only validates a block device, it does not check if the block device is a drive or a partition or a filesystem, etc. """ if os.path.exists(device): dev = os.stat(device).st_mode if stat.S_ISBLK(dev): return raise CommandExecutionError("Invalid device passed to partition module.") def _validate_partition_boundary(boundary): """ Ensure valid partition boundaries are supplied. """ boundary = str(boundary) match = re.search(r"^([\d.]+)(\D*)$", boundary) if match: unit = match.group(2) if not unit or unit in VALID_UNITS: return raise CommandExecutionError(f'Invalid partition boundary passed: "{boundary}"') def probe(*devices): """ Ask the kernel to update its local partition data. When no args are specified all block devices are tried. Caution: Generally only works on devices with no mounted partitions and may take a long time to return if specified devices are in use. CLI Examples: .. code-block:: bash salt '*' partition.probe salt '*' partition.probe /dev/sda salt '*' partition.probe /dev/sda /dev/sdb """ for device in devices: _validate_device(device) cmd = "partprobe -- {}".format(" ".join(devices)) out = __salt__["cmd.run"](cmd).splitlines() return out def list_(device, unit=None): """ Prints partition information of given <device> CLI Examples: .. code-block:: bash salt '*' partition.list /dev/sda salt '*' partition.list /dev/sda unit=s salt '*' partition.list /dev/sda unit=kB """ _validate_device(device) if unit: if unit not in VALID_UNITS: raise CommandExecutionError("Invalid unit passed to partition.part_list") cmd = f"parted -m -s {device} unit {unit} print" else: cmd = f"parted -m -s {device} print" out = __salt__["cmd.run_stdout"](cmd).splitlines() ret = {"info": {}, "partitions": {}} mode = "info" for line in out: if line in ("BYT;", "CHS;", "CYL;"): continue cols = line.rstrip(";").split(":") if mode == "info": if 7 <= len(cols) <= 8: ret["info"] = { "disk": cols[0], "size": cols[1], "interface": cols[2], "logical sector": cols[3], "physical sector": cols[4], "partition table": cols[5], "model": cols[6], } if len(cols) == 8: ret["info"]["disk flags"] = cols[7] # Older parted (2.x) doesn't show disk flags in the 'print' # output, and will return a 7-column output for the info # line. In these cases we just leave this field out of the # return dict. mode = "partitions" else: raise CommandExecutionError( "Problem encountered while parsing output from parted" ) else: # Parted (v3.1) have a variable field list in machine # readable output: # # number:start:end:[size:]([file system:name:flags;]|[free;]) # # * If units are in CHS 'size' is not printed. # * If is a logical partition with PED_PARTITION_FREESPACE # set, the last three fields are replaced with the # 'free' text. # fields = ["number", "start", "end"] if unit != "chs": fields.append("size") if cols[-1] == "free": # Drop the last element from the list cols.pop() else: fields.extend(["file system", "name", "flags"]) if len(fields) == len(cols): ret["partitions"][cols[0]] = dict(zip(fields, cols)) else: raise CommandExecutionError( "Problem encountered while parsing output from parted" ) return ret def align_check(device, part_type, partition): """ Check if partition satisfies the alignment constraint of part_type. Type must be "minimal" or "optimal". CLI Example: .. code-block:: bash salt '*' partition.align_check /dev/sda minimal 1 """ _validate_device(device) if part_type not in {"minimal", "optimal"}: raise CommandExecutionError("Invalid part_type passed to partition.align_check") try: int(partition) except Exception: # pylint: disable=broad-except raise CommandExecutionError("Invalid partition passed to partition.align_check") cmd = f"parted -m {device} align-check {part_type} {partition}" out = __salt__["cmd.run"](cmd).splitlines() return out def check(device, minor): """ Checks if the file system on partition <minor> has any errors. CLI Example: .. code-block:: bash salt '*' partition.check 1 """ _validate_device(device) try: int(minor) except Exception: # pylint: disable=broad-except raise CommandExecutionError("Invalid minor number passed to partition.check") cmd = f"parted -m -s {device} check {minor}" out = __salt__["cmd.run"](cmd).splitlines() return out def cp(device, from_minor, to_minor): # pylint: disable=C0103 """ Copies the file system on the partition <from-minor> to partition <to-minor>, deleting the original contents of the destination partition. CLI Example: .. code-block:: bash salt '*' partition.cp /dev/sda 2 3 """ _validate_device(device) try: int(from_minor) int(to_minor) except Exception: # pylint: disable=broad-except raise CommandExecutionError("Invalid minor number passed to partition.cp") cmd = f"parted -m -s {device} cp {from_minor} {to_minor}" out = __salt__["cmd.run"](cmd).splitlines() return out def get_id(device, minor): """ Prints the system ID for the partition. Some typical values are:: b: FAT32 (vfat) 7: HPFS/NTFS 82: Linux Swap 83: Linux 8e: Linux LVM fd: Linux RAID Auto CLI Example: .. code-block:: bash salt '*' partition.get_id /dev/sda 1 """ _validate_device(device) try: int(minor) except Exception: # pylint: disable=broad-except raise CommandExecutionError("Invalid minor number passed to partition.get_id") cmd = f"sfdisk --print-id {device} {minor}" out = __salt__["cmd.run"](cmd).splitlines() return out def set_id(device, minor, system_id): """ Sets the system ID for the partition. Some typical values are:: b: FAT32 (vfat) 7: HPFS/NTFS 82: Linux Swap 83: Linux 8e: Linux LVM fd: Linux RAID Auto CLI Example: .. code-block:: bash salt '*' partition.set_id /dev/sda 1 83 """ _validate_device(device) try: int(minor) except Exception: # pylint: disable=broad-except raise CommandExecutionError("Invalid minor number passed to partition.set_id") if system_id not in system_types(): raise CommandExecutionError("Invalid system_id passed to partition.set_id") cmd = f"sfdisk --change-id {device} {minor} {system_id}" out = __salt__["cmd.run"](cmd).splitlines() return out def system_types(): """ List the system types that are supported by the installed version of sfdisk CLI Example: .. code-block:: bash salt '*' partition.system_types """ ret = {} for line in __salt__["cmd.run"]("sfdisk -T").splitlines(): if not line: continue if line.startswith("Id"): continue comps = line.strip().split() ret[comps[0]] = comps[1] return ret def _is_fstype(fs_type): """ Check if file system type is supported in module :param fs_type: file system type :return: True if fs_type is supported in this module, False otherwise """ return fs_type in ( "btrfs", "ext2", "ext3", "ext4", "fat", "fat32", "fat16", "linux-swap", "reiserfs", "hfs", "hfs+", "hfsx", "NTFS", "ntfs", "ufs", "xfs", ) def mkfs(device, fs_type): """ Makes a file system <fs_type> on partition <device>, destroying all data that resides on that partition. <fs_type> must be one of "ext2", "fat32", "fat16", "linux-swap" or "reiserfs" (if libreiserfs is installed) CLI Example: .. code-block:: bash salt '*' partition.mkfs /dev/sda2 fat32 """ _validate_device(device) if not _is_fstype(fs_type): raise CommandExecutionError("Invalid fs_type passed to partition.mkfs") if fs_type == "NTFS": fs_type = "ntfs" if fs_type == "linux-swap": mkfs_cmd = "mkswap" else: mkfs_cmd = f"mkfs.{fs_type}" if not salt.utils.path.which(mkfs_cmd): return f"Error: {mkfs_cmd} is unavailable." cmd = f"{mkfs_cmd} {device}" out = __salt__["cmd.run"](cmd).splitlines() return out def mklabel(device, label_type): """ Create a new disklabel (partition table) of label_type. Type should be one of "aix", "amiga", "bsd", "dvh", "gpt", "loop", "mac", "msdos", "pc98", or "sun". CLI Example: .. code-block:: bash salt '*' partition.mklabel /dev/sda msdos """ if label_type not in { "aix", "amiga", "bsd", "dvh", "gpt", "loop", "mac", "msdos", "pc98", "sun", }: raise CommandExecutionError("Invalid label_type passed to partition.mklabel") cmd = ("parted", "-m", "-s", device, "mklabel", label_type) out = __salt__["cmd.run"](cmd, python_shell=False).splitlines() return out def mkpart(device, part_type, fs_type=None, start=None, end=None): """ Make a part_type partition for filesystem fs_type, beginning at start and ending at end (by default in megabytes). part_type should be one of "primary", "logical", or "extended". CLI Examples: .. code-block:: bash salt '*' partition.mkpart /dev/sda primary fs_type=fat32 start=0 end=639 salt '*' partition.mkpart /dev/sda primary start=0 end=639 """ _validate_device(device) if part_type not in {"primary", "logical", "extended"}: raise CommandExecutionError("Invalid part_type passed to partition.mkpart") if fs_type and not _is_fstype(fs_type): raise CommandExecutionError("Invalid fs_type passed to partition.mkpart") if start is not None and end is not None: _validate_partition_boundary(start) _validate_partition_boundary(end) if start is None: start = "" if end is None: end = "" if fs_type: cmd = ( "parted", "-m", "-s", "--", device, "mkpart", part_type, fs_type, start, end, ) else: cmd = ("parted", "-m", "-s", "--", device, "mkpart", part_type, start, end) out = __salt__["cmd.run"](cmd, python_shell=False).splitlines() return out def mkpartfs(device, part_type, fs_type=None, start=None, end=None): """ The mkpartfs actually is an alias to mkpart and is kept for compatibility. To know the valid options and usage syntax read mkpart documentation. CLI Examples: .. code-block:: bash salt '*' partition.mkpartfs /dev/sda primary fs_type=fat32 start=0 end=639 salt '*' partition.mkpartfs /dev/sda primary start=0 end=639 """ out = mkpart(device, part_type, fs_type, start, end) return out def name(device, partition, name): """ Set the name of partition to name. This option works only on Mac, PC98, and GPT disklabels. The name can be placed in quotes, if necessary. CLI Example: .. code-block:: bash salt '*' partition.name /dev/sda 1 'My Documents' """ _validate_device(device) try: int(partition) except Exception: # pylint: disable=broad-except raise CommandExecutionError("Invalid partition passed to partition.name") valid = string.ascii_letters + string.digits + " _-" for letter in name: if letter not in valid: raise CommandExecutionError("Invalid characters passed to partition.name") cmd = f'''parted -m -s {device} name {partition} "'{name}'"''' out = __salt__["cmd.run"](cmd).splitlines() return out def rescue(device, start, end): """ Rescue a lost partition that was located somewhere between start and end. If a partition is found, parted will ask if you want to create an entry for it in the partition table. CLI Example: .. code-block:: bash salt '*' partition.rescue /dev/sda 0 8056 """ _validate_device(device) _validate_partition_boundary(start) _validate_partition_boundary(end) cmd = f"parted -m -s {device} rescue {start} {end}" out = __salt__["cmd.run"](cmd).splitlines() return out def resize(device, minor, start, end): """ Resizes the partition with number <minor>. The partition will start <start> from the beginning of the disk, and end <end> from the beginning of the disk. resize never changes the minor number. Extended partitions can be resized, so long as the new extended partition completely contains all logical partitions. CLI Example: .. code-block:: bash salt '*' partition.resize /dev/sda 3 200 850 """ _validate_device(device) try: int(minor) except Exception: # pylint: disable=broad-except raise CommandExecutionError("Invalid minor number passed to partition.resize") _validate_partition_boundary(start) _validate_partition_boundary(end) out = __salt__["cmd.run"](f"parted -m -s -- {device} resize {minor} {start} {end}") return out.splitlines() def rm(device, minor): # pylint: disable=C0103 """ Removes the partition with number <minor>. CLI Example: .. code-block:: bash salt '*' partition.rm /dev/sda 5 """ _validate_device(device) try: int(minor) except Exception: # pylint: disable=broad-except raise CommandExecutionError("Invalid minor number passed to partition.rm") cmd = f"parted -m -s {device} rm {minor}" out = __salt__["cmd.run"](cmd).splitlines() return out def set_(device, minor, flag, state): """ Changes a flag on the partition with number <minor>. A flag can be either "on" or "off" (make sure to use proper quoting, see :ref:`YAML Idiosyncrasies <yaml-idiosyncrasies>`). Some or all of these flags will be available, depending on what disk label you are using. Valid flags are: * boot * root * swap * hidden * raid * lvm * lba * hp-service * palo * prep * msftres * bios_grub * atvrecv * diag * legacy_boot * msftdata * irst * esp * type CLI Example: .. code-block:: bash salt '*' partition.set /dev/sda 1 boot '"on"' """ _validate_device(device) try: int(minor) except Exception: # pylint: disable=broad-except raise CommandExecutionError("Invalid minor number passed to partition.set") if flag not in VALID_PARTITION_FLAGS: raise CommandExecutionError("Invalid flag passed to partition.set") if state not in {"on", "off"}: raise CommandExecutionError("Invalid state passed to partition.set") cmd = f"parted -m -s {device} set {minor} {flag} {state}" out = __salt__["cmd.run"](cmd).splitlines() return out def toggle(device, partition, flag): """ Toggle the state of <flag> on <partition>. Valid flags are the same as the set command. CLI Example: .. code-block:: bash salt '*' partition.toggle /dev/sda 1 boot """ _validate_device(device) try: int(partition) except Exception: # pylint: disable=broad-except raise CommandExecutionError( "Invalid partition number passed to partition.toggle" ) if flag not in VALID_PARTITION_FLAGS: raise CommandExecutionError("Invalid flag passed to partition.toggle") cmd = f"parted -m -s {device} toggle {partition} {flag}" out = __salt__["cmd.run"](cmd).splitlines() return out def disk_set(device, flag, state): """ Changes a flag on selected device. A flag can be either "on" or "off" (make sure to use proper quoting, see :ref:`YAML Idiosyncrasies <yaml-idiosyncrasies>`). Some or all of these flags will be available, depending on what disk label you are using. Valid flags are: * cylinder_alignment * pmbr_boot * implicit_partition_table CLI Example: .. code-block:: bash salt '*' partition.disk_set /dev/sda pmbr_boot '"on"' """ _validate_device(device) if flag not in VALID_DISK_FLAGS: raise CommandExecutionError("Invalid flag passed to partition.disk_set") if state not in {"on", "off"}: raise CommandExecutionError("Invalid state passed to partition.disk_set") cmd = ["parted", "-m", "-s", device, "disk_set", flag, state] out = __salt__["cmd.run"](cmd).splitlines() return out def disk_toggle(device, flag): """ Toggle the state of <flag> on <device>. Valid flags are the same as the disk_set command. CLI Example: .. code-block:: bash salt '*' partition.disk_toggle /dev/sda pmbr_boot """ _validate_device(device) if flag not in VALID_DISK_FLAGS: raise CommandExecutionError("Invalid flag passed to partition.disk_toggle") cmd = ["parted", "-m", "-s", device, "disk_toggle", flag] out = __salt__["cmd.run"](cmd).splitlines() return out def exists(device=""): """ Check to see if the partition exists CLI Example: .. code-block:: bash salt '*' partition.exists /dev/sdb1 """ if os.path.exists(device): dev = os.stat(device).st_mode if stat.S_ISBLK(dev): return True return False def get_block_device(): """ Retrieve a list of disk devices .. versionadded:: 2014.7.0 CLI Example: .. code-block:: bash salt '*' partition.get_block_device """ cmd = "lsblk -n -io KNAME -d -e 1,7,11 -l" devs = __salt__["cmd.run"](cmd).splitlines() return devs