Current File : //opt/cloudlinux/venv/lib/python3.11/site-packages/__pycache__/lvectllib.cpython-311.pyc
�

��oe�x�	�`�ddlmZddlmZddlmZddlmZddlmZmZddl	m
Z
mZddlm
Z
mZmZmZmZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlmcmZ ddl!Z!dd	l"m#Z#ddl$Z$ddl%Z%dd
lm&Z&ddl'Z'ddl(Z(ddl)m*Z*ddl+m,Z,m-Z-m.Z.m/Z/dd
l0m1Z1ddl2Z2ddl3m4Z4m5Z5ddl6m7Z7ddl8m9Z9m:Z:m;Z;ddl<m=Z=m>Z>ddl'm?Z?m@Z@mAZAmBZBmCZCddlDmEZEddlFmGZGdZHdZIdZJdZKdZLdZMdZNdZOdZPeQejR�Sdd����ZTdZUe/e*jV��sdZWdZXne@eT� ��ZWe?eW�!��ZXd"�ZYd#�ZZd$�Z[d%e1fd&�Z\d�d'�Z]d(�Z^d)d*d)d+dd,dd-d.�Z_d,Z`d/d*ddddddd.�Zagd0�Zbd1acdaddaed2afd2agiahd2aid2ajd2akd2ald2amd2and2aod3apd2aqd2ard2asd4�Ztd5�Zud6�Zvd�d7�Zwd8�Zxd9�Zyex��p	ey��Zzd�d:�Z{d;�Z|d<�Z}d=�Z~d�d>�Zd?�Z�ej�d@���Z�		d�dA�Z�dB�Z�d�dC�Z�dD�Z�dE�Z�d�dF�Z�dG�Z�dH�Z�dI�Z�dJeQdKe�fdL�Z�dM�Z�dN�Z�dOe
e�eQffdP�Z�dQ�Z�d�dS�Z�dT�Z�d�dU�Z�d�dV�Z�dW�Z�dX�Z�dY�Z�d�dZ�Z�d�d[�Z�d\�Z�d]�Z�d^�Z�d�d_�Z�d`�Z�d�da�Z�db�Z�dc�Z�dd�Z�de�Z�df�Z�dg�Z�dh�Z�d�dk�Z�e�fdl�Z�d�dm�Z�dn�Z�do�Z�dp�Z�dq�Z�d�dr�Z�ds�Z�dt�Z�du�Z�dv�Z�dw�Z�dx�Z�dy�Z�dz�Z�d{�Z�d|�Z�d}�Z�d�d~�Z�d�Z�d�d��Z�d�d��Z�d�d��Z�d�e�d�e�d�eeQfd��Z�d��Z�d��Z�d��Z�d��Z�d��Z�d�d��Z�d��Z�d��Z�d��Z�d�d��Z�d��Z�d��Z�d��Z�da�da�da�da�da�d��Z�d�d��Z�d��Z�d�d��Z�d��Z�d��Z�d��Z�d��Z�d��Z�d��Z�d��Z�d��Z�d��Z�d��Z�dS)��)�print_function)�absolute_import)�division)�range)�
basestring�unicode)�	iteritems�reraise)�Dict�List�Tuple�Optional�TextN)�partial)�PAGESIZE)�Feature)�admins�reseller_users�get_main_username_by_uid�is_panel_feature_supported)�
EncodingError)�reseller_limits_disabled_post�reseller_limits_enabled_post)�exec_utility)�get_xml_config�save_xml�BadVeConfigException)�setup_global_lock�LockFailedException)�Lve�PyLve�LVP_XML_TAG_NAME�
PyLveError�NameMap)�detect_panelclass)�write_file_via_tempfilez%/usr/bin/getcontrolpaneluserspackagesz
/proc/cpuinfoi'�
VE_DEFAULTFz/bin/umountz"/etc/container/exclude_mounts.conf�multi�single�PYLVE_DEBUG�plesk_id)�debug)�pyc�t�t���rtj���SgS)z-Helper function for easy mocking in unittests)�lve�reseller_limit_supported�proc�lvp_id_list���py/lvectllib.py�lvp_listr6Ns/��
�#�#�%�%���x�#�#�%�%�%��	r4c�n�t��}|���|���S)zf
    Get list of resellers with activated reseller limits

    :return: list of pairs (name, uid)
    )r$�
link_xml_node�load_from_node)�name_maps r5�get_active_resellersr;Vs1���y�y�H��������"�"�$�$�$r4c�6�|d�t��D��vS)z]
    Check whether giver reseller has activated reseller limits or not
    :return: bool
    c3� K�|]	\}}|V��
dS�Nr3)�.0�name�uids   r5�	<genexpr>z,is_active_reseller_limits.<locals>.<genexpr>fs&����J�J�i�d�C�T�J�J�J�J�J�Jr4)r;��
reseller_names r5�is_active_reseller_limitsrEas%��
�J�J�3G�3I�3I�J�J�J�J�Jr4�ec���tj��st|��tr t	ddt|��g��nt
|��tjd��dS)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(�ERROR�N)	�cldetectlib�	is_cpanelr
�JSON�json_format�str�print�sys�exit�rFs r5�raise_cpanel_encoding_errorrSjsm��� �"�"����
�
�
����G��c�!�f�f�%�	'�	'�	'�	'�	�a�����H�Q�K�K�K�K�Kr4c�h�	t|��dS#t$rtdd��YdSwxYw)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
    rIzcan`t get lockN)rr�check_result_and_exit)�writes r5�get_global_lockrW|sP��3��%� � � � � ���3�3�3��a�!1�2�2�2�2�2�2�3���s��1�1c��|tjkrj|dkrftr(ttddt|��zg��nt
dt|��z��tj|��dSdSdS)NrrHz
lvectl: %szlvectl: Error: )	�errno�ENOSYSrLrM�MULTI_FORMATrNrOrPrQ)�result�messages  r5rUrU�s���	�E�L�=�	 �	 �v��{�{��	3���w��s�7�|�|�0K�&L�M�M�M�M��#�S��\�\�1�2�2�2���������
!�	 �{�{r4�rI�i�)�cpu�ncpu�io�ep�mem�pmem�nproc�iops�d)rbrarcrerfrgrhrd���falsec�
�|adSr>)rL)�	json_flags r5�set_jsonro�s���D�D�Dr4c�
�|adSr>)�
BYTES_FLAG)�
bytes_flags r5�	set_bytesrs�s���J�J�Jr4c��trtdkrd}ntdkrd}ntdkrd}nd}gd�gd�gd�gd	�d
�|}tr1|�d��dz}|d|�d
gz||d�zS|S)N��noiops_8�8��6�4)�ID�SPEED�PMEM�VMEM�EP�NPROC�IO)r{r|r}r~rr�r��IOPS)r{r|r~rr�)rvrwryrzr|rI�CPU)�NOIOPS�LVE_VERSIONrL�index)�version�fields�	speed_idxs   r5�
get_fieldsr��s���
��+��"�"����	��	�	����	��	�	������B�B�B�
B�
B�
B�
;�
;�
;�
,�
,�
,�	��
��F��C��L�L��)�)�!�+�	��z�	�z�"�e�W�,�v�i�j�j�/A�A�B��Mr4c��|�3tj��}|d�td���|dan|at���}|std���t���adS)Nrzget_lve_version failedzinit_lve() failed.)�clcommon�get_lve_version�	Exceptionr��pylve�
initialize�liblve_settings�lve_settings)�lve_ver�
lve_statuss  r5�initr��s}�����*�,�,���1�:���3�4�4�4��a�j������!�!�#�#�J��.��,�-�-�-��(�(�*�*�L�L�Lr4c��tj�d��}|�dS	tj|��S#t
tf$r<}tdt|����tj
d��Yd}~dSd}~wwxYw)z-Get cpu information from environment veriable�CPU_DATANz.Invalid environment variable 'CPU_DATA' formatrI)�os�environ�get�json�loads�	TypeError�
ValueErrorrOrNrPrQ)�packed_cpu_datarFs  r5�_get_cpu_data_from_envr�
s����j�n�n�Z�0�0�O����t���z�/�*�*�*���z�"����
�@�#�a�&�&�I�I�I��������������������s�9�B�
1B�Bc��i}i}d}	ttd��}nK#t$r>tdt	t��zdz��tjd��YnwxYw|D]�}|���s||d|z<|dz}i}�&t|�	d����dkr\|�	d��d���||�	d��d���<��d	||�	d��d���<��||d
dgS)zF
    Parse /proc/cpuinfo

    return [NumProc, frequency in MHZ]

    r�rzlvectl: Error: Can`t open �.rIzproc%s�:�rk�proc0zcpu MHz)
�open�CPUINFO�IOErrorrOrNrPrQ�strip�len�split)�cpuinfo�procinfo�nprocs�f�lines     r5�get_cpu_datar�sQ���G��H�
�F����#����������
�*�S��\�\�9�C�?�@�@�@��������������:�:���z�z�|�|�
	:�)1�G�H�v�%�&��a�Z�F��H�H��4�:�:�c�?�?�#�#�q�(�(�7;�z�z�#���q�7I�7O�7O�7Q�7Q�����C����+�1�1�3�3�4�4�79�����C����+�1�1�3�3�4�4��G�G�$�Y�/�0�0s��AA&�%A&c�\�t|��}|pd}t}t|d��}tjd|��}|�et|��}|dkrP|dkrJtttdz|z|z����}|dkr|St|tz|��SdS)z�
    Try converting to kernel format from old CPU format (percentage of whole
    cpu) and optionally the NCPU format. Return whichever is less.

    :param data: string presumably in old CPU format
    :param lncpu: integer number of cores limit
    rz
\d{1,2}0?$Nri)rN�CPUINFO_DATA�int�re�match�round�CORE_WEIGHT�min)�data�lncpu�cpu_datarb�cpu_percent�from_cpu_limits      r5�convert_from_old_cpur�8s����t�9�9�D��J�Q�E��H��x��{���D��(�=�$�/�/�K����4�y�y���1�H�H�4�3�;�;� ��{�c�'9�D�'@�4�'G�!H�!H�I�I�N���z�z�%�%��u�{�*�N�;�;�;��4r4c�J�t|��}t}t|d��}tjd|��}|�`t|�dd����}||dzkr|dz}|dkr'tttdz|z����SdSdS)zd
    Try converting cpu limit from SPEED in percentage of one CORE format to
    kernel format.
    rz\d+(?:\.\d+)?%$N�%rkri)	rNr�r�r�r��float�replacer�r�)r�r�rb�percents    r5�convert_from_speed_percentr�Ns���
�t�9�9�D��H��x��{���D��h�)�4�0�0�G�������S�"�-�-�.�.���T�C�Z����S�j�G��Q�;�;��u�[�C�/�'�9�:�:�;�;�;��t��4r4c��t|��}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.
    rrIz,(?P<freq>\d+(?:\.\d+)?)(?P<suffix>mhz|ghz)+$N�suffix�freq�GHZi�)rNr�r�r�r��compile�
