Linux premium180.web-hosting.com 4.18.0-553.54.1.lve.el8.x86_64 #1 SMP Wed Jun 4 13:01:13 UTC 2025 x86_64
LiteSpeed
: 162.0.209.168 | : 216.73.216.187
Cant Read [ /etc/named.conf ]
8.3.30
nortrmdp
www.github.com/MadExploits
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
CPANEL RESET
CREATE WP USER
BLACK DEFEND!
README
+ Create Folder
+ Create File
/
opt /
cloudlinux /
venv /
lib /
python3.11 /
site-packages /
[ HOME SHELL ]
Name
Size
Permission
Action
GitPython-3.1.32.dist-info
[ DIR ]
drwxr-xr-x
Jinja2-3.0.3.dist-info
[ DIR ]
drwxr-xr-x
Mako-1.2.4.dist-info
[ DIR ]
drwxr-xr-x
MarkupSafe-2.1.3.dist-info
[ DIR ]
drwxr-xr-x
PyJWT-2.8.0.dist-info
[ DIR ]
drwxr-xr-x
PyMySQL-1.1.0.dist-info
[ DIR ]
drwxr-xr-x
PyVirtualDisplay-3.0.dist-info
[ DIR ]
drwxr-xr-x
PyYAML-6.0.1.dist-info
[ DIR ]
drwxr-xr-x
__pycache__
[ DIR ]
drwxr-xr-x
_distutils_hack
[ DIR ]
drwxr-xr-x
_pytest
[ DIR ]
drwxr-xr-x
_yaml
[ DIR ]
drwxr-xr-x
aiohttp
[ DIR ]
drwxr-xr-x
aiohttp-3.9.2.dist-info
[ DIR ]
drwxr-xr-x
aiohttp_jinja2
[ DIR ]
drwxr-xr-x
aiohttp_jinja2-1.5.dist-info
[ DIR ]
drwxr-xr-x
aiohttp_security
[ DIR ]
drwxr-xr-x
aiohttp_security-0.4.0.dist-in...
[ DIR ]
drwxr-xr-x
aiohttp_session
[ DIR ]
drwxr-xr-x
aiohttp_session-2.9.0.dist-inf...
[ DIR ]
drwxr-xr-x
aiosignal
[ DIR ]
drwxr-xr-x
aiosignal-1.3.1.dist-info
[ DIR ]
drwxr-xr-x
alembic
[ DIR ]
drwxr-xr-x
alembic-1.11.1.dist-info
[ DIR ]
drwxr-xr-x
annotated_types
[ DIR ]
drwxr-xr-x
annotated_types-0.6.0.dist-inf...
[ DIR ]
drwxr-xr-x
astroid
[ DIR ]
drwxr-xr-x
astroid-2.15.6.dist-info
[ DIR ]
drwxr-xr-x
attr
[ DIR ]
drwxr-xr-x
attrs
[ DIR ]
drwxr-xr-x
attrs-23.1.0.dist-info
[ DIR ]
drwxr-xr-x
backports
[ DIR ]
drwxr-xr-x
certifi
[ DIR ]
drwxr-xr-x
certifi-2023.7.22.dist-info
[ DIR ]
drwxr-xr-x
cffi
[ DIR ]
drwxr-xr-x
cffi-1.15.1.dist-info
[ DIR ]
drwxr-xr-x
chardet
[ DIR ]
drwxr-xr-x
chardet-5.2.0.dist-info
[ DIR ]
drwxr-xr-x
charset_normalizer
[ DIR ]
drwxr-xr-x
charset_normalizer-2.1.1.dist-...
[ DIR ]
drwxr-xr-x
cl_dom_collector
[ DIR ]
drwxr-xr-x
cl_website_collector
[ DIR ]
drwxr-xr-x
clcagefslib
[ DIR ]
drwxr-xr-x
clcommon
[ DIR ]
drwxr-xr-x
clconfig
[ DIR ]
drwxr-xr-x
clconfigure
[ DIR ]
drwxr-xr-x
cldashboard
[ DIR ]
drwxr-xr-x
clevents
[ DIR ]
drwxr-xr-x
clflags
[ DIR ]
drwxr-xr-x
cllicense
[ DIR ]
drwxr-xr-x
cllimits
[ DIR ]
drwxr-xr-x
cllimits_validator
[ DIR ]
drwxr-xr-x
cllimitslib_v2
[ DIR ]
drwxr-xr-x
cllvectl
[ DIR ]
drwxr-xr-x
clpackages
[ DIR ]
drwxr-xr-x
clquota
[ DIR ]
drwxr-xr-x
clselect
[ DIR ]
drwxr-xr-x
clselector
[ DIR ]
drwxr-xr-x
clsentry
[ DIR ]
drwxr-xr-x
clsummary
[ DIR ]
drwxr-xr-x
clveconfig
[ DIR ]
drwxr-xr-x
clwizard
[ DIR ]
drwxr-xr-x
configparser-5.0.2.dist-info
[ DIR ]
drwxr-xr-x
contextlib2
[ DIR ]
drwxr-xr-x
contextlib2-21.6.0.dist-info
[ DIR ]
drwxr-xr-x
coverage
[ DIR ]
drwxr-xr-x
coverage-7.2.7.dist-info
[ DIR ]
drwxr-xr-x
cryptography
[ DIR ]
drwxr-xr-x
cryptography-41.0.2.dist-info
[ DIR ]
drwxr-xr-x
ddt-1.4.4.dist-info
[ DIR ]
drwxr-xr-x
dill
[ DIR ]
drwxr-xr-x
dill-0.3.7.dist-info
[ DIR ]
drwxr-xr-x
distlib
[ DIR ]
drwxr-xr-x
distlib-0.3.8.dist-info
[ DIR ]
drwxr-xr-x
docopt-0.6.2.dist-info
[ DIR ]
drwxr-xr-x
dodgy
[ DIR ]
drwxr-xr-x
dodgy-0.2.1.dist-info
[ DIR ]
drwxr-xr-x
filelock
[ DIR ]
drwxr-xr-x
filelock-3.13.1.dist-info
[ DIR ]
drwxr-xr-x
flake8
[ DIR ]
drwxr-xr-x
flake8-5.0.4.dist-info
[ DIR ]
drwxr-xr-x
flake8_polyfill
[ DIR ]
drwxr-xr-x
flake8_polyfill-1.0.2.dist-inf...
[ DIR ]
drwxr-xr-x
frozenlist
[ DIR ]
drwxr-xr-x
frozenlist-1.4.0.dist-info
[ DIR ]
drwxr-xr-x
future
[ DIR ]
drwxr-xr-x
future-0.18.3.dist-info
[ DIR ]
drwxr-xr-x
git
[ DIR ]
drwxr-xr-x
gitdb
[ DIR ]
drwxr-xr-x
gitdb-4.0.10.dist-info
[ DIR ]
drwxr-xr-x
guppy
[ DIR ]
drwxr-xr-x
guppy3-3.1.3.dist-info
[ DIR ]
drwxr-xr-x
hc_json_rpc_client
[ DIR ]
drwxr-xr-x
hc_json_rpc_client-1.0.1.dist-...
[ DIR ]
drwxr-xr-x
idna
[ DIR ]
drwxr-xr-x
idna-3.4.dist-info
[ DIR ]
drwxr-xr-x
iniconfig
[ DIR ]
drwxr-xr-x
iniconfig-2.0.0.dist-info
[ DIR ]
drwxr-xr-x
isort
[ DIR ]
drwxr-xr-x
isort-5.12.0.dist-info
[ DIR ]
drwxr-xr-x
jinja2
[ DIR ]
drwxr-xr-x
jsonschema
[ DIR ]
drwxr-xr-x
jsonschema-3.2.0.dist-info
[ DIR ]
drwxr-xr-x
jwt
[ DIR ]
drwxr-xr-x
lazy_object_proxy
[ DIR ]
drwxr-xr-x
lazy_object_proxy-1.9.0.dist-i...
[ DIR ]
drwxr-xr-x
libfuturize
[ DIR ]
drwxr-xr-x
libpasteurize
[ DIR ]
drwxr-xr-x
lve_stats-2.0.dist-info
[ DIR ]
drwxr-xr-x
lve_utils
[ DIR ]
drwxr-xr-x
lvemanager
[ DIR ]
drwxr-xr-x
lvestats
[ DIR ]
drwxr-xr-x
lxml
[ DIR ]
drwxr-xr-x
lxml-4.9.2.dist-info
[ DIR ]
drwxr-xr-x
mako
[ DIR ]
drwxr-xr-x
markupsafe
[ DIR ]
drwxr-xr-x
mccabe-0.7.0.dist-info
[ DIR ]
drwxr-xr-x
mock
[ DIR ]
drwxr-xr-x
mock-5.1.0.dist-info
[ DIR ]
drwxr-xr-x
multidict
[ DIR ]
drwxr-xr-x
multidict-6.0.4.dist-info
[ DIR ]
drwxr-xr-x
numpy
[ DIR ]
drwxr-xr-x
numpy-1.25.1.dist-info
[ DIR ]
drwxr-xr-x
numpy.libs
[ DIR ]
drwxr-xr-x
packaging
[ DIR ]
drwxr-xr-x
packaging-23.1.dist-info
[ DIR ]
drwxr-xr-x
past
[ DIR ]
drwxr-xr-x
pep8_naming-0.10.0.dist-info
[ DIR ]
drwxr-xr-x
pip
[ DIR ]
drwxr-xr-x
pip-25.0.1.dist-info
[ DIR ]
drwxr-xr-x
pkg_resources
[ DIR ]
drwxr-xr-x
platformdirs
[ DIR ]
drwxr-xr-x
platformdirs-3.11.0.dist-info
[ DIR ]
drwxr-xr-x
pluggy
[ DIR ]
drwxr-xr-x
pluggy-1.2.0.dist-info
[ DIR ]
drwxr-xr-x
prettytable
[ DIR ]
drwxr-xr-x
prettytable-3.8.0.dist-info
[ DIR ]
drwxr-xr-x
prometheus_client
[ DIR ]
drwxr-xr-x
prometheus_client-0.8.0.dist-i...
[ DIR ]
drwxr-xr-x
prospector
[ DIR ]
drwxr-xr-x
prospector-1.10.2.dist-info
[ DIR ]
drwxr-xr-x
psutil
[ DIR ]
drwxr-xr-x
psutil-5.9.5.dist-info
[ DIR ]
drwxr-xr-x
psycopg2
[ DIR ]
drwxr-xr-x
psycopg2_binary-2.9.6.dist-inf...
[ DIR ]
drwxr-xr-x
psycopg2_binary.libs
[ DIR ]
drwxr-xr-x
pycodestyle-2.9.1.dist-info
[ DIR ]
drwxr-xr-x
pycparser
[ DIR ]
drwxr-xr-x
pycparser-2.21.dist-info
[ DIR ]
drwxr-xr-x
pydantic
[ DIR ]
drwxr-xr-x
pydantic-2.4.2.dist-info
[ DIR ]
drwxr-xr-x
pydantic_core
[ DIR ]
drwxr-xr-x
pydantic_core-2.10.1.dist-info
[ DIR ]
drwxr-xr-x
pydocstyle
[ DIR ]
drwxr-xr-x
pydocstyle-6.3.0.dist-info
[ DIR ]
drwxr-xr-x
pyfakefs
[ DIR ]
drwxr-xr-x
pyfakefs-5.2.3.dist-info
[ DIR ]
drwxr-xr-x
pyflakes
[ DIR ]
drwxr-xr-x
pyflakes-2.5.0.dist-info
[ DIR ]
drwxr-xr-x
pylint
[ DIR ]
drwxr-xr-x
pylint-2.17.4.dist-info
[ DIR ]
drwxr-xr-x
pylint_celery
[ DIR ]
drwxr-xr-x
pylint_celery-0.3.dist-info
[ DIR ]
drwxr-xr-x
pylint_django
[ DIR ]
drwxr-xr-x
pylint_django-2.5.3.dist-info
[ DIR ]
drwxr-xr-x
pylint_flask
[ DIR ]
drwxr-xr-x
pylint_flask-0.6.dist-info
[ DIR ]
drwxr-xr-x
pylint_plugin_utils
[ DIR ]
drwxr-xr-x
pylint_plugin_utils-0.7.dist-i...
[ DIR ]
drwxr-xr-x
pylve-2.1-py3.11.egg-info
[ DIR ]
drwxr-xr-x
pymysql
[ DIR ]
drwxr-xr-x
pyparsing
[ DIR ]
drwxr-xr-x
pyparsing-3.0.9.dist-info
[ DIR ]
drwxr-xr-x
pyrsistent
[ DIR ]
drwxr-xr-x
pyrsistent-0.19.3.dist-info
[ DIR ]
drwxr-xr-x
pytest
[ DIR ]
drwxr-xr-x
pytest-7.4.0.dist-info
[ DIR ]
drwxr-xr-x
pytest_check
[ DIR ]
drwxr-xr-x
pytest_check-2.5.3.dist-info
[ DIR ]
drwxr-xr-x
pytest_snapshot
[ DIR ]
drwxr-xr-x
pytest_snapshot-0.9.0.dist-inf...
[ DIR ]
drwxr-xr-x
pytest_subprocess
[ DIR ]
drwxr-xr-x
pytest_subprocess-1.5.0.dist-i...
[ DIR ]
drwxr-xr-x
pytest_tap
[ DIR ]
drwxr-xr-x
pytest_tap-3.5.dist-info
[ DIR ]
drwxr-xr-x
python_pam-1.8.4.dist-info
[ DIR ]
drwxr-xr-x
pyvirtualdisplay
[ DIR ]
drwxr-xr-x
raven
[ DIR ]
drwxr-xr-x
raven-6.10.0.dist-info
[ DIR ]
drwxr-xr-x
requests
[ DIR ]
drwxr-xr-x
requests-2.31.0.dist-info
[ DIR ]
drwxr-xr-x
requirements_detector
[ DIR ]
drwxr-xr-x
requirements_detector-1.2.2.di...
[ DIR ]
drwxr-xr-x
schema-0.7.5.dist-info
[ DIR ]
drwxr-xr-x
semver
[ DIR ]
drwxr-xr-x
semver-3.0.1.dist-info
[ DIR ]
drwxr-xr-x
sentry_sdk
[ DIR ]
drwxr-xr-x
sentry_sdk-1.29.2.dist-info
[ DIR ]
drwxr-xr-x
setoptconf
[ DIR ]
drwxr-xr-x
setoptconf_tmp-0.3.1.dist-info
[ DIR ]
drwxr-xr-x
setuptools
[ DIR ]
drwxr-xr-x
setuptools-78.1.0.dist-info
[ DIR ]
drwxr-xr-x
simplejson
[ DIR ]
drwxr-xr-x
simplejson-3.19.1.dist-info
[ DIR ]
drwxr-xr-x
six-1.16.0.dist-info
[ DIR ]
drwxr-xr-x
smmap
[ DIR ]
drwxr-xr-x
smmap-5.0.0.dist-info
[ DIR ]
drwxr-xr-x
snowballstemmer
[ DIR ]
drwxr-xr-x
snowballstemmer-2.2.0.dist-inf...
[ DIR ]
drwxr-xr-x
sqlalchemy
[ DIR ]
drwxr-xr-x
sqlalchemy-1.3.24.dist-info
[ DIR ]
drwxr-xr-x
ssa
[ DIR ]
drwxr-xr-x
svgwrite
[ DIR ]
drwxr-xr-x
svgwrite-1.4.3.dist-info
[ DIR ]
drwxr-xr-x
tap
[ DIR ]
drwxr-xr-x
tap_py-3.2.1.dist-info
[ DIR ]
drwxr-xr-x
testfixtures
[ DIR ]
drwxr-xr-x
testfixtures-7.1.0.dist-info
[ DIR ]
drwxr-xr-x
toml
[ DIR ]
drwxr-xr-x
toml-0.10.2.dist-info
[ DIR ]
drwxr-xr-x
tomlkit
[ DIR ]
drwxr-xr-x
tomlkit-0.11.8.dist-info
[ DIR ]
drwxr-xr-x
typing_extensions-4.8.0.dist-i...
[ DIR ]
drwxr-xr-x
unshare-0.22.dist-info
[ DIR ]
drwxr-xr-x
urllib3
[ DIR ]
drwxr-xr-x
urllib3-2.0.4.dist-info
[ DIR ]
drwxr-xr-x
vendors_api
[ DIR ]
drwxr-xr-x
virtualenv
[ DIR ]
drwxr-xr-x
virtualenv-20.21.1.dist-info
[ DIR ]
drwxr-xr-x
wcwidth
[ DIR ]
drwxr-xr-x
wcwidth-0.2.6.dist-info
[ DIR ]
drwxr-xr-x
wmt
[ DIR ]
drwxr-xr-x
wrapt
[ DIR ]
drwxr-xr-x
wrapt-1.15.0.dist-info
[ DIR ]
drwxr-xr-x
yaml
[ DIR ]
drwxr-xr-x
yarl
[ DIR ]
drwxr-xr-x
yarl-1.9.2.dist-info
[ DIR ]
drwxr-xr-x
_cffi_backend.cpython-311-x86_...
267.63
KB
-rwxr-xr-x
_pyrsistent_version.py
23
B
-rw-r--r--
cl_proc_hidepid.py
4.53
KB
-rw-r--r--
clcontrollib.py
51.73
KB
-rw-r--r--
cldetectlib.py
18.4
KB
-rw-r--r--
cldiaglib.py
47.56
KB
-rw-r--r--
clhooklib.py
1.27
KB
-rw-r--r--
cli_utils.py
1.66
KB
-rw-r--r--
cllicenselib.py
9.1
KB
-rw-r--r--
clsetuplib.py
4.35
KB
-rw-r--r--
clsudo.py
14.42
KB
-rw-r--r--
configparser.py
1.51
KB
-rw-r--r--
ddt.py
12.43
KB
-rw-r--r--
distutils-precedence.pth
151
B
-rw-r--r--
docopt.py
19.48
KB
-rw-r--r--
hc_lve_profiler.py
6.2
KB
-rw-------
lveapi.py
19.53
KB
-rw-r--r--
lvectllib.py
102.55
KB
-rw-r--r--
lvestat.py
6.83
KB
-rw-r--r--
mccabe.py
10.4
KB
-rw-r--r--
pam.py
7.38
KB
-rw-r--r--
pep8ext_naming.py
18.61
KB
-rw-r--r--
py.py
263
B
-rw-r--r--
pycodestyle.py
101.08
KB
-rw-r--r--
pylve.cpython-311-x86_64-linux...
25.48
KB
-rwxr-xr-x
remove_ubc.py
5.73
KB
-rwxr-xr-x
schema.py
29.51
KB
-rw-r--r--
secureio.py
18.83
KB
-rw-r--r--
simple_rpm.so
11.29
KB
-rwxr-xr-x
six.py
33.74
KB
-rw-r--r--
typing_extensions.py
100.97
KB
-rw-r--r--
unshare.cpython-311-x86_64-lin...
8.17
KB
-rwxr-xr-x
Delete
Unzip
Zip
${this.title}
Close
Code Editor : lveapi.py
#!/usr/bin/env python # -*- coding: utf-8 -*- # 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 contextlib import os import errno import syslog import time import pwd from typing import Optional # NOQA from clcommon.clfunc import uid_max from clcommon.clproc import ProcLve from clcommon import cpapi, ClPwd from clcommon.cpapi.cpapiexceptions import NotSupported try: import pylve except ImportError: pylve = None from clveconfig import ve_config UID_MAX = uid_max() # kernel devs say that lve_id type is uint32_t # so max id should be 0xFFFF_FFFF, it in fact we have this: MAX_LVE_ID = 0x7FFFFFFF - 1 LVP_XML_TAG_NAME = "reseller" LVE_NO_UBC = 1 << 1 LVE_NO_MAXENTER = 1 << 2 class NameMapError(Exception): pass class NameMapConfigError(NameMapError): pass class NameMapNotInitialized(NameMapError): pass class NameMap: """ Container for backend storing resellers_name<=>resellers_id map As backend store use ve.cfg Usage: >>> name_map = NameMap() >>> name_map.link_xml_node() >>> name_map.id_list() [1001] """ def __init__(self, xml_tag_name=LVP_XML_TAG_NAME): self._xml_tag_name = xml_tag_name self._xml_node = None # Reseller name to id map (list of corteges) self._reseller_id_name_map = None def get_id(self, name): for name_, id_ in self.load_from_node(): if name_ == name: return id_ def get_name(self, id_): for name_, _id in self.load_from_node(): if id_ == _id: return name_ def id_list(self): return [id_ for _, id_ in self.load_from_node()] def link_xml_node(self, xml_node=None, use_cache=True): """ Initialize NameMap. If xml_node is none, config will be loaded automatically :param use_cache: Bool whether bypass ve.cfg xml cache :param xml_node: !! DEPRECATED PARAM !! this param is left only for compatibility with our old code """ if xml_node is None: # New mode, Load reseller_id, reseller_name pairs from ve.cfg to dictionary self._xml_node = None self._load_resellers_map_from_ve_cfg(use_cache) else: # For compatibility with our old code self._xml_node = xml_node self._reseller_id_name_map = None def _load_resellers_map_from_ve_cfg(self, use_cache): """ Fills self._reseller_id_name_map from ve.cfg file :return: """ self._reseller_id_name_map = [] ve_cfg, xml_node = self._try_get_xml_node(use_cache=use_cache) for el_ in xml_node: name = el_.getAttribute('user') id_ = int(el_.getAttribute('id')) if name and id_ and id_ not in self._reseller_id_name_map: self._reseller_id_name_map.append((id_, name)) # Force delete XML object to avoid high memory load del xml_node del ve_cfg def _try_get_xml_node(self, use_cache=True): try: ve_cfg, xml_node = ve_config.get_xml_config(use_cache=use_cache) except ve_config.BadVeConfigException as e: self._reseller_id_name_map = None raise NameMapConfigError("Error happened while loading data from ve.cfg") from e return ve_cfg, xml_node.getElementsByTagName(self._xml_tag_name) def load_from_node(self): """ Obtain data from xml node as (name, id_) list """ if self._xml_node is None and self._reseller_id_name_map is None: raise NameMapNotInitialized('Name map is not initialized. ' 'Use obj.link_xml_node() to get data from config') if self._xml_node: # For compatibility with our old code for el_ in self._xml_node.getElementsByTagName(self._xml_tag_name): name = el_.getAttribute('user') id_ = int(el_.getAttribute('id')) if name and id_: yield name, id_ if self._reseller_id_name_map: # New mode, use resellers map for id_, name in self._reseller_id_name_map: yield name, id_ class LvpMap: """ Container for storing information about lve:lvp mapping In which reseller container stored lve """ def __init__(self): self.name_map = NameMap() self._id_name_map = {} self._name_id_map = {} self._reseller_id_map_panel = None self._pwd = ClPwd() def _add_map(self, name, id_): self._id_name_map[id_] = name self._name_id_map[name] = id_ def pw_uid(self, name, default=None): try: return self._pwd.get_pw_by_name(name).pw_uid except ClPwd.NoSuchUserException: return default def _get_panel_reseller_id(self, reseller): # type: (str) -> Optional[int] uid = self.pw_uid(reseller) if uid is not None: return uid # in case when we cannot find reseller in passwd file # let's ask control panel for reseller's id if self._reseller_id_map_panel is None: self._reseller_id_map_panel = cpapi.get_reseller_id_pairs() return self._reseller_id_map_panel.get(reseller) def get_reseller_id(self, name): # type: (str) -> Optional[int] """ Convert reseller name to an LVE id. It supports resellers without a system account (for Plesk compatibility). """ uid = self.name_map.get_id(name) or self._name_id_map.get(name) if uid is not None: return uid try: uid = self._get_panel_reseller_id(name) except NotSupported: uid = None if uid is not None: self._add_map(name, uid) return uid def get_reseller_name(self, id_): """ Convert reseller id to reseller name It support resellers without system account (for Plesk compatibilyty) """ # add attribute fo in memory cache support name = self.name_map.get_name(id_) or self._id_name_map.get(id_) if name is not None: return name try: name = pwd.getpwuid(id_).pw_name if cpapi.is_reseller(name): self._add_map(name, id_) else: name = None except KeyError: name = None return name def lve_lvp_pairs(self): """ This method loops over all user:reseller pairs in control panel and returns appropriate lve_id:lvp_id pairs. THIS METHOD WON'T CHECK IF 'RESELLER LIMITS' IS ENABLED IN ve.cfg """ resellers = set(cpapi.resellers()) reseller_uids = {} for reseller in resellers: try: reseller_uids[reseller] = self.get_reseller_id(reseller) except NotSupported: syslog.syslog( syslog.LOG_WARNING, f"Reseller {reseller} still exists in control panel, " "but absent in /etc/passwd file") for cplogin, reseller in cpapi.cpinfo(keyls=('cplogin', 'reseller')): lve_id = self.pw_uid(cplogin) # for some reasons (process of destroying user died # or admin called 'pure' userdel), user may still exist in control panel # but absent in /etc/passwd file; we can do nothing with that, # so just skip and write a warning to syslog if lve_id is None: syslog.syslog( syslog.LOG_WARNING, f"user {cplogin} still exists in control panel, " "but absent in /etc/passwd file") continue lvp_id = reseller_uids.get(reseller, 0) yield lve_id, lvp_id @staticmethod def resellers(): for reseller_name in cpapi.resellers(): yield reseller_name @staticmethod def reseller_uids(name): """ Obtain from control panel resellers uids """ uids = [] reseller_users = cpapi.reseller_users(name) for user in reseller_users: try: id_ = pwd.getpwnam(user).pw_uid uids.append(id_) except KeyError: syslog.syslog( syslog.LOG_WARNING, f"user {user} still exists in control panel, " "but absent in /etc/passwd file") return uids def lvp_lve_id_list(self, lvp_id): reseller_name = self.get_reseller_name(lvp_id) return self.reseller_uids(reseller_name) class PyLveError(Exception): pass class PyLve: """ Wrapper for generate traceback with pretty descriptions """ @staticmethod def _code_is_error(code): return isinstance(code, int) and code != -errno.ENOSYS and code != 0 def _arg_to_str(self, arg_var): if isinstance(arg_var, self._pylve.liblve_settings): # for pretty print liblve_settings object liblve_settings_attr = ', '.join( [f"{attr}={getattr(arg_var, attr)}" for attr in dir(arg_var) if not attr.startswith('_')] ) arg_var_str = f'<liblve_settings object {liblve_settings_attr}>' else: arg_var_str = str(arg_var) return arg_var_str def _wrapped_fun(self, call, *args, **kwargs): msg_template = kwargs.pop('err_msg', self.default_msg_template) ignore_error = kwargs.pop('ignore_error', self.ignore_error) code = call(*args, **kwargs) is_error = self._code_is_error(code) if is_error and self._retry: # wait and try again run function time.sleep(self._retry_time) code = call(*args, **kwargs) is_error = self._code_is_error(code) format_args = { 'code': code, 'fun_name': call.__name__, 'module': call.__module__, 'args_': ', '.join( list(map(self._arg_to_str, args)) + [f"{k}={self._arg_to_str(v)}" for k, v in kwargs.items()] ) } format_args = { 'code': code, 'fun_name': call.__name__, 'module': call.__module__, 'args_': ', '.join(list(map(self._arg_to_str, args)) + [f"{k}={self._arg_to_str(v)}" for k, v in kwargs.items()]) } if self.debug >= 1: print(self.debug_msg_template.format(**format_args)) if self.debug >= 2: self.traceback.print_stack() if not ignore_error and is_error: msg = msg_template.format(**format_args) raise PyLveError(msg) return code def _wrap_code(self, call): def fun(*args, **kwargs): return self._wrapped_fun(call, *args, **kwargs) return fun def __init__(self, pylve=pylve, retry=True, retry_tyme=0.1, debug=0): self.debug = debug if self.debug >= 2: self.traceback = __import__('traceback') self.default_msg_template = 'Error code {code}; {module}.{fun_name}({args_})' self.debug_msg_template = "DEBUG [lvectl]: call {module}.{fun_name}({args_}) with code {code}" self.ignore_error = False self._pylve = pylve self._retry = retry self._proc = ProcLve() self._retry_time = retry_tyme self.api_version = self._pylve.lve_get_api_version() self.initialize = self._pylve.initialize self.lve_start = self._wrap_code(self._pylve.lve_start) self.liblve_settings = self._pylve.liblve_settings self.lve_create = self._wrap_code(self._pylve.lve_create) self.lve_destroy = self._wrap_code(self._pylve.lve_destroy) self.lve_info = self._pylve.lve_info self.lve_set_default = self._wrap_code(self._pylve.lve_set_default) self.lve_setup = self._wrap_code(self._pylve.lve_setup) self.lve_enter_pid = self._wrap_code(self._pylve.lve_enter_pid) self.lve_enter_pid_flags = self._wrap_code(self._pylve.lve_enter_pid_flags) self.lve_leave_pid = self._wrap_code(self._pylve.lve_leave_pid) if hasattr(pylve, 'lve_lvp_create'): self.lve_lvp_create = self._wrap_code(self._pylve.lve_lvp_create) self.lve_lvp_destroy = self._wrap_code(self._pylve.lve_lvp_destroy) self.lve_lvp_map = self._wrap_code(self._pylve.lve_lvp_map) self.lve_lvp_move = self._wrap_code(self._pylve.lve_lvp_move) # mocked functions. Not implement in pylve self.lve_lvp_setup = self._wrap_code(self.lve_lvp_setup) def resellers_supported(self): """ Check in pylve binding reseller limits supported """ return hasattr(self._pylve, 'lve_lvp_create') def lve_exists(self, lve_id): """ Check if lve exists in kernel :rtype: bool """ try: self.lve_info(lve_id) return True except OSError: return False # TODO: remove this wrapper when kernel logic is ready # upd: kernel logic is still not ready yet (KMODLVE-79) def lve_lvp_setup(self, lvp_id, settings): # pylint: disable=method-hidden """ Wrapper for lve_lvp_setup. When reseller's limits changed, we should iterate over his user's limits and set them again; This behaviour is needed cause kernel does not update users limits after changing reseller's one Adjust parameters for top level container. :param int lvp_id: top level container ID, 0 by default; :param settings: liblve_settings instance. :return: 0 or errno value """ # is it real situation when lvp_id is 0? if lvp_id == 0: return self._pylve.lve_lvp_setup(lvp_id, settings) # reduce lve limits real_lve_settings = {} # type: dict[int, pylve.liblve_settings] for lve_id in self._proc.lve_id_list(lvp_id): # save real settings to restore them later try: real_settings = self.lve_info(lve_id) real_lve_settings[lve_id] = real_settings if real_settings.ls_cpu > settings.ls_cpu: # get current settings and reduce cpu temp_settings = self.lve_info(lve_id) temp_settings.ls_cpu = min(temp_settings.ls_cpu, settings.ls_cpu) self.lve_setup(lve_id, temp_settings) except OSError: # lve was destroyed, ignore that pass # set new reseller settings _lve_lvp_setup = self._wrap_code(self._pylve.lve_lvp_setup) # ignore errors here and raise errors after operations result = _lve_lvp_setup(lvp_id, settings, ignore_error=True) # pass lve's limits again, so kernel will apply them for lve_id in self._proc.lve_id_list(lvp_id): if lve_id in real_lve_settings: self.lve_setup(lve_id, real_lve_settings[lve_id]) else: # some lve was created during operations above # nothing bad, but we can do nothing with that # until we have no lock's for this method self.lve_setup(lve_id, self.lve_info(lve_id)) return result def get_available_lve_id(self, start=UID_MAX, stop=MAX_LVE_ID): """ Iter over lves and find available one. :param int start: value to start search from; UID_MAX by default :param int stop: max value when we will stop search :return int: lve_id """ for lve_id in range(start + 1, stop): try: self.lve_info(lve_id) except OSError: return lve_id raise PyLveError(f"Unable to find free lve in range ({start}, {stop})") @contextlib.contextmanager def context_ignore_error(self, ignore_error): self.ignore_error, saved_ignore_error = ignore_error, self.ignore_error try: yield finally: self.ignore_error = saved_ignore_error class Lve: def __init__(self, proc=None, py=None, map=None): self.proc = proc or ProcLve() self.py = py or PyLve() self.map = map or LvpMap() def lve_id_lvp_id_pairs(self): """ Obtain {lve id}:{lvp id} pairs iterator based on ve.cfg config (detect enabled resellers containers) This method (unlike LvpMap.lve_lvp_pairs) will check if reseller is enabled in ve.cfg and return lvp_id=0 for users of reseller with disabled reseller limits """ enabled_lvp_id = set(self.map.name_map.id_list()) for lve_id, lvp_id in self.map.lve_lvp_pairs(): if lvp_id in enabled_lvp_id: # load map for enabled resellers only yield lve_id, lvp_id else: yield lve_id, 0 def lve2lvp(self, lve_id): """ Obtain lvp id based on ve.cfg config (detect enabled resellers containers) """ for lve_id_, lvp_id_ in self.lve_id_lvp_id_pairs(): if lve_id == lve_id_: return lvp_id_ return 0 def lve_destroy(self, lve_id, *args, **kwargs): """ safe destroy lve container with preserving lvp mapping """ if os.path.exists(self.proc.proc_lve_map()): lvp_id = self.proc.map().get(lve_id, 0) else: lvp_id = 0 self.py.lve_destroy(lve_id, *args, **kwargs) if lvp_id != 0: try: pwd.getpwuid(lve_id) self.py.lve_lvp_map(lvp_id, lve_id) except KeyError: pass def _sync_map(self): """ Load lve_id:lvp_id map to kmod-lve """ # laod mapping information from kernel (/proc/lve/map) proc_map_dict = self.proc.map() # loop over user_id:reseller_id pairs # lve_id_lvp_id_pairs includes all control panel users # and checks for enabled resellers in ve.cfg # so user of reseller without reseller limits # will be listed in response like 'tuple(user_id, 0)' for lve_id, lvp_id in self.lve_id_lvp_id_pairs(): if proc_map_dict.get(lve_id, 0) != lvp_id: # change map if needed only if not self.proc.exist_lvp(lvp_id=lvp_id): self.py.lve_lvp_create(lvp_id) self.py.lve_lvp_move(lvp_id, lve_id) proc_map_dict[lve_id] = lvp_id def sync_map(self): """ wrapped _sync_map function for prevent error if some cpapi not supported """ try: self._sync_map() except NotSupported: pass def is_panel_supported(self): """ Check if current panel supported for reseller's limits; :rtype: bool """ try: return cpapi.is_reseller_limits_supported() except NotSupported: return False def reseller_limit_supported(self): """ Check present all needed (kmod-lve, liblve, /proc/lve, panel) for manipulate resellers limits """ return all((self.py.resellers_supported(), self.proc.resellers_supported(), self.is_panel_supported())) def is_lve10(self): """ Check present all needed (kmod-lve, liblve, /proc/lve) for manipulate resellers limits """ return all((self.py.resellers_supported(), self.proc.resellers_supported()))
Close