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:/lib/python2.7/site-packages/vdo/vdomgmnt/
Upload File :
Current File : //lib/python2.7/site-packages/vdo/vdomgmnt/VDOOperation.py
#
# Copyright (c) 2018 Red Hat, Inc.
#
# 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; either version 2
# of the License, or (at your option) any later version.
# 
# 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA. 
#

"""
  VDOOperation - an object representing a vdo script command

  $Id: //eng/vdo-releases/magnesium/src/python/vdo/vdomgmnt/VDOOperation.py#9 $
"""
from . import ArgumentError
from . import CommandLock
from . import Configuration
from . import Constants
from . import Defaults
from . import MgmntLogger
from . import MgmntUtils
from . import Service
from . import VDOKernelModuleService
from . import VDOService, VDOServiceError, VDOServicePreviousOperationError
from . import ExitStatus, SystemExitStatus, UserExitStatus
from utils import Command, CommandError, runCommand
from utils import Transaction, transactional
from functools import partial
import inspect
import __main__ as main
import os
import re
import sys
import yaml

vdoOperations = dict()

def lock(isExclusive, func, *args, **kwargs):
  commandArgs = args[1]
  confFile = os.path.abspath(commandArgs.confFile)
  confFile = os.path.realpath(confFile)
  # N.B.: We don't filter out shell special characters like " (){}"!
  #
  # Also, no quoting; if two config file names use "/" and "_" such
  # that they both map to the same lock file, so be it.
  lockFileBase = confFile.replace('/', '_') + '.lock'
  lockFile = os.path.join(Constants.LOCK_DIR, lockFileBase)
  with CommandLock(lockFile, isExclusive):
    return func(*args, **kwargs)

def exclusivelock(func):
  "Decorator that locks the configuration for exclusive (write) access."
  def wrap(*args, **kwargs):
    return lock(False, func, *args, **kwargs)
  return wrap

def sharedlock(func):
  "Decorator that locks the configuration for shared (read) access."
  def wrap(*args, **kwargs):
    return lock(False, func, *args, **kwargs)
  return wrap

########################################################################
class OperationError(ExitStatus, Exception):
  """Exception raised to indicate an error executing an operation."""

  ######################################################################
  # Public methods
  ######################################################################

  ######################################################################
  # Overridden methods
  ######################################################################

  ######################################################################
  # Protected methods
  ######################################################################
  def __init__(self, msg, *args, **kwargs):
    super(OperationError, self).__init__(*args, **kwargs)
    self._msg = msg

  def __str__(self):
    return self._msg