IGNORECASEr��group�upperr�r�)r�r�rb�cpu_freq�patternr�r�r�s        r5�convert_from_speed_hzr�`s����t�9�9�D��H��x��{���D��X�a�[�!�!�H��j�H�"�-�X�X�G��M�M�$���E������X�&�&���U�[�[��(�(�)�)���<�<�>�>�U�"�"��$�;�D��(�T�/�!�!��d�?�D��!�8�8��u�T�K�/�(�:�;�;�<�<�<��4r4c�>�t|��pt|��S)z}
    Try converting cpu limit value from either SPEED limit format
    (percentage of CORE or mhz/ghz) to kernel format.
    )r�r�)r�s r5�convert_from_speedr�us$��	#�4�(�(�	'� ��&�&�r4c�z�t||��}|�|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)r�r�r�)r�r��from_cpu�from_speed_percent�
from_speed_hzs     r5�convert_to_kernel_formatr�sV��$�D�%�0�0�H�����3�D�9�9���%�!�!�)�$�/�/�M�� ����4r4c�p�t}t|d��}t|��}d|vrOdtttt|�d����|z������zStttt|��|z������S)zm
    convert speed to old cpu format
    args: cpu limit in speed value
    return: old cpu limit format
    r�*)r�r�rNr��lstrip)�speedr�rgs   r5�speed_to_old_cpur��s����H�������E���J�J�E�
�e�|�|��S��U�3�u�|�|�C�'8�'8�#9�#9�U�#B�C�C�D�D�E�E�E�E��3�u�S��Z�Z�5�0�1�1�2�2�3�3�3r4c#�K�t���t���}	t�||��n1#t$r$tjt
jd|z���wxYw	|V�t�|��dS#t�|��wxYw)zF
    Run subprocess in lve with pseudo-random id and given limits
    zKUnable to setup lve with id %i, something is wrong, check dmesg for detailsN)r�r��get_available_lve_id�	lve_setupr#�syslog�	LOG_ALERT�lve_destroy)�settings�lve_ids  r5�
temporary_lver��s�����
������
�
'�
'�
)�
)�F��
�����)�)�)�)�������
�f�&�)V�X^�)_�	`�	`�	`�
�����
"�����
���&�!�!�!�!�!�����&�!�!�!�!���s�A�.B�B$�$Cc��t���}t||���|_||_||_||_||_ttj
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)
    �r�g�?)
r�r�r��ls_cpu�ls_io�	ls_enters�ls_nproc�ls_iopsr��math�ceilr�
ls_memory_phy)r��ls_cpusr�r�r�r�r��ss        r5�make_liblve_settingsr��sm��	�����A�'��g�>�>�>�A�H��A�G��A�K��A�J��A�I��$�)�B��$6��$A�B�B�C�C�A�O��Hr4c���t|�d����}|s.|�d��}tj|��j}t|��S)N�id�user)rN�getAttribute�pwd�getpwnam�pw_uidr�)�ve_lve_element�user_uid�	user_names   r5�get_ve_lve_user_uidr��sV���>�.�.�t�4�4�5�5�H��2�"�/�/��7�7�	��<�	�*�*�1���x�=�=�r4c���dt|d��i}|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
    �statusrrI�msgN)rNr[�updaterOr��dumps)�
error_typer��
extensionsr\s    r5rMrM�sl����D��G���
%�F��\�!�!��D��G����u�
����
�
�j�!�!�!�	�$�*�V�
�
�����r4c��	tt�|��d�d����||<dS#tt
tf$rg||||<|�|��}|�dt||����	|j
|��YdS#YYdSxYwwxYw)Nr�limit)r��
ve_default�getElementsByTagNamer�r��
IndexErrorr��
createElement�setAttributerN�appendChild)�xml�ve_defaults�ve_cfg�val�default�nodes      r5�check_def_valuer�s���	��z�>�>�s�C�C�A�F�S�S�T[�\�\�]�]��C������
�I�.����"�3�<��C���#�#�C�(�(�����'�#�g�c�l�"3�"3�4�4�4�	��C�O�D�!�!�!�!�!�!��	��D�D�D�������s%�AA�A C�(B;�;C�=C�Cc�*���fd�|jD��S)Nc�^��g|])}t|tj���|j�k�'|��*Sr3)�
isinstancer�Element�tagName)r?�_�tags  �r5�
<listcomp>z"xml_filter_tag.<locals>.<listcomp>�s7���Z�Z�Z�!�*�Q���*D�*D�Z���VY�IY�IY�A�IY�IY�IYr4)�
childNodes)rrs `r5�xml_filter_tagr�s���Z�Z�Z�Z�t��Z�Z�Z�Zr4c��t||��D]9}|�|�|��s�|�|�|��|kr�6|cSdSr>)r�hasAttributer�)rr�attr�attr_val�
child_nodes     r5�xml_filter_firstr$�sn��$�T�3�/�/���
���J�$;�$;�D�$A�$A�����J�$;�$;�D�$A�$A�X�$M�$M�������r4c�p�t|||���}|�t���|�|��S)N)rrr!)r$r
r�)rrr!�filtered_child_nodes    r5�get_child_tag_atrrr's;��*��#�D�I�I�I���"��l�l���+�+�D�1�1�1r4c�x�t||��d}|�|t|����dS)z�
    Find in children nodes node with tag and setup attribute
    insted el.getElementsByTagName not search recursiveli in tree
    rN)rrrN)rrr!r�first_child_nodes     r5�set_child_tag_atrrr*s;��
&�d�C�0�0��3���!�!�$��C���1�1�1�1�1r4c��	t��\aadS#t$rg}tr%ttdt|��g��ntt|����tj
d��Yd}~dSd}~wwxYw)zLoad config from ve.cfgrHrIN)rr�ve_lveconfigrrLrMr[rNrOrPrQrRs r5�_load_config_wrapperr-s���
�-�/�/������������	���w��A���&7�8�8�8�8��#�a�&�&�M�M�M��������������������s��
B�AB�B�lvp_id�lvp_defaultsc��da	|s"ttd��datS|r!t
�d��atStttdt|����}|r|�d��dant�t��atS#t$r@tr'tdddg��t!jd��nt%d	��YnwxYwtS)
z�Load 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
    �true�defaultsrr�r(�WARNINGzdefault section error in ve.cfgrIz(warning: default section error in ve.cfg)�ubcrr,r�LVE_DEFAULTrr�LVP_DEFAULTr$r"rNr	�	cloneNoder
rLrMrPrQrO)r.r/�defaults_root_nodes   r5�_load_default_limitsr9 s���C�>��	�'��j�A�A�!�D�J����	��-�-�j�9�9�J���-�l�<L�d�TW�X^�T_�T_�`�`���	:�+�@�@��L�L�Q�O�J�J�#�-�-�j�9�9�J�����>�>�>��	>���)�-N�!O�P�P�P��H�Q�K�K�K�K��<�=�=�=���>�����s�#B8�"B8�A,B8�8AD�Dc	�|�td�ttttt
tfD����S)Nc3�"K�|]
}|dkV��dS)rkNr3)r?�xs  r5rBz._all_config_elements_loaded.<locals>.<genexpr>Gs&����j�j�1�q�B�w�j�j�j�j�j�jr4)�all�ve_lve�ve_lvp�
ve_package�	ve_binary�ve_enter_by_name�ve_cfg_versionr3r4r5�_all_config_elements_loadedrDFs.���j�j����Y�HX�Zh� i�j�j�j�j�j�jr4c��t�d��at�d��at�t��atjj�	t��t�d��}t|��dkr	|dan9t�
d��at�t��t�d��at�d��}t|��dkrt!|djj��ndadS)	z$Load all config elements from ve.cfgr/�packagez
enter-by-namer�binaryr�rIN)r,r	r>r@r"r?r/�mapr:r8r�rBrrr
rAr��
firstChild�	nodeValuerC)�enter_by_name_elems�cfg_version_elemss  r5�_load_config_elementsrMIs���
.�
.�u�
5�
5�F��2�2�9�=�=�J�
�
.�
.�/?�
@�
@�F��G��"�"�<�0�0�0�&�;�;�O�L�L��
����!�#�#�.�q�1���!�/�/��@�@��� � �!1�2�2�2� �5�5�h�?�?�I�%�9�9�)�D�D��GJ�K\�G]�G]�`a�Ga�Ga�S�*�1�-�8�B�C�C�C�gh�N�N�Nr4�default_limitsc��iattdttt|���}|d���	t�d��d�d��}t|td���td<n�#tttf$r�t|dtd���td<t�d��}|�dt|d����	t�|��n#YnxYwYnwxYw	tt�d	��d�d
����td<n�#tttf$ry|dtd<t�d	��}|�d
t|d����	t�|��n#YnxYwYnwxYw|d���t d
kr|d���n|ddt"i���|d���|d���|d���t%��dS)z~Create ve_defaults dict with default values for all limits

    :param dict default_limits: default limits for lve or lvp
    N)rrrrrrb)rrarrr��other�
maxentryprocsrdrc�re)rrrfrgrh)rrrrrr	r�r�r�r
r�rrrNr
r�r��MEM_DEFAULT_CL5�_check_defaults_for_nones)rN�
check_def_valr�rards     r5�_load_ve_defaultsrVns����K���T�z�{�SY�cq�s�s�s�M��M�f�����
��/�/��6�6�q�9�F�F�w�O�O��5�e�;�v�CV�W�W�W��E�����
�I�.����5�n�U�6K�S^�_e�Sf�g�g�g��E���"�"�5�)�)������#�n�U�&;�"<�"<�=�=�=�	��"�"�3�'�'�'�'��	��D����������	��
� ?� ?�� H� H�� K� X� X�Yh� i� i�j�j��D�����
�I�.����*�4�0��D��
�
!�
!�'�
*�
*��
�����^�D�-A�)B�)B�C�C�C�	��"�"�2�&�&�&�&��	��D�����������M�d����� +�a���M�M�e�����]�]�u�W\�^m�Vn�5o�5o�5o���M�f������M�g������M�f����������sW�AB�BD;�D1�0D;�1D5�3D;�:D;�?AF�A*H�3H�
H�H�H�Hc��t���D]^\}}|��d|�d�}trtdd|g��n"tj�|�d���t	jd���_dS)z*Check that all default values are not NoneNzERROR: Incorrect z default valuer(rH�
rI)r�itemsrLrMrP�stderrrVrQ)�key�value�err_msgs   r5rTrT�s���"�'�'�)�)�	�	�
��U����9�c�9�9�9���	-���'�7�!3�4�4�4�4��J����^�^�^�,�,�,��������	�	r4Tc��t��t||��}|st��st��t	|��dS)z�
    :param bool lvp_defaults: load reseller's default limits instead of global
    :param int lvp_id: lvp id to load customise defaults
    N)r-r9rDrMrV)r.r/�load_config_elementsrNs    r5�get_XML_cfgr`�sW������)�&�,�?�?�N�� �#>�#@�#@� ������n�%�%�%�%�%r4c��	tt||d�����}|||<|S#tttf$rt||��cYSwxYw)Nr�rr!)r�r'r�r
r�)r�elr�
setup_datar\s     r5�check_valuere�sm��%��&�r�s��A�A�A�B�B���
�3������
�I�.�%�%�%��;�s�#�$�$�$�$�$�%���s�%(�,A�Ac��tj��}|���|�|��}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
    �r_N)�lveapir$r8�get_idr`)�reseller�xml_config_load_elementsr:�reseller_ids    r5�_load_resellers_xml_datarm�sN���~���H��������/�/�(�+�+�K���2J�K�K�K�K�K�Kr4c
����tjt��a���Yt��}���|vr�|�vr��fd�}n�t	j��r�|��	t
j|��}d|j�d�}t|��5}|�
��}ddd��n#1swxYwYn#t$rd}YnwxYwd|vr3tjtj
d�|d�����fd	�}tD�]n}	||	���r]t!d
|	tt��}
	t#t%t'|	dd�
