gNddlZddlZddlZddlZddlZddlZddlmZddlm Z ddl m Z ddl m Z mZddlmZ ddlZn #e$rdZYnwxYwddlmZe ZdZd Zd Zd ZGd d eZGddeZGddeZGddZGddZGddeZ GddZ!GddZ"dS)N)Optional)uid_max)ProcLve)cpapiClPwd) NotSupported) ve_configiresellerceZdZdS) NameMapErrorN__name__ __module__ __qualname__ py/lveapi.pyrr(DrrceZdZdS)NameMapConfigErrorNrrrrrr,rrrceZdZdS)NameMapNotInitializedNrrrrrr0rrrcJeZdZdZefdZdZdZdZd dZ d Z d d Z d Z dS)NameMapz Container for backend storing resellers_name<=>resellers_id map As backend store use ve.cfg Usage: >>> name_map = NameMap() >>> name_map.link_xml_node() >>> name_map.id_list() [1001] c0||_d|_d|_dSN) _xml_tag_name _xml_node_reseller_id_name_map)self xml_tag_names r__init__zNameMap.__init__@s)%)"""rcN|D]\}}||kr|cSdSrload_from_node)r"namename_id_s rget_idzNameMap.get_idFsB--//  JE3}}   rcN|D]\}}||kr|cSdSrr&)r"r*r)_ids rget_namezNameMap.get_nameKsB--//  JE3czz   rc>d|DS)Ncg|]\}}|Srr).0_r*s r z#NameMap.id_list..Qs8883888rr&r"s rid_listzNameMap.id_listPs"88$"5"5"7"78888rNTcb|d|_||dS||_d|_dS)aC Initialize NameMap. If xml_node is none, config will be loaded automatically :param use_cache: Bool whether bypass ve.cfg xml cache :param xml_node: !! DEPRECATED PARAM !! this param is left only for compatibility with our old code N)r _load_resellers_map_from_ve_cfgr!)r"xml_node use_caches r link_xml_nodezNameMap.link_xml_nodeSsB  !DN  0 0 ; ; ; ; ;&DN)-D & & &rcg|_||\}}|D]b}|d}t|d}|r'|r%||jvr|j||fc~~dS)zT Fills self._reseller_id_name_map from ve.cfg file :return: r9useridN)r!_try_get_xml_node getAttributeintappend)r"r9ve_cfgr8el_r(r*s rr7z'NameMap._load_resellers_map_from_ve_cfges &("11I1FF ? ?C##F++Dc&&t,,--C ? ?4+E E E*113+>>>  FFrc tj|\}}n.#tj$r}d|_t d|d}~wwxYw|||jfS)Nr<z-Error happened while loading data from ve.cfg)r get_xml_configBadVeConfigExceptionr!rgetElementsByTagNamer)r"r9rCr8es rr?zNameMap._try_get_xml_nodeus ](7)LLL FHH- ] ] ])-D &$%TUU[\ \ ]x44T5GHHHHsAAAc#PK|j|jtd|jrc|j|jD]C}|d}t |d}|r|r||fVD|jr|jD] \}}||fV dSdS)z? Obtain data from xml node as (name, id_) list NzLName map is not initialized. Use obj.link_xml_node() to get data from configr=r>)r r!rrHrr@rA)r"rDr(r*s rr'zNameMap.load_from_node}s > !d&@&H')Z[[ [ > $~::4;MNN $ $''//#**40011$C$)OOO  % !7  TCi    r)NT)T) rrr__doc__LVP_XML_TAG_NAMEr$r+r.r5r:r7r?r'rrrrr4s  %5****   999....$ IIII     rrcpeZdZdZdZdZd dZdZdZdZ d Z e d Z e d Z d ZdS)LvpMapzl Container for storing information about lve:lvp mapping In which reseller container stored lve c|t|_i|_i|_d|_t |_dSr)rname_map _id_name_map _name_id_map_reseller_id_map_panelr_pwdr4s rr$zLvpMap.__init__s4  &*#GG rc.||j|<||j|<dSr)rQrR)r"r(r*s r_add_mapzLvpMap._add_maps"!%#"%$rNcp |j|jS#tj$r|cYSwxYwr)rTget_pw_by_namepw_uidrNoSuchUserException)r"r(defaults rrYz LvpMap.pw_uidsG 9++D118 8(   NNN s !55c||}||S|jtj|_|j|Sr)rYrSrget_reseller_id_pairsget)r"r uids r_get_panel_reseller_idzLvpMap._get_panel_reseller_idsPkk(## ?J  & .*/*E*G*GD '*..x888rc|j|p|j|}||S ||}n#t $rd}YnwxYw|||||S)z Convert reseller name to an LVE id. It supports resellers without a system account (for Plesk compatibility). N)rPr+rRr^r`rrV)r"r(r_s rget_reseller_idzLvpMap.get_reseller_ids m""4((GD,=,A,A$,G,G ?J --d33CC   CCC  ? MM$ $ $ $ sA AAc*|j|p|j|}||S t j|j}tj|r| ||nd}n#t$rd}YnwxYw|S)z Convert reseller id to reseller name It support resellers without system account (for Plesk compatibilyty) N) rPr.rQr^pwdgetpwuidpw_namer is_resellerrVKeyError)r"r*r(s rget_reseller_namezLvpMap.get_reseller_names }%%c**Hd.?.C.CC.H.H  K <$$,D &&  dC((((   DDD  sAB BBc#Kttj}i}|D]N} ||||<#t$r&t jt jd|dYKwxYwtjdD]\\}}||}|$t jt jd|d@| |d}||fV]dS)z This method loops over all user:reseller pairs in control panel and returns appropriate lve_id:lvp_id pairs. THIS METHOD WON'T CHECK IF 'RESELLER LIMITS' IS ENABLED IN ve.cfg z Reseller > still exists in control panel, but absent in /etc/passwd file)cploginr )keylsNuser r) setr resellersrbrsyslog LOG_WARNINGcpinforYr^)r"rp reseller_uidsr rllve_idlvp_ids r lve_lvp_pairszLvpMap.lve_lvp_pairss` ))**  ! J JH J*.*>*>x*H*H h'' J J J &)IH)I)I)IJJJJJ J"'4K!L!L!L ! ! GX[[))F ~ &)I)I)I)IJJJ"&&x33F&.  ! !sA-A32A3c#>KtjD]}|VdSr)rrp) reseller_names rrpzLvpMap.resellerss6"_..  M      rcg}tj|}|D]d} tj|j}||2#t $r&tjtjd|dYawxYw|S)z: Obtain from control panel resellers uids rnrk) rreseller_usersrdgetpwnamrYrBrhrqrr)r(uidsr{r=r*s rrtzLvpMap.reseller_uidss -d33" J JD Jl4((/ C     J J J &)I)I)I)IJJJJJ J s.A  -A;:A;cV||}||Sr)rirt)r"rvrys rlvp_lve_id_listzLvpMap.lvp_lve_id_list s)..v66 !!-000rr)rrrrKr$rVrYr`rbrirw staticmethodrprtrrrrrNrNs&&& 9 9 9"&!!!:  \ \ 11111rrNceZdZdS) PyLveErrorNrrrrrrrrrceZdZdZedZdZdZdZe dddfd Z d Z d Z d Z eefd ZejdZdS)PyLvezA Wrapper for generate traceback with pretty descriptions cZt|to|tj ko|dkS)Nr) isinstancerAerrnoENOSYS)codes r_code_is_errorzPyLve._code_is_errors)$$$L%,)>L419Lrct|jjr5dfdt D}d|d}nt }|S)N, cdg|],}|d|dt|-S)r2=) startswithgetattr)r1attrarg_vars rr3z%PyLve._arg_to_str..sFiiiTXTcTcdgThThiD3377D1133iiirz)r_pylveliblve_settingsjoindirstr)r"rliblve_settings_attr arg_var_strs ` r _arg_to_strzPyLve._arg_to_strsr gt{: ; ; '#'99iiiiG iii$$ M5ILLLKKg,,Krc |dj}|dj}||i|}|}|r=jr6t jj||i|}|}||j|j d ttj |fd|Dzd}||j|j d ttj |fd|Dzd}jdkrt!jjd i|jdkrj|s|r|jd i|} t+| |S) Nerr_msg ignore_errorrcJg|]\}}|d| Srrr1kvr"s rr3z&PyLve._wrapped_fun..5s9III$!QA--((++--IIIr)rfun_namemoduleargs_cJg|]\}}|d| Srrrs rr3z&PyLve._wrapped_fun..=s9XXXA1 < .funIs&$4$T;D;;;F;; ;rr)r"rrs`` r _wrap_codezPyLve._wrap_codeHs' < < < < < < rTg?rc0||_|jdkrtd|_d|_d|_d|_||_||_t|_ ||_ |j |_ |jj |_ ||jj|_|jj|_||jj|_||jj|_|jj|_||jj|_||jj|_||jj|_||jj|_||jj|_t3|dr||jj|_||jj|_||jj|_||jj|_||j|_dSdS)Nr rz/Error code {code}; {module}.{fun_name}({args_})zBDEBUG [lvectl]: call {module}.{fun_name}({args_}) with code {code}Flve_lvp_create)r __import__rrrrrrr_procrlve_get_api_version api_version initializer lve_startr lve_create lve_destroylve_infolve_set_default lve_setup lve_enter_pidlve_enter_pid_flags lve_leave_pidhasattrrlve_lvp_destroy lve_lvp_map lve_lvp_move lve_lvp_setup)r"pylveretry retry_tymers rr$zPyLve.__init__Ms :??' 44DN$U!"f!  YY %;::<<+0)>??#{://$+*@AA??4;+BCC , #t{/JKK)>??!__T[-FGG#'??4;3R#S#S !__T[-FGG 5* + + E"&//$+2L"M"MD #'??4;3N#O#OD #t{/FGGD  $ 0H I ID "&1C!D!DD    E Erc,t|jdS)zB Check in pylve binding reseller limits supported r)rrr4s rresellers_supportedzPyLve.resellers_supportednst{$4555rcT ||dS#t$rYdSwxYw)zD Check if lve exists in kernel :rtype: bool TF)rOSError)r"rus r lve_existszPyLve.lve_existsts@   MM& ! ! !4   55 s  ''c|dkr|j||Si}|j|D]} ||}|||<|j|jkrJ||}t |j|j|_|||x#t$rYwxYw| |jj}|||d}|j|D]L}||vr||||#||||M|S)a Wrapper for lve_lvp_setup. When reseller's limits changed, we should iterate over his user's limits and set them again; This behaviour is needed cause kernel does not update users limits after changing reseller's one Adjust parameters for top level container. :param int lvp_id: top level container ID, 0 by default; :param settings: liblve_settings instance. :return: 0 or errno value rTr) rrr lve_id_listrls_cpuminrrr) r"rvsettingsreal_lve_settingsru real_settings temp_settings_lve_lvp_setupresults rrzPyLve.lve_lvp_setupsz" Q;;;,,VX>> >j,,V44  F  $ f 5 5 ,9!&) '(/99$(MM&$9$9M+.}/CX_+U+UM(NN6=999     )BCCtDDDj,,V44 > >F***v'8'@AAAA vt}}V'<'<==== sA4B66 CCct|dz|D],} ||#t$r|cYcSwxYwtd|d|d)z Iter over lves and find available one. :param int start: value to start search from; UID_MAX by default :param int stop: max value when we will stop search :return int: lve_id rz"Unable to find free lve in range (r))rangerrr)r"startstoprus rget_available_lve_idzPyLve.get_available_lve_idsEAIt,,  F  f%%%%     NeNNtNNNOOOs - >>c#XK||jc|_} dV||_dS#||_wxYwrr)r"rsaved_ignore_errors rcontext_ignore_errorzPyLve.context_ignore_errorsJ0O-- 3 EEE 2D    2D  2 2 2 2s )N)rrrrKrrrrrrr$rrrUID_MAX MAX_LVE_IDr contextlibcontextmanagerrrrrrrsMM\M!!!F #$3aEEEEB666   444l*1z P P P P33333rrcFeZdZd dZdZdZdZdZdZdZ d Z d Z dS) LveNc|p t|_|p t|_|p t |_dSr)rprocrpyrNr)r"rrrs rr$z Lve.__init__s4%GII -?&((rc#Kt|jj}|jD]\}}||vr||fV|dfVdS)a5 Obtain {lve id}:{lvp id} pairs iterator based on ve.cfg config (detect enabled resellers containers) This method (unlike LvpMap.lve_lvp_pairs) will check if reseller is enabled in ve.cfg and return lvp_id=0 for users of reseller with disabled reseller limits rN)rorrPr5rw)r"enabled_lvp_idrurvs rlve_id_lvp_id_pairszLve.lve_id_lvp_id_pairss~TX.668899"h4466  NFF''fn$$$$ai   rcN|D]\}}||kr|cSdS)z\ Obtain lvp id based on ve.cfg config (detect enabled resellers containers) r)r)r"rulve_id_lvp_id_s rlve2lvpz Lve.lve2lvpsB!% 8 8 : :   GW  !qrctj|jr.|j|d}nd}|jj|g|Ri||dkrC tj ||j ||dS#t$rYdSwxYwdS)zH safe destroy lve container with preserving lvp mapping rN) ospathexistsr proc_lve_maprr^rrrdrerrh)r"rurrrvs rrzLve.lve_destroys 7>>$)0022 3 3 Y]]__((33FFFF4T444V444 Q;;  V$$$##FF33333     ;s/B55 CCcJ|j}|D]t\}}||d|krU|j|s|j||j|||||<udS)z4 Load lve_id:lvp_id map to kmod-lve r)rvN)rrrr^ exist_lvprrr)r" proc_map_dictrurvs r _sync_mapz Lve._sync_maps   #6688 / /NFF  ++v55y**&*993G**6222$$VV444(. f%  / /rcR |dS#t$rYdSwxYw)zZ wrapped _sync_map function for prevent error if some cpapi not supported N)rrr4s rsync_mapz Lve.sync_maps?  NN         DD s  &&cL tjS#t$rYdSwxYw)z^ Check if current panel supported for reseller's limits; :rtype: bool F)ris_reseller_limits_supportedrr4s ris_panel_supportedzLve.is_panel_supporteds8  577 7   55 s  ##ct|j|j|fS)zo Check present all needed (kmod-lve, liblve, /proc/lve, panel) for manipulate resellers limits )allrrrrr4s rreseller_limit_supportedzLve.reseller_limit_supported"sKDG//11I1133++--/00 0rct|j|jfS)zh Check present all needed (kmod-lve, liblve, /proc/lve) for manipulate resellers limits )rrrrr4s ris_lve10z Lve.is_lve10*s3DG//11493P3P3R3RSTTTr)NNN) rrrr$rrrrrrrrrrrrrs####     ///$000UUUUUrr)#rrrrqrrdtypingrclcommon.clfuncrclcommon.clprocrclcommonrrclcommon.cpapi.cpapiexceptionsrr ImportError clveconfigr rrrL LVE_NO_UBCLVE_NO_MAXENTER ExceptionrrrrrNrrrrrrr#s ############!!!!!!!!777777LLLL EEE!  '))         9                L   [ [ [ [ [ [ [ [ |z1z1z1z1z1z1z1z1z        x3x3x3x3x3x3x3x3v`U`U`U`U`U`U`U`U`U`Us?A A