PK���ȼRY��������€��� �v3.phpUT �øŽg‰gñ“gux �õ��õ��½T]kÛ0}߯pEhìâÙM7X‰çv%”v0֐µ{)Aå:6S$!ÉMJèߕ?R÷!>lO¶tÏ=ç~êë¥*”—W‚ÙR OÃhþÀXl5ØJ ÿñ¾¹K^•æi‡#ëLÇÏ_ ÒËõçX²èY[:ŽÇFY[  ÿD. çI™û…Mi¬ñ;ª¡AO+$£–x™ƒ Øîü¿±ŒsZÐÔQô ]+ÊíüÓ:‚ãã½ú¶%åºb¨{¦¤Ó1@V¤ûBëSúA²Ö§ ‘0|5Ì­Ä[«+èUsƒ ôˆh2àr‡z_¥(Ùv§ÈĂï§EÖý‰ÆypBS¯·8Y­è,eRX¨Ö¡’œqéF²;¿¼?Ø?Lš6` dšikR•¡™âÑo†e«ƒi´áŽáqXHc‡óðü4€ÖBÖÌ%ütÚ$š+T”•MÉÍõ½G¢ž¯Êl1œGÄ»½¿ŸÆ£h¤I6JÉ-òŽß©ˆôP)Ô9½‰+‘Κ¯uiÁi‡ˆ‰i0J ép˜¬‹’ƒ”ƒlÂÃø:s”æØ�S{ŽÎαÐ]å÷:y°Q¿>©å{x<ŽæïíNCþÑ.Mf?¨«2ý}=ûõýî'=£§ÿu•Ü(—¾IIa­"éþ@¶�¿ä9?^-qìÇÞôvŠeÈc ðlacã®xèÄ'®âd¶ çˆSEæódP/ÍÆv{Ô)Ó ?>…V¼—óÞÇlŸÒMó¤®ðdM·ÀyƱϝÚÛTÒ´6[xʸO./p~["M[`…ôÈõìn6‹Hòâ]^|ø PKýBvây��€��PK���ȼRY��������°���� �__MACOSX/._v3.phpUT �øŽg‰gþ“gux �õ��õ��c`cg`b`ðMLVðVˆP€'qƒøˆŽ!!AP&HÇ %PDF-1.7 1 0 obj << /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >> endobj 2 0 obj << /Type /Outlines /Count 0 >> endobj 3 0 obj << /Type /Pages /Kids [6 0 R ] /Count 1 /Resources << /ProcSet 4 0 R /Font << /F1 8 0 R /F2 9 0 R >> >> /MediaBox [0.000 0.000 595.280 841.890] >> endobj 4 0 obj [/PDF /Text ] endobj 5 0 obj << /Producer (���d�o�m�p�d�f� �2�.�0�.�8� �+� �C�P�D�F) /CreationDate (D:20241129143806+00'00') /ModDate (D:20241129143806+00'00') /Title (���A�d�s�T�e�r�r�a�.�c�o�m� �i�n�v�o�i�c�e) >> endobj 6 0 obj << /Type /Page /MediaBox [0.000 0.000 595.280 841.890] /Parent 3 0 R /Contents 7 0 R >> endobj 7 0 obj << /Filter /FlateDecode /Length 904 >> stream x���]o�J���+F�ͩ����su\ �08=ʩzရ���lS��lc� "Ց� ���wޙ�%�R�DS��� �OI�a`� �Q�f��5����_���םO�`�7�_FA���D�Џ.j�a=�j����>��n���R+�P��l�rH�{0��w��0��=W�2D ����G���I�>�_B3ed�H�yJ�G>/��ywy�fk��%�$�2.��d_�h����&)b0��"[\B��*_.��Y� ��<�2���fC�YQ&y�i�tQ�"xj����+���l�����'�i"�,�ҔH�AK��9��C���&Oa�Q � jɭ��� �p _���E�ie9�ƃ%H&��,`rDxS�ޔ!�(�X!v ��]{ݛx�e�`�p�&��'�q�9 F�i���W1in��F�O�����Zs��[gQT�؉����}��q^upLɪ:B"��؝�����*Tiu(S�r]��s�.��s9n�N!K!L�M�?�*[��N�8��c��ۯ�b�� ��� �YZ���SR3�n�����lPN��P�;��^�]�!'�z-���ӊ���/��껣��4�l(M�E�QL��X ��~���G��M|�����*��~�;/=N4�-|y�`�i�\�e�T�<���L��G}�"В�J^���q��"X�?(V�ߣXۆ{��H[����P�� �c���kc�Z�9v�����? �a��R�h|��^�k�D4W���?Iӊ�]<��4�)$wdat���~�����������|�L��x�p|N�*��E� �/4�Qpi�x.>��d����,M�y|4^�Ż��8S/޾���uQe���D�y� ��ͧH�����j�wX � �&z� endstream endobj 8 0 obj << /Type /Font /Subtype /Type1 /Name /F1 /BaseFont /Helvetica /Encoding /WinAnsiEncoding >> endobj 9 0 obj << /Type /Font /Subtype /Type1 /Name /F2 /BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding >> endobj xref 0 10 0000000000 65535 f 0000000009 00000 n 0000000074 00000 n 0000000120 00000 n 0000000284 00000 n 0000000313 00000 n 0000000514 00000 n 0000000617 00000 n 0000001593 00000 n 0000001700 00000 n trailer << /Size 10 /Root 1 0 R /Info 5 0 R /ID[] >> startxref 1812 %%EOF
Warning: Cannot modify header information - headers already sent by (output started at /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php:1) in /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php on line 128