��|
�����}|td<n#t(t*t,f$rYnwxYwt!d|	tt��t.dkrt!d|	tt��n
dtd<	t#t'|	dd�
����}|td<n#t(t*t,f$rYnwxYwt!d|	tt��t!d|	tt��t!d|	tt����ndSdS)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.
    Nc�h��|�d���ko|�d���kS�Nr�rj�r�)rc�plan_idrjs ��r5�<lambda>z$prepare_setup_data.<locals>.<lambda>�s0�������(=�(=��(H�(t�R�_�_�]g�Mh�Mh�lt�Mt�r4z"/usr/local/directadmin/data/users/z
/user.confrkzpackage=customzNPackage for user with id {} is incorrect, please recover it using Note from {}zYhttps://docs.cloudlinux.com/cloudlinux_os_components/#installation-enabling-and-disablingc�b��|�d���ko|�d��Srprq�rcrrs �r5rsz$prepare_setup_data.<locals>.<lambda>�s0�������(=�(=��(H�(l�QS�Q`�Q`�ak�Ql�Ql�Ml�r4rbrarrbr�rcr1rerrPrQrdrgrfrh)�copyrrd�get_reseller_packages_maprJ�is_dar��getpwuid�pw_namer��readr�r�r��formatr@rer�r�r'r�r
r�r4)
rrrjr��res_pkg_dict�is_needed_plan�user_pwd�filenamer��textrcr�rards
``           r5�prepare_setup_datar��s������;�'�'�J���0�2�2����H��$<�$<��L�Ya�Lb�Ab�Ab�t�t�t�t�t�N�N�� �"�"�
�v�'9��"�|�F�3�3�H�`�H�DT�`�`�`�H��h���(�1� �v�v�x�x��(�(�(�(�(�(�(�(�(�(�(����(�(�(�(��� �����D�D�D�����
$�4�/�/��M��(�h�o�o�"�w������m�l�l�l�N�
�	A�	A�B��~�b�!�!�
A�#�F�B��Z�H�H����6�7I�"�RW�^e�7f�7f�7f�ns�t�t�t�u�u�C�(+�J�u�%�%��"�J�	�:�����D������D�"�k�:�>�>�>��6�M�M���r�;�
�C�C�C�C�()�J�u�%���/���o�V�V�V�W�W�B�')�J�t�$�$��"�J�	�:�����D������G�R��j�A�A�A��F�B��Z�@�@�@��F�B��Z�@�@�@��i��@	A�	AsZ�.B5�B)�B5�)B-�-B5�0B-�1B5�5C�C�68E/�/F	�F	�)H�H�Hc��	tjtd|gtjtj���}|���|jdkS#t$r#tddt�dd�d|�d���YdSwxYw)Nz-l)�stdoutrZr���zfailed to run "� �")�
subprocess�Popen�UMOUNT�PIPE�communicate�
returncode�OSErrorrU)�path�ps  r5�
umount_dirr�s���U���f�d�D�1�*�/�R\�Ra�b�b�b��	�
�
�����|�q� � ���U�U�U��b�b�������d�d�d�"S�T�T�T�T�T�T�U���s�AA�)B�Bc�J�tj�t��sdSg}	t	td��5}|D]?}|���}|r'|�tj|�����@	ddd��n#1swxYwYn(#t$rtddtz��YnwxYw|sdStjtj��	t	dd��5}d�|�
��D��}ddd��n#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
    Nr�r�zfailed to read %sz/proc/mountsc�B�g|]}|���d��S)rI)r�)r?�ms  r5rz"prepare_mounts.<locals>.<listcomp>6s$��:�:�:�q�a�g�g�i�i��l�:�:�:r4zfailed to parse /proc/mounts�
F)r�r��isfile�EXCLUDE_MOUNTS_CONFr�r��appendr�r�r�rU�unshare�CLONE_NEWNS�	readlinesr
r�searchr�)�reg_exp_list�confr�r�r��mounts�ATTEMPTSr�error�mount�reg_expr�s            r5�prepare_mountsr�"s����7�>�>�-�.�.�����L�M�
�%�s�
+�
+�	=�t��
=�
=���'�'�)�)���=� �'�'��
�7�(;�(;�<�<�<��
=�	=�	=�	=�	=�	=�	=�	=�	=�	=�	=�	=����	=�	=�	=�	=���
�M�M�M��b�"5�8K�"K�L�L�L�L�L�M���������O�G�'�(�(�(�B�
�.�#�
&�
&�	;�!�:�:�A�K�K�M�M�:�:�:�F�	;�	;�	;�	;�	;�	;�	;�	;�	;�	;�	;����	;�	;�	;�	;����� �B�B�B��b�"@�A�A�A�A�A�B�����H�
�8�_�_�	�	�����	�	�E�'�
�
���N�N�5�)�)����&�u�-�-�6��E��E����	��E�E�	�	�	sk�B�AB�B�B�B�B�B�"C�?C�&D-�6D!�D-�!D%�%D-�(D%�)D-�-!E�Ec���d}	tj|dd���n #t$rtd|��YnwxYwt	��t
�d���dS)	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 settings�r]N)r��callr�rOr�r��	lve_start)�	MOUNT_CMDs r5r�r�Fs���?�I�5���	��+�F�F�F�F�F���5�5�5�
�(�)�4�4�4�4�4�5��������	�O�O�=�O�>�>�>�>�>s��9�9c�f�t�|d�|��|���dS)zs
    Create LVE container for given ID
    :type lve_id: int
    :type ignore_error: bool
    :return: Nothing
    z8lvectl: Can`t create lve with id {}; error code {{code}}�r]�ignore_errorN)r��
lve_creater|)r�r�s  r5r�r�SsB��
���V�W�^�^�_e�f�f�".��0�0�0�0�0r4c�f�t�|d�|��|���dS)zs
    Create LVP container for given ID
    :type lvp_id: int
    :type ignore_error: bool
    :return: Nothing
    z8lvectl: Can`t create lvp with id {}; error code {{code}}r�N)r��lve_lvp_creater|)r.r�s  r5�
lvp_creater�_sB��
����![�!b�!b�ci�!j�!j�&2��4�4�4�4�4r4c���t��}t��D]F}t�|d�|�����|�|���G|S)N�9lvectl: Can`t destroy lvp with id {}; error code {{code}}r�)�listr6r��lve_lvp_destroyr|r�)�destroyed_listr.s  r5�destroy_lvp_allr�kso���V�V�N��*�*�&�&��
���f�&a�&h�&h�io�&p�&p�	�	r�	r�	r����f�%�%�%�%��r4c��|dkrt��dSt�|d�|�����dS)Nr=r�r�)r�r�r�r|�r.s r5�lvp_destroyr�ts]��
����������
���f�&a�&h�&h�io�&p�&p�	�	r�	r�	r�	r�	rr4c���d�|��}d�|��}d}|dkr�t���rtt	����}tt
tj�������dkr@tj���D] }t�	||���d}�!n�d}n�tj�
|��s=tj���r>tj�|���t�	||���d}n!tj�
|��sd}|r!trttdg��dSdStrtt d	|g��dSt#d
�|����dS)Nz/Can't remove lve {} from kernel - error code -3z1Can`t destroy lve with id {}; error code {{code}}Fr=rr�T�OK�WARNzwarning: {})r|r/r0�boolr�r�r�r1�lve_id_listr��check_inside_list�resellers_supported�detect_inside_lvprLrM�
SINGLE_FORMATr[rO)r��cant_remove_msg�cant_destroy_msg�	destroyed�id_s     r5r�r�}s���H�O�O�PV�W�W�O�J�Q�Q�RX�Y�Y���I�
�����'�'�)�)�	0��_�.�.�/�/�I��t�C�H�(�(�*�*�+�+�,�,�q�0�0��x�+�+�-�-�
!�
!������-=��>�>�>� �	�	�
!��I�I��8�%�%�f�-�-�	���-�-�/�/�	���3�3�F�;�;�G��O�O�F�,<�O�=�=�=��I�I���+�+�F�3�3�	��I��9��	/��
��v�.�.�.�.�.�	/�	/��	9���v��&?�@�@�@�@�@��-�&�&��7�7�8�8�8�8�8r4c	��|r.tj�|��st|��t	j��5t	jd��	ttd��t_
ttd��t_ttd��t_ttd��t_
ttd��t_tdkrHttd��t_ttd	��t_td
kr$ttd��t_|rr|dkr6t&�|td
�|�����n�t&�|td�|�����n]|dkr"t&�td���n5t&�|td�|�����nJ#t0$r=}t3ddt5|��zdzt5|��z��Yd}~nd}~wwxYwddd��dS#1swxYwYdS)Nr�rcrarbrerdrRrfrgrxrhrz'Can`t setup default settings for LVP {}r�z/Can`t setup lvp with id {}; error code {{code}}zCan`t setup default settingsz/Can`t setup lve with id {}; error code {{code}}rIzCan`t setup lve z. RuntimeWarning excepted: )r/r1�	exist_lvpr��warnings�catch_warnings�filterwarningsr�rdr�r�r�r��	ls_memoryr�r�r�r�r�r��lve_set_defaultr|�
lve_lvp_setupr��RuntimeWarningrUrN)r�r.�rws   r5r�r��s���
��c�h�(�(��0�0���6����	�	 �	"�	"�p�p����(�(�(�	p�!$�Z��%5�!6�!6�L��"%�j��&7�"8�"8�L��#&�z�&�'9�#:�#:�L� �%(��E�):�%;�%;�L�"�%(��D�)9�%:�%:�L�"��Q���-0��F�1C�-D�-D��*�(+�J�w�,?�(@�(@��%��Q���'*�:�f�+=�'>�'>��$��
t��Q�;�;��)�)���6_�6f�6f�gm�6n�6n�*�p�p�p�p��'�'���6g�6n�6n�ou�6v�6v�(�x�x�x�x��1����%�%�l�<Z�%�[�[�[�[�����L�2c�2j�2j�kq�2r�2r� �t�t�t����	p�	p�	p�!�!�$6��V���$D�Gd�$d�gj�km�gn�gn�$n�o�o�o�o�o�o�o�o�����	p����7p�p�p�p�p�p�p�p�p�p�p�p����p�p�p�p�p�ps=�J9�HI"�!J9�"
J)�,3J$�J9�$J)�)J9�9J=�J=c��d}d}t}td��t}|at|t��rL	||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-usersrjrF)�packages_users�GetControlPanelUsersr�dict�KeyError)r�rFrj�old_packages_users�temp_packages     r5�"get_package_and_reseller_by_lve_idr��s����G��H�'����&�&�&�"�L�'�N��,��%�%��	�#�F�+�J�7�H��
 ������	�	�	��H�H�H�	����	�"�6�*�9�5�G��
������	�	�	��G�G�G�	�����H��s#�A
�
A�A� A3�3B�Bc�*��t}�dkrtd���t|c}atdkrt|���d}|�|}n1|rtnt
}	t
t�fd�|	��d��}|dkrR	|�d}n#ttf$rd}YnwxYw	|�d}n#ttf$rd}YnwxYw|���t||�	��td
|tt��}
	tt|dd�
