X7ROOT File Manager
Current Path:
/opt/cloudlinux/venv/lib/python3.11/site-packages/clselect
opt
/
cloudlinux
/
venv
/
lib
/
python3.11
/
site-packages
/
clselect
/
??
..
??
__init__.py
(536 B)
??
__pycache__
??
baseclselect
??
clextselect.py
(19.71 KB)
??
clpassenger.py
(26.53 KB)
??
clselect.py
(21.77 KB)
??
clselectctl.py
(9.15 KB)
??
clselectctlnodejsuser.py
(20.66 KB)
??
clselectctlphp.py
(43.82 KB)
??
clselectctlpython.py
(44.75 KB)
??
clselectctlruby.py
(18.59 KB)
??
clselectexcept.py
(10.22 KB)
??
clselectnodejs
??
clselectnodejsuser
??
clselectphp
??
clselectphpuser
??
clselectprint.py
(5.39 KB)
??
clselectpython
??
clselectpythonuser
??
clselectruby
??
clselectstatistics.py
(6.51 KB)
??
cluserextselect.py
(15.19 KB)
??
cluseroptselect.py
(23.65 KB)
??
cluserselect.py
(28.22 KB)
??
locked_extensions.ini
(1.2 KB)
??
utils.py
(16.22 KB)
Editing: clselectctlnodejsuser.py
# -*- 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 from __future__ import print_function from __future__ import absolute_import from __future__ import division import os import pwd import requests import requests.packages.urllib3.exceptions as urllib_exceptions # pylint: disable=E0401 import shutil from requests.exceptions import ConnectionError from future.utils import iteritems from past.builtins import basestring from . import clpassenger from . import clselectctl from . import utils from clcommon.cpapi import userdomains from clcommon.utils import mod_makedirs from .clselectexcept import ClSelectExcept from .clselectnodejs.apps_manager import ApplicationsManager from .clselectnodejsuser import environments, interpreters from .baseclselect import APP_STARTED_CONST, APP_STOPPED_CONST from .clselectprint import clprint DEFAULT_STARTUP_FILE = "app.js" DEFAULT_APP_STATE = APP_STARTED_CONST def _create_environment(user, directory, version, env_name=None, destroy_first=False): prefix = _get_prefix(user, directory) if not env_name: env_name = version environment = environments.Environment(env_name, user, prefix) if not environment.exists() or destroy_first: try: interpreter = interpreters.interpreters(key="version")[version] except KeyError: raise ClSelectExcept.NoSuchAlternativeVersion(version) environment.create(interpreter, destroy_first=destroy_first) return environment def _get_environment(user, directory, app_summary=None): prefix = _get_prefix(user, directory) if app_summary is None: user_summary = clpassenger.summary(user) try: app_summary = utils.get_using_realpath_keys(user, directory, user_summary) except KeyError: raise ClSelectExcept.NoSuchApplication( 'No such application (or application not configured) "%s"' % directory ) binary = app_summary["binary"] env_name = os.path.basename(os.path.dirname(os.path.dirname(binary))) environment = environments.Environment(env_name, user, prefix) return environment def _get_prefix(user, directory): _, rel_dir = utils.get_abs_rel(user, directory) return os.path.join(environments.DEFAULT_PREFIX, rel_dir) def _ensure_version_enabled(version, user): """ Check whether particular interpreter version is enabled and raises exception if not :param user: user to include in exception """ from .clselectnodejs import node_manager if not node_manager.NodeManager().is_version_enabled(version): raise ClSelectExcept.UnableToSetAlternative(user, version, "version is not enabled") def _get_existing_nesting_app_for(new_app_directory, user, apps_manager=None): """ Return None if new_app_directory is not nested inside an existing user application, and the name of conflicting application otherwise """ if apps_manager is None: apps_manager = ApplicationsManager() abs_app_path, _ = utils.get_abs_rel(user, new_app_directory) full_config = apps_manager.get_user_config_data(user) for existing_app in full_config.keys(): # In case home directory was symlinked after config was written existing_app_abs_path, _ = utils.get_abs_rel(user, existing_app) if (abs_app_path + os.sep).startswith(existing_app_abs_path + os.sep): return existing_app return None def create( user, directory, alias, version=None, doc_root=None, app_mode=None, env_vars=None, startup_file=None, domain_name=None, apps_manager=None, passenger_log_file=None, ): """ Create application :param user: unix user name :param directory: application path in user's home (app-root) :param alias: alias (app-uri) :param version: version of interpreter :param doc_root: doc_root :param app_mode: application mode for nodejs :param env_vars: dict with enviroment variables :param startup_file: main application file :param domain_name: domain name :param apps_manager: Application Manager. Class that responsible for gathering and writing information about applications :param passenger_log_file: Passenger log filename to write to app's .htaccess :return: None """ if apps_manager is None: apps_manager = ApplicationsManager() if version is None: raise ClSelectExcept.WrongData("Not passed version as argument") _ensure_version_enabled(version, user) if startup_file is None: startup_file = DEFAULT_STARTUP_FILE if env_vars is None: env_vars = {} if app_mode is None: app_mode = "production" conflicting_app = _get_existing_nesting_app_for(directory, user, apps_manager) if conflicting_app is not None: raise ClSelectExcept.BusyApplicationRoot(conflicting_app) alias = clselectctl.get_alias(alias) environment = _create_environment(user, directory, version) binary = environment.interpreter().binary clpassenger.configure( user, directory, alias, apps_manager.INTERPRETER, binary, doc_root=doc_root, startup_file=startup_file, passenger_log_file=passenger_log_file, ) # webapp was started clpassenger.restart(user, directory) if not domain_name: # if domain name not defined - try to detemine it summary_data = clpassenger.summary(user) app_summary = utils.get_using_realpath_keys(user, directory, summary_data) domain_name = app_summary["domain"] app_data = { "nodejs_version": version, "domain": domain_name, "app_uri": alias, "app_status": DEFAULT_APP_STATE, "startup_file": startup_file, "app_mode": app_mode, "config_files": [], "env_vars": env_vars, } if passenger_log_file: app_data["passenger_log_file"] = passenger_log_file apps_manager.add_app_to_config(user, directory, app_data) try: apps_manager.add_env_vars_for_htaccess(user, directory, env_vars, doc_root) except Exception as err: clprint.print_diag("text", {"status": "ERROR", "message": str(err)}) def _create_symlink_to_node_modules(username, environment_path, app_root): """ Creates symlink to app's node_modules in app_root :param username: user name :param environment_path: Path to app's virtual environment :param app_root: Application root :return: None """ # This function logic is duplicated in npm wrapper, but we still need it here too. See commit # message of LVEMAN-1335 message = ( "Cloudlinux NodeJS Selector demands to store node modules for application " "in separate folder (virtual environment) pointed by symlink " 'called "node_modules". That`s why application should not contain folder/file ' "with such name in application root" ) link_name = os.path.join(pwd.getpwnam(username).pw_dir, app_root, "node_modules") if os.path.islink(link_name): try: os.remove(link_name) except OSError: raise ClSelectExcept.RemoveSymlinkError("Can`t remove symlink %(link_name)s" % {"link_name": link_name}) elif os.path.exists(link_name): # link_name not a old symlink, but exists raise ClSelectExcept.SymlinkError(message) link_to = os.path.join(environment_path, "lib/node_modules") if not os.path.exists(link_to): mod_makedirs(link_to, 0o775) try: os.symlink(link_to, link_name) except OSError: raise ClSelectExcept.CreateSymlinkError("Error creating symlink. " + message) def destroy(user, app_directory, doc_root, apps_manager=None): """ Destroy web app with specified directory for specified user :param user: username :param app_directory: application directory :param doc_root: Document root for selected domain :param apps_manager: Application Manager. Class that responsible for gathering and writing information about applications :return: None """ if apps_manager is None: apps_manager = ApplicationsManager() # get app state app_config = apps_manager.get_app_config(user, app_directory) # remove env from htaccess try: # if domain is already removed we shouldn't do anything if doc_root is not None: apps_manager.add_env_vars_for_htaccess(user, app_directory, None, doc_root) except Exception as err: clprint.print_diag("text", {"status": "ERROR", "message": str(err)}) if app_config.get("app_status") == APP_STOPPED_CONST: # stopped app user_home = pwd.getpwnam(user).pw_dir # Remove app's nodenv, e.g. /home/cltest1/nodevenv/test_app nodevenv_path = "/".join([user_home, "nodevenv", app_directory]) try: # Remove app's nodenv, e.g. /home/cltest1/nodevenv/test_app shutil.rmtree(nodevenv_path) except OSError: pass # if domain is already removed we shouldn't do anything if doc_root is not None: # Remove NodeJS lines from .htaccess htaccess_filename = apps_manager.get_htaccess_by_appdir(user, app_directory, doc_root) clpassenger.remove_passenger_lines_from_htaccess(htaccess_filename) # remove app from node-selector.json file apps_manager.remove_app_from_config(user, app_directory) # Update application status in passenger try: clpassenger.restart(user, app_directory) except ClSelectExcept.MissingApprootDirectory: pass return # Moved before removing an app from node-selector.json because in case if # app_root is absent we still want to remove venv dir of an application. # The method didn't anyhing if app_root is absent and skip other commands # including removal of a venv dir prefix = _get_prefix(user, app_directory) abs_dir, _ = utils.get_abs_rel(user, prefix) try: # Remove app's nodenv, e.g. /home/cltest1/nodevenv/test_app shutil.rmtree(abs_dir) except OSError: pass user_summary = clpassenger.summary(user) # remove app from node-selector.json file app_in_config = apps_manager.remove_app_from_config(user, app_directory) try: utils.get_using_realpath_keys(user, app_directory, user_summary) except KeyError: # if app was existed and app's dir is not exists, we skip all further actions if app_in_config: return None else: raise ClSelectExcept.WrongData('No such application (or application not configured) "%s"' % app_directory) # remove app from passenger clpassenger.unconfigure(user, app_directory) # Clear .htaccess try: clpassenger.restart(user, app_directory) except ClSelectExcept.MissingApprootDirectory: pass def start(user, app_directory, doc_root, apps_manager=None): """ Starts web app with specified directory for specified user :param user: username :param app_directory: application directory :param doc_root: Document root for selected domain :param apps_manager: Application Manager. Class that responsible for gathering and writing information about applications :return: None """ if apps_manager is None: apps_manager = ApplicationsManager() app_config = apps_manager.get_app_config(user, app_directory) if app_config is None: raise ClSelectExcept.WrongData('No such application (or application not configured) "%s"' % app_directory) # Do nothing if application already started if app_config.get("app_status") == APP_STARTED_CONST: return # Create .htaccess file for the application apps_manager.update_htaccess_file(user, app_directory, doc_root) # Save new application status in user's config apps_manager.set_app_status(user, app_directory, APP_STARTED_CONST) # Update application status in passenger clpassenger.restart(user, app_directory) def restart(user, app_directory, doc_root, apps_manager=None): """ Restarts web app with specified directory for specified user :param user: username :param app_directory: application directory :param doc_root: Document root for selected domain :param apps_manager: Application Manager. Class that responsible for gathering and writing information about applications :return: None """ if apps_manager is None: apps_manager = ApplicationsManager() app_config = apps_manager.get_app_config(user, app_directory) if app_config is None: raise ClSelectExcept.WrongData('No such application (or application not configured) "%s"' % app_directory) # If application was stopped - start it if app_config.get("app_status") == APP_STOPPED_CONST: start(user, app_directory, doc_root) else: clpassenger.restart(user, app_directory) def stop(user, app_directory, doc_root, apps_manager=None): """ Stops web app with specified directory for specified user :param user: username :param app_directory: application directory :param doc_root: Document root for selected domain :param apps_manager: Application Manager. Class that responsible for gathering and writing information about applications :return: None """ if apps_manager is None: apps_manager = ApplicationsManager() app_config = apps_manager.get_app_config(user, app_directory) if app_config is None: raise ClSelectExcept.WrongData('No such application (or application not configured) "%s"' % app_directory) # Do nothing if application is not started if app_config.get("app_status") == APP_STOPPED_CONST: return htaccess_filename = apps_manager.get_htaccess_by_appdir(user, app_directory, doc_root, app_config) # Remove NodeJS lines from .htaccess clpassenger.remove_passenger_lines_from_htaccess(htaccess_filename) # Save new application status in user's config apps_manager.set_app_status(user, app_directory, APP_STOPPED_CONST) # Update application status in passenger clpassenger.restart(user, app_directory) def check_response_from_webapp(domain, alias, action=None): """ Check response from user's webapp before and after calling action. Also compare both responses :param domain: domain associated with webapp :param alias: URI associated with webapp :param action: called action, that make something with webapp: install modules, transit it, etc :return: None """ app_is_inaccessible_before = 'Web application is inaccessible by its address "%s". The operation wasn\'t performed.' app_is_inaccessible_after = ( "The operation was performed, but check availability of application has failed. " 'Web application is inaccessible by its address "%s" after the operation.' ) app_is_broken = ( "The operation was performed, but check availability of application has failed. " 'Web application responds, but its return code "%s" or ' 'content type before operation "%s" doesn\'t equal to contet type after operation "%s".' ) requests.packages.urllib3.disable_warnings(urllib_exceptions.InsecureRequestWarning) # pylint: disable=E1101 if not callable(action): raise ClSelectExcept.WrongData("Wrong action for calling in checking webapp") webapp_url = "https://{domain}/{alias}".format( domain=domain, alias=alias, ) # for hiding from the module of Apache `mod_security` headers = { "User-Agent": "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) " "Gecko/20101209 CentOS/3.6-2.el5.centos Firefox/3.6.13" } try: # Applies only to wildcard domains because '*' allows accessing URLs like # Example: http://{anything}.domain/nodejs_app. webapp_url = utils.transform_wildcard_url(webapp_url) request = requests.get(webapp_url, verify=False, headers=headers) except ConnectionError: # site is not available by https protocol webapp_url = webapp_url.replace("https://", "http://") try: request = requests.get(webapp_url, verify=False, headers=headers) except ConnectionError: raise ClSelectExcept.WebAppError(app_is_inaccessible_before % webapp_url) before_mime_type = request.headers.get("Content-Type") before_status = request.headers.get("Status") action() try: request = requests.get(webapp_url, verify=False, headers=headers) except ConnectionError: raise ClSelectExcept.WebAppError(app_is_inaccessible_after % webapp_url) after_mime_type = request.headers.get("Content-Type") after_status = request.headers.get("Status") # assume that app is broken if: # it's response Content-Type or Status code (if first code wasn't 500) changed # if last Status code was 500 (internal error) if ( before_mime_type.lower() != after_mime_type.lower() or (before_status != after_status and before_status is not None and before_status[:3] != "500") or (after_status is not None and after_status[:3] == "500") ): raise ClSelectExcept.WebAppError(app_is_broken % (after_status, before_mime_type, after_mime_type)) def _get_info_about_webapp(app_summary=None, user=None): """ Get info (alias and domain) about user's web application :param app_summary: dict -> summary info about user's web application :param user: str -> name of unix user :return: tuple -> (alias, domain) """ if app_summary is None: raise ClSelectExcept.WrongData("Was passed incorrect summary info about application") if user is None: raise ClSelectExcept.WrongData("Was passed incorrect name of user") alias = app_summary["alias"] user_domains = userdomains(user) found_domains = [ domain for domain, doc_root in user_domains if utils.realpaths_are_equal(user, doc_root, app_summary["docroot"]) ] if len(found_domains) == 0: raise ClSelectExcept.WrongData("Can not found suitable domain for application") app_domain = found_domains[0] return alias, app_domain def install(user, directory, extension="-", skip_web_check=False, apps_manager=None): """ Install nodejs extension to user's webapp :param user: name os unix user :param directory: directory with webapp (app-root) :param extension: name and version of extension :param skip_web_check: skip check web application after change it's properties :param apps_manager: Application Manager. Class that responsible for gathering and writing information about applications :return: None """ if apps_manager is None: apps_manager = ApplicationsManager() user_config = apps_manager.get_user_config_data(user) try: app_data = utils.get_using_realpath_keys(user, directory, user_config) except KeyError: raise ClSelectExcept.WrongData("Record about application {} is absent".format(directory)) if app_data["app_status"] != APP_STARTED_CONST: skip_web_check = True else: alias = app_data["app_uri"] app_domain = app_data["domain"] nodejs_version = app_data["nodejs_version"] cwd, _ = utils.get_abs_rel(user, directory) environment = _create_environment(user, directory, nodejs_version) def action(): # npm install environment.extension_install(extension=extension, cwd=cwd) clpassenger.restart(user, directory) if not skip_web_check: try: check_response_from_webapp( domain=app_domain, alias=alias, action=action, ) except ClSelectExcept.WebAppError as err: raise ClSelectExcept.WebAppError("An error occured during installation of modules. %s" % err) else: action() def summary(user): summ = {} for directory, data in iteritems(clpassenger.summary(user)): if data["interpreter"] != ApplicationsManager.INTERPRETER: continue environment = _get_environment(user, directory, data).as_deepdict() summ[directory] = { "domain": data["domain"], "alias": data["alias"], "environment": environment["name"], "interpreter": environment["interpreter"], } # add only list with additions domains if "domains" in data and len(data["domains"]) > 1: summ[directory]["domains"] = data["domains"] return summ def validate_env_vars(env_vars): if type(env_vars) is not dict: raise TypeError for item in env_vars: if not isinstance(env_vars[item], basestring): raise TypeError return env_vars
Upload File
Create Folder