########################################################################
class VDOOperation(object):
  """Every instance of this class runs one of the subcommands
  requested when 'vdo [<options>] <subcommand>' is called via the
  execute() method."""

  ######################################################################
  # Public methods
  ######################################################################
  def getVdoServices(self, args, conf):
    """Return a list of VDOService objects to be operated on depending
    on the settings of the --name and --all options.
    Arguments:
      args: The arguments passed into vdo.
      conf: The config file
    Raises:
      ArgumentError
    """
    services = []
    if args.all:
      services.extend(conf.getAllVdos().values())
    else:
      self._checkForName(args)
      services.append(conf.getVdo(args.name))
    return services

  ######################################################################
  def applyToVDOs(self, args, method, **kwargs):
    """Apply a method to all specified VDOs. An exception applying the method
    to some VDO will not prevent it from being applied to any other VDO,
    however any exception will result in applyToVDOs raising an exception.

    If the 'readonly' keyword argument is False, the configuration will be
    persisted after the method has been applied to all the VDOs (whether or
    not it succeeded for any of them).

    Arguments:
      args (dict):       The command line arguments
      method (callable): The method to call on each VDO; will be called as
                         method(args, vdo)
      kwargs:            Keyword args controlling what gets returned
                          and to use when making the Configuration
    """
    exception = None
    conf = None

    if kwargs.get('readonly', True):
      conf = Configuration(self.confFile, **kwargs)
    else:
      conf = Configuration.modifiableSingleton(self.confFile)

    for vdo in self.getVdoServices(args, conf):
      try:
        method(args, vdo)
      except Exception as ex:
        exception = ex
    if not kwargs.get('readonly', True):
      conf.persist()
    if exception is not None:
      #pylint: disable=E0702
      raise exception

  ######################################################################
  def execute(self, unused_args):
    """Execute this operation. This method should be overridden by operation
    classes, and is intended only to be called from within the run() method
    below.

    Arguments:
      unused_args (dict): The command line arguments (used by subclasses)
    Raises:
      NotImplementedError
    """
    self.log.error(_("{0} unimplemented").format(self.name))
    raise NotImplementedError

  ######################################################################
  def preflight(self, args):
    """Perform checks prior to actually executing the command.

    Arguments:
      args (dict): The command line arguments (used by subclasses)
    Raises:
      OperationError
    """
    if self.requiresRoot and (os.getuid() != 0):
      msg = _("You must be root to use the \"{0}\" command").format(self.name)
      raise OperationError(msg, exitStatus = UserExitStatus)

    if self.checkBinaries:
      for executable in ['vdodumpconfig',
                         'vdoforcerebuild',
                         'vdoformat']:
        if not MgmntUtils.which(executable):
          msg = _("executable '{0}' not found in $PATH").format(executable)
          raise OperationError(msg, exitStatus = SystemExitStatus)

    if self.requiresRunMode and Command.noRunMode():
      msg = _("{0} command not available with --noRun").format(self.name)
      raise OperationError(msg, exitStatus = UserExitStatus)

  ######################################################################
  def run(self, args):
    """Run this operation. This is the external entry point for users of
    VDOOperation.

    Arguments:
      args (dict): The command line arguments
    """

    self.confFile = Defaults.confFile

    try:
      self.confFile = args.confFile
    except KeyError:
      pass

    self.preflight(args)
    self.execute(args)

  ######################################################################
  # Overridden methods
  ######################################################################
  def __init__(self, **kwargs):
    name = re.sub('Operation$', '', type(self).__name__)
    self.name            = name[0].lower() + name[1:]
    self.log             = MgmntLogger.getLogger(MgmntLogger.myname
                                                  + '.VDOOperations')
    self.requiresRoot    = kwargs.get('requiresRoot', True)
    self.checkBinaries   = kwargs.get('checkBinaries', False)
    self.requiresRunMode = kwargs.get('requiresRunMode', False)
    vdoOperations[self.name] = self

  ######################################################################
  # Protected methods
  ######################################################################
  def _checkForName(self, args):
    """Check that the args contain a non-None name.
    Arguments:
      args: the args passed
    Raises:
      ArgumentError
    """
    if (args.name is None) or (args.name.strip() == ""):
      raise ArgumentError(_("Missing required argument '--name'"))

########################################################################
class ActivateOperation(VDOOperation):
  """Implements the activate command."""

  ######################################################################
  # Overridden methods
  ######################################################################
  def __init__(self):
    super(ActivateOperation, self).__init__()

  ######################################################################
  @exclusivelock
  def execute(self, args):
    self.applyToVDOs(args, self._activate, readonly=False)

  ######################################################################
  # Protected methods
  ######################################################################
  def _activate(self, args, vdo):
    vdo.activate()

########################################################################
class ChangeWritePolicyOperation(VDOOperation):
  """Implements the changeWritePolicy command."""

  ######################################################################
  # Overridden methods
  ######################################################################
  def __init__(self):
    super(ChangeWritePolicyOperation, self).__init__()

  ######################################################################
  @exclusivelock
  def execute(self, args):
    self._newWritePolicy = getattr(args, 'writePolicy')
    if self._newWritePolicy is None:
      return
    self.applyToVDOs(args, self._changeWritePolicy, readonly=False)

  ######################################################################
  # Protected methods
  ######################################################################
  def _changeWritePolicy(self, args, vdo):
    vdo.setWritePolicy(self._newWritePolicy)