��|
���td<n#t t"t$f$rYnwxYwtd�tdtd<td|tt��t&dkrtd|tt��n
dtd<	t)t|dd�
����td<n#t t"t$f$rYnwxYwtd|tt��td|tt��td|tt��n't||����t&dkr
dtd<|st+�|���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
    r�useridrkr�Nc�,��t|����kS)N�r��r�)rr�s �r5rszlve_apply.<locals>.<lambda>s��� 3�4� H� H� H�F� R�r4rFrj�rjrbrarrbr�rcr1rerPrQrdrgrfrh)rjr�rl)r�r�rr`r?r>�next�filter�	NameErrorr�r�rerrdr�r'r�r
r�r4r�r�)r�rrr\rj�out_noder.r��new_packages_usersrc�	node_listr�s`          r5�	lve_applyr��s����$(��
��{�{��X�v�.�.�.�-;�=O�*��N�
��|�|��6�"�"�"�"�	
�B���
���$�0�F�F�&�	�
��R�R�R�R�T]�^�^��
�
����{�{�	�(��0��;�G�G���8�$�	�	�	��G�G�G�	����	�)�&�1�*�=�H�H���8�$�	�	�	��H�H�H�	����
�~��7�X�6�6�6�6��F�B��Z�@�@��	� 8�9K�B�TY�`g�9h�9h�9h�pu� v� v� v�J�u�����J�	�2�	�	�	��D�	�����e��$� +�E� 2�J�u���D�"�k�:�6�6�6��&�=�=���r�;�
�;�;�;�;� !�J�u��	�"�#5�b�g�O�#\�#\�#\�]�]�J�t�����J�	�2�	�	�	��D�	����	�G�R��j�9�9�9��F�B��Z�8�8�8��F�B��Z�8�8�8�8�	�7�X�f�E�E�E�E��'�>�>� !�J�u���)��&��(�(�(�(�(�(�)�)sH�B�B(�'B(�,B;�;C�C�)D/�/E	�E	�='G%�%G?�>G?c�$�t|��dS)a�
    Sometimes python is confused about which encoding
    we should use to print message. E.g. when we use
    "command | grep" to find something in the output.

    According to python docs, "Software should only work with Unicode
    strings internally, converting to a particular encoding on output."

    So let's convert all unicode into str using our "magic" byteify method
    :param string:
    :return:
    N)rO)�strings r5�_print_string_safer�Ds��"
�&�M�M�M�M�Mr4c��td�d�|dd�D��d|dzgz����dS)zz
    Command to print data with only last column 30 symbols wide
    Useful to print data that contains package name.
    rkc��g|]}d|z��S�z%8sr3�r?r�s  r5rz_pprint.<locals>.<listcomp>]���?�?�?�a���	�?�?�?r4Nr��%30s�r��join�r�s r5�_pprintr�XsM��
�r�w�w�?�?�6�#�2�#�;�?�?�?�6�F�SU�J�CV�BW�W�X�X�Y�Y�Y�Y�Yr4c	��td�d�|dd�D��d|dzd|dzgz����dS)z�
    Command to print data with two last columns 30 symbols wide.
    Useful to print full data of every user with package name and reseller name.
    rkc��g|]}d|z��Sr�r3r�s  r5rz_pprint_f.<locals>.<listcomp>er�r4N���r�r�r�r�s r5�	_pprint_fr�`s\��
�r�w�w�?�?�6�#�2�#�;�?�?�?�6�F�SU�J�CV�X^�ag�hj�ak�Xk�Bl�l�m�m�n�n�n�n�nr4c	��td�d|dzgd�|dd�D��z����dS)ze
    Command to print data with first column 30 symbols wide.
    Useful to print packages data.
    rkr�rc��g|]}d|z��Sr�r3r�s  r5rz_pprint_p.<locals>.<listcomp>ms��6U�6U�6U�Q�u�q�y�6U�6U�6Ur4rINr�r�s r5�	_pprint_pr�hsO��
�r�w�w����� 2�3�6U�6U�&�QR�QS�QS�*�6U�6U�6U�U�V�V�W�W�W�W�Wr4c	��td�d|dzgd�|dd�D��zd|dzgz����dS)z�
    Command to print data with first column and last column are 30 symbols wide.
    Useful to print data with user names and package names.
    rkr�rc��g|]}d|z��Sr�r3r�s  r5rz_pprint_r.<locals>.<listcomp>us��6W�6W�6W�Q�u�q�y�6W�6W�6Wr4rIr�Nr�r�s r5�	_pprint_rr�psd��
�r�w�w����� 2�3�6W�6W�&�QR�SU�QU�,�6W�6W�6W�W�[a�dj�km�dn�[n�Zo�o�p�p�q�q�q�q�qr4c� �t|��}t|��ttfvr|�d��rdnd}|�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

    r�TFrkirz*{})rN�typer�
startswithr�r�r|)r\�was_changeds  r5�_pmem_vmem_to_bytes_valuerxs���
��J�J�E��u�+�+�#�w��7�7�E�<L�<L�S�<Q�<Q�7�$�$�W\�K��M�M�#�r�"�"�E����E�
�
��
��
�����#.�9�E�L�L�����E�E��Lr4c�B�d}d}t|t��r!|�d��r|dd�}d}	t|��}n#t$rYdSwxYw|rd}|dzdz}|d	krd
�||��}nd�||dz��}|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"
    rkFr�rINTrjr`rz{}{}Mz{}{}K)rrrr�r�r|)r\r\r�vs    r5�_mb_memr�s����F��K��%��$�$���)9�)9�#�)>�)>���a�b�b�	�������J�J���������r�r���������
��E�T�M�E��q�y�y������.�.��������A��.�.���Ms�A�
A�A�0rc�,�
��t����
�
ddz�
d<�
fd�}|d��dkrt|d����nd}d�}|t|d����t|��t|d����t||d������t||d������t|d	����t|d
����t|d����t|d����|d
��g}t	��}|�||z
}t
r(d��fd�|D����}	d|	zg}n||�|�fd�|D���|S)z^
    Generate header and default package data either as print to stdout or as json string
    raric�0����|d��S)Nrk�r�)r[r2s �r5rsz_formatter.<locals>.<lambda>�s���8�<�<��R�0�0�r4rkc�L�trt|��nt|��Sr>�rqrr�r\s r5rsz_formatter.<locals>.<lambda>�s&���(*�'@��'G�'G�'G�"�5�>�>�r4rbrfrerdrgrcrh)r{r|r��NCPUr}r~rr�r�r��PACKAGEN�,c3�R�K�|]!}d|�d��|d���d�V��"dS)r��":"rkNr�r?r��
fields_maps  �r5rBz_formatter.<locals>.<genexpr>�sB�����Q�Q�Q�Q�q�q�q�*�.�.��B�*?�*?�*?�*?�@�Q�Q�Q�Q�Q�Qr4�{%s}c�<��g|]}��|d����S�rkrrs  �r5rz_formatter.<locals>.<listcomp>�s'���8�8�8�A�*�.�.��B�'�'�8�8�8r4)rrvr�rNr�rLr�)�printer�
default_id�default_package�more_fields�get_data�_cpu�convert_mem_limits�resr�r�r2rs          @@r5�
_formatterr!�s��������!�!�H��u�o��,�H�U�O�0�0�0�0�H�08�����2�0E�0E��H�H�U�O�O�,�,�,�2�D�*�*���3�x�x����#7�#7��4�y�y�#�h�h�v�&6�&6�"7�"7��&�&�x�x��'7�'7�8�8�9�9�3�GY�GY�Zb�Zb�ch�Zi�Zi�Gj�Gj�Ck�Ck��(�(�4�.�.�!�!�C����0A�0A�,B�,B�#�h�h�W[�n�n�J]�J]��H�H�V�$�$�%�%�/���J�
�C�
�\�\�F����+����:��x�x�Q�Q�Q�Q�&�Q�Q�Q�Q�Q����}�o����������8�8�8�8��8�8�8�9�9��Jr4c������fd�}|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
    c����d�t|d}t|d}|dkrd}tdkrt|d���n5|�t|d���nt	d�	��t||���tjt���t|||d
����fd�}d
�}t|���d<t|d�����d<t|d�����d<t||d�������d<t||d�������d<t|d�����d<t|d�����d<t|d�����d<t|d�����d<trt|���d<n|�d<|�trdnd�d<n|�d<d�dvr?dtt�d�d����dz��z�d<nt�d��dz�d<�d�d<tt�d�����d<g}tr(d��fd��D����}d|zg}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
        rkrFrjNrIr�F)rkrgT)rrrjr\c����t�|��tt|��krdtt|��znt�|��S)Nr�)rNrd)r[r�s �r5rsz2_user_formatter.<locals>.wrapper.<locals>.<lambda>�sO����4��9�~�~��Z��_�!5�!5�5�5�%(��J�s�O�(<�(<�$<�$<�;>�t�C�y�>�>�r4c�L�trt|��nt|��Sr>r
rs r5rsz2_user_formatter.<locals>.wrapper.<locals>.<lambda>��&���,.�+D�U�+K�+K�+K�&�u�~�~�r4r�rarbrfre�vmemrdrcrgrh�N/Ar�rir�rc3�Z�K�|]%}d|�d�|����d�V��&dS)r�rN��lower�r?r�r�s  �r5rBz3_user_formatter.<locals>.wrapper.<locals>.<genexpr>s>�����O�O�1�1�1�1�1�d�1�7�7�9�9�o�o�o�>�O�O�O�O�O�Or4rc�D��g|]}�|�����Sr3r*r,s  �r5rz4_user_formatter.<locals>.wrapper.<locals>.<listcomp>s%���6�6�6�!�d�1�7�7�9�9�o�6�6�6r4)r�rCr�rmr`rvrdr�rNrL�_normalize_strr�r�r�r�)
r�rFrj�
check_changedrr r�r�r�rs
       @��r5�wrapperz _user_formatter.<locals>.wrapper�s&������ ��&�y�1��!�$�'�
