§ À•¿j£Þãó@—ddlZddlZddlZddlZddlZddlZddlZddlm Z ddl m Z m Z m Z mZmZddlmZmZmZmZddlZddlZddlmZddlmZddlmZddlmZmZm Z dd l!m"Z"m#Z#dd l$m%Z%m&Z&m'Z'm(Z(m)Z)ej* +¦«Z,d Z-d Z.Gd „de/¦«Z0Gd„de/¦«Z1Gd„de/¦«Z2Gd„de/¦«Z3Gd„de¦«Z4Gd„de/¦«Z5Gd„de/¦«Z6Gd„de6¦«Z7d„Z8d„Z9de:fd „Z;Gd!„d"e<¦«Z=dS)#éN)Ú defaultdict)ÚS_IRGRPÚS_IROTHÚS_IRUSRÚS_IWUSRÚST_DEV)ÚDictÚListÚOptionalÚTuple)ÚFormattedException)ÚClPwd)Úcheck_quota_enabled)Úadmin_packagesÚ list_usersÚresellers_packages)ÚCPAPIExternalProgramFailedÚ EncodingError)ÚExternalProgramFailedÚget_file_linesÚget_filesystem_typeÚ run_commandÚwrite_file_linesÚdefaultÚ VE_DEFAULTcó—eZdZd„ZdS)ÚNoSuchPackageExceptioncóD—t |d|›d�¦«dS)NzNo such package (ú)©Ú ExceptionÚ__init__©ÚselfÚpackages úG/opt/cloudlinux/venv/lib64/python3.11/site-packages/clquota/__init__.pyr"zNoSuchPackageException.__init__+s'€Ý×Ò˜4˜4¸7¸7¸7Ð!DÑEÔEÐEÐEÐEóN©Ú__name__Ú __module__Ú __qualname__r"©r'r&rr*s(€€€€€ðFðFðFðFðFr'rcó—eZdZd„ZdS)ÚNoSuchUserExceptioncóD—t |d|›d�¦«dS)NzNo such user (rr )r$Úusers r&r"zNoSuchUserException.__init__0s'€Ý×Ò˜4˜4¸¸¸Ð!>Ñ?Ô?Ð?Ð?Ð?r'Nr(r,r'r&r.r./s(€€€€€ð@ð@ð@ð@ð@r'r.có—eZdZd„ZdS)ÚInsufficientPrivilegesExceptioncó<—t |d¦«dS)NzInsufficient privilegesr ©r$s r&r"z(InsufficientPrivilegesException.__init__5s€Ý×Ò˜4Ð!:Ñ;Ô;Ð;Ð;Ð;r'Nr(r,r'r&r2r24s#€€€€€ð<ð<ð<ð<ðsQø€€€€€ððð  ˜lÔ7ð  ð  ð  ð  ð  ð  ð  ð  ð  ð  r'r;có—eZdZd„ZdS)ÚGeneralExceptioncó<—t ||¦«dS©Nr )r$r?s r&r"zGeneralException.__init__Qs€Ý×Ò˜4 Ñ)Ô)Ð)Ð)Ð)r'Nr(r,r'r&rKrKPs#€€€€€ð*ð*ð*ð*ð*r'rKcó‡—eZdZˆfd„ZˆxZS)ÚQuotaDisabledExceptioncóX•—tt|¦« d¦«dS)Nz&Quota disabled for all users on server)rArOr")r$rDs €r&r"zQuotaDisabledException.__init__Vs)ø€Ý Õ$ dÑ+Ô+×4Ò4Ð5]Ñ^Ô^Ð^Ð^Ð^r')r)r*r+r"rHrIs@r&rOrOUsAø€€€€€ð_ð_ð_ð_ð_ð_ð_ð_ð_r'rOcó—eZdZdZdd„ZdS)ÚUserQuotaDisabledExceptionz? Raised when quota is disabled for one particular user Ncó|—d}|r|d|zz }|r|d|zz }|r|d|zz }t ||¦«dS)NzQuota disabledz for user id %sz (home directory %s)z; %sr )r$ÚuidÚhomedirr?Úall_msgs r&r"z#UserQuotaDisabledException.__init__^sj€Ø"ˆØ ð /Ø Ð(¨3Ñ.Ñ .ˆGØ ð 8Ø Ð-°Ñ7Ñ 7ˆGØ ð (Ø �v Ñ'Ñ 'ˆGÝ×Ò˜4 Ñ)Ô)Ð)Ð)Ð)r')NNN)r)r*r+rEr"r,r'r&rRrRZs2€€€€€ððð*ð*ð*ð*ð*ð*r'rRcóv—|ddkr|dz }d}|dkrdS|D]}| |¦«rdSŒdS)zd >>> _is_sys_path('/home/username') False >>> _is_sys_path('/var/davecot') True éÿÿÿÿú/) z/root/z/usr/z/var/z/sbin/z/dev/z/bin/z/srv/z/sys/z /etc/ntp/TN)Ú startswith)ÚpathÚ sys_path_Úpath_s r&Ú _is_sys_pathr^isf€ð ˆB„x�3‚€Ø �‰ ˆØg€IØ ˆs‚{€{؈tØððˆØ �?Š?˜5Ñ !Ô !ð Ø�4�4ð ððr'cóh‡—t¦«}| ¦«Šˆfd„‰D¦«}|S)z) Return no system users uid list có^•—g|])}t‰|j¦«°‰|j‘Œ*Sr,)r^Úpw_dirÚpw_uid)Ú.0ÚusrÚpw_dicts €r&ú z#_get_users_list..�s5ø€ÐaÐaÐa¨½|ÈGÐTWÌLÔL_Ñ?`Ô?`Ða�˜”Ô$ÐaÐaÐar')rÚ get_user_dict)Úcl_pwdÚ users_uidres @r&Ú_get_users_listrjzs>ø€õ ‰WŒW€FØ×"Ò"Ñ$Ô$€GØaÐaÐaÐa°ÐaÑaÔa€Ià Ðr'ÚreturncóH—tjtjdd¬¦«}|S)zJ Check `cl_quota_inodes_inheritance` parameter in the config file Úcl_quota_inodes_inheritanceF)Ú default_val)Ú cldetectlibÚget_boolean_paramÚCL_CONFIG_FILE)Úress r&Úis_quota_inheritance_enabledrs†s%€õ Ô '­ Ô(BÐDaÐotÐ uÑ uÔ u€CØ €Jr'có`—eZdZdZdZdZdZdZdZdZ dZ d Z e d zZ d Z d „Zed „¦«Zd„Zd„Zd„Zd„Zd„Zd_d„Zd„Zd„Zd`d„Z dadedeedeedededef d„Z dbdedeedeededed d f d!„Zd"„Zd#„Z dcd$efd%„Z!d&„Z"d_d'ed zfd(„Z#d)„Z$d*„Z% d`ded+eed,eeded e&eeeeff d-„Z'ded+eed,eed e&eeffd.„Z(d/„Z)d0„Z*d e+j+fd1„Z,d2„Z-d3eed eefd4„Z.dddedeedeed e&eeffd5„Z/dddedeedeed e&eeffd6„Z0dededed e&eeffd7„Z1ded e&eeffd8„Z2dededed e&eeffd9„Z3ded e&eeffd:„Z4edeedeed e&eeeeffd;„¦«Z5dededeedeed e&eeff d<„Z6ddd=„Z7ded efd>„Z8d_d?„Z9ded@„Z:dA„Z;dB„ZdE„Z?d_dF„Z@d eAeeBeffdG„ZCd eAeeBeffdH„ZDdI„ZEdJ„ZFdK„ZGdL„ZHdM„ZIdN„ZJdO„ZKd eBe&eeffdP„ZLdQ„ZMdR„ZNdS„ZOdT„ZPdU„ZQdV„ZRdW„ZSedX„¦«ZTdY„ZUdZ„ZVd[„ZWd\„ZXd`d]„ZYd^„ZZd S)fÚ QuotaWrapperaB Base quota class for inode quotas handling * Update system quotas via setquota * Retrieves system quotas via repquota * Stores current quotas in /etc/container/cl-quotas.dat file * Maintaines /etc/container/cl-quotas.cache file with resolved quotas. That file can be read by non-privileged users z /proc/mountsz/usr/bin/quotasyncz/usr/sbin/setquotaz/usr/sbin/repquotaz%/usr/bin/getcontrolpaneluserspackagesz/etc/container/cl-quotas.datz/etc/container/cl-quotas.cacheNz.lockFcóH—| tj¦«| tj¦«| tj¦«t ¦«|_d|_i|_i|_ i|_ i|_ i|_ i|_ | ¦«|_gd¢|_t#j¦«|_| ¦«|_| |j¦«|_d|_d|_dS)N)Ú bytes_usedÚ bytes_softÚ bytes_hardÚ inodes_usedÚ inodes_softÚ inodes_hard)Ú_assert_file_existsruÚ PROC_MOUNTSÚREPQUOTAÚSETQUOTAÚlistÚ_quota_enabled_listÚ_panel_presentÚ_graceÚ_quotaÚ _device_quotaÚ_package_to_uids_mapÚ_uid_to_packages_mapÚ_uid_to_homedir_mapÚ_get_saved_data_handlerÚ_dhÚ_fieldsÚosÚgeteuidÚ_euidÚ_load_quota_devicesÚ_devicesÚ_get_mountpoint_device_mapÚ_mountpoint_device_mappedÚ_device_user_mapÚ_all_package_listr4s r&r"zQuotaWrapper.__init__£s÷€Ø × Ò ¥Ô!9Ñ:Ô:Ð:Ø × Ò ¥Ô!6Ñ7Ô7Ð7Ø × Ò ¥Ô!6Ñ7Ô7Ð7å#'¡6¤6ˆÔ Ø"ˆÔ؈Œ ؈Œ ØˆÔØ$&ˆÔ!Ø$&ˆÔ!Ø#%ˆÔ Ø×/Ò/Ñ1Ô1ˆŒØnÐnÐnˆŒ Ý”Z‘\”\ˆŒ Ø×0Ò0Ñ2Ô2ˆŒ Ø)-×)HÒ)HÈÌÑ)WÔ)WˆÔ&Ø $ˆÔà!%ˆÔÐÐr'cój—tj |¦«std|›d�¦«‚dS)z> Checks if command is present and exits if no zNo such command (rN)r�r[ÚexistsÚ RuntimeError©r[s r&r}z QuotaWrapper._assert_file_exists¹s>€õ Œw�~Š~˜dÑ#Ô#ð AÝ�,¸¸¸Ð?Ñ@Ô@Ð @ð Að Ar'có—|SrMr,r4s r&Ú __enter__zQuotaWrapper.__enter__Ás€Øˆ r'có.—| ¦«dSrM)Ú _release_lock)r$Ú_typeÚ_valueÚ _tracebacks r&Ú__exit__zQuotaWrapper.__exit__Äs€ð ×ÒÑÔÐÐÐr'cóR—| | |¦«¦«S)z9 Returns user limits converted to tuples ©Ú_convert_data_to_tuplesÚ_get_current_quotas©r$rTs r&Úget_user_limitszQuotaWrapper.get_user_limitsÉs&€ð×+Ò+¨D×,DÒ,DÀSÑ,IÔ,IÑJÔJÐJr'cóP—| | ¦«¦«S)z= Returns all user limits converted to tuples r£r4s r&Úget_all_users_limitsz!QuotaWrapper.get_all_users_limitsÏs$€ð×+Ò+¨D×,DÒ,DÑ,FÔ,FÑGÔGÐGr'cóT—| | |¬¦«¦«S)zà :param packname: Package name for get limits. If None, returns all packages, else - only supplied package Returns package limits converted to tuples (called only from main) )Úpackname©r¤Ú_get_package_quotasr#s r&Úget_package_limitszQuotaWrapper.get_package_limitsÕs)€ð ×+Ò+¨D×,DÒ,DÈgÐ,DÑ,VÔ,VÑWÔWÐWr'cóV—| | |d¬¦«¦«S)zY Returns all packages limits converted to tuples (called only from main) T©r«Ú all_packagesr¬r#s r&Úget_all_packages_limitsz$QuotaWrapper.get_all_packages_limitsÝs,€ð×+Ò+¨D×,DÒ,DÈgÐdhÐ,DÑ,iÔ,iÑjÔjÐjr'cóH—|dkrdS|dvrdS| |¦«S)z’ Preprocessed passed limit: 'default' --> '0', 'unlimited' --> -1, else calls _check_limit :param limit: :return: rÚ0)Ú unlimitedú-1r¶)Ú _check_limitr8s r&Ú_preprocess_limitzQuotaWrapper._preprocess_limitãs9€ð �IÒ Ð Ø�3Ø Ð'Ð 'Ð 'Ø�4Ø× Ò  Ñ'Ô'Ð'r'có^—|j d|¦« d¦«S)NÚpackagesú:)r‹ÚgetÚsplitr#s r&Ú_get_package_from_dhz!QuotaWrapper._get_package_from_dhïs&€ØŒx�|Š|˜J¨Ñ0Ô0×6Ò6°sÑ;Ô;Ð;r'cól—i}i}|j d¦«rÐt|j d¦«¦«dkr¥| ¦«}|j d¦«D]`}|r ||vr|j d|¦«Œ$| |¦«}t|¦«dkrŒM|d|df||<Œa|r| ¦«|  ¦«|j   ¦«D]}||vr ||||<Œd||<Œ|S)zí Retrive all available packages with their limits :param clean_dead_packages: if True - remove all nonexistent packages from cl-quotas.dat :return: Dictionary: { 'package_name': (soft_limit, hard_limit) } rºréé©r´r´) r‹Ú has_sectionÚlenÚitemsÚ_get_all_package_listÚoptionsÚ remove_optionr¾Ú _write_dataÚ_get_package_to_users_mapr‡Úkeys)r$Úclean_dead_packagesÚpackage_limits_dictÚ db_packagesÚlist_of_packagesr%Úpackage_limitss r&Ú_get_all_packages_with_limitsz*QuotaWrapper._get_all_packages_with_limitsòsj€ð!Ðàˆ Ø Œ8× Ò   Ñ +Ô +ð #µ°D´H·N²NÀ:Ñ4NÔ4NÑ0OÔ0OÐRSÒ0SÐ0SØ#×9Ò9Ñ;Ô;Ð Øœ8×+Ò+¨JÑ7Ô7ð Lð L�Ø&ð¨7Ð:JÐ+JÐ+JØ”H×*Ò*¨:°wÑ?Ô?Ð?ØØ!%×!:Ò!:¸7Ñ!CÔ!C�å�~Ñ&Ô&¨!Ò+Ð+ØØ'5°aÔ'8¸.ÈÔ:KÐ'K� ˜GÑ$Ð$Ø"ð #Ø× Ò Ñ"Ô"Ð"à ×&Ò&Ñ(Ô(Ð(ØÔ0×5Ò5Ñ7Ô7ð :ð :ˆGؘ+Ð%Ð%à/:¸7Ô/CÐ# GÑ,Ð,à/9Ð# GÑ,Ð,Ø"Ð"r'TrTÚsoftÚhardÚsaveÚ force_saveÚ only_storec ó€—| ¦«| |¦«| |¦«}}| |||¬¦«\} } | | | ¬¦«\} } | |¦«|} | | f| d| dfks|�r-|dkrã| | |¦«¦«}|rS|›d| d›d| d›d| ›d| ›d � }|j |d ¦«|z|j|<td ¦«nftj d || d| d| | |g}t|¦«td ¦«|  |¦«td|›d�¦«|rB| ||||¬¦«\}}| |||¦«td¦«|dkr|dks |dkr,|dkr&| |||¦«td ¦«|dkr%| ¦«td¦«dSdS)a6 Set limits for users * Resolve limits according to those saved in cl-quota.dat Limits are resolved in the following order: user limits --> package limits --> root user (uid=0) limits * Apply new limits when resolved limits differ from those in cache or when `force_save` is True * Write updated values to cl-quota.dat if `save` is True Always update cl-quota.dat in case both zeroes or both unlimited are provided :param uid: user id :param soft: soft limit value :param hard: hard limit value :param save: save limits to cl-quota.dat :param force_save: save limits to cl-quota.dat even if they are not changed :param only_store: store limits in memory, but do not apply them :return: None ©rTrÒrÓ©rÒrÓr{r|r´ú rxryú Úz4Your quota limits have been stored only successfullyz-uz/Your quota limits have been stored successfullyzYour quota limits for device z have been applied successfully.)rÕz+Quota limits have been stored successfully.r¶z3Global quota limits have been applied successfully.N)Ú _check_adminr¸Ú_combine_user_limitsÚ_convert_for_sys_utilityr¥Ú_get_home_deviceÚ_fetch_homedirr†r¼Úprintrur€rÚ_sync_quota_filesÚ_get_user_limits_to_saveÚ_save_user_limitsÚ_apply_all_limits)r$rTrÒrÓrÔrÕrÖÚsoft_validatedÚhard_validatedÚ soft_resolvedÚ hard_resolvedÚsoft_convertedÚhard_convertedÚcachedÚdeviceÚstdinÚcmdÚ soft_user_datÚ hard_user_dats r&Úset_user_limitzQuotaWrapper.set_user_limitsÅ€ð8 ×ÒÑÔÐð*.×)?Ò)?ÀÑ)EÔ)EÀt×G]ÒG]Ð^bÑGcÔGc˜ˆð(,×'@Ò'@ÀSÈ~ÐdrÐ'@Ñ'sÔ'sÑ$ˆ �}ð*.×)FÒ)FÈMÐ`mÐ)FÑ)nÔ)nÑ&ˆ˜ð×)Ò)¨#Ñ.Ô.¨sÔ3ˆð ˜NÐ +°°}Ô0EÀvÈmÔG\Ð/]Ò ]Ð ]ÐakÑ ]à�cŠzˆzØ×.Ò.¨t×/BÒ/BÀ3Ñ/GÔ/GÑHÔH�Øð dØ"ÐvÐv V¨LÔ%9ÐvÐv¸FÀ<Ôd  | ¦«d z} |j | d ¦«| z|j| <�Œ#|r1| |||¦«\}}| |||¦«|s| ¦«dSdS)a, Sets limits for package :param package: package name :param soft: soft limit value :param hard: hard limit value :param save: save limits to cl-quota.dat :param only_store: store limits in memory, but do not apply them :return: None T©r±N)rTr%rÒrÓrÙr{r|rÚrxryrrÛrÜ)rÝr¸r­rÊÚ!_get_saved_package_limits_if_noneÚ_save_package_limitsÚ_check_package_existsÚ_get_device_user_mapr¥rËÚ_combine_package_limitsrßÚappendÚKeyErrorrÄÚjoinr†r¼Ú_get_package_limits_to_saveÚ_flush_device_quota)r$r%rÒrÓrÔrÖrçrèrérêÚdevice_user_mapÚ cached_quotasrîÚstd_inrTrërìÚ soft_cachedÚ hard_cachedÚ soft_dataÚ hard_datas r&Úset_package_limitzQuotaWrapper.set_package_limitas#€ð( ×ÒÑÔÐð*.×)?Ò)?ÀÑ)EÔ)EÀt×G]ÒG]Ð^bÑGcÔGc˜ˆð �4ˆ<ˆ<ؘt×7Ò7ÀTÐ7ÑJÔJÐJÐJØ 4×#AÒ#AÑ#CÔ#CÐCÐCà+/×+QÒ+Qؘ¨ñ,9ô,9Ñ (ˆM˜=à × %Ò % g¨}¸mÑ LÔ LÐ LØ ˆFà×)Ò)¨'Ñ2Ô2ð Ø ˆFð×3Ò3Ñ5Ô5ˆØ×0Ò0Ñ2Ô2ˆ Ø%×*Ò*Ñ,Ô,ð Yñ YˆF؈FØ×5Ò5°gÑ>Ô>ð ð �ؘo¨fÔ5Ð5Ð5Øà/3×/KÒ/KØ W°>Èð0Lñ0Xô0XÑ,� ˜}ð26×1NÒ1NÐTaÐhuÐ1NÑ1vÔ1vÑ.� ð Ø/<¸SÔ/AÀ-Ô/PÐR_Ð`cÔRdÐerÔRs �KØ&¨Ð7¸KÈÐ;UÒUÐUØŸ š Ø"ðAðAØ,¨SÔ1°,Ô?ðAðAØBOÐPSÔBTÐUaÔBbðAðAà-ðAðAà0>ðAðAñôðøøõ  ðððØ�Dðøøøõ�6‰{Œ{˜aÒÐØŸ)š) FÑ+Ô+¨dÑ2�Ø-1Ô-?×-CÒ-CÀFÈBÑ-OÔ-OÐRXÑ-X�Ô" 6Ñ*ùà ð EØ#'×#CÒ#CÀGÈ^Ð]kÑ#lÔ#lÑ ˆI�yØ × %Ò % g¨y¸)Ñ DÔ DÐ Dàð 'Ø × $Ò $Ñ &Ô &Ð &Ð &Ð &ð 'ð 'sÅA!F7Æ7 GÇGcóz—| ¦«| d¬¦«}| ¦«D]S\}\}}tj|vs"tj�tj|vs|dvsd|vrŒ9| |||dd¬¦«ŒT| ¦«| ¦«dS)zN Read limits from file and applies them to packages and users T)rÌN)ú.z..úF)rÔrÖ) rÝrÑrÅr�ÚsepÚaltseprÚ_remove_unexisting_usersrÿ)r$rÐr%rÒrÓs r&Ú synchronizezQuotaWrapper.synchronizeªsÛ€ð ×ÒÑÔÐà×;Ò;ÐPTÐ;ÑUÔUˆØ%3×%9Ò%9Ñ%;Ô%;ð Uð UÑ !ˆG‘\�d˜Dõ”˜'Ð!Ð!Ýœ Ð-µ"´)¸wÐ2FÐ2FØ +Ð-Ð-Ø Ð(Ð(ØØ × "Ò " 7¨D°$¸UÈtÐ "Ñ TÔ TÐ TÐ Tà ×%Ò%Ñ'Ô'Ð'Ø × Ò Ñ"Ô"Ð"Ð"Ð"r'cóü‡‡—‰ ¦«‰ ¦«Šˆˆfd„t‰ ¦«t¬¦«D¦«}‰ d¦«‰ tj¦«}tj |tj ¬¦«}|  |¦«‰  tj¦«‰ ¦«dS)zF Caches the limits to non-privileged user to see them cóB•‡—g|]Љgˆˆfd„‰jD¦«z‘ŒS)có,•—g|]}‰‰|‘ŒSr,r,)rcÚfieldÚcurrent_quotasÚks €€r&rfz;QuotaWrapper.save_user_cache...Ñs#ø€ÐFÐFÐF°�> !Ô$ UÔ+ÐFÐFÐFr'©rŒ)rcrrr$s @€€r&rfz0QuotaWrapper.save_user_cache..ÐsKøø€ð ð ð àðˆCÐFÐFÐFÐFÐF¸¼ÐFÑFÔFÑ Fð ð ð r')ÚkeyT)ÚquotingN)rÝr¥ÚsortedrËÚintÚ_get_global_lockÚ_prepare_writerruÚ CACHEFILEÚcsvÚwriterÚ QUOTE_MINIMALÚ writerowsÚ _end_writerr�)r$Ú cache_contentÚ file_handlerÚcsv_outrs` @r&Úsave_user_cachezQuotaWrapper.save_user_cacheÆs÷øø€ð ×ÒÑÔÐð×1Ò1Ñ3Ô3ˆð ð ð ð ð å˜N×/Ò/Ñ1Ô1µsÐ;Ñ;Ô;ð ñ ô ˆ ð ×Ò˜dÑ#Ô#Ð#Ø×+Ò+­LÔ,BÑCÔCˆ Ý”*˜\µ3Ô3DÐEÑEÔEˆØ×Ò˜-Ñ(Ô(Ð(Ø ×Ò�Ô/Ñ0Ô0Ð0Ø ×ÒÑÔÐÐÐr'Ú skip_rootcóÆ—| ¦« ¦«D]%}|dkr|rŒ | |dddd¬¦«Œ&| ¦«dS)z=Set limits for all users. Skip root user if skip_root is Truer´NFT)rÒrÓrÔrÖ)Ú_get_uid_to_packages_maprËrórÿ)r$r&rTs r&ræzQuotaWrapper._apply_all_limitsÜsv€à×0Ò0Ñ2Ô2×7Ò7Ñ9Ô9ð Xð XˆCØ�cŠzˆz˜iˆzØØ × Ò  ¨$°TÀÐRVÐ Ñ WÔ WÐ WÐ WØ × Ò Ñ"Ô"Ð"Ð"Ð"r'cóÖ—d}|j ¦«D]/}tjd|g}t ||j|¬¦«d}Œ0|r| ¦«i|_dS)zWrite all device quotas to diskFz-bu)rTN)r†rËrur€rrã)r$Úquotas_writtenrîrðs r&rÿz QuotaWrapper._flush_device_quotaäs~€à$ˆàÔ(×-Ò-Ñ/Ô/ð "ð "ˆFÝÔ(¨%°Ð8ˆCÝ ˜ DÔ$6°vÔ$>Ð ?Ñ ?Ô ?Ð ?Ø!ˆNˆNà ð %Ø × "Ò "Ñ $Ô $Ð $àˆÔÐÐr'rîcó´—|�8t|¦«}| ¦«dkrdStj|g}ntjdg}t |¦«dS)a In order to sync inodes limits in kernel with limits in user.quota file run `quotasync` command. Otherwise `repquota` called right after `setquota` may return old limits existed before `setquota` call. Skipped on the XFS filesystem because XFS does not require a separate quota synchronization step as it handles these operations in real-time. Additionally, the specific functionality required by `quotasync` to sync the disk quota information is not implemented, resulting in an error. NÚxfsz-a)rÚlowerruÚ QUOTASYNCr)r$rîÚfs_typerðs r&rãzQuotaWrapper._sync_quota_filesòs_€ð Ð Ý)¨&Ñ1Ô1ˆGØ�}Š}‰Œ %Ò'Ð'Ø�ÝÔ)¨6Ð2ˆCˆCåÔ)¨4Ð0ˆCÝ�CÑÔÐÐÐr'có"—|j d¦«rt|j d¦«D]C} | |¦«Œ#t$r|j d|¦«YŒ@wxYw| ¦«dSdS)zARemove all records from cl-quota.dat for users which do not existÚusersN)r‹rÃrÇrár.rÈrÉr¦s r&r z%QuotaWrapper._remove_unexisting_userss°€à Œ8× Ò  Ñ (Ô (ð Ø”x×'Ò'¨Ñ0Ô0ð 9ð 9�ð9à×'Ò'¨Ñ,Ô,Ð,Ð,øÝ*ð9ð9ð9Ø”H×*Ò*¨7°CÑ8Ô8Ð8Ð8Ð8ð9øøøà × Ò Ñ Ô Ð Ð Ð ð ð s¸AÁ%A6Á5A6cóT— | |¦«dS#t$rYdSwxYw)zCheck whether package existsTF)rÊrr#s r&røz"QuotaWrapper._check_package_existssF€ð Ø × *Ò *¨7Ñ 3Ô 3Ð 3ð�4øõ&ð ð ð Ø�5�5ð øøøs ‚™ '¦'rçrècóØ—| |¬¦«\}}| |||¬¦«\}}| |dd¬¦«\} } || ks|r|�|}|| ks|r|�|}||fS)zè Derive package limit values to save to cl-quota.dat If None passed as limit to method, then replace it by the user's value from cl-quota.dat Update cl-quota.dat only if the derivation result changes ©rTrØN)Ú_get_user_limitsrÞ) r$rTrçrèrÕrñròrérêÚsoft_none_resolvedÚhard_none_resolveds r&räz%QuotaWrapper._get_user_limits_to_saves£€ð(,×'<Ò'<ÀÐ'<Ñ'EÔ'EÑ$ˆ �}à'+×'@Ò'@ÀSÈ~ÐdrÐ'@Ñ'sÔ'sÑ$ˆ �}Ø15×1JÒ1JÈsÐY]ÐdhÐ1JÑ1iÔ1iÑ.ÐÐ.à Ð.Ò .Ð .°:Ð .À.ÐB\Ø*ˆMØ Ð.Ò .Ð .°:Ð .À.ÐB\Ø*ˆMà˜mÐ+Ð+r'cóT—| |¬¦«\}}|�|n|}|�|n|}||fS)z3Derive package limit values to save to cl-quota.dat©r%)Ú_get_package_limits)r$r%rçrèÚp_softÚp_hards r&rþz(QuotaWrapper._get_package_limits_to_save0sF€ð×1Ò1¸'Ð1ÑBÔB‰ˆ�ð$2Ð#=��À6ˆØ#1Ð#=��À6ˆØ�vˆ~Ðr'cóv—|j€,dtddg¦« ¦«k|_|jS)z6 Return True if control panel present NÚUnknownz/usr/bin/cldetectz--detect-cp-nameonly)rƒrÚrstripr4s r&Ú_check_present_panelz!QuotaWrapper._check_present_panel:s>€ð Ô Ð &Ø"+­{Ð}|d|vr g||d<||d |d¦«Œ?||_|jS)zF Returns dictionary mapping devices to lists of users NrrÁ)r”Ú_get_list_of_uidsrûràrárü)r$Ú devices_mapÚdevice_user_pairsrTÚpairs r&rùz!QuotaWrapper._get_device_user_map[sü€ð Ô Ð ,ØÔ(Ð (؈ ØÐØ×)Ò)Ñ+Ô+ð ð ˆCð Ø!×(Ò(¨$×*?Ò*?À×@SÒ@SÐTWÑ@XÔ@XÑ*YÔ*YÐ[^Ð)_Ñ`Ô`Ð`Ð`øÝð ð ð Ø�ð øøøà%ð 1ð 1ˆDØ�AŒw˜kÐ)Ð)Ø')� ˜D œGÑ$Ø ˜˜QœÔ × 'Ò '¨¨Q¬Ñ 0Ô 0Ð 0Ð 0Ø +ˆÔØÔ$Ð$sª=A(Á( A5Á4A5r9có´—|�|dkr|Stjd¦«}| |¦«}|st|¦«‚| d¦«S)Nr¶z(\d+)rÁ)ÚreÚcompileÚsearchr6Úgroup)r$r9Ú limit_patternÚ pattern_matchs r&r·zQuotaWrapper._check_limitos`€Ø ˆ=˜E TšM˜M؈LÝœ  8Ñ,Ô,ˆ Ø%×,Ò,¨UÑ3Ô3ˆ Øð 7Ý/°Ñ6Ô6Ð 6Ø×"Ò" 1Ñ%Ô%Ð%r'cóv—|dkr3| |||¬¦«\}}|dkr|nd|dkr|nd}}||fS| |||¬¦«\}}| |¦«D]}| |||¬¦«\}}Œ| d||¬¦«\}}|dkr|nd|dkr|nd}}||fS)a Determines user limits by resolving them according to the limits inheritance rule: user limits ---(overridden by provided as method param if provided not None)---> ---> package limits ---> root user (uid=0) limits uid: user id soft: Optional[str] = None: limit value, can be: * None -- value not passed * "-1" -- unlimited * "0" -- default (next value from hierarchy should be considered) * "1", "2", ... -- precice limit values hard: soft: Optional[str] = None: limit value, values range the same as for soft return: Tuple[str, str]: (soft_limit, hard_limit), they can be: * "-1" -- unlimited * "1", "2", ... -- precice limit values r´rØr¶)r%rÒrÓ)Ú_get_user_limits_override_noner(Ú$_get_package_limits_override_defaultÚ!_get_user_limits_override_default)r$rTrÒrÓr%s r&rÞz!QuotaWrapper._combine_user_limitsxs€ð$ �#Š:ˆ:Ø×<Ò<ÀÈ4ÐVZÐ<Ñ[Ô[‰JˆD�$Ø"&¨#¢+ +˜$˜$°4ÀÈÂÀ¸¸ÐRV�$ˆDؘ�:Ð à×8Ò8¸SÀtÐRVÐ8ÑWÔW‰ ˆˆdà×4Ò4°SÑ9Ô9ð jð jˆGØ×BÒBÈ7ÐY]ÐdhÐBÑiÔi‰JˆD�$�$à×;Ò;ÀÈ$ÐUYÐ;ÑZÔZ‰ ˆˆdØ" cšk˜k�d�d¨t¸TÀSº[¸[°T°TÈdˆdˆØ�TˆzÐr'có¤—| |¬¦«\}}| |�|n|¬¦«}| |�|n|¬¦«}||fS)aGet user limits from cl-quota.dat. If limit is None, then override it by user's limit :param str uid: user id :param Optional[str] soft: limit value, can be: * None -- value not passed, should be overridden by user's limit * "-1" -- unlimited * "0" -- default (next value from hierarchy should be taken) * "1", "2", ... -- values :param Optional[str] hard: limit values same as for soft :return Tuple[str, str]: derived limits r4N©r9©r5r·©r$rTrÒrÓÚ user_softÚ user_hards r&rWz+QuotaWrapper._get_user_limits_override_none˜sg€ð $×4Ò4¸Ð4Ñ=Ô=ш �9à× Ò ¨tÐ/? t tÀYÐ ÑOÔOˆØ× Ò ¨tÐ/? t tÀYÐ ÑOÔOˆØ�TˆzÐr'có´—| |¬¦«\}}| |dkr|n|¬¦«}| |dkr|n|¬¦«}||fS)aºGet user limits from cl-quota.dat. If limit is default, then override it by user's limit :param str uid: user id :param Optional[str] soft: limit value, can be: * "-1" -- unlimited * "0" -- default (next value from hierarchy should be taken) * "1", "2", ... -- values :param Optional[str] hard: limit values same as for soft :return Tuple[str, str]: derived limits r4r´r[r\r]s r&rYz.QuotaWrapper._get_user_limits_override_defaultªsm€ð $×4Ò4¸Ð4Ñ=Ô=ш �9à× Ò ¨t°sª{¨{ t tÀ Ð ÑJÔJˆØ× Ò ¨t°sª{¨{ t tÀ Ð ÑJÔJˆØ�TˆzÐr'có¼— |j d|¦« d¦«\}}n&#tjtjf$rd\}}YnwxYw||fS)z*Try to get user's limits from cl-quota.datr1r»rÂ)r‹r¼r½rFÚNoSectionErrorÚ NoOptionError)r$rTr^r_s r&r5zQuotaWrapper._get_user_limits»sp€ð ,Ø#'¤8§<¢<°¸Ñ#=Ô#=×#CÒ#CÀCÑ#HÔ#HÑ ˆI�y�yøÝÔ+­\Ô-GÐHð ,ð ,ð ,Ø#+Ñ ˆI�y�y�yð ,øøøà˜)Ð#Ð#s‚14´ AÁAcó´—| |¬¦«\}}| |dkr|n|¬¦«}| |dkr|n|¬¦«}||fS)zeGet package limits from cl-quota.dat. If passed limit is default, then override it by package's limitr9r´r[)r:r·©r$r%rÒrÓÚ pack_softÚ pack_hards r&rXz1QuotaWrapper._get_package_limits_override_defaultÃsk€à#×7Ò7ÀÐ7ÑHÔHш �9Ø× Ò °D¸C²K°K y yÀTÐ ÑJÔJˆØ× Ò °D¸C²K°K y yÀTÐ ÑJÔJˆØ�TˆzÐr'cóŠ— | |¦«\}}n&#tjtjf$rd\}}YnwxYw||fS)z-Try to get package's limits from cl-quota.datrÂ)r¾rFrbrc©r$r%rÒrÓs r&r:z QuotaWrapper._get_package_limitsÊs]€ð "Ø×2Ò2°7Ñ;Ô;‰JˆD�$�$øÝÔ+­\Ô-GÐHð "ð "ð "Ø!‰JˆD�$�$�$ð "øøøà�TˆzÐs ‚› >½>có*—|dkrd}|dkrd}||fS)zAConverts limits for setquota utility which threats 0 as unlimitedr¶r´r,rÙs r&rßz%QuotaWrapper._convert_for_sys_utilityÒs*€ð �4Š<ˆ<؈DØ �4Š<ˆ<؈DØ�TˆzÐr'có —| |¬¦«\}}tr|t¦«rn| |¬¦«}||kr8| |d¬¦«}||dx}} ||dx}} n3| |¬¦«\} } n| |¬¦«\} } |dkr|n|�|n| }|dkr|n|�|n| }| d||¬ ¦«\}}|dkr|nd |dkr|nd }}||fS) z[ Determines package limits taking into account saved user and default ones r4Tr°r{r|r9r´NrØr¶)r5ÚIS_DArsÚ_get_da_real_packager­r:rY) r$r%rTrÒrÓÚu_softÚu_hardÚda_real_packageÚda_real_quotasr;r<s r&rúz$QuotaWrapper._combine_package_limitsÛsT€ð ×.Ò.°3Ð.Ñ7Ô7‰ˆ�å ð GÕ1Ñ3Ô3ð Gð#×7Ò7¸CÐ7Ñ@Ô@ˆOØ 'Ò)Ð)Ø!%×!9Ò!9À?ÐaeÐ!9Ñ!fÔ!f�Ø .¨Ô ?À Ô NÐN��vØ .¨Ô ?À Ô NÐN��v�và!%×!9Ò!9À'Ð!9Ñ!JÔ!J‘�˜˜à!×5Ò5¸gÐ5ÑFÔF‰NˆF�Fð   3š˜ˆvˆv°TÐ5E¨T¨TÈ6ˆØ 3š˜ˆvˆv°TÐ5E¨T¨TÈ6ˆð×;Ò;ÀÈ$ÐUYÐ;ÑZÔZ‰ ˆˆdØ" cšk˜k�d�d¨t¸TÀSº[¸[°T°TÈdˆdˆØ�TˆzÐr'cóü— | |¦«\}}|€|dkr|}|€|dkr|}n!#tjtjf$rYnwxYw| |¦«}| |¦«}||fS)zF Applies saved package limits if none has been passed Nr´)r¾rFrbrcr·res r&röz.QuotaWrapper._get_saved_package_limits_if_noneús£€ð Ø#'×#<Ò#<¸WÑ#EÔ#EÑ ˆI�y؈|  ¨SÒ 0Ð 0Ø �؈|  ¨SÒ 0Ð 0Ø �øøÝÔ+­\Ô-GÐHð ð ð Ø ˆDð øøøà× Ò  Ñ&Ô&ˆØ× Ò  Ñ&Ô&ˆØ�TˆzÐs‚,/¯A Á A có¶—t¦« t|¦«¦«d}tj¦« |¦«S)z€ Get real package name for DA user :param str uid: user id :return str: retrieved package name r)rÚ get_namesrÚ clcontrollibÚ DirectAdminÚ_get_user_package)r$rTÚusernames r&rmz!QuotaWrapper._get_da_real_package sC€õ‘7”7×$Ò$¥S¨¡X¤XÑ.Ô.¨qÔ1ˆÝÔ'Ñ)Ô)×;Ò;¸HÑEÔEÐEr'có—|jdkr| ¦«S|js| ¦«|_|rB ||j|iS#t$r%| |¦«t |¦«‚wxYw|jS)z� Retrieves current quotas. If euid == 0, use data from repquota utility, else from /etc/container/cl-quotas.cache file r)r�Ú_load_user_cacher…Ú_load_current_quotasrüÚ_check_if_quota_enabledr.r¦s r&r¥z QuotaWrapper._get_current_quotass¤€ð Œ:˜Š?ˆ?Ø×(Ò(Ñ*Ô*Ð *ØŒ{ð 6à×3Ò3Ñ5Ô5ˆDŒKØ ð /ð /ؘTœ[¨Ô-Ð.Ð.øÝð /ð /ð /Ø×,Ò,¨SÑ1Ô1Ð1Ý)¨#Ñ.Ô.Ð.ð /øøøðŒ{Ðs ÁAÁ/Bcó —i}|r| ¦«}n| ¦«}|D�](}dg} |tkr2|j dd¦« d¦«\}}n1|j d|¦« d¦«\}}| |¦«}| |¦«}|dkrd}|dkrd}| ||g¦«n8#tj tj f$r| ddg¦«YnwxYw|  |  ||¦«¦«�Œ*|r( |||iS#t$rt|¦«‚wxYw|S)ab Prepares package limits data for outputting (call only from get_package_limits/get_all_packages_limits - main) :param packname: Package name for get limits. If present, function returns limits only for this package, else - all packages :param all_packages: If False reads only used and admin's packages, True - all packages (including reseller packages without users) :return Dictionary of package limits: {package_name: {'inodes_used': 'xxx', 'inodes_soft': 'yyy', 'inodes_hard': 'zzz'} ú-r1r´r»rºr¶)rÆÚ_get_list_of_packagesÚVE_DEFAULT_PACKAGEr‹r¼r½r·ÚextendrFrbrcÚupdateÚ _populaterür) r$r«r±ÚqrÏr%ÚvaluesrÒrÓs r&r­z QuotaWrapper._get_package_quotas&s½€ð ˆØ ð <à#×9Ò9Ñ;Ô;Ð Ð ð $×9Ò9Ñ;Ô;Ð Ø'ð 6ñ 6ˆGØ�UˆFð *ØÕ0Ò0Ð0ð"&¤§¢¨g°sÑ!;Ô!;×!AÒ!AÀ#Ñ!FÔ!F‘J�D˜$˜$à!%¤§¢¨j¸'Ñ!BÔ!B×!HÒ!HÈÑ!MÔ!M‘J�D˜$Ø×(Ò(¨Ñ.Ô.�Ø×(Ò(¨Ñ.Ô.�ؘ4’<�<Ø�Dؘ4’<�<Ø�DØ— ’ ˜t T˜lÑ+Ô+Ð+Ð+øÝ Ô/µÔ1KÐLð *ð *ð *Ø— ’ ˜s C˜jÑ)Ô)Ð)Ð)Ð)ð *øøøà �HŠH�T—^’^ G¨VÑ4Ô4Ñ 5Ô 5Ð 5Ñ 5Ø ð 7ð 7Ø  ! H¤+Ð.Ð.øÝð 7ð 7ð 7Ý,¨XÑ6Ô6Ð6ð 7øøøàˆs·B?C7Ã72D,Ä+D,Å E'Å'Fc ó–‡—|tttˆfd„t|jdd…¦«¦«¦«¦«iS)Ncó0•—|d‰|dfS©NrÁrr,)ÚxÚdatas €r&úz(QuotaWrapper._populate..Usø€°°!´°d¸1¸Q¼4´jÐ/A€r'é)rBr�ÚmapÚ enumeraterŒ)r$ÚitemrŠs `r&rƒzQuotaWrapper._populateTsHø€Ø•d�4¥Ð%AÐ%AÐ%AÐ%AÅIÈdÌlÐ[\Ð[]Ð[]ÔN^ÑD_ÔD_Ñ `Ô `ÑaÔaÑbÔbÐcÐcr'cóh—t| ¦« ¦«¦«SrM)r�rÊrËr4s r&rz"QuotaWrapper._get_list_of_packagesWs(€Ý�D×2Ò2Ñ4Ô4×9Ò9Ñ;Ô;Ñ<Ô<Ð#tttf$r$}t dt |¦«z¦«‚d}~wwxYwt t¦«}t t¦«|_|  ¦«D]f\}}t |¦«}|d�|dnt}||  |¦«|j|  |¦«Œg td¬¦«}n8#ttf$r$}t dt |¦«z¦«‚d}~wwxYw|D]!}|  |�|ntg¦«Œ"|  tg¦«|S)a Retrieve package-uids map from cpapi. Only for custom panels. See LU-610 for details. Null packages coming from cpapi are considered to be 'default' package. :return: Dictionary with data. Example response: {'default': ['1038', '1043', '1046'], 'res1_pack1': ['1044'], 'pack1': ['1042']} Coorresponding self._uid_to_packages_map value: {'1038': ['default'], '1042': ['pack1'], '1043': ['default'], '1044': ['res1_pack1'], '1046': ['default']} z%s. Can not get usersNr%T©Ú raise_excú%s. Can not get admin packages)rÚOSErrorrrrrCrr�rˆrÅr€rûrÚ setdefault) r$Úusers_packagesrIÚpackages_usersrTÚuid_dataÚs_uidr%Ú admin_pkgss r&Ú_get_packages_uids_from_cpapiz*QuotaWrapper._get_packages_uids_from_cpapi{s£€ð LÝ'™\œ\ˆNˆNøÝÕ3µ]ÐCð Lð Lð LÝ'Ð(?Å3ÀqÁ6Ä6Ñ(JÑKÔKÐ Køøøøð Løøøõ%¥TÑ*Ô*ˆÝ$/µÑ$5Ô$5ˆÔ!à+×1Ò1Ñ3Ô3ð =ð =‰MˆC�ݘ‘H”HˆEØ-5°iÔ-@Ð-L�h˜yÔ)Ð)ÕRdˆGØ ˜7Ô #× *Ò *¨5Ñ 1Ô 1Ð 1Ø Ô % eÔ ,× 3Ò 3°GÑ <Ô <Ð <Ð <ð UÝ'°$Ð7Ñ7Ô7ˆJˆJøÝÕ3Ð4ð Uð Uð UÝ'Ð(HÍCÐPQÉFÌFÑ(SÑTÔTÐ Tøøøøð Uøøøð"ð bð bˆGØ × %Ò %°Ð1D g gÕJ\Ð^`Ñ aÔ aÐ aÐ aà×!Ò!Õ"4°bÑ9Ô9Ð9àÐs,‚‘A ¨AÁA Ã8D Ä D>ÄD9Ä9D>có—i}|jdkr|S| ¦«sTtttt ¦«¦«¦«|t <d„|t D¦«|_|S| ¦«S)zÐ Gets map of packages and users :rtype dict :return Dictionary with data. Example: {'default': ['1038', '1043', '1046'], 'res1_pack1': ['1044'], 'pack1': ['1042']} rcó —i|] }|tg“Œ Sr,)r€)rcÚis r&ú z8QuotaWrapper._load_package_uids_data..³s€Ð(gÐ(gÐ(gÀQ¨Õ-?Ð,@Ð(gÐ(gÐ(gr') r�r@r�r�rCrjr€rˆr¤)r$rºs r&r“z$QuotaWrapper._load_package_uids_data¦sƒ€ðˆØ Œ:˜Š?ˆ?؈Oà×(Ò(Ñ*Ô*ð Ý+/µµC½Ñ9JÔ9JÑ0KÔ0KÑ+LÔ+LˆHÕ'Ñ (Ø(gÐ(gÈ(ÕSeÔJfÐ(gÑ(gÔ(gˆDÔ %؈Oà×1Ò1Ñ3Ô3Ð3r'cóf—|jr|jS g|_td¬¦«}|D]}|j |¦«Œn8#ttf$r$}t dt |¦«z¦«‚d}~wwxYw td¬¦«}| ¦«D]!}|D]}|j |¦«ŒŒ"n8#ttf$r$}t dt |¦«z¦«‚d}~wwxYwt|jvr|j t¦«|jS)zm Retrives all (root and resellers) panel package list :return: List of package names TršrœNz!%s. Can not get reseller packages) r•rrûr�rrrCrr…r€)r$Úlist_admin_packagesr%rIÚdict_resellers_packagesÚ packages_lists r&rÆz"QuotaWrapper._get_all_package_list¸s…€ð Ô !ð *ØÔ)Ð )ð UØ%'ˆDÔ "Ý"0¸4Ð"@Ñ"@Ô"@Ð Ø.ð 7ð 7�ØÔ&×-Ò-¨gÑ6Ô6Ð6Ð6ð 7øåÕ3Ð4ð Uð Uð UÝ'Ð(HÍCÐPQÉFÌFÑ(SÑTÔTÐ Tøøøøð Uøøøð XÝ&8À4Ð&HÑ&HÔ&HÐ #Ø!8×!?Ò!?Ñ!AÔ!Að ;ð ;� Ø,ð;ð;�GØÔ*×1Ò1°'Ñ:Ô:Ð:Ð:ð;ð ;øõÕ3Ð4ð Xð Xð XÝ'Ð(KÍsÐSTÉvÌvÑ(VÑWÔWÐ Wøøøøð Xøøøõ  TÔ%;Ð ;Ð ;Ø Ô "× )Ò )Õ*<Ñ =Ô =Ð =ØÔ%Ð%s0�6AÁA<ÁA7Á7A<ÂACÃC<ÃC7Ã7C<c óÀ‡‡—‰ ¦«D]FŠ ttˆˆfd„|jdd…¦«¦«}|‰‰<Œ7#t$rYŒCwxYw‰S)zI Convert dict to tuples for passing to printing routines có$•—|‰‰|fSrMr,)r‰rŠrs €€r&r‹z6QuotaWrapper._convert_data_to_tuples..Ùsø€¨a°°c´¸1´Ð->€r'rŒN)rËÚtupler�rŒrü)r$rŠÚentryrs ` @r&r¤z$QuotaWrapper._convert_data_to_tuplesÓs�øø€ð—9’9‘;”;ð ð ˆCð Ý�cÐ#>Ð#>Ð#>Ð#>Ð#>ÀÄÈaÈbÈbÔAQÑRÔRÑSÔS�Ø!��S‘ � øÝð ð ð Ø�ð øøøàˆ sš3AÁ AÁAc 󌇗i}d}‰j}tjdg}t|¦«}t jdtj¦«}| ¦«D�]¾}| d¦«�r|sŒ|  ¦«}t|¦«dkr‰  |¦«}|ddd…} | dkrŒo ||vr‰  |¦«}||vrn‰  ‰ | ¦«|¦«rEtt!t#ˆfd „t%|d d…¦«¦«¦«¦«|| <Œü#t&t(t*f$rY�ŒwxYw| d ¦«r1|| d ¦«d… ¦«}�Œ`d |vrZ| |¦«} | rC‰j tt!t#d„| ¦«¦«¦«¦«�ŒÀ| ‰ ¦«¦«|S)zZ Gets current quota settings from repqouta utility for further processing Nz-unaz2(block|inode)\sgrace\stime:?\s(\d[\w:]+)(?:;|$|\s)ú#érrÁr´có:•—‰j|d|dfS©NrrÁr)r‰r$s €r&r‹z3QuotaWrapper._load_current_quotas..÷sø€¸4¼<ÈÈ!ÌÔ;MÈqÐQRÌtÐ:T€r'rÀz***z/devÚgracecóF—|d ¦«|dfSrµ)r-)r‰s r&r‹z3QuotaWrapper._load_current_quotas..ÿs€ÀÀ1ÄÇÂÁÄÈqÐQRÌtÐ@T€r')r‘rurrrPrQÚ IGNORECASEÚ splitlinesrZr½rÄÚ#_remove_redundant_fields_from_inputÚ_find_unknown_deviceÚ_is_home_devicerárBr�r�rŽrüÚ IndexErrorr.ÚfindÚstripÚfindallr„r‚Ú _add_default) r$r„rîÚdevicesrðrŠÚgrace_regex_patternÚlineÚpartsrTÚfounds ` r&r{z!QuotaWrapper._load_current_quotasßsJø€ð ˆØˆØ”-ˆÝÔ$ fÐ-ˆÝ˜3ÑÔˆÝ œjÐ)^Õ`bÔ`mÑnÔnÐØ—O’OÑ%Ô%ð añ aˆDØ�Š˜sÑ#Ô#ñ aØðØØŸ š ™ œ �Ý�u‘:”: ’?�?Ø ×DÒDÀUÑKÔK�EؘA”h˜q˜r˜r”l�ؘ#’:�:ØðØ WÐ,Ð,Ø!%×!:Ò!:¸6Ñ!BÔ!B˜Ø Ð(Ð(¨T×-AÒ-AÀ$×BUÒBUÐVYÑBZÔBZÐ\bÑ-cÔ-cÐ(Ý!%¥d­3Ð0TÐ0TÐ0TÐ0TÕW`ÐafÐghÐgiÐgiÔajÑWkÔWkÑ+lÔ+lÑ&mÔ&mÑ!nÔ!n˜˜#™øøÝ ¥*Õ.AÐBðððØ‘Hðøøøà—’ Ñ'Ô'ð aؘdŸiši¨Ñ/Ô/Ð0Ð0Ô1×7Ò7Ñ9Ô9�‘ؘD��Ø+×3Ò3°DÑ9Ô9�ØðaØ”K×&Ò&¥t­DµÐ6TÐ6TÐW\Ñ1]Ô1]Ñ,^Ô,^Ñ'_Ô'_Ñ`Ô`Ð`ùØ �Š�×"Ò"Ñ$Ô$Ñ%Ô%Ð%؈sà B EÅE4Å3E4có–‡—|dd…}tjd¦«Š| ˆfd„|dd…D¦«¦«|S)NrÀz^\d+$có>•—g|]}‰ |¦«¯|‘ŒSr,)rR)rcrÚis_digit_patterns €r&rfzDQuotaWrapper._remove_redundant_fields_from_input..s-ø€Ð LÐ LÐ L�uÐ-=×-DÒ-DÀUÑ-KÔ-KÐ LˆUÐ LÐ LÐ Lr')rPrQr�)r$rÅÚstripped_partsrÉs @r&rºz0QuotaWrapper._remove_redundant_fields_from_inputs`ø€Ø˜r ˜rœˆÝœ: hÑ/Ô/ÐØ×ÒØ LÐ LÐ LÐ L  a b b¤ Ð LÑ LÔ Lñ Nô Nð NàÐr'cóò—t|j¦«dkr5|j d„tj¦«D¦«¦« |j|S#t $rt |¦«‚wxYw)NrcóB—i|]}t|j¦«|j“ŒSr,)rCrbra)rcr°s r&r¨z/QuotaWrapper._fetch_homedir.. s'€Ð,iÐ,iÐ,iÐQV­S°´Ñ->Ô->ÀÄ Ð,iÐ,iÐ,ir')rÄr‰r‚ÚpwdÚgetpwallrür.r¦s r&rázQuotaWrapper._fetch_homedir s„€Ý ˆtÔ'Ñ (Ô (¨AÒ -Ð -Ø Ô $× +Ò +Ð,iÐ,iÕZ]ÔZfÑZhÔZhÐ,iÑ,iÔ,iÑ jÔ jÐ jð +ØÔ+¨CÔ0Ð 0øÝð +ð +ð +Ý% cÑ*Ô*Ð *ð +øøøs Á AÁA6có —i}ttj¦«}tjd¦«}|D]æ}| d¦«rŒ| |¦«}|d}d|di}|D]~}| d¦«s| d¦«r| d¦«d|d <ŒK| d ¦«r| d¦«d|d <Œ||vr|| |¦«Œà|g||<Œç| ¦«t|¦«dkrt¦«‚|S) aj Gets mounted filesystems list and picks ones with quota on Example of returned data structure: {'/dev/mapper/VolGroup-lv_root': [ {'mountpoint': '/', 'quota_file': 'quota.user', 'quota_type': 'vfsv0'}, {'mountpoint': '/var', 'quota_file': 'quota.user', 'quota_type': 'vfsv0'} ], '/dev/mapper/VolGroup-lv_root2': [ {'mountpoint': '/', 'quota_file': 'quota.user', 'quota_type': 'vfsv0'}, {'mountpoint': '/var', 'quota_file': 'quota.user', 'quota_type': 'vfsv0'} ] } z |,zrootfs /rÚ mountpointrÁz usrquota=zusruota=ú=Ú quota_filezjqfmt=Ú quota_type) Úopenrur~rPrQrZr½rûÚcloserÄrO) r$rÂÚproc_mounts_streamÚ split_pattrÄÚ line_splitedrîÚmountpoint_dataÚline_splited_elements r&r�z QuotaWrapper._load_quota_devicessy€ðˆÝ!¥,Ô":Ñ;Ô;ÐÝ”Z Ñ'Ô'ˆ Ø&ð 4ð 4ˆDØ�Š˜zÑ*Ô*ð ØØ%×+Ò+¨DÑ1Ô1ˆLØ! !”_ˆFØ+¨l¸1¬oÐ>ˆOØ(4ð Wð WÐ$Ø'×2Ò2°;Ñ?Ô?ðWÐCW×CbÒCbÐcmÑCnÔCnðWØ4H×4NÒ4NÈsÑ4SÔ4SÐTUÔ4V�O LÑ1Ð1Ø)×4Ò4°XÑ>Ô>ðWØ4H×4NÒ4NÈsÑ4SÔ4SÐTUÔ4V�O LÑ1øØ˜Ð Рؘ”×&Ò& Ñ7Ô7Ð7Ð7à#2Ð"3�˜‘�Ø× Ò Ñ"Ô"Ð"Ý ˆw‰<Œ<˜1Ò Ð å(Ñ*Ô*Ð *؈r'có>‡‡—i} ‰ ¦«ttj¦«}t j|d¬¦«}n_#t tf$rKt‰j ¦«t  ‰j d¦«icY‰  ¦«SwxYw ‰  ¦«n#‰  ¦«wxYwt‰j ¦«}|D]xЉd|krj| ‰dttt!ˆˆfd„t#t%‰j ¦«¦«¦«¦«¦«i¦«nŒy|s4t‰j ¦«t  ‰j d¦«iS|S)zJ For non-privileged user we outputting data from the file ú,)Ú delimiterr´rcó4•—‰j|‰|dzfS)NrÁr)r‰Úrowr$s €€r&r‹z/QuotaWrapper._load_user_cache..Lsø€ ¤ ¨Q¤Ø # A a¡C¤ð *€r')rrÔrurrÚreaderr�ÚIOErrorrCr�rBÚfromkeysrŒr�r‚r�r�ÚrangerÄ)r$r„ÚfoÚcvs_inrTrßs` @r&rzzQuotaWrapper._load_user_cache9s¸øø€ð ˆð !Ø × !Ò !Ñ #Ô #Ð #Ý•lÔ,Ñ-Ô-ˆBÝ”Z ¨cÐ2Ñ2Ô2ˆFˆFøÝ�Ð!ð Gð Gð Gõ˜œ ‘O”O¥T§]¢]°4´<ÀÑ%EÔ%EÐFÐ FÐ Fà × Ò Ñ Ô Ð Ð ð  Gøøøð ð × Ò Ñ Ô Ð Ð øˆD× Ò Ñ Ô Ð Ð øøøÝ�$”*‰oŒoˆØð ð ˆCØ�1Œv˜Š}ˆ}Ø—’˜#˜aœ&¥$¥t­Cð*ð*ð*ð*ð*å�#˜dœlÑ+Ô+Ñ,Ô,ñ-.ô-.ñ(/ô(/ñ#0ô#0ð1ñ2ô2ð2ð�ð ðð Gݘœ ‘O”O¥T§]¢]°4´<ÀÑ%EÔ%EÐFÐ F؈s+†AA Á B?Á AB&ÂB?Â%B&Â&B?Â?Ccóº—d„}g}| ¦«D])\}}|D]!}|d}| ||f¦«Œ"Œ*| |d¬¦«|S)z¸ return list tuple ('mountpoin tpath', 'device') reverse sorted by deep mountpoint path [('/mountpoint_path/path', '/device'), ('/mountpoint_path', '/device')] cóZ—|ddkrd}n|d d¦«}|S)NrrY)Úcount)Údevice_mountpointÚ deep_paths r&Úsort_by_deep_pathzBQuotaWrapper._get_mountpoint_device_map..sort_by_deep_pathZs7€Ø  Ô# sÒ*Ð*Ø� � à-¨aÔ0×6Ò6°sÑ;Ô;� ØÐ r'rÐT)rÚreverse)rÅrûÚsort)r$rÂrëÚmountpoint_device_maprîÚmountpoint_data_listrÙÚmountpoint_paths r&r’z'QuotaWrapper._get_mountpoint_device_mapUs—€ð  ð ð ð !#ÐØ,3¯MªM©O¬Oð Hð HÑ (ˆFÐ(Ø#7ð Hð H�Ø"1°,Ô"?�Ø%×,Ò,¨o¸vÐ-FÑGÔGÐGÐGð Hð ×"Ò"Ð'8À$Ð"ÑGÔGÐGØ$Ð$r'cóº—d„}|tj |¦«¦«}|jD]'\}}| ||¦«¦«r|cSŒ(dS)z3 Returns device user homedir is on có,—|r|ddkr|dz }|S)NrXrYr,r™s r&Ú _add_slashz1QuotaWrapper._get_home_device.._add_slashls$€Øð ˜˜Rœ Cš˜Ø˜‘ �؈Kr'N)r�r[Údirnamer“rZ)r$ÚhomerórôÚmounpoint_pathrîs r&ràzQuotaWrapper._get_home_devicehs€ð ð ð ð�*�RœWŸ_š_¨TÑ2Ô2Ñ3Ô3ˆØ&*Ô&Dð ð Ñ "ˆN˜FØ×!Ò! * *¨^Ñ"<Ô"<Ñ=Ô=ð Ø� � � ð ð ð r'có4—| |¦«|kS)z; Checks if a device is user homedir device )rà)r$rõrîs r&r¼zQuotaWrapper._is_home_deviceus€ð×$Ò$ TÑ*Ô*¨fÒ4Ð4r'có�— tj|¦«t}tj|¦«tj|¦«f}|j ¦«D]Q}tj|¦«t}|tj|¦«tj|¦«fkr|cSŒRdS#t$r|cYSwxYwrM)r�ÚstatrÚmajorÚminorr‘rËr�)r$rîÚdevÚ dev_to_findÚcurrent_devices r&r»z!QuotaWrapper._find_unknown_device{sÆ€ð Ý”'˜&‘/”/¥&Ô)ˆCÝœ8 C™=œ=­"¬(°3©-¬-Ð8ˆKØ"&¤-×"4Ò"4Ñ"6Ô"6ð *ð *�Ý”g˜nÑ-Ô-­fÔ5�Ø¥2¤8¨C¡=¤=µ"´(¸3±-´-Ð"@Ò@Ð@Ø)Ð)Ð)Ð)ðAð *ð *øõð ð ð ØˆMˆMˆMð øøøs‚B0B6Â3B6Â6 CÃCc 󲇗gd¢Š |j dd¦« d¦«\}}|dkrd}|dkrd}‰ ||g¦«n8#tjtjf$r‰ ddg¦«YnwxYwdtttˆfd„t|j ¦«¦«¦«¦«iS)zw Insert 'default' quota. Calls only from _load_current_quotas, after parsing repquota's output )r~r´r´r~r1r´r»r¶có0•—|d‰|dfSrˆr,)r‰r…s €r&r‹z+QuotaWrapper._add_default..–sø€¨q°¬t°V¸A¸a¼D´\Ð.B€r') r‹r¼r½r�rFrbrcrBr�r�rŽrŒ)r$r^r_r…s @r&rÁzQuotaWrapper._add_default†sòø€ð &Ð%Ð%ˆð &Ø#'¤8§<¢<°¸Ñ#=Ô#=×#CÒ#CÀCÑ#HÔ#HÑ ˆI�yà˜DÒ Ð Ø� ؘDÒ Ð Ø� Ø �MŠM˜9 iÐ0Ñ 1Ô 1Ð 1Ð 1øÝÔ+­\Ô-GÐHð &ð &ð &Ø �MŠM˜3 ˜*Ñ %Ô %Ð %Ð %Ð %ð &øøøà•T�$�sÐ$BÐ$BÐ$BÐ$BÅYÈtÌ|ÑE\ÔE\Ñ]Ô]Ñ^Ô^Ñ_Ô_Ð`Ð`s‡AA Á 2BÂBcól—|€d}|€d}|dkr<|dkr6|j d¦«r|j d|¦«nU|j d¦«s|j d¦«|j d||›d|›�¦«| ¦«dS)z# Saves user limits Nr´r1r»)r‹rÃrÈÚ add_sectionÚsetrÉ)r$rTrÒrÓs r&råzQuotaWrapper._save_user_limits˜sÀð ˆ<؈DØ ˆ<؈Dð �3Š;ˆ;˜4 3š;˜;¨4¬8×+?Ò+?ÀÑ+HÔ+H˜;Ø ŒH× "Ò " 7¨CÑ 0Ô 0Ð 0Ð 0à”8×'Ò'¨Ñ0Ô0ð .Ø”×$Ò$ WÑ-Ô-Ð-Ø ŒH�LŠL˜ #°$°$°$¸¸Ð'=Ñ >Ô >Ð >Ø ×ÒÑÔÐÐÐr'có–—|€d}|€d}|dkr<|dkr6|j d¦«r|j d|¦«nU|j d¦«s|j d¦«|j d||›d|›�¦«| ¦«| |¦«dS)z& Saves package limits Nr´rºr»)r‹rÃrÈrrrÉÚ_copy_package_limits_to_cpanelris r&r÷z!QuotaWrapper._save_package_limitsªsÕ€ð ˆ<؈DØ ˆ<؈Dà �3Š;ˆ;˜4 3š;˜;¨4¬8×+?Ò+?À Ñ+KÔ+K˜;Ø ŒH× "Ò " :¨wÑ 7Ô 7Ð 7Ð 7à”8×'Ò'¨ Ñ3Ô3ð 1Ø”×$Ò$ ZÑ0Ô0Ð0Ø ŒH�LŠL˜ W¸¸¸¸t¸tÐ.DÑ EÔ EÐ EØ ×ÒÑÔÐØ ×+Ò+¨GÑ4Ô4Ð4Ð4Ð4r'có|—tj¦«sdSd|›�}t|¦«}t|¦«dkrdS| |¦«\}}|€|€dS| |d¬¦«|}| ¦«D]\}}|dkrd||<Œ| dd ¦«| d d ¦«f} |d|d f} | | krdSd D]E} d t| ¦«zd zt|| ¦«zdz} |  | ¦«ŒFt||d¦«dS)zV Copy package quota limits from cl-quotas.dat to cpanel packages data Nz/var/cpanel/packages/rTrõr~r¶r{r´r|©r{r|Úlve_rÑrÛÚw) roÚ is_cpanelrrÄÚ_parse_cpanel_package_datar­rÅr¼rCrûr) r$r%Ú package_pathÚcpanel_package_linesÚold_cpanel_dataÚmodified_cpanel_linesÚ quotas_datarÚvalueÚold_cpanel_limitsÚcurrent_quota_limitsÚ limit_typeÚ limit_strings r&rz+QuotaWrapper._copy_package_limits_to_cpanel¼sŠ€õÔ$Ñ&Ô&ð Ø ˆFØ8¨wÐ8Ð8ˆ Ý-¨lÑ;Ô;ÐÝ Ð#Ñ $Ô $¨Ò )Ð )Ø ˆFØ15×1PÒ1PÐQeÑ1fÔ1fÑ.ˆÐ.Ø Ð "Ð'<Ð'DØ ˆFà×.Ò.¨wÀTÐ.ÑJÔJÈ7ÔSˆ ð&×+Ò+Ñ-Ô-ð (ð (‰JˆC�ؘŠ|ˆ|Ø#'� ˜CÑ øØ,×0Ò0°ÀÑDÔDÀo×FYÒFYÐZgÐilÑFmÔFmÐnÐØ +¨MÔ :¸KÈ ÔÔ>×DÒDÑFÔF� ؘa”= IÒ-Ð-Ø2<¸Q´-�O JÑ/ØÐ!?Ð?Ð?Ø1×8Ò8¸Ñ>Ô>Ð>Ø�ŠÐ4Ñ5Ô5ð "¸%ÀtÐ:KÐ:KØ!�z�zøØÐ =Ð=Ð=r'cóT—|dkr8|dkr2 |j ||¦«nj#tj$rYnYwxYw|j |¦«s|j |¦«|j |||›d|›�¦«| ¦«dS)z& Saves data to a file r´r»N)r‹rÈrFrbrÃrrrÉ)r$rÒrÓr�Ú item_types r&Ú _save_datazQuotaWrapper._save_dataísÀð �3Š;ˆ;˜4 3š;˜;ð Ø”×&Ò& y°$Ñ7Ô7Ð7Ð7øÝÔ.ð ð ð Ø�ð øøøð”8×'Ò'¨ Ñ2Ô2ð 0Ø”×$Ò$ YÑ/Ô/Ð/Ø ŒH�LŠL˜ D°T°T°T¸4¸4Ð*@Ñ AÔ AÐ AØ ×ÒÑÔÐÐÐs Ž*ª<»<có^—tj |¦«} tjd|¬¦«\}}tj|d¦«}||_|S#ttf$rCtj  |¦«rtj |¦«td¦«‚wxYw)zH Open temporary file for writing and return file object Úlvetmp_)ÚprefixÚdirr zCould not save data) r�r[rôÚtempfileÚmkstempÚfdopenÚ_tmprár�r—ÚunlinkrK)r$Úfilepathr[ÚfdÚ temp_pathr#s r&rzQuotaWrapper._prepare_writerüs¨€õŒw�Š˜xÑ(Ô(ˆð :Ý$Ô,°IÀ4ÐHÑHÔH‰MˆB� Ýœ9 R¨Ñ-Ô-ˆLØ!ˆDŒIØÐ øÝ�Ð!ð :ð :ð :ÝŒw�~Š~˜iÑ(Ô(ð %Ý” ˜)Ñ$Ô$Ð$Ý"Ð#8Ñ9Ô9Ð 9ð :øøøs ¡6AÁAB,có— |tjkr ttztzt z}nttz}t j|j|¦«t j ||¦«dS#t$rYdSwxYw)z0 Routines after writing to file N) rurrrrrr�Úrenamer*Úchmodr�)r$r[Úmasks r&r!zQuotaWrapper._end_writer s…€ð ð •|Ô-Ò-Ð-Ý¥Ñ(­7Ñ2µWÑ<��å¥Ñ(�Ý ŒI�d”i Ñ &Ô &Ð &Ý ŒH�T˜4Ñ Ô Ð Ð Ð øÝð ð ð Ø ˆDˆDð øøøs‚A.A2Á2 BÁ?Bcó—| d¦«| tj¦«}|j |¦«| tj¦«| ¦«dS)z7 Actual place of saving data to a file TN)rrrurGr‹Úwriter!r�)r$r#s r&rÉzQuotaWrapper._write_datasq€ð ×Ò˜dÑ#Ô#Ð#Ø×+Ò+­LÔ,AÑBÔBˆ Ø Œ�Š�|Ñ$Ô$Ð$Ø ×Ò�Ô.Ñ/Ô/Ð/Ø ×ÒÑÔÐÐÐr'có€—tj¦«dkr|rt¦«‚dS|r dt_tj€ú tjtjtjtj zd¦«}n#t$rtd¦«‚wxYwtj |d¦«t_ tjtj ¦«tj¦«dS#t"$r:tj ¦«dt_td¦«‚wxYwdS)NrTi€zCan't open lock filezr+zCan't get lock)r�rŽr2ruÚ LOCK_WRITEÚLOCK_FDrÔÚ LOCK_FILEÚO_RDWRÚO_CREATr�rKr)ÚfcntlÚflockÚfilenoÚLOCK_EXrárÕ)r$r4r-s r&rzQuotaWrapper._get_global_lock)s/€õ Œ:‰<Œ<˜1Ò Ð Øð 8Ý5Ñ7Ô7Ð7Ø ˆFð ð +Ø&*�LÔ #Ý Ô Ð 'ð  ?Ý”W�\Ô3ÝœY­¬Ñ3°Uñ<ô<��øåð ?ð ?ð ?Ý&Ð'=Ñ>Ô>Ð>ð ?øøøå#%¤9¨R°Ñ#6Ô#6�LÔ ð 9Ý” �LÔ0×7Ò7Ñ9Ô9½5¼=ÑIÔIÐIÐIÐIøÝð 9ð 9ð 9ÝÔ$×*Ò*Ñ,Ô,Ð,Ø'+• Ô$Ý&Ð'7Ñ8Ô8Ð8ð 9øøøð (Ð 'sÁ7A=Á=BÂ:;C7Ã7AD;có$—tj�w tjtj ¦«tj¦«n#t $rYnwxYwtj ¦«dt_dt_dS©NF) rur7r;r<r=ÚLOCK_UNrárÕr6r4s r&r�zQuotaWrapper._release_lockNsƒ€õ Ô Ð +ð Ý” �LÔ0×7Ò7Ñ9Ô9½5¼=ÑIÔIÐIÐIøÝð ð ð Ø�ð øøøå Ô × &Ò &Ñ (Ô (Ð (Ø#'�LÔ Ø"'� ÔÐÐsŽ;A Á AÁArM)F)NNTFF)NNTF)Trr@)[r)r*r+rEr~r.r€rÚGETPACKSrGrr7r8r6r"Ú staticmethodr}r›r¡r§r©r®r²r¸r¾rÑrCr Úboolrórrr%rærÿrãr rør rärþr@rÝrFrŠrùr·rÞrWrYr5rXr:rßrúrörmr¥r­rƒrrKrÊr|r(r r r¤r“rÆr¤r{rºrár�rzr’ràr¼r»rÁrår÷rr r"rr!rÉrr�r,r'r&ruruŽsƒ€€€€€ððð!€KØ%€IØ$€HØ$€HØ7€HØ.€HØ0€Ià€Gؘ7Ñ"€IØ€Jð&ð&ð&ð,ðAðAñ„\ðAððððððð KðKðKð HðHðHð XðXðXðkðkðkðkð (ð (ð (ð<ð<ð<ð #ð #ð #ð #ðJ#'Ø"&ØØ$Ø$ðKIðKIàðKIð˜3”-ðKIð˜3”-ð KIð ð KIð ð KIððKIðKIðKIðKIð`#'Ø"&ØØ$ð G'ðG'àðG'ð˜3”-ðG'ð˜3”-ð G'ð ð G'ð ð G'ð ðG'ðG'ðG'ðG'ðR#ð#ð#ð8ððð,#ð#¨4ð#ð#ð#ð#ð  ð  ð  ðð¨¨d© ððððð$ ð ð ðððð %ð ,ð,àð,ð% SœMð,ð% SœMð ,ð ð ,ð ˆx˜Œ}˜h sœmÐ+Ô ,ð ,ð,ð,ð,ð0ØðØ08¸´ ðØOWÐX[Ì}ðØafÐgjÐloÐgoÔapððððð#ð#ð#ð4ð4ð4ð¨Ô)Bððððð$%ð%ð%ð(& (¨3¤-ð&°H¸S´Mð&ð&ð&ð&ðð¨ð°8¸C´=ðÈxÐX[Ì}ðÐhmÐnqÐsvÐnvÔhwððððð@ð°#ð¸XÀc¼]ðÐYaÐbeÔYfðÐrwÐx{ð~AðyAôsBððððð$°SðÀðÈ3ðÐSXÐY\Ð^aÐYaÔSbððððð"$ Cð$¨E°#°s°(¬Oð$ð$ð$ð$ð¸CðÀsðÐRUðÐZ_Ð`cÐehÐ`hÔZiððððð¨3ð°5¸¸c¸´?ðððððð x°¤}ð¸HÀS¼MðÈeÐT\Ð]`ÔTaÐckÐloÔcpÐTpÔNqðððñ„\ððØðØ%(ðØ08¸´ ðØEMÈcÄ]ðØW\Ð]`ÐbeÐ]eÔWfððððð>ðððð F¨ðF°ðFðFðFðFððððð$,ð,ð,ð,ð\dðdðdð=ð=ð=ð<ð<ð<ð)ð)ð)ð)ð1ð1ð1ð)ð)ð)ð)ð)¨t°C¸¸c¼°NÔ/Cð)ð)ð)ð)ðV4¨¨c°4¸´9¨nÔ)=ð4ð4ð4ð4ð$&ð&ð&ð6 ð ð ð"ð"ð"ðHððð+ð+ð+ð%ð%ð%ðNððð8%°T¸%ÀÀSÀ¼/Ô5Jð%ð%ð%ð%ð& ð ð ð5ð5ð5ð ð ð ðaðaðað$ððð$5ð5ð5ð$CðCðCð:ð>ð>ñ„\ð>ð& ð ð ð :ð :ð :ðððð$ððð#9ð#9ð#9ð#9ðJ (ð (ð (ð (ð (r'ru)>Ú configparserrFrr;r�rÍrPr'Ú collectionsrrùrrrrrÚtypingr r r r ruroÚclcommonr Úclcommon.clpwdrÚclcommon.clquotarÚclcommon.cpapirrrÚclcommon.cpapi.cpapiexceptionsrrÚclcommon.utilsrrrrrÚdetectÚis_darlÚDEFAULT_PACKAGEr€r!rr.r2r6r;rKrOrRr^rjrDrsÚobjectrur,r'r&úrRs}ðð$Ð#Ð#Ð#Ø € € € Ø € € € Ø € € € Ø € € € Ø € € € Ø€€€Ø#Ð#Ð#Ð#Ð#Ð#Ø;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ø.Ð.Ð.Ð.Ð.Ð.Ð.Ð.Ð.Ð.Ð.Ð.àÐÐÐØÐÐÐØ'Ð'Ð'Ð'Ð'Ð'à Ð Ð Ð Ð Ð Ø0Ð0Ð0Ð0Ð0Ð0ØIÐIÐIÐIÐIÐIÐIÐIÐIÐIØTÐTÐTÐTÐTÐTÐTÐTððððððððððððððð Ô×!Ò!Ñ#Ô#€Ø€Ø!ÐðFðFðFðFðF˜YñFôFðFð @ð@ð@ð@ð@˜)ñ@ô@ð@ð <ð<ð<ð<ð< iñ<ô<ð<ð JðJðJðJðJ IñJôJðJð  ð ð ð ð Ð1ñ ô ð ð$*ð*ð*ð*ð*�yñ*ô*ð*ð _ð_ð_ð_ð_˜Yñ_ô_ð_ð *ð *ð *ð *ð *Ð!7ñ *ô *ð *ðððð" ð ð ð dðððððJ(ðJ(ðJ(ðJ(ðJ(�6ñJ(ôJ(ðJ(ðJ(ðJ(r'