########################################################################
class CreateOperation(VDOOperation):
  """Implements the create command."""

  ######################################################################
  # Overridden methods
  ######################################################################
  def __init__(self):
    super(CreateOperation, self).__init__(checkBinaries=True)

  ######################################################################
  def preflight(self, args):
    super(CreateOperation, self).preflight(args)

    if not args.name:
      raise ArgumentError(_("Missing required argument '--name'"))

    if not args.device:
      raise ArgumentError(_("Missing required argument '--device'"))

  ######################################################################
  @exclusivelock
  @transactional
  def execute(self, args):
    # Get configuration
    conf = Configuration.modifiableSingleton(self.confFile)

    argsDict = vars(args).copy()
    name = argsDict['name']
    del argsDict['name']

    vdo = VDOService(args.name, conf, **argsDict)

    transaction = Transaction.transaction()
    vdo.create(args.force)
    transaction.addUndoStage(vdo.remove)

    conf.persist()
    vdo.announceReady()

########################################################################
class DeactivateOperation(VDOOperation):
  """Implements the deactivate command."""

  ######################################################################
  # Overridden methods
  ######################################################################
  def __init__(self):
    super(DeactivateOperation, self).__init__()

  ######################################################################
  @exclusivelock
  def execute(self, args):
    self.applyToVDOs(args, self._deactivate, readonly=False)

  ######################################################################
  # Protected methods
  ######################################################################
  def _deactivate(self, args, vdo):
    vdo.deactivate()

########################################################################
class GrowLogicalOperation(VDOOperation):
  """Implements the growLogical command."""

  ######################################################################
  # Overridden methods
  ######################################################################
  def __init__(self):
    super(GrowLogicalOperation, self).__init__()

  ######################################################################
  @exclusivelock
  def execute(self, args):
    conf = Configuration.modifiableSingleton(self.confFile)
    self._checkForName(args)

    vdo = conf.getVdo(args.name)
    vdo.growLogical(args.vdoLogicalSize)
    conf.persist()

########################################################################
class GrowPhysicalOperation(VDOOperation):
  """Implements the growPhysical command."""

  ######################################################################
  # Overridden methods
  ######################################################################
  def __init__(self):
    super(GrowPhysicalOperation, self).__init__()

  ######################################################################
  @exclusivelock
  def execute(self, args):
    conf = Configuration.modifiableSingleton(self.confFile)
    self._checkForName(args)

    vdo = conf.getVdo(args.name)
    vdo.growPhysical()
    conf.persist()

########################################################################
class ListOperation(VDOOperation):
  """Implements the list command."""

  ######################################################################
  # Overridden methods
  ######################################################################
  def __init__(self):
    super(ListOperation, self).__init__()

  ######################################################################
  def execute(self, args):
    vdos = set()
    for line in runCommand(['dmsetup', 'status'], noThrow=True).splitlines():
      m = re.match(r"(.+?): \d \d+ " + Defaults.vdoTargetName, line)
      if m:
        vdos.add(m.group(1))

    if args.all:
      conf = Configuration(self.confFile)
      vdos |= set(conf.getAllVdos().keys())

    # We want to provide a stable ordering and a set, while great for
    # avoiding duplicates, doesn't guarantee ordering.  So, make a list
    # from the set and sort it.
    vdos = list(vdos)
    vdos.sort()
    print(os.linesep.join(vdos))

########################################################################
class ModifyOperation(VDOOperation):
  """Implements the modify command."""

  ######################################################################
  # Overridden methods
  ######################################################################
  def __init__(self):
    super(ModifyOperation, self).__init__()

  ######################################################################
  @exclusivelock
  def execute(self, args):
    self.applyToVDOs(args, self._modifyVDO, readonly=False)

  ######################################################################
  def preflight(self, args):
    super(ModifyOperation, self).preflight(args)

    # Validate that the user didn't specify anything that can't be changed.
    VDOService.validateModifiableOptions(args)

  ######################################################################
  # Protected methods
  ######################################################################
  def _modifyVDO(self, args, vdo):
    vdo.setModifiableOptions(args)