�3���r�>�>��H��Q���
�w��6�6�6�6�6��#�)��E�R�R�R�R�R���7�7�7�7��w��:�:�:�:��y��$�$���$��(�4�H�H�H�H�J�J�J�J�
�.�.����Y�Y��T�
��-�-��.�.�/�/��U���=�=��0�0�1�1��V���-�-�m�m�F�.C�.C�D�D�E�E��V���-�-�m�m�E�.B�.B�C�C�D�D��V�����t�,�,�-�-��T�
����t�,�,�-�-��T�
��M�M�'�2�2�3�3��W�
��=�=��0�0�1�1��V���	&�,�W�5�5�D��O�O�%�D��O���(,�4�u�u�"�D����'�D����$�u�+����#�c�$�u�+�*<�*<�S�*A�*A�&B�&B�c�&I�"J�"J�J�D��K�K��d�5�k�*�*�c�1�D��K��U���W�
��*�4��=�9�9�:�:��U�����	8��8�8�O�O�O�O��O�O�O�O�O�D��D�=�/�C�C��G�6�6�6�6�v�6�6�6�7�7��
r4r3)r�rr0s`` r5�_user_formatterr1�s0����A�A�A�A�A�A�D�Nr4c���t��	td��|�|rtd|��n#|�td|���ntd��n#YnxYwdg}tt|���}t	��|z}t|��}tD]}|||��z
}�tr*tdd�	|��zd	z��dSdS)
Nr�r��list-reseller-usersr�r�r�	{"data":[r�]})
r`r�r!r�r�r1r�rLrOr�)r�rjrr\r��	formatterr�s       r5�paneluserslimitsr8s���M�M�M�
��\�*�*�*���&�� ��6�2�2�2�2�
�
!� �!6��J�J�J�J�J� ��.�.�.���
�������+�K�
��[�
9�
9�
9�F�
�\�\�K�
'�F���'�'�I��"�"���)�)�D�/�/�!����5�
�k�C�H�H�V�,�,�,�t�3�4�4�4�4�4�5�5s�AA�Ac��td��g}tt��D]6\}}|�t	|��|d|df���7|S)z@Get list of tuples[lve_id, reseller, package] from control panelr�rjrF)r�r	r�r�r�)r\�str_uid�payloads   r5�paneluserslistr<3sf����&�&�&�
�F�%�n�5�5�O�O�����
�
�s�7�|�|�W�Z�%8�'�)�:L�M�N�N�N�N��Mr4c���ddlm}i}td��tt�����||<td��|�t��|S)zBGet dict of pairs[provider, list[package_name]] from control panelr)�DEFAULT_PROVIDER�
list-packages�list-resellers-packages)�
clveconfigr>r�r�r��keysr)r>�packagess  r5�panelpackagesdictrD=sp��,�+�+�+�+�+��H���)�)�)�!%�n�&9�&9�&;�&;�!<�!<�H�
���2�3�3�3�
�O�O�N�#�#�#��Or4c�T�t��td��ttddg���}t	��ddgz}t|t���}tD]}|||��z
}�tr*tdd�	|��zdz��d	Sd	S)
z]
    Implements lvectl all-user-list command

    :return: None, prints result to stdout
    r�r�RESELLERr4)rr5rr6N)
r`r�r!r�r�r1r�rLrOr�)r\r�r7r�s    r5�all_users_limitsrGOs����M�M�M���&�&�&�
�	�	�:�/F�
G�
G�
G�F�
�\�\�Y�
�3�
3�F���	�:�:�:�I��"�"���)�)�D�/�/�!����5�
�k�C�H�H�V�,�,�,�t�3�4�4�4�4�4�5�5r4c���tj��dkr3d�t��D����fd�t|��D��}|S)z�
    Filtering DirectAdmin's admins for `lvectl apply all` command

    :param ve_dict: dict with LVE
    :return: filtering dict

    �DirectAdminc�@�g|]}tj|��j��Sr3)r�r�r�)r?r�s  r5rz(_filtering_da_admins.<locals>.<listcomp>ns%��I�I�I��#�,�t�,�,�3�I�I�Ir4c�$��i|]\}}|�v�	||��
Sr3r3)r?r[r\�uids_da_adminss   �r5�
<dictcomp>z(_filtering_da_admins.<locals>.<dictcomp>os*���`�`�`�*�#�u�c�Q_�F_�F_�3��F_�F_�F_r4)rJ�	getCPNamerr	)�ve_dictrLs @r5�_filtering_da_adminsrPcsV�������-�/�/�I�I����I�I�I��`�`�`�`�	�'�0B�0B�`�`�`���Nr4c���
�	t��tt��}|rHtjj����
�
fd�t���D��}n#t��}YnxYw|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�	||��
Sr3r3)r?�kr�cfg_lvp_id_lists   �r5rMz&prepare_apply_data.<locals>.<dictcomp>{s)���_�_�_���1�!��J^�J^�q�!�J^�J^�J^r4Tr�)rrjr�rr)r�r�r�r/rHr:�id_listrYr?r6r>r1r�r�r�rP�guess_reseller_by_package)r.�packages_users_r�rUrOrr�rA�pkg�	resellersrTs          @r5�prepare_apply_datarZts����!������~�.�.���	`�!�g�.�6�6�8�8�O�_�_�_�_��0D�0D�0F�0F�_�_�_�O���!��&�&�������
��~�~��	��*�*����	��(�&�&�f�&�5�5���G��_�_��FJ�Y]�<^�<^��#�4�8�8�8�9�9��?�?���� � �'+��>�>�G�F�O���O����!�!�'�w�/�/��"�	B�	B�C��'�!�!�����s�|�F�+��!�#�&�C�1�#�6�6�I��9�~�~��!�!�)-�I�a�L�I�I�����)-�D�A�A������Ns�A,A0�0Bc��t��td��t��}t���r&tt�����ni}tj�d���5|�	��D]F}|�
|d��dkr*t|||d||d����G	ddd��n#1swxYwYtd���t���sdStd��}tj�
��}|�	��D�]}t|dd	�
��t|||d||d|���t|d	���td|�
��tj
�|��}tj�|��D]o}t%j|��j}|�
|d��|kr)tj�||d|�d|�d����t||����p��dS)Nr�T)r�rrrj)r�rj)r�F)r.r/r_)r�r�rjr.)r.r_�r�r.zCan`t move lve_id=z to lvp_id=�; error code {code}r�)r�rj)r`r�rZr/r0r��lve_id_lvp_id_pairsr-�context_ignore_errorrBr�r�r1rH�get_reseller_namer��cpapirr�r�r��lve_lvp_move)rO�lve_lvp_mapr��kernel_mapping�lvp_id_rDr��lve_id_s        r5�
lve_apply_allrg�s����M�M�M���&�&�&� �"�"�G�58�5Q�5Q�5S�5S�[�$�s�.�.�0�0�1�1�1�Y[�K�	��	$�	$�$�	$�	7�	7�j�j��l�l�n�n�	j�	j�F����v�q�)�)�Q�.�.��&�7�6�?�6�+B�W�U[�_�]g�Mh�i�i�i�i��	j�j�j�j�j�j�j�j�j�j�j�j����j�j�j�j�
�Q������'�'�)�)���� ��&�&�G��X�\�\�^�^�N��<�<�>�>�>�>��	�7��E�R�R�R�R���"�7�+�F�3�"�7�+�J�7� �	"�	"�	"�	"�	�7��?�?�?�?���7�+�+�+�+���1�1�'�:�:�
��N�1�1�-�@�@�		>�		>�D��l�4�(�(�/�G��!�!�'�1�-�-��8�8���#�#���c��c�c�W�c�c�c�$����

�W�}�=�=�=�=�=�		>�>�>s�
AC6�6C:�=C:c���td��t|���tD�]F}t|���|k�r.tj�|��}|dd�D]�}t�d|��	tj
|���3#t$rQtj�
|��rt�|��|�|��Y��wxYwt!|��|j�|��t't(��td���|D]}t+|���t|���dS��HdS)z,Remove reseller from ve.cfg and from procfs.Tr�r�NrF)rWr`r?r�r/r1�map_lve_id_listr�rbr�ryr�r-�
lve_existsr��remover��
parentNode�removeChildrrr�)r.rc�usersr�s    r5�_remove_resellerro�s����D�����v����������b�1�1�1�V�;�;��H�,�,�V�4�4�E�����(�
)�
)���"�"�1�f�-�-�-�)��L��(�(�(�(���)�)�)��v�(�(��0�0�0�����/�/�/��L�L��(�(�(�(�(�)����
������M�%�%�b�)�)�)��V�����q�!�!�!�!��
"�
"���&�!�!�!�!��v�&�&�&�&��4�4�)<�*�5s�B�AC6�5C6c���t|��rtj|���dStr+t	ddd|zg��tjd��dStd|z��dS)z&Disable reseller limits and call hooksr�r(r3z!no configuration found for LVP %sr�z*warning: no configuration found for LVP %sN)ror�throw_eventrLrMrPrQrO)rDr.s  r5�disable_reseller_limitsrr�s}������I�%�1�=�I�I�I�I�I�I��	I���)�-P�SY�-Y�!Z�[�[�[��H�R�L�L�L�L�L��>��G�H�H�H�H�Hr4c���td��t��d}tD]�}t|���|krkd}t	|��t|��|j�|��tt��t��t|����|sFtr+tddd|zg��tjd��dStd|z��dSdS)	NTFr�r(r3z no configuration found for VE %sr�z)warning: no configuration found for VE %s)rWr`r>r�r�r�rlrmrrr�rLrMrPrQrO)r��Deletedrcs   r5�
lve_deleteru�s���D�����M�M�M��G������b�1�1�1�V�;�;��G�������v�����M�%�%�b�)�)�)��V�����M�M�M��f������J��	J����+M�QW�+X� Y�Z�Z�Z��H�R�L�L�L�L�L��=��H�I�I�I�I�I�J�Jr4c���tj�d��s?trt	dddg��ntd��t
jd��dSdS)N�/proc/lve/enterr(r3zenter by name not supportedz$warning: enter by name not supportedr�)r�r��existsrLrMrOrPrQr3r4r5�lve_enter_checkrysd��
�7�>�>�+�,�,���	:���)�-J�!K�L�L�L�L��8�9�9�9����������r4c���t��	||���z}tdd��}|�|��|���dS#YdSxYw)Nrw�w)ryr�r�rV�close)�signrGrr�s    r5�enter_applyr~se������
��6�<�<�>�>�!���"�C�(�(��	�������	���	�	�	�	�	��
������s�AA"�"A'c�N�t��trTd}d}tD]2}|�d��}|r|d|zdzz
}d}�'|d|zdzz
}�3|dz
}t	|��dSt	d��tD]$}t	|�d�����%dS)	Nr5Tr�r�Fz,"r6�Binaries)r`rLrAr�rO)r\�firstrcr�s    r5�
list_binariesr�(s����M�M�M��+������	,�	,�B��?�?�6�*�*�D��
,��#��*�s�*�*������$��+��+�+����$���
�f�
�
�
�
�
�
�j�����	+�	+�B��"�/�/�&�)�)�*�*�*�*�	+�	+r4c�|�t��tD]%}td|�d�����&dS)N�+r�)r`rAr~r�)rcs r5�
load_binariesr�<sC���M�M�M��2�2���C�����0�0�1�1�1�1�2�2r4c���t��tdd��}|���}|���|D]}t	d|���t��dS)Nrwr��-)ryr�r�r|r~r�)r��lines�ls   r5�reload_binariesr�Bsg�������
��$�$�A�
�K�K�M�M�E��G�G�I�I�I�
�����C�������O�O�O�O�Or4c���td��t��t��d}tD]i}|�d��|krNd}td|��|j�|��tt��t���j|sEtrtddd|zg��ntd|z��tjd	��dSdS)
NTFr�r�r(r3zno configuration found for %sz&warning: no configuration found for %sr�)rWryr`rAr�r~rlrmrrrLrMrOrPrQ)rG�deletedrcs   r5�
del_binaryr�Ls����D���������M�M�M��G�����
�?�?�6�"�"�f�,�,��G���V�$�$�$��M�%�%�b�)�)�)��V�����M�M�M�����	G���)�-L�PV�-W�!X�Y�Y�Y�Y��:�f�E�F�F�F����������r4c��td��t��tD]}|�d��|krdS�t	d|��t
�d��}|�d|��t�	|��tt
��t��dS)NTr�r�rG)rWr`rAr�r~rrrrBr
r)rGrc�bin_xmls   r5�
set_binaryr�as����D�����M�M�M�����
�?�?�6�"�"�f�,�,��F�F�-���V�����"�"�8�,�,�G������(�(�(�� � ��)�)�)��V�����M�M�M�M�Mr4c�R���	|rt}n|rt}nt}��fd�|D��d}n#t$rYdSwxYw|rR�dD]G}|dkrt	|dd��}nt	||d��}|r|j�|���HdStt���dz
}|D]�}	|	dkr\t|�
d����dkr6|	�vr1|�
d��d�d���|	<�dt|�
|	����dkr5|	�vr1|�
|	��d�d���|	<��|rt�d	��dSt�d	��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|]}�|����|��Sr3r3)r?rF�	is_needed�set_datas  ��r5rz#lve_set_default.<locals>.<listcomp>�s*���
8�
8�
8�A���1�h�!7�!7�
8�a�
8�
8�
8r4rN�set-defaultrdrPrQr�ve_id)r@r?r>r
r$rlrm�set�LIMITS_LIST_NAMEr�r	r��plan_deleteru)
r��package_flagr�r.r�rc�tag_�n�to_keeprs
` `       r5r�r�qs�����	��	��D�D�
�	��D�D��D�
8�
8�
8�
8�
8��
8�
8�
8��
;���������������
�	��]�+�	,�	,�D��t�|�|�$�R��/�B�B���$�R��w�7�7���
,���(�(��+�+�+�����"�#�#�h�}�&=�=�G��Z�Z���D�=�=�S��!8�!8��!A�!A�B�B�Q�F�F��H�$�$�"$�"9�"9�'�"B�"B�1�"E�"R�"R�Sb�"c�"c�����
��(�(��/�/�
0�
0�1�
4�
4��H�$�$�"$�"9�"9�%�"@�"@��"C�"P�"P�QX�"Y�"Y������&��H�W�%�&�&�&�&�&��8�G�$�%�%�%�%�%s�05�
A�Ac�|�|dvrdSt|��}|dvrdS	t|��}n	#g}YnxYw||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
    )N�rootT)r�r(F)rr)rArD�username�reseller_users_lists    r5�_check_reseller_user_pairr��st����&�&��t�(��,�,�H��?�"�"��u�!�,�]�;�;����!� ��������&�&�&��t��5s�-�3c