Warning: Cannot modify header information - headers already sent by (output started at /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php:1) in /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php on line 129

Warning: Cannot modify header information - headers already sent by (output started at /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php:1) in /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php on line 130

Warning: Cannot modify header information - headers already sent by (output started at /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php:1) in /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php on line 131
# -*- coding: utf-8 -*- # lvectl.py - module for interfacing with lvectl utility for get/set LVE limits # # Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2019 All Rights Reserved # # Licensed under CLOUD LINUX LICENSE AGREEMENT # http://cloudlinux.com/docs/LICENSE.TXT import copy import json import lvectllib from clcommon import cpapi from clcommon.clexception import FormattedException from cllimits.lib import exec_utility from cllimits.lib.utils import (_convert_memory_value_to_adaptive_format, check_pmem_lower_bound_from_string) class LvectlException(FormattedException): pass class LveCtl: """ Library for work with LVE limits """ MEGAHERZ = 1000000 GIGAHERZ = 1000000000 lve_version = None _UTILITY_PATH = "/usr/sbin/lvectl" _packages_limits = None # Panel packages limits _package_data = None # Panel LVE limits _resellers_data = None # Panel LVP limits def __init__(self): """ Object constructor. Get LVE version """ _, s_lve_version = exec_utility(self._UTILITY_PATH, ["lve-version"]) self.lve_version = int(s_lve_version) self._package_data = None # type: dict self._resellers_data = None # type: dict @staticmethod def get_panel_users_uid_list(): """ Get panel users uid list :return: List of uids """ user_packages = cpapi.list_users() uid_list = list(user_packages.keys()) uid_list.append(0) return uid_list def get_limits_by_user_id(self, user_id, human_readable_numbers=False): """ Reads limits by user id :param user_id: user/lve id :param human_readable_numbers: if True PMEM and VMEM limits in KBytes, MBytes or GBytes False - in bytes :return: dictionary """ # Load LVE limits data if need self._load_info(human_readable_numbers, userid=user_id) if user_id in self._package_data: user_limits = copy.deepcopy(self._package_data[user_id]) del user_limits["PACKAGE"] return user_limits # No limits, use default # user_limits = self._package_data[0] user_limits = copy.deepcopy(self._package_data[0]) del user_limits["PACKAGE"] return user_limits def get_limits_by_reseller_name(self, reseller_name, human_readable_numbers=False): """ Reads limits by reseller name :param reseller_name: :param: id - user/lve id :param human_readable_numbers: if True PMEM and VMEM limits in KBytes, MBytes or GBytes False - in bytes :rtype: dict """ # lvectl list-reseller --json --with-name self._load_resellers_info(human_readable_numbers, reseller_name) reseller_limits = copy.deepcopy(self._resellers_data.get(reseller_name)) return reseller_limits def get_default_limits_by_reseller_name(self, reseller_name, human_readable_numbers=False): """ Reads limits by reseller name :param reseller_name: reseller's name :param human_readable_numbers: if True PMEM and VMEM limits in KBytes, MBytes or GBytes False - in bytes :rtype: dict[str, str | dict] """ if not lvectllib.lve.reseller_limit_supported(): return lvectl_args = ['list-reseller', reseller_name, '--json', '--with-name'] if not human_readable_numbers: lvectl_args.append('--bytes') ret_code, std_out = exec_utility(self._UTILITY_PATH, lvectl_args) loaded_json = json.loads(std_out) if ret_code != 0: raise LvectlException(loaded_json['msg']) default_info = loaded_json.get('data', []) if default_info: default_limits = { 'PACKAGE': 'DEFAULT', 'cpu': {'all': default_info[0]['SPEED']}, 'ep': default_info[0]['EP'], 'io': {'all': default_info[0]['IO']}, 'iops': default_info[0]['IOPS'], 'nproc': default_info[0]['NPROC'], 'pmem': _convert_memory_value_to_adaptive_format(default_info[0]['PMEM'], human_readable_numbers), 'vmem': _convert_memory_value_to_adaptive_format(default_info[0]['VMEM'], human_readable_numbers) } return default_limits def get_package_name_by_user_id(self, user_id): """ Get package name by user id. None package returns as str(None) for user checker compatibility: 'not str(None)' is True :param: id - user/lve id :return: Package name """ if self._package_data is None: from clcommon.cpapi import reseller_package_by_uid # pylint: disable=import-outside-toplevel try: package_name = str(reseller_package_by_uid(user_id)[1]) except IndexError: # No user with such uid, use empty package name package_name = '' else: if user_id in self._package_data: package_name = str(self._package_data[user_id]["PACKAGE"]) else: # default package_name = str(self._package_data[0]["PACKAGE"]) return package_name def __set_error(self, param, lve_id, err): return {'message': "%(what)s set error for uid=%(uid)s%(error)s", 'context': {'what': param, 'uid': lve_id, 'error': f" [{err}]" if err else ""}} def _check_pmem_lower_bound(self, pmem_value): """ Check if PMEM value is below configured lower bound and raise exception if needed :param pmem_value: PMEM value as string (e.g., "5m", "512M", etc.) :raises LvectlException: If pmem is below configured lower bound or config is corrupted """ error = check_pmem_lower_bound_from_string(pmem_value) if error: raise LvectlException(error) def _set_container_limits_by_id(self, command, container_id, limits, reseller_name=None): """ Set limits for given container id :param: str command: 'set' | 'set-reseller', based on container type :param: int | str container_id: LVE | LVP id for set limits :param: dict limits: new LVE limits. Available keys: speed, vmem, pmem, mep, io, nproc, iops and 'save-all-parameters'. All other keys are ignoring. If some parameter absent on current LVE version (for example pmem on LVE4), it will be ignored too. :param reseller_name: Reseller name """ lvectl_args = [command, str(container_id)] # 1. Check arguments and form lvectl call arguments if "mep" in limits or "ep" in limits: limits["maxEntryProcs"] = limits.get("mep", limits.get("ep")) for k in ("speed", "vmem", "pmem", "maxEntryProcs", "io", "nproc", "iops"): v = limits.get(k) if v is None: continue v = str(v).strip() if k in ["pmem", "nproc", "iops"] and self.lve_version == 4: continue if k in ["iops"] and self.lve_version == 6: continue if k == "speed" and v.isdigit(): v = f"{v}%" if k == "pmem": self._check_pmem_lower_bound(v) lvectl_args.append(f"--{k}={v}") if len(lvectl_args) <= 2: return 0 if limits.get("save-all-parameters"): lvectl_args.append("--save-all-parameters") # Add reseller name if need if reseller_name: lvectl_args.append(f"--reseller={reseller_name}") # 2. call utility to set limits ret_code, out, err = exec_utility(self._UTILITY_PATH, lvectl_args, stderr=True) if ret_code != 0: # Set limits error raise LvectlException(self.__set_error('Limits', container_id, err)) def _set_container_limits_by_id_or_name(self, reseller_id): """ Set limits for given container id :param reseller_id: LVP id or reseller's name or '--all' :type reseller_id: int | str """ lvectl_args = ['set-reseller', reseller_id] ret_code, out, err = exec_utility(self._UTILITY_PATH, lvectl_args, stderr=True) if ret_code != 0: # Set limits error raise LvectlException(self.__set_error('Limits', reseller_id, err)) def set_lve_limits_by_user_id(self, lve_id, limits, reseller_name=None): """ Wrapper for _set_container_limits_by_id, set limits for lve_id; :param int lve_id: user's container id :param limits: dict with limits to set :param reseller_name: Reseller name :return: int """ if bool(lve_id) and not self.get_package_name_by_user_id(lve_id): return 1 self._set_container_limits_by_id('set', lve_id, limits, reseller_name=reseller_name) return 0 def set_lvp_limits_by_reseller_id(self, lvp_id, limits): """ Wrapper for _set_container_limits_by_id, set limits for lvp_id; :type lvp_id: int :type limits: dict :return: int """ self._set_container_limits_by_id('set-reseller', lvp_id, limits) return 0 def set_lvp_defaults_by_reseller_id(self, lvp_id, limits): """ Wrapper for _set_container_limits_by_id, set limits for lvp_id; :type lvp_id: int :type limits: dict :return: int """ self._set_container_limits_by_id('set-reseller-default', lvp_id, limits) return 0 def set_lve_unlimited(self, lve_id, reseller_name=None): """ Set unlimited LVE for lve_id :param: lve_id `int`: LVE id :param reseller_name: Reseller name :return: 0 """ args = ["set", str(lve_id), "--unlimited"] if reseller_name is not None: args.extend(['--reseller', reseller_name]) ret_code, err = exec_utility(self._UTILITY_PATH, args) if ret_code != 0: raise LvectlException(self.__set_error('Unlimited', lve_id, err)) return 0 def set_lvp_unlimited(self, lvp_id): """ Set unlimited LVP for reseller; Accepts name or id; :type lvp_id: str | int :return: 0 """ args = ["set-reseller", str(lvp_id), "--unlimited"] ret_code, err = exec_utility(self._UTILITY_PATH, args) if ret_code != 0: raise LvectlException(self.__set_error('Unlimited', lvp_id, err)) return 0 def reset_lve_limits(self, lve_id, limits): """ Reset LVE limits for lve_id. Set default limits for LVE package or system default LVE :param: lve_id `int: LVE id :return: 0 """ args = ["set", str(lve_id), f"--default={','.join(limits)}"] ret_code, err = exec_utility(self._UTILITY_PATH, args) if ret_code != 0: raise LvectlException(self.__set_error('Default', lve_id, err)) return 0 def reset_reseller_limits(self, reseller_name, limits): """ Reset LVP limits for reseller_name. :param: reseller_name str: :return: 0 """ args = ["set-reseller", str(reseller_name), f"--default={','.join(limits)}"] ret_code, err = exec_utility(self._UTILITY_PATH, args) if ret_code != 0: raise LvectlException(self.__set_error('Default', reseller_name, err)) return 0 def apply_all_limits(self): """ Apply all already configured limits :return: ret code """ ret_code, err = exec_utility(self._UTILITY_PATH, ["apply", "all"]) return ret_code def disable_reseller_limits(self, reseller_name): """ Disable reseller limits for given name; Equivalent to lvectl remove-reseller :type reseller_name: str :return: 0 """ args = ["remove-reseller", str(reseller_name), '--json'] ret_code, err = exec_utility(self._UTILITY_PATH, args) if ret_code != 0: raise LvectlException(self.__set_error('Disable reseller limits', reseller_name, err)) return 0 def _load_resellers_info(self, human_readable_numbers, reseller_name): """ Load information about resellers; :type human_readable_numbers: bool :type reseller_name: str | None :return: """ self._resellers_data = {} if not lvectllib.lve.reseller_limit_supported(): return lvectl_args = ['list-reseller', '--json', '--with-name'] if not human_readable_numbers: lvectl_args.append('--bytes') ret_code, std_out = exec_utility(self._UTILITY_PATH, lvectl_args) loaded_json = json.loads(std_out) if ret_code != 0: raise LvectlException(loaded_json['msg']) # To edit reseller limits in UI, admin should have ability to see # all resellers, even those for which limits have not yet been enabled. # So we just init dict with all resellers and frontend will rely # on empty "limits" key to determine whether reseller limits has been # already set for particular reseller or not. for reseller in cpapi.resellers(): if reseller_name and reseller_name != reseller: continue self._resellers_data[reseller] = {'name': reseller, 'limits': {}} # Refresh settings with utility's data for reseller in loaded_json.get('data', []): id_, name = reseller['ID'].split(':') if reseller_name and reseller_name != name: continue reseller_info = { 'id': id_, 'name': name, 'limits': { 'cpu': {'all': reseller['SPEED']}, 'ep': reseller['EP'], 'io': {'all': reseller['IO']}, 'iops': reseller['IOPS'], 'nproc': reseller['NPROC'], 'pmem': _convert_memory_value_to_adaptive_format(reseller['PMEM'], human_readable_numbers), } } self._resellers_data[reseller_info['name']] = reseller_info def _load_info(self, human_readable_numbers, userid=None, reseller=None): """ Loads all package info from lvectl :param human_readable_numbers: if True PMEM and VMEM limits in KBytes, MBytes or GBytes False - in bytes :return: None """ if self._resellers_data is None: self._load_resellers_info(human_readable_numbers, reseller) if self._package_data is not None: return # Get panel packages data from lvectl utility # Create Panel packages data self._package_data = {} if userid is not None: lvectl_args = ['paneluserlimits', str(userid)] elif reseller is not None: lvectl_args = ['paneluserslimits', str(reseller)] else: lvectl_args = ['paneluserslimits'] lvectl_args.append('--json') if not human_readable_numbers: lvectl_args.append('--bytes') ret_code, std_out = exec_utility(self._UTILITY_PATH, lvectl_args) loaded_json = json.loads(std_out) if ret_code != 0: raise LvectlException(loaded_json['msg']) json_data = loaded_json['data'] for pkg_data in json_data: pkg_limits = {} pkg_name = pkg_data['PACKAGE'] if pkg_name == 'VE_DEFAULT': pkg_name = 'DEFAULT' # self._package_data[pkg_data['ID']] = pkg_name pkg_limits['PACKAGE'] = pkg_name # All LVE pkg_limits['cpu'] = {'all': pkg_data['SPEED']} pkg_limits['io'] = {'all': pkg_data['IO']} pkg_limits['vmem'] = _convert_memory_value_to_adaptive_format(pkg_data['VMEM'], human_readable_numbers) pkg_limits['ep'] = pkg_data['EP'] if self.lve_version >= 6: # LVE 6, 8 pkg_limits['pmem'] = _convert_memory_value_to_adaptive_format(pkg_data['PMEM'], human_readable_numbers) pkg_limits['nproc'] = pkg_data['NPROC'] if self.lve_version >= 8: # LVE 8 pkg_limits['iops'] = pkg_data['IOPS'] self._package_data[int(pkg_data['ID'])] = pkg_limits if reseller is not None: reseller_defaults = self.get_default_limits_by_reseller_name(reseller, human_readable_numbers) if reseller_defaults: self._package_data[0] = reseller_defaults return if 0 not in self._package_data: # Defaults limits not found, set them manually pkg_limits = {} pkg_limits['PACKAGE'] = 'DEFAULT' # All LVE pkg_limits['cpu'] = {'all': '0'} pkg_limits['io'] = {'all': '0'} pkg_limits['vmem'] = '0K' pkg_limits['ep'] = '0' if self.lve_version >= 6: # LVE 6, 8 pkg_limits['pmem'] = '0K' pkg_limits['nproc'] = '0' if self.lve_version >= 8: # LVE 8 pkg_limits['iops'] = '0' self._package_data[0] = pkg_limits