########################################################################
class PrintConfigFileOperation(VDOOperation):
  """Implements the printConfigFile command."""

  ######################################################################
  # Overridden methods
  ######################################################################
  def __init__(self):
    super(PrintConfigFileOperation, self).__init__(requiresRoot=False,
                                                   requiresRunMode=True)

  ######################################################################
  @sharedlock
  def execute(self, args):
    #pylint: disable=R0201
    conf = Configuration(self.confFile, mustExist=True)
    print(conf.asYAMLForUser())

########################################################################
class RemoveOperation(VDOOperation):
  """Implements the remove command."""

  ######################################################################
  # Overridden methods
  ######################################################################
  def __init__(self):
    super(RemoveOperation, self).__init__()

  ######################################################################
  @exclusivelock
  def execute(self, args):
    """Implements the remove command."""
    self.applyToVDOs(args, self._removeVDO, readonly=False)

  ######################################################################
  # Protected methods
  ######################################################################
  def _removeVDO(self, args, vdo):
    removeSteps = []
    try:
      vdo.remove(args.force, removeSteps = removeSteps)
    except VDOServicePreviousOperationError:
      print(_("A previous operation failed."))
      print(_("Recovery from the failure either failed or was interrupted."))
      print(_("Add '--force' to 'remove' to perform the following cleanup."))
      print(os.linesep.join(removeSteps))
      raise

########################################################################
class StartOperation(VDOOperation):
  """Implements the start command."""

  ######################################################################
  # Overridden methods
  ######################################################################
  def __init__(self):
    super(StartOperation, self).__init__(checkBinaries=True)

  ######################################################################
  @exclusivelock
  def execute(self, args):
    self.applyToVDOs(args, self._startVDO, readonly=False)

  ######################################################################
  # Protected methods
  ######################################################################
  @transactional
  def _startVDO(self, args, vdo):
    vdo.start(args.forceRebuild)
    vdo.announceReady(False)

########################################################################
class StatusOperation(VDOOperation):
  """Implements the status command."""

  ######################################################################
  # Overridden methods
  ######################################################################
  def __init__(self):
    super(StatusOperation, self).__init__(requiresRoot=False,
                                          checkBinaries=True,
                                          requiresRunMode=True)

  ######################################################################
  @exclusivelock
  def execute(self, args):
    #pylint: disable=R0201
    conf = Configuration(self.confFile, readonly=False)
    if not args.name:
      args.all = True

    try:
      # To be consistent with previous output we must present each section as
      # its own rather than organizing them into one structure to dump.
      # Also, we gather all the info before printing it out to avoid
      # interspersing command info when run in verbose mode.
      values = {}
      vdoStatus = { _("VDO status") : values }
      values[_("Node")] = runCommand(['uname', '-n'], noThrow=True, strip=True)
      values[_("Date")] = runCommand(['date', '--rfc-3339=seconds'],
                                      noThrow=True, strip=True)
      if os.getuid() != 0:
        values[_("Note")] = _("Not running as root,"
                              + " some status may be unavailable")

      kernelStatus = { _("Kernel module") : VDOKernelModuleService().status() }

      confStatus = { _("Configuration") : conf.status() }

      vdos = {}
      perVdoStatus = { _("VDOs") : vdos }
      for vdo in self.getVdoServices(args, conf):
        try:
          vdos[vdo.getName()] = vdo.status()
        except VDOServiceError as ex:
          vdos[vdo.getName()] = str(ex)

      # YAML adds a newline at the end.  To maintain consistency with the
      # previous output we need to eliminate that.
      print(yaml.safe_dump(vdoStatus, default_flow_style = False)[:-1])
      print(yaml.safe_dump(kernelStatus, default_flow_style = False)[:-1])
      print(yaml.safe_dump(confStatus, default_flow_style = False)[:-1])
      print(yaml.safe_dump(perVdoStatus, default_flow_style = False, 
                           width=float("inf"))[:-1])

      sys.stdout.flush()
      sys.stderr.flush()
    except IOError as ex:
      self.log.debug("exception ignored: {0}".format(ex))