��|dkr0|�dd��}|d}t||��sdStd��|rN||dkrBtj�|��rt
|d���ntt
|���nc|dkrMt���r4t
tj�|d�����nt
|���	t��n#YnxYw	t|d}t|��}|r|dnd}t||�	��n#taYnxYw|ddk�r�d}d
�}d|vrt|d||���d
|vrt!|d
��}	n
td
}	d}
d|vr*t#|d|	���}|tdkrd}
|rt$}nt&}|D�]<}
||
|���r,t(D�]+}||v�r#	|dkrt+|
dd||��nt+|
|d||���A#t,t.t0f$r�|dkr|
}nt|||k}|s|dr�|dkrDt2�d��}|�dt9||����nCt2�|��}|�dt9||����|
�|��Y��'wxYw��-|�dd��st=t2��d}|rN||dkrBtj�|��rt
|d���ntt
|���nc|dkrMt���r4t
tj�|d�����nt
|���t?|d|�����<��>|�s�|d�r�|rt@nd}t2�|��}
|rZ|
�dt9|����|
�d|d��|
�tB��nr|�d��r4|
�dtEj#|d��j$��n)|
�dt9|d����t(D]�}||vr�|dkr|
}nt|||k}|s|dr�|dkrDt2�d��}|�dt9||����nCt2�|��}|�dt9||����|
�|����d}tJD]}|j&�'|
|��d}|st2j(�|
��|�dd��st=t2��|�rtj�|��}t
|d���t?|d|���tR�|tR�*d����t
|���tj+�,|��}tj+�-|���D]3}tj.�/||��t?||�	���4|rtaj1|�	���ngt���r4t
tj�|d�����nt
|���t?|d��n�t(D]�}||vr�|dkrHtB�2d��d�dt9||�����TtB�2|��d�dt9||������|�dd��st=t2��t
|���t?|d|���dS)NrrDr�FT)r.r/r�rkr�c�6�t|���|dkS)Nr�r�r��rcr�s  r5rszlve_set.<locals>.<lambda>�s��.A�QS�.T�.T�.T�X`�ah�Xi�.i�r4r�)r�r�r.rbrar�rdrPrQr�savezskip-update-cfgr/r�r�z
save-username)3r�r�rWr/r1r�r`r0r�r�r�rVr�rrdr�r�r�r?r>r�r*r�r
r�rrrrNr
rr�r"rr�ryrzr@rl�insertBefore�	lastChildr��lve_inforHr`�lvp_lve_id_listr-rbrrqr	)r�r.rDr�rFrYrj�has_ve�is_needed_userr��cpu_is_different�
setted_cpu�el_listrcr[�is_differentr�el_name�added�el2�enables_reseller_limitsrfs                      r5�lve_setr��s&	����{�{� ���_�d�;�;�
��'�"��(���?�?�	��5��D����
�
#�&�H�W�-�-�-��8���f�%�%�	'��v�D�9�9�9�9�9�
�v�&�&�&�&�&�	�1����5�5�7�7���3�8�5�5�h�w�6G�H�H�I�I�I�I�I�	�6�"�"�"�"�
�������
������!�!��'�!2�3��-�g�6�6�	�#,�4�9�Q�<�<�"���7�X�6�6�6�6�6��!� �
�
�
�������A�����i�i���H�$�$��H�5�N�[a�b�b�b�b��X������(�)�)�E�E���'�E� ���H���1�(�5�/�5�Q�Q�Q�J��Z��.�.�.�#(� ��	��G�G��G��-	�-	�B��~�b�(�+�+�,
�+�5�5�C��h���5�"�d�{�{� 2�2�w��QY�Z]�Q^� _� _� _� _� 2�2�s�G�X�c�]� S� S� S��� *�J�	�B�5�5�5�"�e�|�|�/?���0:�#��(�3�-�/O��+�5�x��/?�5�#&�$�;�;�+1�+?�+?��+H�+H�D�$(�$5�$5�o�c�(�SV�-�FX�FX�$Y�$Y�$Y�$Y�+1�+?�+?��+D�+D�D�$(�$5�$5�g�c�(�3�-�>P�>P�$Q�$Q�$Q� "���t� 4� 4� 4���5����
'�, �|�|�$5�u�=�=�%��V�$�$�$����
/�f���(9�9�9��x�)�)�&�1�1�3�#�6��E�E�E�E�E�$�6�2�2�2�2�2��q�[�[�S�%A�%A�%C�%C�[��s�x�'A�'A�(�7�BS�'T�'T�U�U�U�U�U� �v�.�.�.�.��(�7�+�F�;�;�;�;�;���?	-�(�7�+�?	-�*0�;�&�&�e�G��%�%�g�.�.�B��	
B�����c�&�k�k�2�2�2�������(8�9�9�9����z�*�*�*�*��<�<��0�0�B��O�O�F�C�L��'�9J�,K�,K�,S�T�T�T�T��O�O�D�#�h�w�.?�*@�*@�A�A�A�'�
-�
-���(�?�?��e�|�|�'7���(2�#��(�3�-�'G��#�-�x��'7�-��$�;�;�#)�#7�#7��#@�#@�D� �-�-�o�c�(�3�-�>P�>P�Q�Q�Q�Q�#)�#7�#7��#<�#<�D� �-�-�g�c�(�3�-�6H�6H�I�I�I����t�,�,�,���E�!�
�
����+�+�B�s�3�3�3�����
1�� �,�,�R�0�0�0��<�<� 1�5�9�9�
!��� � � ��
-�.1�h�.@�.@��.H�.H�*H�'��6��=�=�=�=��(�7�+�F�;�;�;�;��%�%�f�e�n�n�Q�.?�.?�@�@�@��6�*�*�*�*� #�� 9� 9�&� A� A�
�"�w�6�6�f�6�E�E�?�?�G��F�'�'���8�8�8��g�
�>�>�>�>�>�*�U�0�<�m�T�T�T�T���/�/�1�1�/��s�x�'A�'A�(�7�BS�'T�'T�U�U�U�U�U��v�.�.�.�.��(�7�+�,�,�,��#�	e�	e�C��h����$�;�;��3�3�G�<�<�Q�?�L�L�_�]`�ai�jm�an�]o�]o�p�p�p�p��3�3�C�8�8��;�H�H��QT�U]�^a�Ub�Qc�Qc�d�d�d���|�|�-�u�5�5�	��V�����6�"�"�"�"��(�7�#�F�3�3�3�3��4s+�:D	�	D
�?E�	E�7I
�
C#L1�0L1c�8�td��t��t|d��}t|��dkrd}nt|��dkr|d}|�#tdkr||d<t|d���dSt|d���dS)	zX
    Set package with some heuristic algorithm to simulate old package set behavior
    Tr�rNrIrD��is_resellerF)rWr`rVr�rC�package_set_ext)r�r��
reseller_listrjs    r5�package_setr�s����D�����M�M�M�.�h�w�.?�@�@�M�
�=���Q������	�]�	�	�q�	 �	 � ��#������ 2� 2�$,���!���d�3�3�3�3�3�3���e�4�4�4�4�4�4r4c
�r�td��t��d}|rd�}nd�}d|vrt|d|���tD�]�}|||���r�tD�]U}||v�rM	|dkrC|�d��d	�d
t||����nB|�|��d	�dt||������#tttf$r�|dkrDt�d��}|�d
t||����nCt�|��}|�dt||����|�
|��Y��QwxYw��Wtj��rRt!|�dd
��|d��}|�t$t|����d}���|�s~d
}t�d��}|�d|d��|r$|�d|d��|d}tj��r>t!||d��}|�t$t|����tD]�}||vr�|dkrDt�d��}|�d
t||����nCt�|��}|�dt||����|�
|����tj�
|��t)t��t��t+|��d|vrt-|d��}	n
t.d}	d|vrt1|d|	���|d<|r|dnd}
t3|d|
���dS)NTFc�~�|�d��|dko|�d��|dkS)Nr�r�rjrDrqr�s  r5rsz!package_set_ext.<locals>.<lambda>�s?��b�o�o�d�.C�.C�x�PW�GX�.X�/V��_�_�Z�8�8�H�_�<U�U�r4c�l�|�d��|dko|�d��S)Nr�r�rjrqr�s  r5rsz!package_set_ext.<locals>.<lambda>�s7��b�o�o�d�.C�.C�x�PW�GX�.X�/=�!#����!<�!<�<�r4r�)r�r�rdrPrrQrrDrkr�rFr�rjrbrar�r�)rWr`r�r@r�r	rrNr�r
r�rrr
rJ�is_plesk�_plesk_get_package_idr��XML_PLESK_IDr�r�copy_package_settings_to_cpanelr�rr��
plan_apply)r�r��has_packager~rcr[rr+�package_resellerr�rjs           r5r�r��s0���D�����M�M�M��K��=�V�V���=�=���� � ���t�~�N�N�N�N������>�"�h�'�'�	�'�
-�
-���(�?�?�-��$�;�;��3�3�G�<�<�Q�?�L�L�_�]`�ai�jm�an�]o�]o�p�p�p�p��3�3�C�8�8��;�H�H��QT�U]�^a�Ub�Qc�Qc�d�d�d���&�
�I�>�-�-�-��$�;�;�#)�#7�#7��#@�#@�D� �-�-�o�c�(�3�-�>P�>P�Q�Q�Q�Q�#)�#7�#7��#<�#<�D� �-�-�g�c�(�3�-�6H�6H�I�I�I����t�,�,�,�,�,�-����
#��#�%�%�
=�0����o�r�1R�1R�T\�]d�Te�f�f������c�(�m�m�<�<�<��K���)���
�
!�
!�)�
,�
,��
����h�w�/�0�0�0��	9��O�O�J���(A�B�B�B�'��8����!�!�	9�,�-=�x��?P�Q�Q�H��O�O�L�#�h�-�-�8�8�8�#�	%�	%�C��h����$�;�;�!�/�/��8�8�D��%�%�o�c�(�3�-�6H�6H�I�I�I�I�!�/�/��4�4�D��%�%�g�c�(�3�-�.@�.@�A�A�A����t�$�$�$����$�$�R�(�(�(��V�����M�M�M�#�H�-�-�-�
�����H�V�$�%�%����F�#������2�8�E�?�%�P�P�P����,7�A�x��(�(�T�H��x�� �8�4�4�4�4�4�4s�&BC2�2B9F/�.F/rjrF�returnc����t��}|���}	tt��fd�|����}|dS#t$rYdSwxYw)z7
    Find the right package id from plesk DB query
    c�4��|d�dhvo|d�kS)Nrr�rIr3)r<rFrjs ��r5rsz'_plesk_get_package_id.<locals>.<lambda>�s"���a��d�x��0�0�D�Q�q�T�W�_�r4r�N)r%�list_domain_packages_with_idr�r��
StopIteration)rjrF�panelrC�packs``   r5r�r��s�����
���E��1�1�3�3�H���F�D�D�D�D�D��
�
�����A�w��������t�t����s�(A�
A�Ac�h�t���}td��t}|a|S)z�
    Retrives resellers to packages map from panel using /usr/bin/getcontrolpaneluserspackages
    :return: Dictionary:
    { 'reseller1' -> ['pack1', 'pack2'], 'reseller2' -> ['pack'] }
    r@)r�rvr�)�packages_users_copy�reseller_packages_maps  r5rwrw�s6��)�-�-�/�/���2�3�3�3�*��(�N� � r4c��|d}|d}t��}||vr|||vrt|d���dSdS)z�
    Set reseller package limits
    :param set_data: input data dictionary
    :return: True - limits was set succesfully
            False - supplied provider has no supplied package
    rDr�Tr�F)rwr�)r�rD�package_namer�s    r5�reseller_package_setr��s`���_�-�M��G�$�L�5�7�7���-�-�-�,�BW�Xe�Bf�2f�2f���d�3�3�3�3��t��ur4c���|d}tj��sdSd|��}tj�|��sdSt|�����}|dd�}i}|D]�}|�d��r�|����	d��}|d�
