r'h!z NddlZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl mcmZddlmZddlmZddlmZddlmZmZmZmZmZmZddlZddlZddlZddl Z ddl!m"Z"ddl#m$Z$m%Z%m&Z&m'Z'ddl(m)Z)dd l*m+Z+dd l,m-Z-dd l.m/Z/m0Z0dd l1m2Z2dd l3m4Z4ddl5m6Z6m7Z7m8Z8ddl9m:Z:m;Z;ddl mZ>m?Z?m@Z@ddlAmBZBmCZCddlDmEZFddlDmGZHddlImJZJdZKdZLdZMdZNdZOdZPdZQdZRdZSeTejUVddZWdZXe&e"jYsdZZdZ[ne?eW ZZe=eZ!Z[Gd"d#eZ\d$e\fd%Z]d&Z^d'Z_d(Z`d)e)fd*Zadd+Zbd,Zcd-d.d-d/dd0dd1d2Zdd0Zed3d.ddddddd2Zfgd4Zgd5ahdaidajd6akd6aliamd6and6aod6apd6aqd6ard6asd6atd7aud6avd6awd6axd8Zyd9Zzd:Z{dd;Z|d<Z}d=Z~e}p e~Zdd>Zd?Zd@ZdAZddBZdCZejdDZdEe\fdFZdGZddHZdIZdJZddKZdLZdMZdNZdOeTdPefdQZdRZdSZdTeeeTffdUZdVZddXZdYZddZZdd[Zd\Zd]Zd^Zdd_Zdd`ZdaZdbZdcZdddZdeZiadfZdgZddhZdiZdjeTd$efdkZd$efdlZGdmdneZdjeTd$dfdoZddpZdqZdrZdsZdtZddvedwedxeTd$efdyZdzZd{Zdd~ZefdZddZdZdZdZdZddZdZdZd$eeeffdZddZdZdZdZdZdZdZdZdZdZdZdZdZdZdZddZdZddZddZddZdeded$eeTfdZdZdZdZdZdZddZdZdZdZddZdZdZdZdadadadadadZddZdZddZdZdZdZdZdZdZdZdZdZddZdZdZdS)N)range)partial)PAGESIZE)DictListOptionalTextTuple TypedDict)Feature)adminsget_main_username_by_uidis_panel_feature_supportedreseller_users) EncodingError) acquire_lock)detect_panelclass)reseller_limits_disabled_postreseller_limits_enabled_post) exec_utility)get_subprocess_logger)BadVeConfigExceptionget_xml_configsave_xml)LockFailedExceptionsetup_global_lock)LVP_XML_TAG_NAMELveNameMapPyLve PyLveError)create_dir_securewrite_file_via_tempfile)config) id_registry)LvdErrorz%/usr/bin/getcontrolpaneluserspackagesz /proc/cpuinfoi' VE_DEFAULTFz /bin/umountz"/etc/container/exclude_mounts.confmultisingle PYLVE_DEBUGplesk_id)debug)pyc\eZdZUeezed<eed<eed<eed<eed<eed<eed<dS) LiblveSettingsls_cpuls_cpusls_io ls_enters ls_memory_phyls_nprocls_iopsN)__name__ __module__ __qualname__intstr__annotations__py/lvectllib.pyr/r/MsY #I LLL JJJNNNMMM LLLLLr>r/returnc Ddddddddd}|||S)Nr)r0r1r2r3r4r5r6)update)kwargsdefaultss r?create_liblve_settingsrEWs<  H OOF Or>cttrtjSgS)z-Helper function for easy mocking in unittests)lvereseller_limit_supportedproc lvp_id_listr=r>r?lvp_listrKes/ ##%%&x##%%% Ir>cnt}||S)zf Get list of resellers with activated reseller limits :return: list of pairs (name, uid) )r link_xml_nodeload_from_node)name_maps r?get_active_resellersrPls1 yyH   " " $ $$r>c6|dtDvS)z] Check whether giver reseller has activated reseller limits or not :return: bool c3 K|] \}}|V dSNr=).0nameuids r? z,is_active_reseller_limits..|s&JJidCTJJJJJJr>)rP reseller_names r?is_active_reseller_limitsrZws% JJ3G3I3IJJJ JJr>ectjs|tr tddt |gnt |t jddS)a" Since cPanel user can corrupt config file for some user with wrong encodings, we want to notify him that he should fix encoding problems with the link to documentation. Print error message and exit with code 1 or raise given exception if it isn't cPanel. :return: None r(ERRORN) cldetectlib is_cpanelJSON json_formatr;printsysexitr[s r?raise_cpanel_encoding_errorrgsg  " " Gc!ff% ' ' ' ' aHQKKKKKr>ch t|dS#t$rtddYdSwxYw)az ~~~~~~~~~~~~~~~~~~ !!! DEPRECATED !!! ~~~~~~~~~~~~~~~~~~ Please, use setup_global_lock instead if possible Wrapper over setup_global_lock. If lock cannot be set, it will write message and close app The only reason why it is here is legacy function check_result_and_exit that we use in TWO places :type write: bool :return: Nothing r^zcan`t get lockN)rrcheck_result_and_exit)writes r?get_global_lockrksP3%     333a!12222223s 11c|dtj fvrJtrttdd|gnt d|t j|dSdS)Nrr]zlvectl: zlvectl: Error: )errnoENOSYSrarb MULTI_FORMATrcrdre)resultmessages r?ririst a%,'''  /  w0D70D0D&E F F F F -G-- . . .  ('r>r^i)cpuncpuioepmempmemnprociopsd)rvrurwryrzr{r|rxfalsec |adSrS)ra) json_flags r?set_jsonrs DDDr>c |adSrS) BYTES_FLAG) bytes_flags r? set_bytesrs JJJr>ctrtdkrd}ntdkrd}ntdkrd}nd}gdgdgdgd d |}tr1|d d z}|d|d gz||dzS|S)Nnoiops_8864)IDSPEEDPMEMVMEMEPNPROCIO)rrrrrrrIOPS)rrrrr)rrrrrr^CPU)NOIOPS LVE_VERSIONraindex)versionfields speed_idxs r? get_fieldsrs +""      BBB B B B ; ; ; , , ,   F  CLL))A- z z"eW,vijj/AAB Mr>c|3tj}|dtd|dan|at}|stdtadS)Nrzget_lve_version failedzinit_lve() failed.)clcommonget_lve_version RuntimeErrorrpylve initializeliblve_settings lve_settings)lve_ver lve_statuss r?initr s}*,, 1: 788 8aj  !!##J 1/000((**LLLr>ctjd}|dS tj|S#t t f$r<}tdt|tj dYd}~dSd}~wwxYw)z-Get cpu information from environment veriableCPU_DATANz.Invalid environment variable 'CPU_DATA' formatr^) osenvirongetjsonloads TypeError ValueErrorrcr;rdre)packed_cpu_datar[s r?_get_cpu_data_from_envr sjnnZ00Otz/*** z " @#a&&III  s9B 1BBci}i}d} ttdd5}|D]}|s||d|<|dz}i}&t|ddkr\|dd||dd<d ||dd< d d d n #1swxYwYn<#t $r/t d td tjdYnwxYw||d dgS)zF Parse /proc/cpuinfo return [NumProc, frequency in MHZ] rrutf-8encodingrIr^:rNzlvectl: Error: Can`t open .proc0zcpu MHz) openCPUINFOstriplensplitIOErrorrcrdre)cpuinfoprocinfonprocsflines r? get_cpu_datar-sGH F '3 1 1 1 BQ B Bzz|| B/7GO6OO,#aZF!HH4::c??++q00?Czz#q?Q?W?W?Y?YC!3!9!9!;!;<cJt|}t}t|d}tjd|}|`t |dd}||dzkr|dz}|dkr'tttdz|zSdSdS)zd Try converting cpu limit from SPEED in percentage of one CORE format to kernel format. rz\d+(?:\.\d+)?%$N%rr}) r;rr:rrfloatreplacerr)rrrvpercents r?convert_from_speed_percentrhs t99DH x{  Dh)400G S"--.. TCZ  SjG Q;;u[C/'9::;; ;t 4r>ct|}t}t|d}t|d}t jdtj}||}||d}t|d}| dkr|dz}|||zkr||z}|dkr'tt|tz|z SdS) zQ Try converting cpu limit from SPEED in mhz/gzh format to kernel format. rr^z,(?P\d+(?:\.\d+)?)(?Pmhz|ghz)+$NsuffixfreqGHZi) r;rr:rrcompile IGNORECASErgroupupperrr)rrrvcpu_freqpatternrrrs r?convert_from_speed_hzrzs t99DH x{  DXa[!!HjH"-XXG MM$  E X&&U[[(()) <<>>U " "$;D (T/ ! !d?D !88uTK/(:;;<< < 4r>c>t|pt|S)z} Try converting cpu limit value from either SPEED limit format (percentage of CORE or mhz/ghz) to kernel format. )rr)rs r?convert_from_speedrs$ #4(( '  & &r>czt||}||St|}||St|}||SdS)z Convert different variants of cpu limit to kmod ver 8 variant :param data: Value in old CPU format or SPEED with % or mhz/ghz. :param lncpu: Limit in old NCPU format. :return: CPU limit in kmod ver 8+ format or None for bad format N)rrr)rrfrom_cpufrom_speed_percent from_speed_hzs r?convert_to_kernel_formatrsV$D%00H3D99%!!)$//M  4r>c pt}t|d}t|}d|vrOdtttt|d|zzStttt||zS)zm convert speed to old cpu format args: cpu limit in speed value return: old cpu limit format r*)rr:r;rlstrip)speedrr{s r?speed_to_old_cpurs H   E JJE e||SU3u||C'8'8#9#9U#BCCDDEEEE s5Uu,--.. / //r>c#Ktt} t||n2#t$r%t jt jd|dwxYw |Vt|dS#t|wxYw)zF Run subprocess in lve with pseudo-random id and given limits zUnable to setup lve with id z-, something is wrong, check dmesg for detailsN)rrget_available_lve_id lve_setupr!syslog LOG_ALERT lve_destroy)settingslve_ids r? temporary_lvers    ' ' ) )F ))))  f&)Vv)V)V)V W W W  "  &!!!!!&!!!!sA/BB%%CrcRt}t|d|d|_|d|_|d|_|d|_|d|_ttj d|d ztz |_ |S) a Just a nice user-friendly constructor of liblve_settings object You can pass the following ls_cpu and ls_cpus values: - in percents of one core (just ls_cpu='75%', ls_cpus will be ignored) - in old 'CPU' format (two arguments, ls_cpu and ls_cpus required, both int) r0r1rr2r3r5r6g?r4) rrrr0r2r3r5r6r:mathceilrr4)rss r?make_liblve_settingsrs A'(:(9BUVVVAHwAG;'AK*%AJ#AI$)B/)B$BX$MNNOOAO Hr>ct|d}|s.|d}tj|j}t |S)Niduser)r; getAttributepwdgetpwnampw_uidr:)ve_lve_elementuser_uid user_names r?get_ve_lve_user_uidr sV>..t4455H 2"//77 < **1 x==r>cdt|di}|tkrt|d|d<|||tt j|dS)a Print output in json as: {"status": "ERROR/OK", "msg": "Some Message", "ext1": "foo", "ext2": "bar"} where "status" and "msg" field are mandatory :param str error_type: Either MULTI_ERROR or SINGLE_ERROR :param list data: List with a status string and a message string :param dict extensions: Some additional fields for the final json object :return: None statusrr^msgN)r;rorBrcrdumps) error_typer extensionsrps r?rbrbslDG %F\!!DG u  j!!! $*V  r>c tt|dd||<dS#tt t f$rp||||<||}|dt|| |j |YdS#t$rYYdSwxYwwxYw)Nrlimit) r: ve_defaultgetElementsByTagNamerr IndexErrorr createElement setAttributer; appendChild Exception)xml ve_defaultsve_cfgvaldefaultnodes r?check_def_valuer#s z>>sCCAFSST[\\]] C  I ."3< C##C(( '#gcl"3"3444  COD ! ! ! ! ! !    DDD  s+AAA C(B;; C C C  Cc*fd|jDS)Nc^g|])}t|tj|jk'|*Sr=) isinstancerElementtagName)rT_tags r? z"xml_filter_tag.. s7 Z Z Z!*Q *D*D ZVYIYIYAIYIYIYr>) childNodes)r"r*s `r?xml_filter_tagr- s Z Z Z Zt Z Z ZZr>ct||D]9}|||s||||kr6|cSdSrS)r- hasAttributer)r"r*attrattr_val child_nodes r?xml_filter_firstr3sn$T3//  J$;$;D$A$A    J$;$;D$A$AX$M$M  r>cpt|||}|t||S)N)r"r*r0)r3rr)r"r*r0filtered_child_nodes r?get_child_tag_atrrr6s;*#DIII"ll  + +D 1 11r>cxt||d}||t|dS)z Find in children nodes node with tag and setup attribute insted el.getElementsByTagName not search recursiveli in tree rN)r-rr;)r"r*r0r first_child_nodes r?set_child_tag_atrrr9 s; &dC003!!$C11111r>c t\aadS#t$rg}tr%t t dt|gntt|tj dYd}~dSd}~wwxYw)zLoad config from ve.cfgr]r^N) rr ve_lveconfigrrarbror;rcrdrerfs r?_load_config_wrapperr<)s -//     wA&7 8 8 8 8 #a&&MMM  s BABBlvp_id lvp_defaultsczda |s"ttddatS|r!t datStttdt|}|r| ddanPttdr t tanttddatS#t$r@tr't!dddgt#jd nt'd YnwxYwtS) zLoad default limits :param int lvp_id: lvp id :param bool lvp_defaults: load reseller's default limits instead of global :return: dict with default limits truerDrr cloneNoder(WARNINGzdefault section error in ve.cfgr^z(warning: default section error in ve.cfg)ubcr-r;r LVE_DEFAULTrr LVP_DEFAULTr3rr;rhasattrrArrarbrdrerc)r=r>defaults_root_nodes r?_load_default_limitsrH8s8 C> ' jAA!DJ   --j99J -l>>  > )-N!O P P P HQKKKK < = = = > s#C)"C) BC))AD32D3c |tdttttt t fDS)Nc3"K|] }|dkV dS)rNr=)rTxs r?rWz._all_config_elements_loaded..bs&jj1qBwjjjjjjr>)allve_lveve_lvp ve_package ve_binaryve_enter_by_nameve_cfg_versionr=r>r?_all_config_elements_loadedrSas. jjYHXZh ijjj j jjr>ctdatdattat jj ttd}t|dkr |da n9t da tttdatd}t|dkrt!|djjndadS) z$Load all config elements from ve.cfgrGpackagez enter-by-namerbinaryrr^N)r;rrMrOrrNrGmaprOrMrrQrrrrPr: firstChild nodeValuerR)enter_by_name_elemscfg_version_elemss r?_load_config_elementsr\ds . .u 5 5F229==J  . ./? @ @FG""<000&;;OLL !##.q1!//@@  !1222 55h??I%99)DDGJK\G]G]`aGaGaS*1-8BCCCghNNNr>default_limitsc0iattttt|}|d tddd}t|tdtd<n#tttf$rt|dtdtd<t d}| dt|d t|n#t$rYnwxYwYnwxYw t!tddd td <n#tttf$r|d td <t d}| d t|d  t|n#t$rYnwxYwYnwxYw|d t"d kr |d n|d d t$i|d|d|dt'dS)z~Create ve_defaults dict with default values for all limits :param dict default_limits: default limits for lve or lvp )rrrr!rv)r rurrrother maxentryprocsrxrwry)r r!rzr{r|N)rrr#rrrrrrrrrrr;rrr:rMEM_DEFAULT_CL5_check_defaults_for_nones)r] check_def_valrrurxs r?_load_ve_defaultsresK  MMf //66q9FFwOO5e;vCVWWW E  I .5nU6KS^_eSfggg E""5)) #nU&;"<"<===   " "3 ' ' ' '    D    ? ? H H K X XYh i ijj D  I .*40 D  ! !' * * ^D-A)B)BCCC   " "2 & & & &    D  MdQ %      %%)ABBBBMfMgMfsoABBED0/E0 D=:E<D==EEAFA*H);HH) H# H)"H##H)(H)ctD]^\}}|d|d}trtdd|gn"tj|dt jd_dS)z*Check that all default values are not NoneNzERROR: Incorrect z default valuer(r] r^)ritemsrarbrdstderrrjre)keyvalueerr_msgs r?rcrcs"''))   U   9c999  - '7!3 4 4 4 4 J  ^^^ , , ,    r>Tctt||}|ststt |dS)z :param bool lvp_defaults: load reseller's default limits instead of global :param int lvp_id: lvp id to load customise defaults N)r<rHrSr\re)r=r>load_config_elementsr]s r? get_XML_cfgrosW )&,??N #>#@#@ n%%%%%r>c tt||d}|||<|S#tttf$rt||cYSwxYw)Nrr*r0)r:r6rrr)r elr setup_datarks r? check_valuertsm%&rsAAABB 3  I .%%%;s#$$$$$%s%(,AActj}|||}t ||dS)a5 This function is a pure workaround for our ugly globals-based API which should be fixed partially with LU-496, because there is no clean way to retrieve reseller's data from ve.cfg without touching globals :param reseller: reseller name :return: Nothing. It just updates some globals rnN)lveapirrMget_idro)resellerxml_config_load_elementsrO reseller_ids r?_load_resellers_xml_datar|sN~H //(++K 2JKKKKKKr>c tjtaKt}|vr|vrfd}nt jr| t j|}d|jd}t|d5}| }dddn #1swxYwYn#t$rd}YnwxYwd|vr#tj tj d |d fd }tD]n} || r]td | tt} t!t#t%| d d| } | td <n#t&t(t*f$rYnwxYwtd| ttt,dkrtd| ttn dtd< t!t%| dd} | td<n#t&t(t*f$rYnwxYwtd| tttd| tttd| ttndSdS)a Put limit values that will be applied later in a global variable `setup_ve`. :param plan_id: package :param reseller: If reseller is None we only inherit from admin packages. In that case we ignore all tags in ve.cfg with a "reseller" attribute. Nch|dko|dkSNrryr)rrplan_idrys r?is_needed_planz*prepare_setup_data..is_needed_plan s1t,,7cBOOJz"/usr/local/directadmin/data/users/z /user.confrrrzpackage=customzPackage for user with id z is incorrect, please recover it using Note from https://docs.cloudlinux.com/cloudlinux_os_components/#installation-enabling-and-disablingcb|dko|d Srrrrrs r?rz*prepare_setup_data..is_needed_plan!s/t,,7[PZ@[@[<[[r>rvrurrqrrwr@ryrr_r`rxr{rzr|)copyrrsget_reseller_packages_mapr_is_dargetpwuidpw_namerreadrrrrOrtr:rr6rrrrC) rryr res_pkg_dictruser_pwdfilenamertextrrrrurxs `` r?prepare_setup_datars.;''J022   H $<$<LYaLbAbAb d d d d d d d "" v'9"|F33H`HDT```Hh999(Q vvxx((((((((((((((( DDD $4//M(tFttt \ \ \ \ \ A AB~b!! A#FB ZHH67I"RW^e7f7f7fnstttuuC(+Ju%%"J :DD"k:>>>6MMr; CCCC()Ju%/oVVVWWB')Jt$$"J :DGRjAAAFB Z@@@FB Z@@@qH A AsZ0B7 B+ B7+B//B72B/3B77 CC(8E!!E;:E; )G77HHc 6 tjtd|gtjtj5}||jdkcdddS#1swxYwYdS#t $r tddtd|dYdSwxYw)Nz-l)stdoutrirzfailed to run "z -l ") subprocessPopenUMOUNTPIPE communicate returncodeOSErrorri)pathrIs r? umount_dirr?s I   T4 ??    (      ?a'  ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( IIIb"GF"G"G"G"G"GHHHHHHIs43A.A! A.!A%%A.(A%)A..&BBcRtjtsdSg} t tdd5}|D]?}|}|r'|tj|@ dddn #1swxYwYn(#t$rtddtYnwxYw|sdStj tj  t ddd5}d| D}dddn #1swxYwYn'#ttf$rtdd YnwxYwd }t|D]=}d }|D]1} |D],} | | } | rt#| p|}n-2|sdS>dS) zy Unmount all paths from /proc/mounts that match regular expressions from /etc/container/exclude_mounts.conf file Nrrrrzfailed to read z /proc/mountscBg|]}|dS)r^)r)rTms r?r+z"prepare_mounts..as$:::qaggiil:::r>zfailed to parse /proc/mounts F)rrisfileEXCLUDE_MOUNTS_CONFrrappendrrrriunshare CLONE_NEWNS readlinesrrsearchr) reg_exp_listconfrrrmountsATTEMPTSr)errormountreg_exprs r?prepare_mountsrMs 7>>- . .LK %sW = = = = = =''))= '' 7(;(;<<< = = = = = = = = = = = = = = = = KKKb"I4G"I"IJJJJJK  OG'(((B .# 8 8 8 ;A::AKKMM:::F ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;  BBBb"@AAAAABH 8__    E'  NN5))&u--6EE  EE   slBAB BBBBB"CC(D1:D% D1%D))D1,D)-D11!EEcd} tj|ddn #t$rtd|YnwxYwt t ddS) zI Start LVE engine and initialize default mount namespace for LVE z,/bin/mount --make-rprivate / >/dev/null 2>&1Tz /bin/bash)shell executablezError: failed to executezCan`t init lve default settingsrlN)rcallrrcrr lve_start) MOUNT_CMDs r?rrqs?I5 +FFFFF 555 ()444445 OO=O>>>>>s 99cHt|d|d|dS)zs Create LVE container for given ID :type lve_id: int :type ignore_error: bool :return: Nothing z!lvectl: Can`t create lve with id ; error code {code}rl ignore_errorN)r lve_create)rrs r?rr~s> V^^^^".00000r>cHt|d|d|dS)zs Create LVP container for given ID :type lvp_id: int :type ignore_error: bool :return: Nothing z!lvectl: Can`t create lvp with id rrN)rlve_lvp_create)r=rs r? lvp_creaters> !bV!b!b!b&244444r>ctd}g}tD]M}|d|t|d|d||N|S)N lvectllibz*destroy_lvp_all: destroying LVP with id %s"lvectl: Can`t destroy lvp with id rr)rrKr,rlve_lvp_destroyr)loggerdestroyed_listr=s r?destroy_lvp_allrs "; / /FN**&& A6JJJ f&h6&h&h&h  j j jf%%%% r>ctd}|dkrtdS|d|t|d|ddS)NrrLz&lvp_destroy: destroying LVP with id %srrr)rrr,rr)r=rs r? lvp_destroyrsz "; / /F  LL96BBB &"dv"d"d"dfffffr>ctd}d|d}d|d}d}|dkrtrtt }t t tjdkrVtjD]6}| d |t || d }7nd }ntj |s=tj rTtj |5| d |t || d }n!tj |sd }|r!trtt d gdSdStrtt"d|gdSt%d|dS)NrzCan't remove lve z from kernel - error code -3zCan`t destroy lve with id rFrLrz*lve_destroy all: destroying LVE with id %srTz&lve_destroy: destroying LVE with id %sOKWARNz warning: )rrGrHboolrrlistrI lve_id_listr,rcheck_inside_listresellers_supporteddetect_inside_lvprarb SINGLE_FORMATrorc)rrcant_remove_msgcant_destroy_msg destroyedid_s r?rrs "; / /FO6OOOOQFQQQI   ' ' ) ) 0_..//I tCH((**++ , ,q 0 0x++-- ! ! I3OOO-=>>>  ! II 8 % %f - - --// 47H4N4Nv4V4V4b LLA6 J J J OOF,c 0|r.tj|st|t j5t jd ttdt_ ttdt_ ttdt_ ttdt_ ttdt_tdkrHttdt_ttd t_td kr$ttd t_|rS|d kr&t&|td |nut&|td|dnN|d kr"t&tdn&t&|td|dnJ#t.$r=}t1ddt3|zdzt3|zYd}~nd}~wwxYwddddS#1swxYwYdS)Nrrwrurvryrxrarzr{rr|r%Can`t setup default settings for LVP rzCan`t setup lvp with id rzCan`t setup default settingszCan`t setup lve with id r^zCan`t setup lve z. RuntimeWarning excepted: )rGrI exist_lvprwarningscatch_warningsfilterwarningsr:rsrr2r0r1 ls_memoryr3rr4r5r6rlve_set_default lve_lvp_setuprRuntimeWarningrir;)rr=rws r?rrs ch((006  " "pp((( p!$Z%5!6!6L "%j&7"8"8L #&z&'9#:#:L %(E):%;%;L "%(D)9%:%:L "Q-0F1C-D-D *(+Jw,?(@(@ %Q'*:f+='>'> $ lQ;;)) 6f^d6f6f*hhhh'' 6nQW6n6n6n(pppp1%%l3I61J 6I;;J  JJcd}d}t}tdt}|at|trL ||d}|sd}n#t$rd}YnwxYw ||d}|sd}n#t$rd}YnwxYw||fS)z Get pair of package, reseller for lve_id :param lve_id: lve_id, UID with package, reseller :return: tuple of (package, reseller); Both can be None N list-usersryrU)packages_usersGetControlPanelUsersr&dictKeyError)rrUryold_packages_users temp_packages r?"get_package_and_reseller_by_lve_idrsGH'&&&"L'N,%% #F+J7H    HHH  "6*95G    GGG  H s#A AA A33 BBz+/var/run/cloudlinux/effective-normal-limitsz;/opt/cloudlinux/flags/enabled-flags.d/burstable-limits.flagcttjtsdS tjt }tj|s2tj|}t|ddd|n(#t$r}td|d|d}~wwxYwtt d}|5|ri}n tj t rDtt dd 5}tj|}dddn #1swxYwYni}nZ#tj$r }td t d|d}~wt$r }td t d|d}~wwxYw|t" t%tj|t dn1#t$r$}td t d|Yd}~nd}~wwxYwddddS#1swxYwYdS) ai Save calculated effective normal limits for an LVE to a cache file. The cache file is stored in /var/run (tmpfs) for faster operations. It disappears on reboot, but lvectl apply all runs in the lvectl systemd service anyway, so the file will always reappear if the service functions normally. If additional speed is desired, consider replacing the standard JSON lib with a faster one like rapidjson or orjson. :param reset: If True, recreate the cache file from scratch with data available in the dict, instead of updating it, defaults to False :type reset: bool, optional Nirz#Error: failed to create the folder : z.lockrutf8rz=Error: failed to parse the effective normal limit cache file z>4 5 5(<== w}}]++ G'//-88K mUAq+ F F F  HMHHQHHIII (+?(F(F(FGG nn  !   7>>"677*2C&III?X+/9X+>+>(???????????????(*$'   qVjqqnoqqrrr   pUippmnppqqq   7888 n #DJ/?$@$@BVX] ^ ^ ^ ^ n n n lQellijll m m m m m m m m n)nnnnnnnnnnnnnnnnnnsA5B C(B>>CH-&;E!E6 EE E E EH-F( E;; F(F##F((H-(G/.H-/ H9HH-HH--H14H1c>ttt|<dS)a Cache the calculated effective normal limits for an LVE to a dictionary. setup_data is a global dict that contains the LVE configuration last applied. Holds only one entry - during operations like lvectl apply all, we enter this function repeatedly with setup_data containing info for one processed LVE each time. These limits can be used by the Burstable Limits components to set/reset burst or normal limits without having to go through effective limit calculation or invoking lvectl as a middleman. Comparing the cached limits to current active limits (in kernel) also shows whether or not the LVE has burst limits active at the moment. This function gets called in lve_apply, which means it also runs within: * lvectl apply all * lvectl apply-many * lvectl set * and others, that also call lve_apply :param lve_id: LVE ID for which the limits are being saved. :type lve_id: int N)rsrr;rs r?cache_effective_limitsres0,6CKK(((r>rc|dkstjsdS|tt jvrdSt tj|S)u0Return True if the user has at least one isolated domain registered. CLOS-4370: the per-domain branch in lve_apply only does meaningful work when the user has at least one docroot in the lvd-map. A bare marker file from ``lvectl allow-domain-limits`` (with no ``enable-domain-limits`` follow-up) or a 0-row hashtable left behind by ``lvd_map_remove`` after the last ``disable-domain-limits`` both leave the per-uid file in place, so existence alone is not enough — we must also check that the hashtable actually has entries. rF) rGr-domains_supportedset ws_configfind_all_lve_ids_with_configrws_id_registryget_all_entriesrs r?_is_domain_isolated_userrs^{{#&2244{u S?AABBBBu .v66 7 77r>ctjstSt jS)u8Collect all known domain LVE IDs from the on-disk registries. Domain LVEs (created by lvdctl set) appear in /proc/lve/list at root level, but lve_apply() must not process them as regular users — their limits are managed by apply_domain_lve_limits() inside the domain-isolated-user branch. )rGr-rrrget_all_domain_idsr=r>r?_get_all_domain_lve_idsr s2 6 # # % %uu  , . ..r>ceZdZdZdS)DomainLveIdErrorz>Raised when lvectl set/delete/destroy targets a domain LVE ID.N)r7r8r9__doc__r=r>r?r r sHHHHr>r c|dkstjsdSt}|sdSt j}||ks||vrt d|d|ddS)aRefuse to operate on domain LVE IDs from lvectl set/delete/destroy. Domain LVEs are managed exclusively by lvdctl; lvectl operations on them corrupt the domain configuration or create phantom entries in ve.cfg. The check only activates when at least one domain LVE is registered, so existing customers without domain isolation see no change in behaviour. rNzLVE ID z is in the domain LVE range (>= zV) or is a registered domain LVE. Domain limits must be managed via lvdctl, not lvectl.)rGr-rr rmin_idr )r domain_ids min_domain_ids r?_reject_if_domain_lve_idrs{{#&2244{(**J ")++M &J"6"6 Ef E Em E E E   #7"6r>czt}dkrtdt|c}atdkrt|d}||}n1|rtnt } t tfd| d}|dkrR |d}n#ttf$rd}YnwxYw |d}n#ttf$rd}YnwxYw|t|| td |tt} tt|d d | td <n#t t"t$f$rYnwxYwtd td td <td|ttt&dkrtd|ttn dtd< t)t|dd td<n#t t"t$f$rYnwxYwtd|tttd|tttd|ttn't||t&dkr dtd<|s:t+dkrt-rt/t/ t0} t0t0j| t:t>dt0 | dS#tBtDtFf$r0} tIj$tHj%dd| Yd} ~ dSd} ~ wwxYwt/|dSdS)a  Aplly limits to LVE lve_id :param lve_id: lve id :type lve_id: int :param plan_id: package for user with lve_id. deprecated :type plan_id: string :param result: if True = don't apply limits. only create setup_data with actual limits :type result: boolean :param reseller: if True = plan_id is resellers plan. deprecated :type reseller: boolean :param out_node: node with limits for lve_id :type out_node: xml_node :param lvp_id: reseller container id; host container if 0 ruseridrr=Nc,t|kS)Nr r )r"rs r?zlve_apply..s 34 H H HF Rr>rUryryrvrurrqrrwr@ryr_r`rxr{rzr|)ryrr domain_maprrz1lve_apply: skipping per-domain isolation for uid=r)&rrrrorNrMnextfilter NameErrorrrrtrrsrr6rrrrCr:rrrrG_build_domain_map_map_domain_lvesrIrWrrrapply_domain_lve_limitsrr&r!r LOG_WARNING) rrrpryout_noder=rnew_packages_usersrr node_listrrexcs ` r? lve_applyr's'$( {{Xv...-;=O*N ||6"""" B $0FF&  RRRRT] ^ ^    {{ (0;GG8$   GGG  )&1*=HH8$   HHH  ~7X6666FB Z@@  89KBTY`g9h9h9hpu v v vJu  J 2    D  e  $ +E 2Ju D"k:666 &== r; ; ; ; ; !Ju  "#5bgO#\#\#\]]Jt  J 2    D  GRj999FB Z888FB Z8888 7XfEEEE '>> !Ju   -v&&& Q;;3F;;; fV , , , , f     !226:: $$VSX\\^^ $SSS%%flDtlrDtDt%uuu++Fz+JJJJJXz2    &WWWRUWW  fV , , , , , ,A - -saBB('B(,B;;CC)D//E E ='G%%G?>G?BMN%5%N  N%cht|t|dz g}t|dS)zt Print data with the last column 30 symbols wide. Useful for printing data that contains package names. r^ wide_indicesN_format_fieldsrrcrformatted_strings r?_pprintr/5s9 &fCKK!O;LMMM r>ct|t|dz t|dz g}t|dS)z Print data with the two last columns 30 symbols wide. Useful for printing full data of every user with package name and reseller name. rr^r)Nr+r-s r? _pprint_fr1>sO &&kkAos6{{Q7 r>cHt|dg}t|dS)zb Print data with the first column 30 symbols wide. Useful for printing packages data. rr)N)r,rcr-s r? _pprint_pr3Ks. &fA3??? r>cjt|dt|dz g}t|dS)z Print data with the first and last columns 30 symbols wide. Useful for printing data with user names and package names. rr^r)Nr+r-s r? _pprint_rr5Ts; &fAs6{{Q;OPPP r>rr*widthcg}t|D]J\}}t|}||vr||d|3||dKd|S)aK Helper function to format fields based on specified indices for wide columns. Args: fields: The fields to format. wide_indices: List of indices in the fields that should be wide. width: The width of the wide columns. Returns: A formatted string with specified fields widened. >z>8r) enumerater;rjoin)rr*r7formatted_fieldsrfield field_strs r?r,r,]s!&))77 uJJ L  # #y$;5$;$;$; < < < <  # #y$5$5 6 6 6 6 77# $ $$r>ct|}t|to|d}|dd}|rt |}|dz}nd}|rd|n|}|S)z Convert pmem or vmem limits to bytes value :param value: pmem or vmem limits in kbytes value :return: bytes value of limit rrir)r;r& startswithrr:)rk was_changeds r?_pmem_vmem_to_bytes_valuerBxs JJEUC((BU-=-=c-B-BK MM#r " "E E   & 1KKKKEE Lr>cd}d}t|tr!|dr |dd}d} t|}n#t$rYdSwxYw|rd}|dzdz}|d kr||d }n ||dzd }|S) z Convert amount of RAM to M format :param string value: amount of memory in KB :rtype: string :return: amount of memory in MB like "1234M" rFrr^NTr~rtrMK)r&r;r@r:r)rkrprAvs r?_mb_memrGsFK%%"2"23"7"7abb   JJ rr ETME qyy$E$$$$AE$$$ MsA AA0r!c. t ddz d< fd}|ddkrt|dnd}d}|t|dt|t|dt||dt||dt|d t|d t|d t|d |d g}t }|||z }t r)d fd|D} d| dg}n||| fd|D|S)z^ Generate header and default package data either as print to stdout or as json string rur}c0|dS)Nrr)rjrDs r?get_dataz_formatter..get_datas||C$$$r>rcLtrt|nt|SrSrrBrGrks r?convert_mem_limitsz&_formatter..convert_mem_limitss!3=Q(///75>>Qr>rvrzryrxr{rwr|) rrrNCPUrrrrrrPACKAGEN,c3RK|]!}d|d|ddV"dS)r":"rNrKrTr fields_maps r?rWz_formatter..sEKKq:A::*..B"7"7:::KKKKKKr>{}c<g|]}|dSrrKrVs r?r+z_formatter..s'888A*..B''888r>)rrrr;rrar;) printer default_iddefault_package more_fieldsrL_cpurPresrrrDrWs @@r? _formatterrbs!!Huo,HUO%%%%%1920E0E HHUOO , , ,2DRRR3xx#7#74yy#hhv&6&6"7"7&&xx'7'788993GYGYZbZbchZiZiGjGjCkCk((4..!!C0A0A,B,B#hhW[nnJ]J]HHV$$%%/ J C \\F+ :xxKKKKFKKKKKD}}}o888888899 Jr>cfd}|S)aA Generate inner function with closured fields names and printer function :param list fields: List of strings that represent names of fields in final output :param callable printer: Function to format and print data for every entry :rtype: callable :return: function to format data for every user cdt|d}t|d}|dkrd}tdkrt|dn5|t|dnt d t||t jt t|||d fd }d }t|d<t|dd<t|dd<t||dd<t||dd<t|dd<t|dd<t|dd<t|dd<trt|d<n|d<|trdndd<n|d<ddvr?dttd ddzzd<ntddzd<dd<ttdd<g}tr)dfdD}d|dg}n fd D|S)!z :param string user: Find and format data for this User ID :rtype: list :return: List of given user's statistics data line or empty list rrUryNr^rF)rzrvT)rryrpct|tt|krdtt|znt|S)Nr)r;rs)rjrs r? check_changedz7_user_formatter..wrapper..check_changedsP14T#Y3zRUCWCW1W1W3Z_----]`aefiaj]k]k kr>cLtrt|nt|SrSrNrOs r?rPz<_user_formatter..wrapper..convert_mem_limits!7AU,U333wu~~ Ur>rrurvrzryvmemrxrwr{r|N/Arr}rrSc3ZK|]%}d|d|dV&dS)rrUNlowerrTrrs r?rWz3_user_formatter..wrapper..sCIIQ888d17799o888IIIIIIr>rXrYcDg|]}|Sr=rlrns r?r+z4_user_formatter..wrapper..s%666!d17799o666r>)rrRrr|rorrsr'r;ra_normalize_strr:rrr;) rrUryrfrPrarrrr\s @r?wrapperz _user_formatter..wrappers5  &y1!$' 3 r>>H Q   w 6 6 6 6 6#)ERRRRR 7777 w : : : :y$$$(4HHHH l l l l l V V VYYT --..//U ==0011V --mmF.C.CDDEEV --mmE.B.BCCDDV t,,--T t,,--T MM'2233W ==0011V  &,W55DOO%DO  (,4uu"D  'D  $u+  #c$u+*<*r=)rr\rqs`` r?_user_formatterrrs0DDDDDDJ Nr>ct td||rtd|n#|td|ntdn#t$rYnwxYwdg}tt|}t |z}t |}tD]}|||z }tr*tdd |zd zdSdS) Nrrlist-reseller-usersrrRr_ {"data":[rS]}) rorrrbr/rrrrrarcr;)rryr_rpr formatterrs r?paneluserslimitsry sMMM \***  &  6 2 2 2 2  ! !6 J J J J J  . . .      +K [ 9 9 9F \\K 'F''I""))D//! 5 kCHHV,,,t34444455sAA A%$A%ctdg}tD]6\}}|t ||d|df7|S)z@Get list of tuples[lve_id, reseller, package] from control panelrryrU)rrrhrr:)rpstr_uidpayloads r?paneluserslistr};sj&&& F*0022OO s7||WZ%8'):LMNNNN Mr>cddlm}i}tdtt||<td|t|S)zBGet dict of pairs[provider, list[package_name]] from control panelr)DEFAULT_PROVIDER list-packageslist-resellers-packages) clveconfigrrrrkeysrB)rpackagess r?panelpackagesdictrEsp,+++++H)))!%n&9&9&;&;!cTttdttddg}t ddgz}t |t}t D]}|||z }tr*tdd |zdzd Sd S) z] Implements lvectl all-user-list command :return: None, prints result to stdout rrRRESELLERru)r\rvrSrwN) rorrbr1rrrrrarcr;)rprrxrs r?all_users_limitsrWs MMM&&&  :/F G G GF \\Y 3 3F :::I""))D//! 5 kCHHV,,,t34444455r>ctjdkr8dtDfd|D}|S)z Filtering DirectAdmin's admins for `lvectl apply all` command :param ve_dict: dict with LVE :return: filtering dict DirectAdminc@g|]}tj|jSr=)rrr )rTrs r?r+z(_filtering_da_admins..vs%III#,t,,3IIIr>c$i|] \}}|v || Sr=r=)rTrjrkuids_da_adminss r? z(_filtering_da_admins..ws)]]]*#u3nC\C\3C\C\C\r>)r_ getCPNamer rh)ve_dictrs @r?_filtering_da_adminsrksV-//IIIII]]]] ]]] Nr>c ttt}|rHtjj fdtD}n#t$ri}YnwxYw|durt}t}n't}tj |}i}|D]}|dd|t|<|D]}||vrddd||<t|dkrjt!|}|D]X}||vrd}n||d}||}t#|} t| dkr|| dd||<P|dd||<Y|S)Nc$i|] \}}|v || Sr=r=)rTkrFcfg_lvp_id_lists r?rz&prepare_apply_data..s)___1!J^J^q!J^J^J^r>Tr)r"ryrrr")rrrrGrWrOid_listrhrrNrKrMrIrr rrguess_reseller_by_package) r=packages_users_r%rrr"rrVpkg resellersrs @r?prepare_apply_datar|s~..  `!g.6688O____0D0D0F0F___O ~~ ** (&&f&55 G__FJY]<^<^#488899??  '+>>GFO O!!'w//" B BC'!!s|F+!#&C1#66I9~~!!)-IaLII )-DAA NsA,A00 A?>A?c 0t\}}ttj}|D]}||ddkr||2||vr/t|||tj d5t|||d||ddddn #1swxYwYtdt rtd}ttj}|D]E}||vr/t|||t#||tj|}tj}t(j|D]} t/j| j}||vr/t|||||d|kr)tj ||d|d |d  t|| G|D]}t||D]}t|dS) NrTrr"ryr#ryrCan`t move lve_id= to lvp_id=rrrry)_get_lve_ve_dict_and_lvp_maprrGrIrrrdiscardrr-context_ignore_errorr'rHrrJrr&_create_if_necessary_and_configure_lvprWget_reseller_namercpapirrrr  lve_lvp_move) lve_ve_dict lve_lvp_mapremaning_alive_lvesr lvp_ve_dictremaining_alive_lvpsr=rYkernel_mappingrs r?lve_destroy_and_recreate_allrsX;==Kch224455""$$ ??61 % % * *  ' ' / / /  ( ( ( OOF # # #  ' ' / / / V ( (d ( ; ;   $V,V4$V,Z8                   Q ##%%*(.. "38#7#7#9#9::"&&(( A AF---%%f---$,,V444 2; G G G G55f==M X\\^^N 55mDD A Ad++2000OOF+++'//777!%%fa00F::F'' eV e e e e e( -@@@@@ A+ * *F  ! !& ) ) ) ) &     s+D  D D c t\}}t}tjd5|D]K}||vr||ddkr*t|||d||dL dddn #1swxYwYtdtsdStd}tj }|D]}t|rt||tj |}tj|D]T}t%j|j}t|rtj |st,||nUtj ||s5t,|t,||||d|kr)tj||d |d |d  nC||d|kr)tj||d |d |d  t|| VdS)NTrrr"ryrrrrrrrr)rr rGr-rrrr'rHrrIrWrrrrrrrrr rrlve_lvp_create2rrr) rrdomain_lve_idsrrlvp_id_rYrlve_id_s r? lve_apply_allrs>799G[,..N  $ $$ $ 7 7jjllnn j jF''vq))Q..&76?6+BWU[_]gMhiiii jjjjjjjjjjjjjjjjQ  ' ' ) ) &&GX\\^^N<<>>)>)> $G , ,  .w@@@11':: N11-@@ > >Dl4((/G'00 x)))99<))'7;;;;33GWEE<))'222))'7;;;"%%gq11W<<F'' gW g g g g g("%%gq11W<<F'' gW g g g g g( W} = = = = == >)>)>sA!B..B25B2cttdt}tr&t tni}||fS)Nr)rorrrGrHrlve_id_lvp_id_pairs)rrs r?rr0s_MMM&&&$&&K585Q5Q5S5S[$s..00111Y[K  ##r>ct|ddt|||d||d|t|dtd| dS) NTF)r=r>rnr"ry)rr#ryr=)r=rnr)rr=)ror')rr=s r?rr8s{vDuMMMM Vvv.vz2 vE:::: Qv&&&&&&r>ctdt|tD]}t||krtj|}tj|}t|D]U} tj |j }n#t$rY)wxYwt|r||vr||V|ddD]}t d| tj|3#t$rQtj|rt|||YwxYwt/||j|t5t6td|D]}t9|t|dSdS)z,Remove reseller from ve.cfg and from procfs.TrrNrF)rkrorNr rGrImap_lve_id_listrWrrrrr rrrrrrr- lve_existsrremover parentNode removeChildrrr')r=rrusersrYusernamerVrs r?_remove_resellerrEsDv%% b 1 1 1V ; ;H,,V44E G55f==M*=99 & &,x007CCH+C00&S5E5ELL%%% ( ) )""1f---)L(((()))v((000///LL((((()     M % %b ) ) ) V    q ! ! ! ! " "&!!!! v & & & &44I (nested under the user's reseller LVP if any), and moves lve under it. Analogous to set-reseller for reseller limits. Any existing domain IDs in the registry are pre-mapped to lvp via lve_lvp_map so that subsequent lve_setup calls will place domain LVEs under the correct LVP automatically. rrrrrrN)rcreate_empty_registryrGlve2lvprIrrrrrrWrr-rrvaluesr)r parent_lvpr domain_ids r?enable_domain_isolationrrsm(000V$$J 8  V  , ,2 fj1111 2CH66vzJJ2 f%%% fj111X\\^^N&!$$..  FYYYFYYY    $3F;;BBDD11   i + +v 5 5   fi 0 0 011r>ctj|sdSt|}tj|D]}t ||tj}||d|krt ||tj | D];}tj |rt | back to the parent LVP (reseller or root), destroys domain LVEs, destroys lvp, and removes the id_registry file. Analogous to remove-reseller for reseller limits. rNr)rGrIrrrrrrWrrrrrrrremove_all_entries)rr child_lverrs r?disable_domain_isolationrs' 8  V  , ,V$$JX--f5522  :y1111X\\^^N&!$$.. :v...$3F;;BBDD'' 8 % %i 0 0 ' OOI & & &%f-----r>c^tj||}ttj}|||kr tj||tj | |dS)avRegister a single domain LVE under the user's LVP. Assigns a domain ID for *docroot* in the per-user registry, then pre-maps it to *owner_uid*'s LVP so that lve_setup will place the domain LVE under the correct LVP when it is first created. Also records the domain name in ``~/.lve/domains.json`` so we can obtain list of enabled domains for user. N) rassign_domain_idrorGrIrWrr-rr LvdConfigradd_domain_by_docroot) owner_uiddocrootrproc_maps r?enable_domain_lvers/ 7CCIMMMx||~~H||I)++ 9i000 Y''==gFFFFFr>ctj||}|ttj|rX t|n<#t$r/}tjtj d|d|Yd}~nd}~wwxYwtj ||tj ||dS)zUnregister a single domain LVE and remove its registry entry. Destroys the kernel LVE (if it exists) and removes *docroot* from the per-user domain ID registry. Also removes the corresponding domain from ``~/.lve/domains.json``. Nz*disable_domain_lve: failed to destroy lve r)r get_domain_idrorGr-rrr!rr"remove_domain_idrrrremove_domain_by_docroot)rrrr&s r?disable_domain_lvers,Y@@I 6  Y ' ' 9 9 **** 9 9 9 f08%.88258899999999 9 ' 7;;; Y''@@IIIIIsA!! B+%BBct|rtj|dStr+t ddd|gt jddStd|dS)z&Disable reseller limits and call hooksrr(rBzno configuration found for LVP rz(warning: no configuration found for LVP N)rr throw_eventrarbrdrerc)rYr=s r?disable_reseller_limitsrsG%1=IIIIII  G )-Wv-W-W!X Y Y Y HRLLLLL EVEE F F F F Fr>ct|tdtd}tD]}t ||krkd}t |t ||j|tttt||sFtr+tddd|gtjddSt!d|dSdS) NTFrr(rBzno configuration found for VE rz'warning: no configuration found for VE )rrkrorMr rrrrrrr'rarbrdrerc)rDeletedrrs r? lve_deletersV$$$DMMMG b 1 1 1V ; ;G     v    M % %b ) ) ) V    MMM f    F  F )-Vf-V-V!W X X X HRLLLLL DFDD E E E E E FFr>ctjds?trt dddgnt dt jddSdS)N/proc/lve/enterr(rBzenter by name not supportedz$warning: enter by name not supportedr)rrrrarbrcrdrer=r>r?lve_enter_checkrsd 7>>+ , ,  : )-J!K L L L L 8 9 9 9  r>ct ||z}tddd5}||ddddS#1swxYwYdS#t$rYdSwxYw)Nrwrr)rrrrjr)signrVrrs r? enter_applyrs V\\^^# #S7 ; ; ; q GGCLLL                        s4)A)A A)A  A)#A $A)) A76A7cNttrTd}d}tD]2}|d}|r|d|zdzz }d}'|d|zdzz }3|dz }t |dSt dtD]$}t |d%dS) NrvTrrFz,"rwBinaries)rorarPrrc)rpfirstrrrs r? list_binariesrsMMM + , ,B??6**D ,#*s**$+++$ f  j + +B "//&)) * * * * + +r>c|ttD]%}td|d&dS)N+r)rorPrr)rrs r? load_binariesr$sCMMM22C00111122r>cttddd5}|D]}td| dddn #1swxYwYtdS)Nrrrr-)rrrr)rrs r?reload_binariesr*s w 7 7 7#1 # #D T " " " " ################OOOOOsAA Actdttd}tD]i}|d|krNd}t d||j|tttj|sEtrtddd|gntd|tjd dSdS) NTFrrr(rBzno configuration found for z$warning: no configuration found for r)rkrrorPrrrrrrrarbrcrdre)rVdeletedrrs r? del_binaryr2sDMMMG ??6 " "f , ,G V $ $ $ M % %b ) ) ) V    MMM   C )-S6-S-S!T U U U U AAA B B B  r>ctdttD]}|d|krdSt d|t d}|d|t |tt tdS)NTrrrV) rkrorPrrrrrrQrr)rVrrbin_xmls r? set_binaryrGsDMMM ??6 " "f , , FF -V""8,,G (((  ))) VMMMMMr>cR |rt}n|rt}nt}fd|Dd}n#t$rYdSwxYw|rRdD]G}|dkrt |dd}nt ||d}|r|j|HdSttdz }|D]} | dkr\t| ddkr6| vr1| dd d| <dt| | dkr5| vr1| | d d| <|rtd dStd dS) a Set given lve or package to default values for given parameters :param dict set_data: Arguments of lvectl call :param bool package_flag: Should we delete package or lve with given id :param callable is_needed: Function that takes xml element and set_data dict and returns whether current xml element contains info about needed ID from set_data c,g|]}||Sr=r=)rTr[ is_neededset_datas r?r+z#lve_set_default..gs* 8 8 8A1h!7!7 8a 8 8 8r>rN set-defaultrxr_r`rve_id)rOrNrMrr3rrrLIMITS_LIST_NAMErrr plan_deleter) r package_flagrr=rrrtag_nto_keeprs ` ` r?rrWs   DD  DDD 8 8 8 8 8 8 8 8 ;  ]+ , ,Dt||$R/BB$Rw77 , ((+++"##h}&==GZZ D==S!8!8!A!ABBQFFH$$"$"9"9'"B"B1"E"R"RSb"c"c ((// 0 01 4 4H$$"$"9"9%"@"@"C"P"PQX"Y"Y&HW%&&&&&8G$%%%%%s05 AAc|dvrdSt|}|dvrdS t|}n#t$rg}YnwxYw||vrdSdS)a Checks is uid owned by reseller :param uid: uid for check :param reseller_name: Reseller name, None treats as root :return: True - valid reseller/user pair, False - else Special case: if reseller_name is None (root) - always valid )NrootT)rrjF)rrr)rVrYrreseller_users_lists r?_check_reseller_user_pairrs&&t(,,H?""u!,];; !!! !&&&t 5s - <<c r|dkr!|ddkrt|d|dkr0|dd}|d}t||sdStd|rN||dkrBtj|rt|dntt|nc|dkrMtr4ttj |dnt| tn#t$rYnwxYw t|d}t|}|r|dnd}t|| n#t$r taYnwxYw|ddkrd}d }d |vrt#|d|| d |vrt%|d } n td } d} d|vr*t'|d| } | t dkrd} |rt(} nt*} | D]<} || |r,t,D]+}||vr# |dkrt/| dd||nt/| |d||A#t0t2t4f$r|dkr| }nt |||k}|s|dr|dkrDt6d}|dt=||nCt6|}|dt=||| |Y'wxYw-|ddstAt6d}|rN||dkrBtj|rt|dntt|nc|dkrMtr4ttj |dnt|tC|d|<>|s|dr|rtDnd}t6|} |rZ| dt=|| d|d| tFnr|dr4| dtIj%|dj&n)| dt=|dt,D]}||vr|dkr| }nt |||k}|s|dr|dkrDt6d}|dt=||nCt6|}|dt=||| |d}tND]}|j()| |d}|st6j*| |ddstAt6|rtj| }t|dtC|d|tV|tV,dt|tj-.|}tj-/|D]3}tj01||tC|| 4|rtej3| ngtr4ttj |dnt|tC|dnt,D]}||vr|dkrHtF4dddt=||TtF4|ddt=|||ddstAt6t|tC|d|dS)NrrrYFT)r=r>rrrc6t||dkS)Nrrrrrrs r?is_needed_userzlve_set..is_needed_users&b999Xg=NN Nr>r)rrr=rvrurrxr_r`rsavezskip-update-cfgrGrrz save-username)5rrrrkrGrIrrorHrrrrrrrrsrr:rrNrMrr9rrrrrrr;rrr'rrrrrrOr insertBefore lastChildrlve_inforWrlvp_lve_id_listr-rrrr)rr=rYrrUrryhas_ver rcpu_is_different setted_cpuel_listrrrj is_differentr"el_nameaddedel2enables_reseller_limitsrs r?lve_setrs {{x(A-- '!2333 {{ _d;; '"(?? 5D #&HW--- 8  f % % ' vD 9 9 9 9 9 v & & & & & 155773855hw6GHHIIIII 6""""       !!'!23-g66 #,49Q<<"7X66666 !!! !A O O O H $ $ H5N[a b b b b X  ())EE'E  H  1(5/5QQQJZ...#(  GGG- - B~b(++, +55Ch5"d{{ 22wQYZ]Q^ _ _ _ _ 22sGXc] S S S *J B555"e||/? 0:#(3-/O +5x/?5#&$;;+1+?+?+H+HD$($5$5oc(SV-FXFX$Y$Y$Y$Y+1+?+?+D+DD$($5$5gc(3->P>P$Q$Q$Q "t 4 4 45 ', ||$5u==%V$$$ /f(999x))&113#6EEEEE$622222q[[S%A%A%C%C[sx'A'A(7BS'T'TUUUUU v....(7+F;;;;;? -(7+? -*0;&&eG%%g..B Bc&kk222(8999z****<<00BOOFCL'9J,K,K,STTTTOOD#hw.?*@*@AAA' - -(??e||'7 (2#(3-'G #-x'7-$;;#)#7#7#@#@D --oc(3->P>PQQQQ#)#7#7#<#>>>>*U0c rtdtd}|rd}nd}d|vrt|d|tD]}|||rtD]U}||vrM |dkrC|dd d t||nB||d d t||#tttf$r|dkrDt d}|d t||nCt |}|d t||| |YQwxYwWtjrRt!|d d |d}|t$t|d}|s~d }t d}|d|d|r$|d|d |d }tjr>t!||d}|t$t|tD]}||vr|dkrDt d}|d t||nCt |}|d t||| |tj |t)ttt+|d|vrt-|d} n t.d} d|vrt1|d| |d<|r|d nd} t3|d| dS)NTFc~|d|dko|d|dkS)NrrryrYrr s r?rz'package_set_ext..is_needed_plan s=%%')::wrz?Z?Z^fgv^w?w r>cl|d|dko|d S)Nrrryrr s r?rz'package_set_ext..is_needed_plan s3??4((HW,==abooV`FaFaBa ar>r)rrrxr_rr`rrYrrrUrryrvrurr)rkrorrOrrrr;rrrrrrr_is_plesk_plesk_get_package_idr XML_PLESK_IDr rcopy_package_settings_to_cpanelr:rr plan_apply) rr has_packagerrrrjr"r+package_resellerrrys r?rr s=DMMMKb      b b b  t~NNNN >"h ' ' ' - -(?? -$;;33G<---$;;#)#7#7#@#@D --oc(3->P>PQQQQ#)#7#7#<#. s"adx00DQqTW_r>rN)rlist_domain_packages_with_idrr StopIteration)ryrUpanelrpacks`` r?r$r$ s   E1133HF D D D D D     Aw tts(A AAcht}tdt}|a|S)z Retrives resellers to packages map from panel using /usr/bin/getcontrolpaneluserspackages :return: Dictionary: { 'reseller1' -> ['pack1', 'pack2'], 'reseller2' -> ['pack'] } r)rrr)packages_users_copyreseller_packages_maps r?rr s6)--//2333*(N  r>c|d}|d}t}||vr|||vrt|ddSdS)z Set reseller package limits :param set_data: input data dictionary :return: True - limits was set succesfully False - supplied provider has no supplied package rYrTrF)rr)rrY package_namer2s r?reseller_package_setr5 s^_-MG$L577---,BWXeBf2f2fd3333t 5r>c|d}tjsdSd|}tj|sdSt |dd5}|}dddn #1swxYwY|dd}i}|D]}|dr| d}|d  dd } |d d kr |d || <| tvr| ||d rd|vrdSdD]2} | |vr,tj|| } | p t| || <3t!||rdSt#|t$} tD](} | | } d| d| d} || )t)d ||ddS)zA Copy package limits from ve.cfg to cpanel packages data rNz/var/cpanel/packages/rrrlve_=rrr^DEFAULT_PACKAGE_EXTENSIONSrG)rzryrirgi)r_r`rrrrrr@rrrrrrmemory_to_pageris_limits_equalscreate_cpanel_limitsrOrr#r;)rrU package_pathrcpanel_package_datanew_cpanel_package_dataold_cpanel_datar line_parts limit_namememory_page_value cpanel_data limit_value limit_lines r?r&r& szwG  " "4744L 7>>, ' ' lC' 2 2 2,akkmm,,,,,,,,,,,,,,,1!!!4O$   ??6 " " 5++C00J#A..vr::@@BBJ!} )).8m +---'..t444 ??0 1 1 e46G6G FF-WW  ( ( ( 7 8S T T *;*V{:?VOJ '22'w ;;K&33 !*- 8J88888 &&z2222BGG$;<A;c|D]/}|dvr ||||krdS#t$rYdSwxYwdS)zC check if new set of limits for package are equals to used )rr FT)rr) old_limits new_limitsrjs r?r<r</ sy   # # #  #*S/11uu2   555  4s3 AAc i}|D]h}|d|krKtD]B} |dkrQt|ddd||<n|dvrptt jt||dd||<nPt||dd||<!#tttf$r d||<Y@wxYwj|S) z create limits for cpanel package file use data from ve.cfg: limit = limit if found in ve.cfg or DEFAULT return dict rrxr_rr`)ryrirzrr9) rrr;rrrpage_to_memoryr:rrr) package_id xml_packages result_datarrrs r?r=r=> sK33 ??4 J . .) 3 33}}-033G<.is_needed_packagea s.??4((G3WBOOJch|dko|dkSrr)rrrrYs r?rRz&plan_delete..is_needed_packaged s1??4((G3d 8S8SWd8d dr>rr(rBz no configuration found for plan rz)warning: no configuration found for plan )rkrorOrrrrrrrrarbrdrercr)rrYrrRrrresellers_listrys`` r?rr\ sDMMMG X X X X X X e e e e e e  R  G M % %b ) ) ) V    E   I  6w??N>""a''*!,#GX...  I HwHHI    HRLLLL GgGG H H HOOOOOr>c(t||dS)NrX)r)rrYs r?reseller_plan_deleterV s}555555r>c t||ddS#ttf$r)|dkr t |nt |dzdcYSwxYw)Nrrrur}r)r;rrrrr)rrrjs r? get_xml_limitrX sS2**3//2??HHIII  #SSS#&%<<{3 C8HC8O5R5R5RRRRSs:=7A76A7cd}|dStjd|i}||dd}|d}||dz|S)z Normalize string for JSON output. Example: - Input string: -_&[{}]'"`te\s/t - Output string: -_&[{}]'"`te\\s/t\a :param data_str: String for normalize :return: Normalied string c^d}t|D]\}}||kr|dz }||kr|cSdS)z Get the index of the specified occurrence of character in string :param input_string: String :param char_to_search: Character to search :param ordinal: Required occurence number :return: Char index rr^r)r:) input_stringchar_to_searchordinalcountidxchs r?_get_char_indexz'_normalize_str.._get_char_index sR ..  GC^## G##JJJrr>Nr;rr^)rrrfind)data_strrajson_strtrd_idxlast_idxs r?rprp sl$tz5(+,,HohQ//G~~c""H GaK( ))r>cDnrtntdfd }|S)a Generate inner function with closured fields names, is_reseller flag and printer function :param list fields: List of strings that represent names of fields in final output :param boolean is_reseller: Format output with info about reseller or not :param callable printer: Function to format and print data for every entry :rtype: callable :return: function to format data for every user Nc < r4ttjtd<fd}nfd}tjttrt nd<d}|dd<t dkr|d d <t D]^}||rOt|d }|d kr|nttd d <ttt|d td  dzd< tt| dd dd<n#ttf$rYnwxYw|t|d d <|t|dd<t|dd<t|dd<t|dd<`dd dzd<tt!dd <g}tr)dfd D}d|dg}n fd D|S)a :param string package_name: Find and format data for this package name :param string reseller_name: reseller name, owner of supplied package :rtype: list :return: List of giver package's statistics data line or empty list rych|dko|dkSrr)rrr4rYs r?rRz>_package_formatter..wrapper..is_needed_package s2#rt'<'<<mQ[A\A\`mAmmr>cb|dko|d Srr)rrr4s r?rRz>_package_formatter..wrapper..is_needed_package s/#rt'<'<<`R__U_E`E`A``r>rcLtrt|nt|SrSrNrOs r?rPz?_package_formatter..wrapper..convert_mem_limits rhr>ryrir~rzrvrrurr}rr_rr`rxrwr{r|NrSc3vK|]3}d|d|ddV4dS)rrUrjNrrmrns r?rWz6_package_formatter..wrapper.. sMTTCCCdhhqwwyy%&@&@CCCTTTTTTr>rXrYc`g|]*}|d+Sr[rnrns r?r+z7_package_formatter..wrapper.. s/>>>!dhhqwwyy"-->>>r>)r|rrrarprrOrXr;rr:rrrrrrr;) r4rYrRrPrrrrarrrrr\s `` @r?rqz#_package_formatter..wrapper s,  * $] 3 3 39[))D,D  n n n n n n n a a a a a9[))D59K^L111|T  V V V*)$u+66V ??--d6l;;DL 9 9B  $$ 9%b&11(- uu[=P9Q9QV #$<!"e,,CV 4E4E%G%G%GJM%N!!W !$S//88;HHYY&&""DJJ#J/D11-F2K2KLLV 11-E2J2JKKV *2t44T -b' : :W ,R88V 88G   $ K3.DM*4=99::U   @88TTTTVTTTTTD ===/CC G>>>>v>>> ? ? s;A FFFrS)r5r3)rrr\rqs``` r?_package_formatterrp sO!,gg{2Y))PYG<<<<<<<<z Nr>cttdt}tdt}t t t }ttdt }|D]}|||z }tdkr#ttdt }| D]M\}}tj r|dkr|D]+}tdkr||||z }|||z },Ntr*td d |zd zdSdS) Nrrr]Frr\r^TadminrvrSrw)rorrrrbr3DEFAULT_PACKAGErprrRrhr_rrarcr;)rreseller_packagesrprxrUrY packages_listreseller_packages r?get_packages_listry sMMM)))""$$H2333&++--  o > > >F":<cttddg}t|z}ttt }t |d}tD]\}}|D]}||||z }tr*tdd |zdzdSdS) NrrrrTrrvrSrw) rorrrbr3rurprrhrarcr;)r_rrprxrYrwrxs r?get_resellers_packages_listr{# sMMM2333,K \\K 'F  o > > >F"6t<<(>AA$ } - A A  ii 0-@@ @FF A 5 kCHHV,,,t34444455r>cVttdt}tdt}dg}t |z}t t t|}t|dt }|D]}|||z }t|d}| D]\}}|D]} ||| |z }tr*td d |zd zdSdS) Nrrr)r]r_FrsTrz {"data": [rSrw) rorrrrrbr5rurprhrarcr;) rrvr_rrprxrUrYrwrxs r?get_all_packages_listr}6 sPMMM)))""$$H2333&++--,K \\K 'F  o; W W WF"6uiPPPI%%))G$$$"6t<<ci}|D]}|||<|S)z Converts package list to internal format :param package_list: Package list. Example: ['BusinessPackage', 'Package2'] :return: Package list as dictionary. Example: {'BusinessPackage': 'BusinessPackage', 'Package2': 'Package2'} r=) package_listpackages_users_dictrUs r?_convert_packages_listrW s- //'.G$$ r>list-allcf|dvrdS|dvr|dkrdSddlm}m}m}m}m}m}m}  |dkrxtD |t|d t|d d ia n #t$r |ddd ia Yn wxYw ||\} } n#t$rdx} } YnwxYw|| | d ia d S|d kr||||ia d S|d kr1t!|} t| a ta nta d S|dkr"t| a tanta d S|dkrt |ata d S|dkr t||} | a| a nta d S|dkrt |at a d Sn1#t"$r}t%|Yd}~nd}~wt&$rYnwxYwdS)a Parse output from GET_CP_PACKAGE_SCRIPT and get package and lve relations :param option: option for GET_CP_PACKAGE_SCRIPT. Option is one from the following possible values: 'userid', 'package', 'list-packages', 'list-resellers-packages' :type option: string :param lve_package_id: lve_id or package_name :type lve_package_id: string or int :param reseller: :type reseller: string )rrrUrrrrtF)rrUrr)admin_packagesget_reseller_usersget_uids_list_by_packagelist_all list_usersreseller_package_by_uidresellers_packagesrNrUry)rUryTrrrrtr)clcommon.cpapirrrrrrr cached_usersrrrcached_list_packagesrcached_resellers_packagescached_reseller_userscached_defaultrrgr)optionlve_package_idryrrrrrrrrYrUrreseller_users_dictr[s r?rrd s&VVVu &&&>R+?+?uP X  'W&'3N'CI'N(4^(DZ(P))&NN  WWW&4"RT6U6U%VNNNW1-D-D^-T-T*M77!111.00MGGG1#1gS`2a2a!bt y ,.F.F~W_.`.`aN4  & &$+-~// !7 !E!E'5$$"64 0 0 0)0!3!3!5!5,:))";4 | # # #)z|| )N4 , , ,%,&8&8&B&B#)<%!4"74 z ! !%!)+N4 '''#A&&&&&&&&      5s F)AFA40F3A44F8BFBFB F$F:5F1&FF9$FF F. F F.-F.cFtttS)z2 Retrieves panel users count :return: )rrrr=r>r?get_panel_users_countr s  ~  r>ctdtd||r/t|D]#}tt|||"dSdS)NrrUr)rrr'r:)rryrVs r?r'r' sm&&&IwBBB<!'* < c|D]}|dd}|}|D]E}t|dkr0 t |}t |5#t $rYAwxYwFdSNrgrr)rrrrr:rr users_listrrrs r? destroy_manyr s  ||D$$ ""$$  DD Qt99D%%%% D    sA88 BBctt tn#t$rYnwxYw|D]}|dd}|}|D]E}t |dkr0 t|}t|5#t$rYAwxYwFdSr) rorrrrrrr:r'rs r? apply_manyr sMMM         ||D$$ ""$$  DD Qt99DdOOOO D    s ,,B&& B32B3c tt|t||d|d|ddS)NzCan`t put proccess with pid z in lve rr)rlve_enter_pid_flagsr:)rpidflagss r? limit_pidr sR  F SXXuYsYYFYYYr>c^tt|d|dS)NzCan`t release process with pid r)r lve_leave_pidr:)rs r? release_pidr s0 C*QC*Q*QRRRRRr>c htttttt t tdS)Nrr;rrMrrOrCrQrr=r>r? get_globalsr s(l$[$S 0  2 22r>c*g}t}tdt}|a|D]&\}}|D]}||kr||g'|S)Nr)rrrrhextend)rUry pkg_users_oldrvrYrwpackage_name_in_keys r?rr/ sH"''))M2333&++--"''))N):(?(?(A(A11$ }#0 1 1 ---000 1 Or>c~tjtjdd}|rtj|rxt ||\}}|dkrad|}trtdd|gd Sd|}tj |d tj |d Sd Sd Sd S) z Call Endurance's custom script :param args: list of arguments for pass to Endurance's custom script :return: None ENDURANCE_CUSTOM_SCRIPTr8) separatorrz0Error while executing Endurance's custom script r(r]zerror: rgN) r_get_param_from_fileCL_CONFIG_FILErrrrrarbrdrirjre)argsendurance_custom_scriptret_codestd_outrq err_messages r?call_endurance_custom_scriptr@ s*=k>X>WHKMMM #27>>2I#J#J #()@$GG' q==T7TTG #Ggw%788888111    K!3!3!3444""""" # # # # =r>ctr)tt|tjzSt |S)a Convert page value to human-readable value or bytes, depending on BYTES_FLAG; E.g. >>> _page_to_memory_or_bytes(1233254) # BYTES_FLAG=False '100M' >>> _page_to_memory_or_bytes(1233254) # BYTES_FLAG=True 654321 :type value: int :rtype: str | int )rr:rmmaprrGrOs r?_page_to_memory_or_bytesrY s515.//000 5>>r>cg}ttj}t t D]m} tj|}||vr||<#tttf$r||YjwxYw|D]}t|dS)zV Remove from LVE all resellers, which are absent from panel :return: None N) rrGrWrrorKrrrrrr)reseller_id_list_for_deletecpapi_resellers_listlve_reseller_idlve_reseller_namereseller_id_for_deletes r?remove_absent_resellersrj s #%  1 1 3 344MMM#::@@ @ # 9 9/ J J  (<<<+22?CCC'7+ @ @ @ ' . . ? ? ? ? ? @#>11/000011s 8B,B54B5c|t|dS|r~tj|5tj|}||}|||_|dddn #1swxYwY tj|}n#t$rYdSwxYwtj |}d}||vr$|r"||vr||}tj ||||ttj||rt |tj||} | tj} | | d|krt || t|} t|| dSdSdSdS)aiUpdate LVD domain config, docroot-to-ID mapping, and kernel LVEs. Called after a control-panel hook detects a domain rename, document-root change, or user rename. Two modes of operation: **Single-domain** (*domain* is given): 1. Rename domain in ~/.lve/domains.json (if *old_domain* given). Uses privilege drop so files stay user-owned. 2. Ensure the current docroot has a domain_id in the registry. If *old_docroot* is given, removes the old mapping and assigns a new domain_id for the new docroot. 3. Destroy the old domain LVE in the kernel (if it existed). 4. Map the new domain_id to the user's LVP and re-apply limits from domains.json so that per-domain limits keep working. **All domains** (*domain* is ``None``): Iterates every domain in the user's ``domains.json``, detects stale registry entries whose docroot no longer matches (e.g. after a user rename shifted the home directory), and performs the single-domain reassignment for each one. Args: uid: numeric user ID. domain: current (possibly renamed) domain name. When ``None``, all domains from the user's config are checked. old_domain: previous domain name if it was renamed. old_docroot: previous document root path if it changed. N)rUrrr)_regenerate_all_domainsr user_contextrr find_domainrUr resolve_docrootrrrreassign_docrootrGrIrrrrrWrrrr!) rVdomain old_domain old_docrootr$entryrregistry old_domain_id new_domain_idrrs r?regenerate_domainsr s6>~$$$  #C ( (  (--c22F&&J&77E #                 +F33 -c22HMh  G;(22$[1M  +Cg F F F S_ 8 % %mC % @ @ -   m , , ,&4S'BB  $ X\\^^N!!-33s::!!#}555..s33J  ' ' ' C C C C C! __ % $s$AB  B B B** B87B8c "tj|}|sdS tj|}nD#t t f$r0}tjtjd|d|Yd}~dSd}~wwxYwt}|j D]p} | tj |j 0#t $r4}tjtjd|j d|Yd}~id}~wwxYwt|D]a\}}||vr t ;t j||rt&|tj||bd}|D]@} | |vrtj|| }t t&||d}A|r?t :t |} t || dSdSdS) aSynchronise the domain-ID registry with current docroots. Compares docroots currently reported by the control panel against the docroots stored in the registry. Orphaned entries (docroots no longer valid) are removed and their kernel LVEs destroyed; missing entries (current docroots not yet registered) get a fresh domain ID assigned and mapped to the user's LVP. Nz6regenerate-domains: failed to load LVD config for uid rz7regenerate-domains: cannot resolve docroot for domain 'z': rFTr)rrrrrr&rrr"rdomainsaddrrUrrhrGrIrrrrrrrr!) rVrr$r&current_docrootsrold_drrchangeddrrs r?rr s-c22H $))#.. g  f(.!$..(+.. / / /   uu?? ?  !:5:!F!F G G G G ? ? ? M&,>).>>8;>> ? ? ? ? ? ? ? ? ? "(.."2"23355 % % %  ?**9S*AA    i ( ( ('V4444G >> "3C<< ?   c9 - - -@3?**3//  ##CJ#?????@@??s-:A; %A66A;,C D *C<<Dc2t}tjrt j}tjD]\}}||vr tj | #t$rz t |n[#t$rN tj|t |n#t$rYnwxYwYnwxYwYwxYwdS)zM Remove from LVE all users, which absent in system :return: None N)rrGr-rrrrIrWrhrrrrr!r)rrr=s r?remove_absent_usersr s. #uuN v!!=':<<(,,....00 ^ # #   L     ''''   F%%f---OOF++++!D    sZ;B DB65D6 D9C;:D; D DD D D DDD)FrS)r)NN)rFT)T)NNN)NFNNr)r6)rHr!N)r@N)FN)rrN) contextlibrrmrrrrrrrrdrrxml.dom.minidomdomminidomrbuiltinsr functoolsrrtypingrrrr r r rrr_rwclcommon.constr rr rrrclcommon.cpapi.cpapiexceptionsr clcommon.lockr clcontrollibrcleventsrr cllimits.libr cllvectl.logrclveconfig.ve_configrrrclveconfig.ve_lockrrrrrr r!secureior"r#websiteisolationr$rr%rwebsiteisolation.exceptionsr&GET_CP_PACKAGE_SCRIPTrrrurrrrorr:rrIS_DEBUGr%LVErrGr/rErKrPrZrgrkrirDrbrErrrarrrsrrr;rrMrNrrOrCrQrPrRrrrrrrrrrrrrrcontextmanagerrrr rbr#r-r3r6r9r<rrHrSr\r;rercrortr|rrrrrrrrrrrrrrrrrrr rr rr'r/r1r3r5tuplerr,rBrGrbrrryr}rrrrrrrrrrrrrrrrrrrrrrrrrrrrr$rr5r&r<r=rrVrXrprpryr{r}rrrrrrrrr'rrrrrrrrrrrrr=r>r?rs   ???????????????? """"""gggggggggggg888888&&&&&&******PPPPPPPP%%%%%%......OOOOOOOOOOEEEEEEEEDDDDDDDDDDDDDD????????000000::::::000000@    :  3rz~~mQ// 0 0 !!'+.. E CC E ! ! !E #---CY     %%%KKK=$3333*             ONN                 ,++++,   111D&%''9<<>> ,$** 0 0 0 """( >    &&   [[[222222   &&D&&&&Rkkk"i"i"iJ3 d38n3 3 3 3 l    & & & & %%% L L L LEAEAEAEAP I I I!!!H ? ? ? 0 0 0 0 4 4 4 4    f f f!1!1!1J"p"p"p"pJ!!!NDZ>n>n>n>nB66688S8T8888$ / / / / /IIIIIyIII S T    6s-s-s-s-l   %%5%%S%#%%%%6,6!!!!H%,NNNNf55556$555("....b< < < @@>@>@>F$eD$J&7$$$$ ' ' ' '***Z!1!1!1H...:GGG$JJJ* G G GFFF,   +++(222 *    +&+&+&+&\FD55552H5H5H5H5V C # (3-     ! ! !*+S+S+S\   <&&&&R666SSS$*$*$*NJJJJ\555:555&6664!       ttttn<<<<   (SSS222$   "###2"1114BDBDBDBDJ1@1@1@hr>