########################################################################
class StopOperation(VDOOperation):
  """Implements the stop command."""

  ######################################################################
  # Overridden methods
  ######################################################################
  def __init__(self):
    super(StopOperation, self).__init__()

  ######################################################################
  @exclusivelock
  def execute(self, args):
    self.applyToVDOs(args, self._stopVDO, readonly=False)

  ######################################################################
  # Protected methods
  ######################################################################
  def _stopVDO(self, args, vdo):
    vdo.stop(args.force)

########################################################################
class VersionOperation(VDOOperation):
  """Implements the version command."""

  ######################################################################
  # Overridden methods
  ######################################################################
  def __init__(self):
    super(VersionOperation, self).__init__()

  ######################################################################
  def execute(self, unused_args):
    kms = VDOKernelModuleService()
    kms.start()
    print(kms.version())

########################################################################
class OptionToggle(VDOOperation):
  """Base class for operations which either enable or disable an option."""

  ######################################################################
  # Overridden methods
  ######################################################################
  def __init__(self, enable, optionName, checkBinaries=False):
    super(OptionToggle, self).__init__(checkBinaries=checkBinaries)
    self._enable     = enable
    self._optionName = optionName

  ######################################################################
  @exclusivelock
  def execute(self, args):
    self.applyToVDOs(args, self._configure, readonly=False)

  ######################################################################
  # Protected methods
  ######################################################################
  def _configure(self, args, vdo):
    """Actually update the configuration for this operation. This method must
    be overridden by derived classes."""
    self.log.error(_("{0} unimplemented").format(self.name))
    raise NotImplementedError

########################################################################
class DisableCompressionOperation(OptionToggle):
  """Implements the disableCompression command."""

  ######################################################################
  # Overridden methods
  ######################################################################
  def __init__(self):
    super(DisableCompressionOperation, self).__init__(False, "compression")

  ######################################################################
  def _configure(self, args, vdo):
    vdo.setCompression(False)

########################################################################
class DisableDeduplicationOperation(OptionToggle):
  """Implements the disable deduplication command."""

  ######################################################################
  # Protected methods
  ######################################################################
  def __init__(self):
    super(DisableDeduplicationOperation, self).__init__(False, "deduplication")

  ######################################################################
  def _configure(self, args, vdo):
    vdo.setDeduplication(False)

########################################################################
class EnableCompressionOperation(OptionToggle):
  """Implements the enableCompression command."""

  ######################################################################
  # Overridden methods
  ######################################################################
  def __init__(self):
    super(EnableCompressionOperation, self).__init__(True, "compression")

  ######################################################################
  def _configure(self, args, vdo):
    vdo.setCompression(True)

########################################################################
class EnableDeduplicationOperation(OptionToggle):
  """Implements the enableDeduplication command."""

  ######################################################################
  # Overridden methods
  ######################################################################
  def __init__(self):
    super(EnableDeduplicationOperation, self).__init__(True, "deduplication",
                                                       checkBinaries=True)

  ######################################################################
  def _configure(self, args, vdo):
    vdo.setDeduplication(True)

########################################################################
operationRE = re.compile("^[A-Z].*Operation$")

########################################################################
def _isOperation(member):
  return (inspect.isclass(member) and (member.__name__ != "VDOOperation")
          and operationRE.match(member.__name__))

########################################################################
def makeOperations(moduleName):
  for operation in inspect.getmembers(sys.modules[moduleName], _isOperation):
    operation[1]()

########################################################################
makeOperations(__name__)