dd�����}|dd	kr|d||<|tvr|�|��|�d
��rd|vrdS��dD]2}||vr,tj||��}	|	pt|||<�3t!||��rdSt#|t$��}
tD](}|
|}d|�d|�d
�}|�|���)t)d�|��|d��dS)zA
    Copy package limits from ve.cfg to cpanel packages data
    r�Nz/var/cpanel/packages/�lve_�=rrkrI�DEFAULT�_PACKAGE_EXTENSIONSr/)rfrer'rXi�)rJrKr�r�r�r�r�rr�r�r�r�rkr��memory_to_pager�is_limits_equals�create_cpanel_limitsr@r�r&r�)
r�rF�package_path�cpanel_package_data�new_cpanel_package_data�old_cpanel_datar��
line_parts�
limit_name�memory_page_value�cpanel_data�limit_value�
limit_lines
             r5r�r�s���w��G�� �"�"����4�7�4�4�L�
�7�>�>�,�'�'�����|�,�,�6�6�8�8��1�!�!�!�4���O�$�	�	���?�?�6�"�"�	5������+�+�C�0�0�J�#�A��.�.�v�r�:�:�@�@�B�B�J��!�}�	�)�)�.8��m��
�+��-�-�-�'�.�.�t�4�4�4��?�?�0�1�1�	�e�4�6G�6G��F�F��-�W�W�
���(�(� (� 7��
�8S� T� T��*;�*V�{�:�?V�O�J�'�����2�2����'�w�
�;�;�K�&�3�3�
�!�*�-��8�J�8�8��8�8�8�
��&�&�z�2�2�2�2��B�G�G�$;�<�<�l�E�R�R�R�R�Rr4c��|���D]7}|dks|dkr�	||||krdS�&#t$rYdSwxYwdS)zC
    check if new set of limits for package are equals to used
    r�r�FT)rBr�)�
old_limits�
new_limitsr[s   r5r�r�As~����� � �����'�>�>�S�F�]�]��	��#��*�S�/�1�1��u�u�2���	�	�	��5�5�5�	�����4s�;�
A
�	A
c���i}|D�]h}|�d��|k�rKtD�]B}	|dkrQt|�d��d�d�������||<n�|dvrpttjt|�|��d�d�����������||<nPt|�|��d�d�������||<��!#tttf$r	d||<Y��@wxYw��j|S)	z�
    create limits for cpanel package file
    use data from ve.cfg:
    limit = limit if found in ve.cfg or DEFAULT
    return dict
    r�rdrPrrQ)rer'rfrr�)r�r�rNr	r�r��page_to_memoryr�r�r
r�)�
package_id�xml_packages�result_datarcrs     r5r�r�Ps����K��3�3��
�?�?�4� � �J�.�.�)�
3�
3��3���}�}�-0��3�3�G�<�<�Q�?�L�L�_�]�]�.�.��%�'�'�$�E�*�*��"9�9�9�-0�$�3� #�B�$;�$;�E�$B�$B�1�$E�$R�$R�SZ�$[�$[� \� \���.�.� �%�'�'�	$�E�*�*�.1��1H�1H��1O�1O�PQ�1R�1_�1_�`g�1h�1h�-i�-i�-o�-o�-q�-q��E�*���"�J�	�:�3�3�3�)2�K��&�&�&�3������s�DE
�
E*�)E*c����td��t��d}���fd�}n��fd�}tD]?}||��r2d}|j�|��tt��n�@|s���At���}t|��dkrd}n|d}|�t�|��dStr*tddd�zg��tj
d	��ntd
�z��t��dS)NTFc�b��|�d���ko|�d��Srprqrus �r5rszplan_delete.<locals>.<lambda>ss0���r���t�'<�'<��'G�'k�PR�P_�P_�`j�Pk�Pk�Lk�r4c�h��|�d���ko|�d���kSrprq)rcrrrDs ��r5rszplan_delete.<locals>.<lambda>us0���r���t�'<�'<��'G�'x�B�O�O�\f�Lg�Lg�kx�Lx�r4rr(r3z"no configuration found for plan %sr�z+warning: no configuration found for plan %s)rWr`r@rlrmrrrVr�r�rLrMrPrQrOrg)rrrDrt�is_needed_packagerc�resellers_listrjs``     r5r�r�ns\�����D�����M�M�M��G���k�k�k�k���x�x�x�x�x��������R� � �	��G��M�%�%�b�)�)�)��V�����E�		�
�M�� �6�w�?�?�N��>�"�"�a�'�'����*�!�,���#��G�X�.�.�.����	M����@�G�L�M�
�
�
�
�H�R�L�L�L�L��?�7�K�L�L�L��O�O�O�O�Or4c�(�t||���dS)NrC)r�)rrrDs  r5�reseller_plan_deleter��s����}�5�5�5�5�5�5r4c��	t|�|��d�d����S#ttf$r9|dkr
t
|n"d�t
|dz��cYSwxYw)Nrrraz{}%ri)rNr	r�r�r
rr|)rcr[s  r5�
get_xml_limitr��s���Y��2�*�*�3�/�/��2�?�?��H�H�I�I�I���
�#�Y�Y�Y�#&�%�<�<�{�3���U�\�\�+�c�BR�TW�BW�5X�5X�X�X�X�Y���s�:=�AB�Bc��d�}|�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|cS�dS)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
        rrIr�)�	enumerate)�input_string�char_to_search�ordinal�count�idx�chs      r5�_get_char_indexz'_normalize_str.<locals>._get_char_index�sR���� ��.�.�	�	�G�C���^�#�#���
���G�#�#��J�J�J���rr4NrNr��rI)r�r�rfind)�data_strr��json_str�trd_idx�last_idxs     r5r.r.�sl�����$���t��z�5�(�+�,�,�H��o�h��Q�/�/�G��~�~�c�"�"�H��G�A�I�h�&�'�'r4c�D�������n�rtnt�d���fd�	}|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
�:������
r4t���tjt�����d<��fd�}n�fd�}tjt���trt	���n��d<d�}|�d���d<t
dkr|�d	���d	<tD�]^}||���rOt|d
��}|dkr|nttd
���d
<ttt|d��t�d
���
��dz���d<	tt|�d��d�d�������d<n#ttf$rYnwxYw|t|d	�����d	<|t|d�����d<t|d���d<t|d���d<t|d���d<��`��d����ddz�d<tt!�d�����d<g}tr(d��fd��	D����}d|zg}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
        rjc�h���|�d��ko|�d���kSrprq)rcr�rDs ��r5rsz5_package_formatter.<locals>.wrapper.<locals>.<lambda>�s5���<�2�?�?�4�;P�;P�+P�,Q�$&�O�O�J�$?�$?�=�$P�r4c�b���|�d��ko|�d��Srprq)rcr�s �r5rsz5_package_formatter.<locals>.wrapper.<locals>.<lambda>�s3���<�2�?�?�4�;P�;P�+P�,D�(*���
�(C�(C�$C�r4r�c�L�trt|��nt|��Sr>r
rs r5rsz5_package_formatter.<locals>.wrapper.<locals>.<lambda>�r&r4rer'rjrfrbrkrar�rir�rPrrQrdrcrgrhNrc3�v�K�|]3}d|�d��|���d���d�V��4dS)r�rr(N�r�r+r,s  �r5rBz6_package_formatter.<locals>.wrapper.<locals>.<genexpr>
	sJ�����Z�Z�a�a�1�1�1�d�h�h�q�w�w�y�y�%�.H�.H�.H�.H�I�Z�Z�Z�Z�Z�Zr4rc�`��g|]*}��|���d����+Srrr,s  �r5rz7_package_formatter.<locals>.wrapper.<locals>.<listcomp>
	s/���>�>�>�!�d�h�h�q�w�w�y�y�"�-�-�>�>�>r4)rmrvrrLr.r�r@r�rNr�r�r	r�r
r�r�r�r�)r�rDr�rrcr�r r�r�r�r�rs``      @���r5r0z#_package_formatter.<locals>.wrapper�s�������	*�$�]�3�3�3��9�[�)�)�D�,�D���!Q�!Q�!Q�!Q�!Q���!D�!D�!D�!D���9�[�)�)�D�59�K�^�L�1�1�1�|��T�
�.�.��)�)�$�u�+�6�6��V����?�?�-�-�d�6�l�;�;�D��L��	9�	9�B� � ��$�$�
9�%�b�&�1�1��(-����u�u��[��=P�9Q�9Q��V�� #�$<�!�"�e�,�,�C��V��4E�4E�%G�%G�%G�HK�%L�!�!��W�
��!$�S��/�/��8�8��;�H�H��Y�Y�&�&�"�"�D��J�J��#�J�/�����D�����1�1�-��F�2K�2K�L�L��V��1�1�-��E�2J�2J�K�K��V��*�2�t�4�4��T�
� -�b�'� :� :��W�
�,�R��8�8��V����8�8�G���$� ��K��,�D��M��*�4��=�9�9�:�:��U�����	@��8�8�Z�Z�Z�Z�SY�Z�Z�Z�Z�Z�D��D�=�/�C�C��G�>�>�>�>�v�>�>�>�?�?��
s�;AF�F�Fr>)r�r�)r�r�rr0s``` r5�_package_formatterr�sO�����!�,�g�g�{�2Y�)�)�PY�G�:�:�:�:�:�:�:�:�v�Nr4c���t��td��t���}td��t���}t	t
t���}tt��dt
���}|D]}|||��z
}�tdkr#tt��dt
���}t|��D]M\}}tj��r|dkr�|D]+}tdkr||||��z
}�|||��z
}�,�Ntr*td	d
�|��zdz��dSdS)Nr?r@�rF�r�rrIT�adminr5rr6)r`r�r�rvr!r��DEFAULT_PACKAGErr�rCr	rJrxrLrOr�)rC�reseller_packagesr\r7rFrD�
packages_list�reseller_packages        r5�get_packages_listr	s����M�M�M���)�)�)��"�"�$�$�H��2�3�3�3�&�+�+�-�-��
�	�o�
>�
>�
>�F�"�:�<�<�U�I�V�V�V�I��%�%���)�)�G�$�$�$�������&�z�|�|��y�Y�Y�Y�	�(1�2C�(D�(D�6�6�$�
�}�����	�=�G�#;�#;�� -�	6�	6����!�!��)�)�$4�m�D�D�D����)�)�$4�5�5�5���		6��5�
�k�C�H�H�V�,�,�,�t�3�4�4�4�4�4�5�5r4c�~�t��td��dg}t��|z}ttt
���}t
|d���}tt��D]\}}|D]}||||��z
}��tr*tdd�|��zdz��dSdS)	Nr@rFrTr�r5rr6)r`r�r�r!r�rrr	r�rLrOr�)rr�r\r7rDrrs       r5�get_resellers_packages_listr0	s����M�M�M��2�3�3�3��,�K�
�\�\�K�
'�F�
�	�o�
>�
>�
>�F�"�6�t�<�<�<�I�(1�.�(A�(A�A�A�$�
�}� -�	A�	A���i�i� 0�-�@�@�@�F�F�	A��5�
�k�C�H�H�V�,�,�,�t�3�4�4�4�4�4�5�5r4c�L�t��td��t���}td��t���}dg}t	��|z}ttt|���}t|dt���}|D]}|||��z
}�t|d���}t|��D]\}}|D]}	|||	|��z
}��tr*td	d
�|��zdz��dSdS)Nr?r@rF)rrFrTr�z
{"data": [rr6)
r`r�r�rvr�r!r�rrr	rLrOr�)
rCrrr�r\r7rFrDrrs
          r5�get_all_packages_listrC	sM���M�M�M���)�)�)��"�"�$�$�H��2�3�3�3�&�+�+�-�-���,�K�
�\�\�K�
'�F�
�	�o�;�
W�
W�
W�F�"�6�u�i�P�P�P�I��%�%���)�)�G�$�$�$���"�6�t�<�<�<�I�(1�2C�(D�(D�A�A�$�
�}� -�	A�	A���i�i� 0�-�@�@�@�F�F�	A��6�
�l�S�X�X�f�-�-�-��4�5�5�5�5�5�6�6r4c�6�t��}|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_list�packages_users_dictrFs   r5�_convert_packages_listrd	s1���&�&���/�/��'.��G�$�$��r4�list-allc�f�|dvrdS|dvr|dkrdSddlm}m}m}m}m}m}m}		|dkrxt�D	|t|d	t|d
d�ia	�n #t$r|ddd�ia	Y�n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
    )r r�rFr?r@r�r3F)r�rFrkr)�
list_users�admin_packages�reseller_package_by_uid�get_uids_list_by_package�resellers_packages�get_reseller_users�list_allr�NrFrj)rFrjTr?r@r�r3r )�clcommon.cpapir"r#r$r%r&r'r(�cached_usersr�r�r��cached_list_packagesr�cached_resellers_packages�cached_reseller_users�cached_defaultrrSr�)�option�lve_package_idrjr"r#r$r%r&r'r(rDrFr�reseller_users_dictrFs               r5r�r�q	s��&�V�V�V��u�
�&�&�&�>�R�+?�+?��u�S�S�S�S�S�S�S�S�S�S�S�S�S�S�S�S�S�S�P
��X����'�W�&�'3�N�'C�I�'N�(4�^�(D�Z�(P�)�)�&�N�N�� �W�W�W�&4�"�RT�6U�6U�%V�N�N�N�W����1�-D�-D�^�-T�-T�*�M�7�7��!�1�1�1�.0�0�M�G�G�G�1����#1�g�S`�2a�2a�!b���t�
�y�
 �
 �,�.F�.F�~�W_�.`�.`�a�N��4�
��
&�
&�$�+�-�~�/�/��!7��!E�!E��'5�$�$�"6���4�
�0�
0�
0�)�0�!3�!3�!5�!5��,:�)�)�";���4�
�|�
#�
#�
�#�)�z�|�|��)�N��4�
�,�
,�
,�%�,�&8�&8��&B�&B�#�)<�%�!4���"7���4�
�z�
!�
!��%�!)�����+�N��4����'�'�'�#�A�&�&�&�&�&�&�&�&������
�
�
���
�����5s��
F�)A�F�A4�0F�3A4�4F�8B�F�B�F�B�
F�$F�:5F�1&F�F�9$F�F�
F.�
F�
F.�-F.c�F�t��tt��S)z2
    Retrieves panel users count
    :return:
    )r�r�r�r3r4r5�get_panel_users_countr3�	s��
