§ ½@¾j-’ãóh—ddlZddlZddlZddlZddlmZddlmZddlm Z m Z ddl m Z ddl mZddlmZmZddlmZdd lmZdd lmZejd ¦«Zd Zd ZdZGd„de¦«ZGd„de¦«ZGd„de¦«Z Gd„d¦«Z!Gd„d¦«Z"Gd„d¦«Z#dS)éN)ÚOptional)ÚProcLve)ÚcpapiÚClPwd)Ú NotSupported)Ú ve_config)Ú PyLveErrorÚPyLve)Úconfig)Ú id_registry)Údomain_lve_sentry_extraz lvectl.lveapiÚreselleréécó—eZdZdS)Ú NameMapErrorN©Ú__name__Ú __module__Ú __qualname__©óú py/lveapi.pyrr,ó€€€€€Ø€Drrcó—eZdZdS)ÚNameMapConfigErrorNrrrrrr0rrrcó—eZdZdS)ÚNameMapNotInitializedNrrrrrr4rrrcóJ—eZdZdZefd„Zd„Zd„Zd„Zd d„Z d „Z d d „Z d „Z dS)ÚNameMapzÚ Container for backend storing resellers_name<=>resellers_id map As backend store use ve.cfg Usage: >>> name_map = NameMap() >>> name_map.link_xml_node() >>> name_map.id_list() [1001] có0—||_d|_d|_dS©N)Ú _xml_tag_nameÚ _xml_nodeÚ_reseller_id_name_map)ÚselfÚ xml_tag_names rÚ__init__zNameMap.__init__Ds€Ø)ˆÔ؈Œà%)ˆÔ"Ð"Ð"rcóN—| ¦«D]\}}||kr|cSŒdSr"©Úload_from_node)r&ÚnameÚname_Úid_s rÚget_idzNameMap.get_idJsB€Ø×-Ò-Ñ/Ô/ð ð ‰JˆE�3ؘŠ}ˆ}Ø� � � ðð ð rcóN—| ¦«D]\}}||kr|cSŒdSr"r*)r&r.r-Ú_ids rÚget_namezNameMap.get_nameOsB€Ø×-Ò-Ñ/Ô/ð ð ‰JˆE�3Ø�cŠzˆzØ� � � ðð ð rcó>—d„| ¦«D¦«S)Ncó—g|]\}}|‘ŒSrr)Ú.0Ú_r.s rú z#NameMap.id_list..Us€Ð8Ð8Ð8™˜˜3�Ð8Ð8Ð8rr*©r&s rÚid_listzNameMap.id_listTs"€Ø8Ð8 $×"5Ò"5Ñ"7Ô"7Ð8Ñ8Ô8Ð8rNTcób—|€d|_| |¦«dS||_d|_dS)aC Initialize NameMap. If xml_node is none, config will be loaded automatically :param use_cache: Bool whether bypass ve.cfg xml cache :param xml_node: !! DEPRECATED PARAM !! this param is left only for compatibility with our old code N)r$Ú_load_resellers_map_from_ve_cfgr%)r&Úxml_nodeÚ use_caches rÚ link_xml_nodezNameMap.link_xml_nodeWsB€ð Ð à!ˆDŒNØ × 0Ò 0°Ñ ;Ô ;Ð ;Ð ;Ð ;ð&ˆDŒNØ)-ˆDÔ &Ð &Ð &rcó—g|_| |¬¦«\}}|D]b}| d¦«}t| d¦«¦«}|r'|r%||jvr|j ||f¦«Œc~~dS)zT Fills self._reseller_id_name_map from ve.cfg file :return: ©r=ÚuserÚidN)r%Ú_try_get_xml_nodeÚ getAttributeÚintÚappend)r&r=Úve_cfgr<Úel_r,r.s rr;z'NameMap._load_resellers_map_from_ve_cfgis¦€ð &(ˆÔ"Ø×1Ò1¸IÐ1ÑFÔFш�Øð ?ð ?ˆCØ×#Ò# FÑ+Ô+ˆDÝ�c×&Ò& tÑ,Ô,Ñ-Ô-ˆCØð ?˜ð ? ¨4Ô+EÐ EÐ EØÔ*×1Ò1°3¸°+Ñ>Ô>Ð>øà Ø ˆFˆFrcóÊ— tj|¬¦«\}}n.#tj$r}d|_t d¦«|‚d}~wwxYw|| |j¦«fS)Nr@z-Error happened while loading data from ve.cfg)rÚget_xml_configÚBadVeConfigExceptionr%rÚgetElementsByTagNamer#)r&r=rGr<Úes rrCzNameMap._try_get_xml_nodeys€€ð ]Ý(Ô7À)ÐLÑLÔLÑ ˆF�H�HøÝÔ-ð ]ð ]ð ]Ø)-ˆDÔ &Ý$Ð%TÑUÔUÐ[\Ð \øøøøð ]øøøð�x×4Ò4°TÔ5GÑHÔHÐHÐHs‚›AªAÁAc#óPK—|j€|j€td¦«‚|jrc|j |j¦«D]C}| d¦«}t | d¦«¦«}|r|r||fV—ŒD|jr|jD] \}}||fV—Œ dSdS)z? Obtain data from xml node as (name, id_) list NzLName map is not initialized. Use obj.link_xml_node() to get data from configrArB)r$r%rrLr#rDrE)r&rHr,r.s rr+zNameMap.load_from_node�sîèè€ð Œ>Ð ! dÔ&@Ð&HÝ'ð)Zñ[ô[ð [à Œ>ð $à”~×:Ò:¸4Ô;MÑNÔNð $ð $�Ø×'Ò'¨Ñ/Ô/�ݘ#×*Ò*¨4Ñ0Ô0Ñ1Ô1�Øð$˜Cð$Ø ˜)�O�O�Oøà Ô %ð à!Ô7ð ð ‘ ��TؘC�i����ð ð ð ð r)NT)T) rrrÚ__doc__ÚLVP_XML_TAG_NAMEr(r/r2r9r>r;rCr+rrrr r 8s®€€€€€ð ð ð%5ð*ð*ð*ð*ð ððð ððð 9ð9ð9ð.ð.ð.ð.ð$ððð IðIðIðIð ð ð ð ð rr cóp—eZdZdZd„Zd„Zd d„Zd„Zd„Zd„Z d „Z e d „¦«Z e d „¦«Z d „ZdS)ÚLvpMapzl Container for storing information about lve:lvp mapping In which reseller container stored lve có|—t¦«|_i|_i|_d|_t ¦«|_dSr")r Úname_mapÚ _id_name_mapÚ _name_id_mapÚ_reseller_id_map_panelrÚ_pwdr8s rr(zLvpMap.__init__›s4€Ý™ œ ˆŒ ØˆÔØˆÔØ&*ˆÔ#Ý‘G”GˆŒ ˆ ˆ rcó.—||j|<||j|<dSr")rUrV)r&r,r.s rÚ_add_mapzLvpMap._add_map¢s"€Ø!%ˆÔ˜#ÑØ"%ˆÔ˜$ÑÐÐrNcóp— |j |¦«jS#tj$r|cYSwxYwr")rXÚget_pw_by_nameÚpw_uidrÚNoSuchUserException)r&r,Údefaults rr]z LvpMap.pw_uid¦sG€ð Ø”9×+Ò+¨DÑ1Ô1Ô8Ð 8øÝÔ(ð ð ð ØˆNˆNˆNð øøøs ‚!¡5´5có¦—| |¦«}|�|S|j€tj¦«|_|j |¦«Sr")r]rWrÚget_reseller_id_pairsÚget)r&rÚuids rÚ_get_panel_reseller_idzLvpMap._get_panel_reseller_id¬sP€à�kŠk˜(Ñ#Ô#ˆØ ˆ?؈Jð Ô &Ð .Ý*/Ô*EÑ*GÔ*GˆDÔ 'ØÔ*×.Ò.¨xÑ8Ô8Ð8rcóø—|j |¦«p|j |¦«}|�|S | |¦«}n#t $rd}YnwxYw|�| ||¦«|S)z‡ Convert reseller name to an LVE id. It supports resellers without a system account (for Plesk compatibility). N)rTr/rVrbrdrrZ)r&r,rcs rÚget_reseller_idzLvpMap.get_reseller_id·s•€ð Œm×"Ò" 4Ñ(Ô(ÐG¨DÔ,=×,AÒ,AÀ$Ñ,GÔ,GˆØ ˆ?؈Jð Ø×-Ò-¨dÑ3Ô3ˆCˆCøÝð ð ð ØˆCˆCˆCð øøøà ˆ?Ø �MŠM˜$ Ñ $Ô $Ð $؈ sºAÁ AÁAcó*—|j |¦«p|j |¦«}|�|S t j|¦«j}tj|¦«r|  ||¦«nd}n#t$rd}YnwxYw|S)z„ Convert reseller id to reseller name It support resellers without system account (for Plesk compatibilyty) N) rTr2rUrbÚpwdÚgetpwuidÚpw_namerÚ is_resellerrZÚKeyError)r&r.r,s rÚget_reseller_namezLvpMap.get_reseller_nameÈsª€ð Œ}×%Ò% cÑ*Ô*ÐH¨dÔ.?×.CÒ.CÀCÑ.HÔ.HˆØ Р؈Kð Ý”< Ñ$Ô$Ô,ˆDÝÔ  Ñ&Ô&ð Ø— ’ ˜d CÑ(Ô(Ð(Ð(à�øøÝð ð ð ØˆDˆDˆDð øøøàˆ sºAB BÂBc#óÔK—ttj¦«¦«}i}|D]N} | |¦«||<Œ#t$r&t jt jd|›d�¦«YŒKwxYwtjd¬¦«D]\\}}| |¦«}|€$t jt jd|›d�¦«Œ@|  |d¦«}||fV—Œ]dS)zÐ This method loops over all user:reseller pairs in control panel and returns appropriate lve_id:lvp_id pairs. THIS METHOD WON'T CHECK IF 'RESELLER LIMITS' IS ENABLED IN ve.cfg z Reseller ú> still exists in control panel, but absent in /etc/passwd file)Úcploginr)ÚkeylsNúuser r) ÚsetrÚ resellersrfrÚsyslogÚ LOG_WARNINGÚcpinfor]rb)r&rtÚ reseller_uidsrrpÚlve_idÚlvp_ids rÚ lve_lvp_pairszLvpMap.lve_lvp_pairsÛs`èè€õ �œÑ)Ô)Ñ*Ô*ˆ ؈ Ø!ð Jð JˆHð JØ*.×*>Ò*>¸xÑ*HÔ*H� ˜hÑ'Ð'øÝð Jð Jð JÝ” ÝÔ&ð)I°Hð)Ið)Ið)IñJôJðJðJðJð Jøøøõ"'¤Ð4KÐ!LÑ!LÔ!Lð !ð !Ñ ˆG�XØ—[’[ Ñ)Ô)ˆFð ˆ~Ý” ÝÔ&ð)I°ð)Ið)Ið)IñJôJðJðØ"×&Ò& x°Ñ3Ô3ˆFؘ&�.Ð Ð Ð Ð ð !ð !sªAÁ-A3Á2A3c#ó>K—tj¦«D]}|V—ŒdSr")rrt)Ú reseller_names rrtzLvpMap.resellersøs6èè€å"œ_Ñ.Ô.ð ð ˆMØÐ Ð Ð Ð ð ð rcó—g}tj|¦«}|D]d} tj|¦«j}| |¦«Œ2#t $r&tjtjd|›d�¦«YŒawxYw|S)z: Obtain from control panel resellers uids rrro) rÚreseller_usersrhÚgetpwnamr]rFrlrurv)r,ÚuidsrrAr.s rrxzLvpMap.reseller_uidsýsÀ€ð ˆÝÔ-¨dÑ3Ô3ˆØ"ð Jð JˆDð JÝ”l 4Ñ(Ô(Ô/�Ø— ’ ˜CÑ Ô Ð Ð øÝð Jð Jð JÝ” ÝÔ&ð)I°ð)Ið)Ið)IñJôJðJðJðJð Jøøøðˆ sœ.A Á -A;Á:A;cóV—| |¦«}| |¦«Sr")rmrx)r&rzr}s rÚlvp_lve_id_listzLvpMap.lvp_lve_id_lists)€Ø×.Ò.¨vÑ6Ô6ˆ Ø×!Ò! -Ñ0Ô0Ð0rr")rrrrOr(rZr]rdrfrmr{Ú staticmethodrtrxrƒrrrrRrR–sÑ€€€€€ðððððð&ð&ð&ððððð 9ð 9ð 9ðððð"ððð&!ð!ð!ð:ð ð ñ„\ð ðððñ„\ðð 1ð1ð1ð1ð1rrRcór—eZdZdd„Zdefd„Zdd„Zd„Zd„Zd„Z d „Z d „Z d „Z d „Z d „Zd„Zd„Zd„Zd„ZdS)ÚLveNcó¸—|p t¦«|_|p t¦«|_|p t ¦«|_t ¦«|_d|_dSr") rÚprocr ÚpyrRÚmaprsÚ_mapped_domain_usersÚ_lve_lvp_map_cache)r&rˆr‰rŠs rr(z Lve.__init__sL€ØÐ%�G™IœIˆŒ Ø�-�™œˆŒØ�?�&™(œ(ˆŒÝ),©¬ˆÔ!ð04ˆÔÐÐrÚreturncóʇ—|j€Ut|jj ¦«¦«Šˆfd„|j ¦«D¦«|_|jS)a {lve_id: lvp_id} from ve.cfg, built once per instance. Callers that need a single lookup must use this rather than scanning `lve_id_lvp_id_pairs()`; the scan is O(accounts) and doing it per account is what made `apply all` quadratic. Ncó(•—i|]\}}||‰vr|nd“ŒS)rr)r5ryrzÚenabled_lvp_ids €rú z#Lve.lve_lvp_map../s=ø€ð'ð'ð'á"�F˜Fð 6¨^Ð#;Ð#;˜˜Àð'ð'ð'r)rŒrsrŠrTr9r{)r&r�s @rÚ lve_lvp_mapzLve.lve_lvp_map#spø€ð Ô "Ð *Ý  ¤Ô!2×!:Ò!:Ñ!<Ô!<Ñ=Ô=ˆNð'ð'ð'ð'à&*¤h×&<Ò&<Ñ&>Ô&>ð'ñ'ô'ˆDÔ #ðÔ&Ð&rcó—d|_dS)zBDrop the memoised map after ve.cfg or the panel user list changes.N)rŒr8s rÚinvalidate_lve_lvp_mapzLve.invalidate_lve_lvp_map5s€à"&ˆÔÐÐrc#óbK—| ¦« ¦«Ed{V—†dS)a5 Obtain {lve id}:{lvp id} pairs iterator based on ve.cfg config (detect enabled resellers containers) This method (unlike LvpMap.lve_lvp_pairs) will check if reseller is enabled in ve.cfg and return lvp_id=0 for users of reseller with disabled reseller limits N)r’Úitemsr8s rÚlve_id_lvp_id_pairszLve.lve_id_lvp_id_pairs9s>èè€ð×#Ò#Ñ%Ô%×+Ò+Ñ-Ô-Ð-Ð-Ð-Ð-Ð-Ð-Ð-Ð-Ð-rcóR—| ¦« |d¦«S)z\ Obtain lvp id based on ve.cfg config (detect enabled resellers containers) r)r’rb)r&rys rÚlve2lvpz Lve.lve2lvpDs&€ð×ÒÑ!Ô!×%Ò% f¨aÑ0Ô0Ð0rc ó¶—| |d¦«}||kr7|j |¦«r|j ||¦«rdSt  d|||¦«||krB||krdn|}t  d|||¦«|j ||¦«|j ||d|›d|›d�¬¦«|||<|j |¦«r]|j ||¦«sBt  d ||¦«tj tj d |›d |›d �¦«d S)avMake sure lve really sits inside its isolation LVP lvp. *kernel_map* is the shared /proc/lve/map snapshot (CLOS-6868); this writes its own effect back into it. *parent_lvp* is where lve belongs when it is NOT isolated -- its reseller LVP, or 0. lvp must already exist; callers create it first. CLOS-7493. Two things this must not do, both of which reported success while leaving the account outside its own aggregate cap: * Trust the map. /proc/lve/map records where an LVE is *meant* to live, not where it is; a row can name lvp while the LVE itself is still at the host LVP. So when the map claims the move is done, confirm it against lvp's own listing -- the kernel's answer. That read is skipped in every other case, and skipped entirely for an LVE that does not exist yet: ordinarily lve is created later by lve_setup, already parented by the mapping this registers. * Trust lve_lvp_move's return code. It returns 0 without touching the LVE when the mapping already names the target (kmod lve_lvp_map_move(): `old_lvp_id == lvp_id` -> return 0), which is exactly the state above. Park the LVE on *parent_lvp* first, so the move back has a mapping change to act on. Measured: the bare move leaves it at /lve, the pair lands it at /lvp/lve. A self-owned reseller that isolates a domain of its own is its own parent (*parent_lvp* == *lve_id*), and parking there would be the same no-op, so it is parked on the host LVP instead. Whether lve_lvp_move should repair that divergence by itself is a question for lve-kmod (CLOS-7468 left it open); until it does, the re-seat is what re-homes such an LVE from here. rFzÔ>ð ð�5å �ŠÐOؘ ñ ,ô ,ð ,à ˜Ò Ð Ø&¨&Ò0Ð0�q�q°jˆHÝ �HŠHð!Ø"(¨&°(ñ <ô <ð <à ŒG× Ò  ¨6Ñ 2Ô 2Ð 2Ø Œ×ÒØ �FØY¨ÐYÐY¸FÐYÐYÐYð ñ ô ð ð$ˆ �6Ñð Œ7× Ò ˜fÑ %Ô %ð ¨d¬i×.IÒ.IÈ&ÐRXÑ.YÔ.Yð Ý �IŠIð;ØŠ>˜$œ)×0Ò0Ñ2Ô2Ñ 3Ô 3ð Ø”Y—]’]‘_”_×(Ò(¨°Ñ3Ô3ˆFˆFàˆF؈ŒÔ˜FÐ4 TÐ4Ð4Ð4¨VÐ4Ð4Ð4Ø �QŠ;ˆ;ð Ý” ˜VÑ$Ô$Ð$Ø”×#Ò# F¨FÑ3Ô3Ð3Ð3Ð3øÝð ð ð Ø��ð øøøð ˆ;sÂ/B5Â5 CÃCcó–‡—tj|¦«} tj|¦«j}t t j|¦«pg¦«}n#t$ri}YnwxYwg}dx}x}}|j D�]T} | j s!|dz }t  d|¦«Œ+ |  | j ¦«} | €'|dz }t  d|| j ¦«Œotj|| ¦«} | €(|dz }t d|| j | ¦«Œ®| | | j ¦«f¦«ŒÝ#t(t*t,f$r_} t/jt.jd|›d| j ›d | ›�¦«|dz }t  d || j | ¦«Yd} ~ �ŒNd} ~ wwxYwt3|j ¦«t3|¦«z } d}|rPt5| ¦«¦«Št9ˆfd „tj|¦«piD¦«¦«}|s|s|r t<j}n t<j }t  |d |t3|¦«t3|j ¦«| rd | ›d|›d|›d|›d� nd|rd |›d�ndtCd¦«¬¦«|S)uäResolve all domain→docroot→domain_id mappings once. Returns a list of (domain_id, limits_dict) tuples. Callers pass this to _map_domain_lves / apply_domain_lve_limits to avoid redundant resolve_docroot + assign_domain_id calls. Uses cpapi.userdomains() to fetch all domain→docroot pairs in a single file read instead of calling resolve_docroot per domain, which would re-parse the entire userdatadomains file each time. rézeuid %s: domains.json holds a domain entry with no name; skipped, so no per-domain limits come from itNzfuid %s: domain %r from domains.json has no docroot in the panel; its per-domain limits are NOT appliedz‡uid %s: domain %r (docroot %r) has no domain LVE id -- not enabled via enable-domain-limits -- so its per-domain limits are NOT appliedz)Skipping malformed domain entry for user z (name=ú): z^uid %s: malformed domain entry (name=%r) skipped, so its per-domain limits are NOT applied: %sc3ó$•K—|] }|‰v¯dV—Œ dS)r³Nr)r5ÚdocrootÚpanel_docrootss €rú z(Lve._build_domain_map..s:øèè€ð)ð)ØØ .Ð0Ð0ðØ0Ð0Ð0Ð0ð)ð)rzYuid %s: domain map built -- %s of %s configured domain(s) resolved to a domain LVE id%s%sz; z skipped (z stale, z malformed, z not enabled)Úz0 registered docroot(s) the panel no longer listszdomain-map-skipped)Úextra)"Ú _ws_configÚ load_configrhrirjÚdictrÚ userdomainsrlÚdomainsr,r¡ÚwarningrbÚ_ws_id_registryÚ get_domain_idÚdebugrFÚlimitsÚto_dictÚ ValueErrorÚ TypeErrorÚ OverflowErrorrurvÚlenrsÚvaluesÚsumÚget_all_entriesÚloggingÚWARNINGÚDEBUGr )r&ryr ÚusernameÚdocroot_by_domainÚentriesÚ skipped_staleÚskipped_not_enabledÚskipped_tenant_dataÚdr¶Ú domain_idÚexcÚskippedÚorphaned_registrationsÚlevelr·s @rÚ_build_domain_mapzLve._build_domain_map›sÐø€õÔ'¨Ñ/Ô/ˆð #Ý”| FÑ+Ô+Ô3ˆHÝ $¥UÔ%6°xÑ%@Ô%@Ð%FÀBÑ GÔ GÐ Ð øÝð #ð #ð #Ø "Ð Ð Ð ð #øøøðˆð EFÐEˆ ÐEÐ+Ð.AØ”ð> ñ> ˆAØ”6ð ð$ qÑ(Ð#Ý— ’ ðLØMSñUôUðUàð5 Ø+×/Ò/°´Ñ7Ô7�Ø�?ð" QÑ&�MÝ—K’Kð@ØAGÈÌñQôQðQðõ ,Ô9¸&À'ÑJÔJ� ØÐ$ð(¨1Ñ,Ð'Ý—I’Ið_à ¤¨ñ1ô1ð1ðØ—’  ¨1¬8×+;Ò+;Ñ+=Ô+=Ð>Ñ?Ô?Ð?Ð?øÝ¥ ­=Ð9ð ð ð õ” ÝÔ&ð0Àð0ð0ØœVð0ð0Ø*-ð0ð0ñ1ô1ð1ð$ qÑ(Ð#Ý— ’ ðDØEKÈQÌVÐUXñZôZðZà���‘øøøøð øøøõ�f”nÑ%Ô%­¨G© ¬ Ñ4ˆð@"#ÐØ ð õ !Ð!2×!9Ò!9Ñ!;Ô!;Ñ<Ô<ˆNÝ%(ð)ð)ð)ð)Ý"1Ô"AÀ&Ñ"IÔ"IÐ"OÈRð)ñ)ô)ñ&ô&Ð "ð "ð " ]ð "Ð6Ið "Ý”OˆEˆEå”MˆEõ �ŠØ ð Ø ¥# g¡,¤,µ°F´NÑ0CÔ0Cà5<ð Eð 2�ð 2ð 2 Mð 2ð 2Ð;Nð 2ð 2Ø"ð 2ð 2ð 2ð 2ØBDà%ð .Ð YÐ'Ð YÐ YÐ YÐ YØ+-Ý)Ð*>Ñ?Ô?ð ñ Aô Að Aðˆs7—EÄ#.EÅGÅ)AGÇGc óP—dx}}|D]Ô\}}| |¦«|krt d|||¦«Œ<||vrRt d||| |¦«|¦«|j ||¦«|dz }n=t d|||¦«|j ||¦«|dz }|||<ŒÕ|s|r,t d||||t|¦«¦«|j  |¦«dS)uBPlace every domain LVE that belongs to *lve_id* under its user LVP. Uses lve_lvp_move for domain LVEs that already exist in the kernel, and falls back to lve_lvp_map for those that do not yet exist (so the kernel will place them under the correct LVP when lve_setup creates them later). *proc_map* is an lve_id→lvp_id dict (from /proc/lve/map) used to skip mappings that are already correct. Updated in-place so callers see the new state. *domain_map* is a precomputed list from _build_domain_map(). rz)uid %s: domain LVE %s already under lvp%sz0uid %s: moving domain LVE %s from lvp%s to lvp%sr³zAuid %s: pre-registering not-yet-created domain LVE %s under lvp%szYuid %s: mapped domain LVEs under lvp%s -- %s moved, %s pre-registered, %s domain(s) totalN) rbr¡rÃr‰r£r’r¢rÉr‹Úadd)r&ryÚproc_mapÚ domain_mapÚmovedÚpre_registeredr×Ú_limitss rÚ_map_domain_lveszLve._map_domain_lves7sm€ð"#Ð"ˆ�Ø",ð )ð )Ñ ˆI�wØ�|Š|˜IÑ&Ô&¨&Ò0Ð0Ý— ’ ÐEØ  )¨Vñ5ô5ð5àà˜HÐ$Ð$å— ’ ÐLØ  )¨X¯\ª\¸)Ñ-DÔ-DÀfñNôNðNà”×$Ò$ V¨YÑ7Ô7Ð7ؘ‘ ��õ— ’ Ð]Ø  )¨Vñ5ô5ð5à”×#Ò# F¨IÑ6Ô6Ð6Ø !Ñ#�Ø"(ˆH�YÑ Ð Ø ð c�Nð cÝ �HŠHð*Ø+1°6¸5À.ÕRUÐV`ÑRaÔRañ cô cð cà Ô!×%Ò% fÑ-Ô-Ð-Ð-Ð-rc óz—d„|D¦«}|s+t d|t|¦«¦«dS |j |¦«j}n(#t $rtj¦«pddz}YnwxYw|D�]´\}}|j  ¦«} d|vrt|d¦«p||_n||_d|vr-t|d¦«}|r|tj znd|_ d |vrt|d ¦«|_d |vrt|d ¦«|_d |vrt|d ¦«|_d |vrt|d ¦«|_d |vr-t|d ¦«} | r| tj znd|_nM#t&t(t*f$r3} t-jt,jd|›d|›d| ›�¦«Yd} ~ �Œhd} ~ wwxYw|j ||d|›d�¬¦«t d||||j¦«�Œ¶dS)uêApply per-domain limits from domains.json to each domain LVE. Must be called after lve_set_default() resets all LVEs inside the user LVP to the user's defaults. Each domain LVE is set to its stored limits, or the user's current cpu when unconfigured (cpu=0). CLOS-4024: the kernel rejects lve_lvp_setup when any child has cpu=0 inside a finite-cpu parent, so we never write cpu=0 to the kernel. CLOS-4060: domains with no custom limits are skipped — lve_set_default already reset their existing LVEs to user defaults, and non-existing ones will be lazily created by lve_enter under the user's LVP. *domain_map* is a precomputed list from _build_domain_map(). có —g|] \}}|¯||f‘Œ Srr)r5rÖÚls rr7z/Lve.apply_domain_lve_limits..ns%€Ð<Ð<Ð<¡D A q¸!Ð<˜!˜Q˜Ð<Ð<ÐHÐO˜ ¥jÔ&:Ñ:Ð:ÈaðÔ*à˜6�>�>Ý%(¨°¬Ñ%6Ô%6�H”NؘfÐ$Ð$Ý(+¨F°7¬OÑ(<Ô(<�HÔ%ؘVÐ#Ð#Ý'*¨6°&¬>Ñ':Ô':�HÔ$ؘ6�>�>Ý),¨V°D¬\Ñ):Ô):�HÔ&ؘVÐ#Ð#Ý!$ V¨F¤^Ñ!4Ô!4�Jà>HÐO˜ ¥jÔ&:Ñ:Ð:ÈaðÔ&øøå¥ ­=Ð9ð ð ð õ ” ÝÔ&ð.À ð.ð.Ø#ð.ð.Ø(+ð.ð.ñ/ô/ð/ð���‘øøøøð øøøð ŒG× Ò Ø˜8ØR°)ÐRÐRÐRð ñ ô ð õ �IŠIÐKؘi¨°´ñ Bô Bð Bñ Bð]/ Bð/ Bs*»AÁ"BÁ?BÂ%DF(Æ(G2Æ?(G-Ç-G2c óÒ—|j ¦«}|j ¦«rd„t j¦«D¦«}nt ¦«}t dt|¦«|j ¦«¦«dx}}|  ¦«D�]\}}||v�rB|dkrV|j  |¬¦«s;t  d||¦«|j  |¦«|dz }|j  |¬¦«sZt d|||¦«|r|j ||¦«n|j  |¦«|dz }| |||¦«r|dz }||jvr/| |¦«}| |||¬¦«�Œ0t  d |¦«�ŒM| |d¦«|kr«|j  |¬¦«s:t  d |¦«|j  |¦«|dz }t  d || |d¦«|¦«|j ||¦«|||<|dz }�Œt d ||¦«d S)uj Load lve_id:lvp_id map to kmod-lve. For users with per-domain isolation configured, builds a nested LVP hierarchy instead of a flat reseller mapping: lvp<0> [lvp] â†� reseller LVP (if enabled) lvp â†� user-level LVP with isolation lve â†� user LVE lve ... â†� domain LVEs lvp<0> [lvp] â†� reseller LVP (without isolation) lve â†� user LVE (flat, existing behaviour) có:—h|]}tj|¦«¯|’ŒSr)rÁrÌ)r5rcs rú z Lve._sync_map..Ðs9€ðððØÝ"Ô2°3Ñ7Ô7ðØðððrz;sync-map: %s domain-isolated user(s), per-domain support=%sr)rzzTsync-map: uid %s is isolated under reseller lvp%s; creating the missing reseller LVPr³z=sync-map: creating isolation LVP lvp%s for uid %s under lvp%s)rßràz4sync-map: uid %s domain LVEs already mapped this runzsync-map: creating lvp%sz*sync-map: moving lve%s from lvp%s to lvp%sz4sync-map: done -- %s LVP(s) created, %s LVE(s) movedN)rˆrŠr‰Údomains_supportedr»Úfind_all_lve_ids_with_configrsr¡r¢rÉr—Ú exist_lvprÃÚlve_lvp_createÚlve_lvp_create2r©r‹rÜrärbr£)r&Ú proc_map_dictÚisolated_usersÚ created_lvpsÚ moved_lvesryrzràs rÚ _sync_mapz Lve._sync_map­s2€ð$œ Ÿ š ™œˆ ð Œ7× $Ò $Ñ &Ô &ð #ððÝ)ÔFÑHÔHðñôˆNˆNõ !™UœUˆNå �ŠÐNÝ�^Ñ$Ô$ d¤g×&?Ò&?Ñ&AÔ&Añ Cô Cð Cà$%Ð%ˆ �zà"×6Ò6Ñ8Ô8ð/ $ñ/ $‰NˆF�FؘÐ'Ñ'ð˜Q’;�; t¤y×':Ò':À&Ð':Ñ'IÔ'I�;Ý—I’IðBØCIÈ6ñSôSðSà”G×*Ò*¨6Ñ2Ô2Ð2Ø  AÑ%�Lð ”y×*Ò*°&Ð*Ñ9Ô9ð&Ý—H’HÐ\Ø# V¨Vñ5ô5ð5àð7Øœ×/Ò/°¸Ñ?Ô?Ð?Ð?àœ×.Ò.¨vÑ6Ô6Ð6Ø  AÑ%�Lð ×%Ò% f¨f°mÑDÔDð$Ø !‘O�Jà Ô!:Ð:Ð:Ø!%×!7Ò!7¸Ñ!?Ô!?�JØ×)Ò)¨&¸=Ø5?ð*ñAôAðAñAõ—I’IÐTÐV\Ñ]Ô]Ð]Ñ]ð!×$Ò$ V¨QÑ/Ô/°6Ò9Ð9Øœ9×.Ò.°fÐ.Ñ=Ô=ð*ÝŸ š Ð"<¸fÑEÔEÐEØœ×.Ò.¨vÑ6Ô6Ð6Ø$¨Ñ)˜ Ý—I’IÐJØ$ m×&7Ò&7¸ÀÑ&BÔ&BÀFñLôLðLà”G×(Ò(¨°Ñ8Ô8Ð8Ø,2�M &Ñ)Ø !‘O�Jùå �ŠÐGؘzñ +ô +ð +ð +ð +rcó†— | ¦«dS#t$rt d¦«YdSwxYw)zZ wrapped _sync_map function for prevent error if some cpapi not supported z8sync-map: skipped, the control panel does not support itN)rrr¡r¢r8s rÚsync_mapz Lve.sync_maps[€ð QØ �NŠNÑ Ô Ð Ð Ð øÝð Qð Qð Qõ �HŠHÐOÑ PÔ PÐ PÐ PÐ PÐ Pð  Qøøøs‚˜$A¿AcóL— tj¦«S#t$rYdSwxYw)z^ Check if current panel supported for reseller's limits; :rtype: bool F)rÚis_reseller_limits_supportedrr8s rÚis_panel_supportedzLve.is_panel_supporteds8€ð  ÝÔ5Ñ7Ô7Ð 7øÝð ð ð Ø�5�5ð øøøs ‚• #¢#có¦—t|j ¦«|j ¦«| ¦«f¦«S)zo Check present all needed (kmod-lve, liblve, /proc/lve, panel) for manipulate resellers limits )Úallr‰Úresellers_supportedrˆrr8s rÚreseller_limit_supportedzLve.reseller_limit_supported%sK€õ�D”G×/Ò/Ñ1Ô1Ø”I×1Ò1Ñ3Ô3Ø×+Ò+Ñ-Ô-ð/ñ0ô0ð 0rcó€—t|j ¦«|j ¦«f¦«S)zh Check present all needed (kmod-lve, liblve, /proc/lve) for manipulate resellers limits )rr‰rrˆr8s rÚis_lve10z Lve.is_lve10-s3€õ�D”G×/Ò/Ñ1Ô1°4´9×3PÒ3PÑ3RÔ3RÐSÑTÔTÐTr)NNN)r�N)rrrr(r½r’r”r—r™r©r¯rÜrärrrrrrrrrr†r†s$€€€€€ð 4ð 4ð 4ð 4ð'˜Tð'ð'ð'ð'ð$'ð'ð'ð'ð .ð .ð .ð1ð1ð1ð ?ð?ð?ðBððð ZðZðZðx%.ð%.ð%.ðNMBðMBðMBð^`+ð`+ð`+ðD Qð Qð Qðððð0ð0ð0ðUðUðUðUðUrr†)$rÍr«rurhÚtypingrÚclcommon.clprocrÚclcommonrrÚclcommon.cpapi.cpapiexceptionsrÚ clveconfigrÚlve_utils.pylve_wrapperr r Úwebsiteisolationr r»r rÁr Ú getLoggerr¡rPÚ LVE_NO_UBCÚLVE_NO_MAXENTERÚ Exceptionrrrr rRr†rrrúr%s#ðð€€€Ø € € € Ø € € € Ø € € € ØÐÐÐÐÐà#Ð#Ð#Ð#Ð#Ð#Ø!Ð!Ð!Ð!Ð!Ð!Ð!Ð!Ø7Ð7Ð7Ð7Ð7Ð7à Ð Ð Ð Ð Ð à5Ð5Ð5Ð5Ð5Ð5Ð5Ð5à1Ð1Ð1Ð1Ð1Ð1Ø;Ð;Ð;Ð;Ð;Ð;Ø4Ð4Ð4Ð4Ð4Ð4ð€gÔ˜Ñ(Ô(€àÐØ € Ø€ð  ð ð ð ð �9ñ ô ð ð ð ð ð ð ˜ñ ô ð ð ð ð ð ð ˜Lñ ô ð ð[ ð[ ð[ ð[ ð[ ñ[ ô[ ð[ ð|z1ðz1ðz1ðz1ðz1ñz1ôz1ðz1ð~\Uð\Uð\Uð\Uð\Uñ\Uô\Uð\Uð\Uð\Ur