^?(` bddlZddlZddlZddlZddlZddlZddlZddlZddlZddl 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)Zad*Zbd+Zcd,e)fd-Zddd.Zed/Zfd0d1d0d2dd3dd4d5Zgd3Zhd6d1ddddddd5Zigd7Zjd8akdaldamd9and9aoiapd9aqd9ard9asd9atd9aud9avd9awd:axd9ayd9azd9a{d;Z|d<Z}d=Z~dd>Zd?Zd@Zep eZddAZdBZdCZdDZddEZdFZejdGZdHe\fdIZdJZddKZdLZdMZddNZdOZdPZdQZdReTdSefdTZdUZdVZdWeeeTffdXZdYZdd[Zd\Zdd]Zdd^Zd_Zd`ZdaZddbZddcZddZdeZdfZddgZdhZiadiZdjZddkZdlZdmeTd$efdnZd$efdoZGdpdqeZdmeTd$dfdrZddsZdtZduZdvZdwZddyedzed{eTd$efd|Zd}Zd~ZddZefdZddZdZdZdZdZddZdZdZd$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)zRaw kernel LVP list (/proc/lve/resellers), including per-user domain-isolation LVPs. Reserved for isolation-aware internals; reseller- management code MUST iterate reseller_lvp_list() instead.)lvereseller_limit_supportedproc lvp_id_listr=r>r?lvp_listrKes1 ##%%&x##%%% Ir>cBttjS)uPer-user domain-isolation LVP ids (lvp). The kernel registers an LVP named lvp in /proc/lve/resellers for every user that has per-domain isolation allowed/enabled (a marker in the websiteisolation config), even when the user has 0 registered domains. These are not resellers — they are maintained by the isolation feature — so reseller-management code must never treat them as reseller LVPs. This is the single source of truth for "is this kernel LVP an isolation LVP"; it mirrors the same find_all_lve_ids_with_config() signal that lveapi uses to build the nested LVP/LVE hierarchy. Note this is broader than _is_domain_isolated_user(), which additionally requires >= 1 domain: the kernel LVP exists on the marker alone (see CLOS-4513). Disk-only: callable from non-lvectl entrypoints (cloudlinux-packages, clsummary) that do not initialize pylve, so this MUST NOT make a kernel call. ws_config.find_all_lve_ids_with_config() reads /etc/container/lvd_ids and returns [] when the directory is absent, which covers both "kernel does not support domains" and "no isolation configured" without needing lve_kapi_ver(). ) frozenset ws_configfind_all_lve_ids_with_configr=r>r?_isolation_lvp_idsrPns, Y;== > >>r>c"|tvS)zKTrue if lvp_id is a per-user domain-isolation LVP (see _isolation_lvp_ids).)rPlvp_ids r?is_isolation_lvprTs ')) ))r>cTtfdtDS)aGKernel reseller LVPs, excluding per-user domain-isolation LVPs. Use this everywhere reseller-management code enumerates resellers (destroy all, apply all, remove absent resellers, list-reseller, package limits, summaries). Centralizing the phantom-isolation-LVP filter here means a new reseller command cannot reintroduce the CLOS-4370/4390/4419/4513 class of bug as long as it iterates this function instead of the raw lvp_list(). Backward compatible: on kernels without domain support the isolation set is empty, so the result equals lvp_list(). cg|]}|v| Sr=r=).0rS isolations r? z%reseller_lvp_list..s# G G GvvY/F/FF/F/F/Fr>)rPrK)rXs@r?reseller_lvp_listrZs.#$$I G G G G G G GGr>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_resellersr_s1 yyH   " " $ $$r>c6|dtDvS)z] Check whether giver reseller has activated reseller limits or not :return: bool c3 K|] \}}|V dSNr=)rWnameuids r? z,is_active_reseller_limits..s&JJidCTJJJJJJr>)r_ reseller_names r?is_active_reseller_limitsrhs% 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;printsysexitris r?raise_cpanel_encoding_errorrusg  " " 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 rlzcan`t get lockN)rrcheck_result_and_exit)writes r?get_global_lockrysP3%     333a!12222223s 11c|dtj fvrJtrttdd|gnt d|t j|dSdS)Nrrkzlvectl: zlvectl: Error: )errnoENOSYSrorp MULTI_FORMATrqrrrs)resultmessages r?rwrwst a%,'''  /  w0D70D0D&E F F F F -G-- . . .  ('r>rli)cpuncpuioepmempmemnprociopsd)rrrrrrrrfalsec |adSrb)ro) json_flags r?set_jsonrs DDDr>c |adSrb) 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)rrrrrrlCPU)NOIOPS LVE_VERSIONroindex)versionfields speed_idxs r? get_fieldsr$s +""      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' formatrl) osenvirongetjsonloads TypeError ValueErrorrqr;rrrs)packed_cpu_dataris r?_get_cpu_data_from_envrPsjnnZ00Otz/*** 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-8encodingrIrl:rNzlvectl: Error: Can`t open .proc0zcpu MHz) openCPUINFOstriplensplitIOErrorrqrrrs)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)rrrpercents r?convert_from_speed_percentrs 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. rrlz,(?P\d+(?:\.\d+)?)(?Pmhz|ghz)+$NsuffixfreqGHZi) r;rr:rrcompile IGNORECASErgroupupperrr)rrrcpu_freqpatternrrrs r?convert_from_speed_hzrs 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)speedrrs 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_lver s    ' ' ) )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_uidrsV>..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 statusrrlmsgN)r;r}rBrqrdumps) error_typer extensionsr~s r?rprpslDG %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_valuer1/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=) isinstancer+ElementtagName)rW_tags r?rYz"xml_filter_tag..=s7 Z Z Z!*Q *D*D ZVYIYIYAIYIYIYr>) childNodes)r0r8s `r?xml_filter_tagr:<s Z Z Z Zt Z Z ZZr>ct||D]9}|||s||||kr6|cSdSrb)r: hasAttributer)r0r8attrattr_val child_nodes r?xml_filter_firstr@@sn$T3//  J$;$;D$A$A    J$;$;D$A$AX$M$M  r>cpt|||}|t||S)N)r0r8r=)r@r&r)r0r8r=filtered_child_nodes r?get_child_tag_atrrrCIs;*#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:r(r;)r0r8r=r.first_child_nodes r?set_child_tag_atrrrFPs; &dC003!!$C11111r>c t\aadS#t$rg}tr%t t dt|gntt|tj dYd}~dSd}~wwxYw)zLoad config from ve.cfgrkrlN) rr- ve_lveconfigrrorpr}r;rqrrrsrts r?_load_config_wrapperrIYs -//     wA&7 8 8 8 8 #a&&MMM  s BABBrS 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.cfgrlz(warning: default section error in ve.cfg)ubcr:rHr$ LVE_DEFAULTr-r' LVP_DEFAULTr@rr;r%hasattrrMr&rorprrrsrq)rSrJdefaults_root_nodes r?_load_default_limitsrThs8 C> ' jAA!DJ   --j99J -l>>  > )-N!O P P P HQKKKK < = = = > s#C)"C) BC))AD32D3c |tdttttt t fDS)Nc3"K|] }|dkV dS)rNr=)rWxs r?rez._all_config_elements_loaded..s&jj1qBwjjjjjjr>)allve_lveve_lvp ve_package ve_binaryve_enter_by_nameve_cfg_versionr=r>r?_all_config_elements_loadedr_s. 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-namerbinaryrrlN)rHr%rYr[rrZrGmapr^r\rr]r-r'r)r\r: firstChild nodeValuer^)enter_by_name_elemscfg_version_elemss r?_load_config_elementsrhs . .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 )r+r,r-r/r)r.rrr#r other maxentryprocsrrr)r.r/rrrN)r,rr1r$r-r%rrrr&rr'r(r;r)r*r:rMEM_DEFAULT_CL5_check_defaults_for_nones)ri check_def_valrrrs r?_load_ve_defaultsrqsK  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(rk rl)r,itemsrorprrstderrrxrs)keyvalueerr_msgs r?roros"''))   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)rIrTr_rhrq)rSrJload_config_elementsris r? get_XML_cfgr{sW )&,??N #>#@#@ n%%%%%r>c tt||d}|||<|S#tttf$rt||cYSwxYw)Nr#r8r=)r:rCrr&r)r.elr, setup_datarws r? check_valuersm%&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 rzN)lveapirr\get_idr{)resellerxml_config_load_elementsr^ reseller_ids r?_load_resellers_xml_datarsN~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|dkSNrrr)r~plan_idrs 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 Srrr~rs r?rz*prepare_setup_data..is_needed_planQs/t,,7[PZ@[@[<[[r>rrr#r}r rrLrrrkrlrrrr)copyr,rget_reseller_packages_maprmis_dargetpwuidpw_namerreadr*rrr[rr:rrCrr&rrO) rrr  res_pkg_dictruser_pwdfilenamertextr~rrrs `` r?prepare_setup_datar's.;''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)stdoutrurzfailed to run "z -l ") subprocessPopenUMOUNTPIPE communicate returncodeOSErrorrw)pathrIs r? umount_dirros 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)rl)r)rWms r?rYz"prepare_mounts..s$:::qaggiil:::r>zfailed to parse /proc/mounts F)rrisfileEXCLUDE_MOUNTS_CONFrrappendrrrrwunshare CLONE_NEWNS readlinesr&rsearchr) reg_exp_listconfrrrmountsATTEMPTSr7errormountreg_exprs r?prepare_mountsr}s 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 settingsrxN)rcallrrqrr lve_start) MOUNT_CMDs r?rrs?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}rx ignore_errorN)r lve_create)r rs r?rrs> 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)rSrs r? lvp_creaters> !bV!b!b!b&244444r>cNtd}g}tD]}tj|s|d|9|d|t |d|d|||S)N lvectllibrRz=destroy_lvp_all: lvp %s n(cascaded with its parent), skippingz*destroy_lvp_all: destroying LVP with id %s"lvectl: Can`t destroy lvp with id rr) rrKrGrI exist_lvpr,rlve_lvp_destroyr)loggerdestroyed_listrSs r?destroy_lvp_allrs "; / /FN**&&x!!!00  LLXZ` a a a  A6JJJ f&h6&h&h&h  j j jf%%%% r>ctd}|dkrtdS|d|t|d|ddS)NrrXz&lvp_destroy: destroying LVP with id %srrr)rrr,rr)rSrs 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 rFrXrz*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_lvprorp SINGLE_FORMATr}rq)r rcant_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)Nrrrrrrrmrrrrr%Can`t setup default settings for LVP rzCan`t setup lvp with id rzCan`t setup default settingszCan`t setup lve with id rlzCan`t setup lve z. RuntimeWarning excepted: )rGrIrrwarningscatch_warningsfilterwarningsr:rrr2r0r1 ls_memoryr3rr4r5r6rlve_set_default lve_lvp_setuprRuntimeWarningrwr;)r rSrws 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-usersrra)packages_usersGetControlPanelUsersr4dictKeyError)r rarold_packages_users temp_packages r?"get_package_and_reseller_by_lve_idr7sGH'&&&"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)rrr;r s r?cache_effective_limitsr s0,6CKK(((r>r c|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_supportedsetrNrOrws_id_registryget_all_entriesr s 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-r r rget_all_domain_idsr=r>r?_get_all_domain_lve_idsrs2 6 # # % %uu  , . ..r>ceZdZdZdS)DomainLveIdErrorz>Raised when lvectl set/delete/destroy targets a domain LVE ID.N)r7r8r9__doc__r=r>r?rrsHHHHr>rc|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-r rrmin_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 ruseridrrRNc,t|kS)Nrr)r0r s r?zlve_apply..s 34 H H HF Rr>rarrrrr#r}r rrLrrkrlrrrr)rr r domain_maprrz1lve_apply: skipping per-domain isolation for uid=r)&rrr-r{rZrYnextfilter NameErrorrrrr,rrrCrr&rrOr:r rrrG_build_domain_map_map_domain_lvesrIrcrrrapply_domain_lve_limitsrr&r!r LOG_WARNING) r rr~rout_noderSrnew_packages_usersr~ node_listrr$excs ` r? lve_applyr0s'$( {{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. rl wide_indicesN_format_fieldsrrqrformatted_strings r?_pprintr8ss9 &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. rrlr2Nr4r6s r? _pprint_fr:|sO &&kkAos6{{Q7 r>cHt|dg}t|dS)zb Print data with the first column 30 symbols wide. Useful for printing packages data. rr2N)r5rqr6s r? _pprint_pr<s. &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. rrlr2Nr4r6s r? _pprint_rr>s; &fAs6{{Q;OPPP r>rr3widthcg}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)rr3r@formatted_fieldsrfield field_strs r?r5r5s!&))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;r4 startswithrr:)rw was_changeds r?_pmem_vmem_to_bytes_valuerKs 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" rFrrlNTrrrMK)r4r;rIr:r)rwr~rJvs r?_mb_memrPsFK%%"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 rrc0|dS)Nrr)rvrDs r?get_dataz_formatter..get_datas||C$$$r>rcLtrt|nt|SrbrrKrPrws r?convert_mem_limitsz&_formatter..convert_mem_limitss!3=Q(///75>>Qr>rrrrrrr) rrrNCPUrrrrrrPACKAGEN,c3RK|]!}d|d|ddV"dS)r":"rNrTrWr fields_maps r?rez_formatter..sEKKq:A::*..B"7"7:::KKKKKKr>{}c<g|]}|dSrrTr_s r?rYz_formatter..s'888A*..B''888r>)r,rrr;rrorD) printer default_iddefault_package more_fieldsrU_cpurYresrrrDr`s @@r? _formatterrks!!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 rrarNrlr"F)rrT)rrr~ct|tt|krdtt|znt|S)Nr)r;r)rvrs r? check_changedz7_user_formatter..wrapper..check_changed3sP14T#Y3zRUCWCW1W1W3Z_----]`aefiaj]k]k kr>cLtrt|nt|SrbrWrXs r?rYz<_user_formatter..wrapper..convert_mem_limits6!7AU,U333wu~~ Ur>rrrrrvmemrrrrN/Arrrr\c3ZK|]%}d|d|dV&dS)rr^NlowerrWrrs r?rez3_user_formatter..wrapper..TsCIIQ888d17799o888IIIIIIr>rarbcDg|]}|Sr=rurws r?rYz4_user_formatter..wrapper..Ws%666!d17799o666r>)rr^rrr{rrr0r;ro_normalize_strr:rrrD) rrarrorYrjrrrres @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=)rrerzs`` r?_user_formatterr{ s0DDDDDDJ Nr>ct td||rtd|n#|td|ntdn#t$rYnwxYwdg}tt|}t |z}t |}tD]}|||z }tr*tdd |zd zdSdS) Nrrlist-reseller-usersr"r[rh {"data":[r\]}) r{rr*rkr8rr{rrorqrD)rrrhr~r formatterrs r?paneluserslimitsr^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 panelrrra)rrrtrr:)r~str_uidpayloads r?paneluserslistrysj&&& 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?panelpackagesdictrsp,+++++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 rr[RESELLERr~)rerr\rN) r{rrkr:rr{rrorqrD)r~rrrs r?all_users_limitsrs 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)rWrs r?rYz(_filtering_da_admins..s%III#,t,,3IIIr>c$i|] \}}|v || Sr=r=)rWrvrwuids_da_adminss r? z(_filtering_da_admins..s)]]]*#u3nC\C\3C\C\C\r>)rm getCPNamer rt)ve_dictrs @r?_filtering_da_adminsrsV-//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=)rWkrOcfg_lvp_id_lists r?rz&prepare_apply_data..s)___1!J^J^q!J^J^J^r>TrR)r0rrrr0)rrrrGrcr^id_listrtr*rZrKrYrIrrrrguess_reseller_by_package) rSpackages_users_r.rrr0r rdpkg resellersrs @r?prepare_apply_datars~..  `!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 t\}}ttj}|D]}||ddkr||2||vr/t|||tj d5t|||d||ddddn #1swxYwYtdt rtd}ttj}|D]j}t|r||(||vr/t |||t%||tj|}tj}t*j|D]} t1j| j}||vr/t|||||d|kr)tj ||d|d |d  t|| l|D],}t|rt |-|D]}t|dS) NrTrr0rr,rr Can`t move lve_id= to lvp_id=rrr r)_get_lve_ve_dict_and_lvp_mapr rGrIrrrdiscardrr-context_ignore_errorr0rHrrJrTrr&_create_if_necessary_and_configure_lvprcget_reseller_namercpapirrrr lve_lvp_move) lve_ve_dict lve_lvp_mapremaning_alive_lvesr  lvp_ve_dictremaining_alive_lvpsrSrgkernel_mappingrs r?lve_destroy_and_recreate_allrs;==Kch224455""$$ ??61 % % * *  ' ' / / /  ( ( ( OOF # # #  ' ' / / / V ( (d ( ; ;   $V,V4$V,Z8                   Q ##%%,*(.. "38#7#7#9#9::"&&(( A AF '' $,,V444---%%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)NTrrr0rrr rRrrrrr)rrrGr-rrrr0rHrrIrcrTrrrrrrrrrrrlve_lvp_create2rrr) rrdomain_lve_idsr rlvp_id_rgrlve_id_s r? lve_apply_allr9s>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)r{rrrGrHrlve_id_lvp_id_pairs)rrs r?rrs_MMM&&&$&&K585Q5Q5S5S[$s..00111Y[K  ##r>ct|ddt|||d||d|t|dtd| dS) NTF)rSrJrzr0r)r r,rrS)rSrzr)r rS)r{r0)rrSs r?rrs{vDuMMMM Vvv.vz2 vE:::: Qv&&&&&&r>c`tdt|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|dS|dkrdS|t;t=jvrdStj |sdStj|}|ddD]}t d| tj|3#t$rQtj|rt|||YwxYwt/|td|D]}t9|dS)uRemove reseller from ve.cfg and from procfs. CLOS-4419: idempotent for orphan kernel LVPs. When no block is present, the function falls through to a recovery branch that distinguishes three states: * domain-isolated user — kernel LVP is legitimately maintained by _sync_map for the per-domain isolation feature; do not destroy. * already clean — neither block nor kernel LVP exist; return True so disable_reseller_limits reports OK instead of WARNING. * true orphan — block missing but kernel LVP exists with no isolation marker; destroy the LVP and re-parent any mapped LVEs to the host LVP. TrRrNrF)!ryr{rZrrGrImap_lve_id_listrcrrrrrrrTrrrrr- lve_existsrremover parentNode removeChildrr-r0r rNrOr)rSr~usersrgusernamerdr s r?_remove_resellerrsoDv44 b 1 1 1V ; ;H,,V44E" G55f==M*=99 & &,x007CCH#C((&S-=-=LL%%% ( ) )""1f---)L(((()))v((000///LL((((()     M % %b ) ) ) V    q ! ! ! ! " "&!!!! v & & & &44g >>> u 8  V  , , t H $ $V , ,E(!! 1f%%% ! L  ! ! !v  (( (''' LL  !q& 4s8B)) B65B6 DAE:9E:JAK87K8c tj|t|}tj|st ||nW|rUtj||s5t |t ||tj }| |d|kr)tj ||d|d|dtj|D]7}| |d|krt ||8dS)aEnable per-domain LVE isolation for the given user. Creates an empty id_registry file (marking the user as domain-isolated), creates lvp (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. rRrrrrrN)rcreate_empty_registryrGlve2lvprIrrrrrrcrr-rrvaluesr)r  parent_lvpr domain_ids r?enable_domain_isolationrsm(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. rRNr)rGrIrrrrrrcrrrrrrrremove_all_entries)r r child_lverrs r?disable_domain_isolationr)s' 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_idr{rGrIrcrr-rrN LvdConfigradd_domain_by_docroot) owner_uiddocrootrproc_maps r?enable_domain_lverFs/ 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_idr{rGr-rrr!rr+remove_domain_idrNrrremove_domain_by_docroot)rrrr/s r?disable_domain_lverXs,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 hooksr"r(rNzno configuration found for LVP rz(warning: no configuration found for LVP N)rr throw_eventrorprrrsrq)rgrSs r?disable_reseller_limitsrmsG%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(rNzno configuration found for VE rz'warning: no configuration found for VE )rryr{rYrrrrrrr-r0rorprrrsrq)r Deletedr~s r? lve_deleterzsV$$$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(rNzenter by name not supportedz$warning: enter by name not supportedr)rrrrorprqrrrsr=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)rrrrxr*)signrbrrs 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) NrTrrFz,"rBinaries)r{ror\rrq)r~firstr~rs r? list_binariesrsMMM + , ,B??6**D ,#*s**$+++$ f  j + +B "//&)) * * * * + +r>c|ttD]%}td|d&dS)N+r)r{r\rr)r~s r? load_binariesrsCMMM22C00111122r>cttddd5}|D]}td| dddn #1swxYwYtdS)Nrrrr-)rrrr)rrs r?reload_binariesrs w 7 7 7#1 # #D T " " " " ################OOOOOsAA Actdttd}tD]i}|d|krNd}t d||j|tttj|sEtrtddd|gntd|tjd dSdS) NTFrrr(rNzno configuration found for z$warning: no configuration found for r)ryrr{r\rrrrrr-rorprqrrrs)rbdeletedr~s r? del_binaryrsDMMMG ??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)NTrrrb) ryr{r\rrr-r'r(r]r)r)rbr~bin_xmls r? set_binaryrsDMMM ??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=)rWri is_neededset_datas r?rYz#lve_set_default..s* 8 8 8A1h!7!7 8a 8 8 8r>rN set-defaultrrkrlr#ve_id)r[rZrYr&r@rrr LIMITS_LIST_NAMErr%r plan_deleter) r package_flagrrSrr~tag_nto_keepr#s ` ` r?rrs   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)r rsF)rrr*)rdrgrreseller_users_lists r?_check_reseller_user_pairr s&&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)NrrrgFT)rSrJrRrr"c6t||dkS)Nrrr r~rs r?is_needed_userzlve_set..is_needed_useri s&b999Xg=NN Nr>r)rrrSrrr rrkrlr#savezskip-update-cfgrGrrz save-username)5rrrryrGrIrr{rHrrr*rrrr,rrr:rrZrYrrFrr&rr-r'r(r;r)rr0rr$rrrr[r insertBefore lastChildrlve_inforcrlvp_lve_id_listr-rrrr%)rrSrgr rarrhas_verrcpu_is_different setted_cpuel_listr~rv is_differentr0el_nameaddedel2enables_reseller_limitsrs r?lve_setr"; s {{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)Nrrrrgrrs r?rz'package_set_ext..is_needed_plan s=%%')::wrz?Z?Z^fgv^w?w r>cl|d|dko|d S)Nrrrrrs r?rz'package_set_ext..is_needed_plan! s3??4((HW,==abooV`FaFaBa ar>r)rrrrkrrlr#rgrrrarrrrr r")ryr{rr[rr%r(r;rr&rr-r'r)rmis_plesk_plesk_get_package_idr XML_PLESK_IDrrcopy_package_settings_to_cpanelr:r,r plan_apply) rr% has_packagerr~rvr0r+package_resellerrrs r?r&r& s=DMMMKb      b b b  t~NNNN >"h ' ' ' - -(?? -$;;33G<---$;;#)#7#7#@#@D --oc(3->P>PQQQQ#)#7#7#<#.i s"adx00DQqTW_r>rN)rlist_domain_packages_with_idr%r& StopIteration)rrapanelrpacks`` r?r-r-a 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?rrq 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 rgrTr$F)rr&)rrg package_namer;s r?reseller_package_setr> 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_=rrrlDEFAULT_PACKAGE_EXTENSIONSrG)rrrrrsi)rmrnrrrrrrIrrrrrrmemory_to_pager,is_limits_equalscreate_cpanel_limitsr[rr#rD)rra 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 )rrFT)rr) old_limits new_limitsrvs r?rErE 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 rrrkrrl)rrrrr#rB) rrr;r%rrpage_to_memoryr:rr&r) package_id xml_packages result_datar~r#s r?rFrF sK33 ??4 J . .) 3 33}}-033G<.is_needed_package s.??4((G3WBOOJch|dko|dkSrr)r~rrgs r?r[z&plan_delete..is_needed_package s1??4((G3d 8S8SWd8d dr>rr(rNz no configuration found for plan rz)warning: no configuration found for plan )ryr{r[rrrr-rrrrorprrrsrqr)rrgrr[r~resellers_listrs`` 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)Nrf)r)rrgs r?reseller_plan_deleter_ s}555555r>c t||ddS#ttf$r)|dkr t |nt |dzdcYSwxYw)Nrr#rrr)r;r%rrr&r,)r~rvs r? get_xml_limitra 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 rrlr)rC) input_stringchar_to_searchordinalcountidxchs r?_get_char_indexz'_normalize_str.._get_char_index- sR ..  GC^## G##JJJrr>Nr;rrl)rrrfind)data_strrjjson_strtrd_idxlast_idxs r?ryry$ 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 rch|dko|dkSrr)r~r=rgs r?r[z>_package_formatter..wrapper..is_needed_packagef s2#rt'<'<<mQ[A\A\`mAmmr>cb|dko|d Srr)r~r=s r?r[z>_package_formatter..wrapper..is_needed_packagej s/#rt'<'<<`R__U_E`E`A``r>rcLtrt|nt|SrbrWrXs r?rYz?_package_formatter..wrapper..convert_mem_limitsq rqr>rrrrrrrrr rrrkrrlrrrrNr\c3vK|]3}d|d|ddV4dS)rr^rsNrrvrws r?rez6_package_formatter..wrapper.. sMTTCCCdhhqwwyy%&@&@CCCTTTTTTr>rarbc`g|]*}|d+Srdrwrws r?rYz7_package_formatter..wrapper.. s/>>>!dhhqwwyy"-->>>r>)rrr,roryrr[rar;rr:r%rr&rrrrD) r=rgr[rYr~rrjrrrr%res `` @r?rzz#_package_formatter..wrapperX 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 FFFrb)r>r<)rr%rerzs``` r?_package_formatterryK 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) NrrrfFr%rerlTadminrr\r)r{rrrrkr<DEFAULT_PACKAGEryrr^rtrmrrorqrD)rreseller_packagesr~rrarg packages_listreseller_packages r?get_packages_listr sMMM)))""$$H2333&++--  o > > >F":<cttddg}t|z}ttt }t |d}tD]\}}|D]}||||z }tr*tdd |zdzdSdS) Nrrr{Tr$rr\r) r{rrrkr<r~ryrrtrorqrD)rhrr~rrgrrs 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)rfrhFr|Tr$z {"data": [r\r) r{rrrrrkr>r~ryrtrorqrD) rrrhrr~rrargrrs r?get_all_packages_listr 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_dictras r?_convert_packages_listr 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 )rrrarrrr}F)rrarr)admin_packagesget_reseller_usersget_uids_list_by_packagelist_all list_usersreseller_package_by_uidresellers_packagesrNrar)rarTrrrr}r)clcommon.cpapirrrrrrr cached_usersrrrcached_list_packagesrcached_resellers_packagescached_reseller_userscached_defaultrrur)optionlve_package_idrrrrrrrrrgrarreseller_users_dictris r?rr 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_countrn s  ~  r>ctdtd||r/t|D]#}tt|||"dSdS)Nrrar")rrr0r:)rrrds r?r0r0x sm&&&IwBBB<!'* < c|D]}|dd}|}|D]E}t|dkr0 t |}t |5#t $rYAwxYwFdSNrsrr)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) r{rr*rrrrr:r0rs 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:)r pidflagss 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)Nr-rHr$rYr,r[rOr]rr=r>r? get_globalsr s(l$[$S 0  2 22r>c*g}t}tdt}|a|D]&\}}|D]}||kr||g'|S)Nr)rrrrtextend)rar pkg_users_oldrrgrpackage_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_SCRIPTrA) separatorrz0Error while executing Endurance's custom script r(rkzerror: rsN) rmget_param_from_fileCL_CONFIG_FILErrrrrorprrrurxrs)argsendurance_custom_scriptret_codestd_outr 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:rmmaprrPrXs r?_page_to_memory_or_bytesr 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) rrGrcrr{rKrrrrrr)reseller_id_list_for_deletecpapi_resellers_listlve_reseller_idlve_reseller_namereseller_id_for_deletes r?remove_absent_resellersr 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)rcrRrr#)_regenerate_all_domainsrN user_contextrr find_domainrcrresolve_docrootr*rrreassign_docrootrGrIrrrrrcrrr(r*) rddomain old_domain old_docrootr$entryrregistry old_domain_id new_domain_idrr$s 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': rRFTr#)rrrNrrr&rrr+r domainsaddrrcrrtrGrIrrrrrrr(r*) rdrr$r/current_docrootsrold_drrchangeddrr$s 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)r rGr-r rrrIrcrtrrrrr!r)rr rSs r?remove_absent_usersr s. #uuN v!!=':<<(,,....00 ^ # #   L     ''''   F%%f---OOF++++!D    sZ;B DB65D6 D9C;:D; D DD D D DDD)Frb)r)NN)rFT)T)NNN)NFNNr)r?)rQr/N)r@N)FN)rrN( contextlibrr{rr rrrrrrrrrxml.dom.minidomdomminidomr+builtinsr functoolsrrtypingrrrr r r rrrmrclcommon.constr rr rrrclcommon.cpapi.cpapiexceptionsr clcommon.lockr clcontrollibrcleventsrr cllimits.libr cllvectl.logrclveconfig.ve_configrrrclveconfig.ve_lockrrrrrr r!secureior"r#websiteisolationr$rNr%rwebsiteisolation.exceptionsr&GET_CP_PACKAGE_SCRIPTrrr~rrrr}rr:rrIS_DEBUGr.LVErrGr/rErKrPrTrZr_rhruryrwrPrnrQrrrorrrrr-rHr$rYrZr,r[rOr]r\r^rrrrrrrrrrrrrcontextmanagerr rrrpr1r:r@rCrFrIrrTr_rhr;rqror{rrrrrrrrrrrrrrrrrr rr rr*rrr0r8r:r<r>tuplerr5rKrPrkr{rrrrrrrrrrrrrrrrrrrrrrrrrrrr"r(r&r-rr>r/rErFrr_raryryrrrrrrrrrrrr0rrrrrrrrrrrrr=r>r?rs   ???????????????? """"""gggggggggggg888888&&&&&&******PPPPPPPP%%%%%%......OOOOOOOOOOEEEEEEEEDDDDDDDDDDDDDD????????000000::::::000000@    :  3rz~~mQ// 0 0 !!'+.. E CC E ! ! !E #---CY     ???2*** H H H %%%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 44 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("....bJ J J \C>C>C>L$eD$J&7$$$$ ' ' ' 'nnnb!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>