�����~���r4c��td��td||���r/t|D]#}tt|��||����"dSdS)Nr�rFr�)r�r�r�r�)rrrjrAs   r5r�r��	sm����&�&�&��I�w��B�B�B�<�!�'�*�	<�	<�C��c�#�h�h��(�;�;�;�;�;�<�<�	<�	<r4c��|D]}}|�dd��}|������}|D]<}t|��dkr'	t	|��}t|���5#Y�9xYw�=�~dS�NrXrkr)r�r�r�r�r�r���
users_listr�rnr�s    r5�destroy_manyr9�	s����	�	���|�|�D��$�$���
�
���"�"�$�$���	�	�D��D�	�	�Q�����t�9�9�D���%�%�%�%����D�����	�	�	s�A8�8A<c�P�t��	t��n#YnxYw|D]}}|�dd��}|������}|D]<}t|��dkr'	t
|��}t|���5#Y�9xYw�=�~dSr6)r`r�r�r�r�r�r�r�r7s    r5�
apply_manyr;
s����M�M�M�
�������
�������	�	���|�|�D��$�$���
�
���"�"�$�$���	�	�D��D�	�	�Q�����t�9�9�D��d�O�O�O�O����D�����	�	�	s��#�>B�B!c	���t�t|��t|��|dt|��zdzt|��zdz���dS)NzCan`t put proccess with pid z in lve r]r�)r��lve_enter_pid_flagsr�rN)�LVEid�PID�flagss   r5�	limit_pidrA
s`��	����E�
�
�C��H�H�e�.��S���9�J�F��U���S�Vk�k������r4c�x�t�t|��dt|��z���dS)NzCan`t release process with pid r�)r��
lve_leave_pidr�rN)r?s r5�release_pidrD
s4��	����C���*K�c�RU�h�h�*V��W�W�W�W�Wr4c	�h�tttttt
ttd�S)N�rr,rr>rr@r4rBrFr3r4r5�get_globalsrG#
s(���l�$��[�$�S� 0�	2�2�2r4c� �g}t���}td��t���}|���at|��D]&\}}|D]}||kr|�|g����'|S)Nr@)r�rvr�r	�extend)rFrj�
pkg_users_oldrrDr�package_name_in_keys       r5rVrV5
s����H�"�'�'�)�)�M��2�3�3�3�&�+�+�-�-��"�'�'�)�)�N�)2�2C�(D�(D�1�1�$�
�}�#0�	1�	1���-�-�-������0�0�0��	1��Or4c��tjtjdd���}|r�tj�|��r�t
||��\}}|dkrqd�|��}trtdd|g��d
Sd|z}tj�d	|z��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_SCRIPTr�)�fileName�	paramName�	separatorrz2Error while executing Endurance's custom script
{}r(rHz	error: %sz%s
N)rJ�get_param_from_file�CL_CONFIG_FILEr�r�r�rr|rLrMrPrZrVrQ)�args�endurance_custom_script�ret_code�std_outr]�err_messages      r5�call_endurance_custom_scriptrXF
s���*�=�{�Ga�Ha�HK�M�M�M���
#�2�7�>�>�2I�#J�#J�
#�(�)@�$�G�G���'��q�=�=�L�S�S�T[�\�\�G��
#��G�g�w�%7�8�8�8�8�8�)�G�3���
� � ��+�!5�6�6�6����"�"�"�"�"�
#�
#�
#�
#��=r4c��tr)tt|tjz����St|��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
    )rqr�r��mmaprrrs r5�_page_to_memory_or_bytesr[_
s5���1��5����.�/�/�0�0�0��5�>�>�r4c��t��}ttj�����}t	��t��D]m}	tj�|��}||vr|�|���<#tttf$r|�|��Y�jwxYw|D]}t|���dS)zV
    Remove from LVE all resellers, which are absent from panel
    :return: None
    N)r�r/rHrYr`r6r`r�r�r�r�ro)�reseller_id_list_for_delete�cpapi_resellers_list�lve_reseller_id�lve_reseller_name�reseller_id_for_deletes     r5�remove_absent_resellersrbp
s���#'�&�&�� ��� 1� 1� 3� 3�4�4���M�M�M�#�:�:�@�@��	@� #�� 9� 9�/� J� J�� �(<�<�<�+�2�2�?�C�C�C����'�7�+�	@�	@�	@�'�.�.��?�?�?�?�?�	@����#>�1�1���/�0�0�0�0�1�1s�8B�,C�Cc��ttj�����D]�\}}	t	j|���#t$rz	t�|��n[#t$rN	tj	�
|��t�|��n#t$rYnwxYwYnwxYwY��wxYwdS)zM
    Remove from LVE all users, which absent in system
    :return: None
    N)r	r/r1rHr�ryr�r�r#r-r�r\s  r5�remove_absent_usersrd�
s���$�C�H�L�L�N�N�3�3������	��L�� � � � ���		�		�		�
�����'�'�'�'���
�
�
���F�%�%�f�-�-�-��O�O�F�+�+�+�+��!�����D�������
������		�����sY�A�
C�A-�,C�-
C�89B2�1C�2
B?	�<C�>B?	�?C�C�C�C�
C)Fr>)r)rrrrrrr)NN)rFT)T)NNN)NFNNr)rrN)FN)r rkN)��
__future__rrr�builtinsr�
past.builtinsrr�future.utilsr	r
�typingrrr
rr�
contextlibr�rvr�rYr�r�r�rZrPr��xml.dom.minidom�dom�minidomrr��	functoolsrr�r�rrhr��clcommon.constrr)rrrr�clcommon.cpapi.cpapiexceptionsrrJ�cleventsrr�cllimits.libr�clveconfig.ve_configrrr�clveconfig.ve_lockrrr r!r"r#r$�clcontrollibr%�secureior&�GET_CP_PACKAGE_SCRIPTr�r�rr�r�r�r[r�r�r�r��IS_DEBUGr��LVEr�r/r6r;rErSrWrUr5rSr6r�r�rLrqr�rdr�rr,rr>r?rr@r4rBrArCrorsr�r�r�r�r�r�r�r�r�r�r��contextmanagerr�r�r�rMrrr$r'r*r-r�r9rDrMrNrVrTr`rermr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrr!r1r8r<rDrGrPrZrgrorrruryr~r�r�r�r�r�r�r�r�r�r�r�rwr�r�r�r�r�r�r�r.rrrrr,r+r*r-r.rr�r3r�r9r;rArDrGrVrXr[rbrdr3r4r5�<module>r{s���&�%�%�%�%�%�&�&�&�&�&�&�������������-�-�-�-�-�-�-�-�+�+�+�+�+�+�+�+�4�4�4�4�4�4�4�4�4�4�4�4�4�4���������������������	�	�	�	�
�
�
�
�	�	�	�	�����
�
�
�
����������������������������
�
�
�
�������
�
�
�
�����"�"�"�"�"�"�g�g�g�g�g�g�g�g�g�g�g�g�8�8�8�8�8�8�����P�P�P�P�P�P�P�P�%�%�%�%�%�%�O�O�O�O�O�O�O�O�O�O�E�E�E�E�E�E�E�E�D�D�D�D�D�D�D�D�D�D�D�D�D�D�*�*�*�*�*�*�,�,�,�,�,�,�?��
������	��	��:�����
��3�r�z�~�~�m�Q�/�/�0�0����!�!�'�+�.�.���E�
�C�C��E��!�!�!�E�

�#��-�-�-�C����%�%�%�K�K�K��=�����$3�3�3�3�*����
�
�
���
��
�
�����
�
�
��
�
�
�	�	��O�N�N������
�
���
�
�
��
����
�
�	��	����
�
�
�����	������
���
���,+�+�+�+�,
�
�
�1�1�1�<&�%�'�'�9�<�<�>�>������,���$���*�������*4�4�4���"�"���"�(BC�>?�
�
�
�
�(�������&
�
�
�[�[�[�����2�2�2�2�2�2����#��#�D�#�#�#�#�Lk�k�k�"i�"i�"i�J+ �d�3��8�n�+ �+ �+ �+ �\
�
�
� 
&�
&�
&�
&� %�%�%�L�L�L�L�AA�AA�AA�AA�HU�U�U�!�!�!�H
?�
?�
?�	0�	0�	0�	0�	4�	4�	4�	4����r�r�r�9�9�9�F"p�"p�"p�"p�J!�!�!�LV)�V)�V)�V)�r���(Z�Z�Z�o�o�o�X�X�X�r�r�r����,���6����>%,�K�K�K�K�`5�5�5�5�6������$5�5�5�(���".�.�.�.�d,>�,>�,>�^���:	I�	I�	I�J�J�J�*���
�
�
�+�+�+�(2�2�2�������*
�
�
� +&�+&�+&�+&�\���Fz�z�z�z�z5�5�5�5�2E5�E5�E5�E5�P
�C�
�#�
�(�3�-�
�
�
�
� !�!�!����,*S�*S�*S�Z������<#�#�#�#�L6�6�6�Y�Y�Y�$(�$(�$(�NH�H�H�H�X5�5�5�:5�5�5�&6�6�6�4!�� �� �� �� ��	�	�	�m�m�m�m�`���<�<�<�<�
�
�
����(���X�X�X�2�2�2�$
�
�
�"#�#�#�2���"1�1�1�4����r4