j9~ddlmZddlmZddlmZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlZddlZddlmZddlmZddlZddlZddlZddlZddlZddlZddlZddlmZddlm Z dd l!m"Z"m#Z#dd l$m%Z%m&Z&m'Z'dd l(m)Z)dd lm*Z*dd lm+Z+ddlm,Z,m-Z-m.Z.ddl/m0Z0m1Z1m2Z2m3Z3ddlm4Z4ddl5m6Z6m7Z7ddlm8Z9ddl:m;Z;ddlm?Z?ddl@mAZAmBZBddlCmDZDddlEmFZGddlHmFZIddlJmKZKmLZLmMZMmNZNmOZOmPZPddlQmRZRddlSmTZTmUZUGddeZ8Gdde8ZVd d!iZWGd"d#eXZYdS)$)print_function)division)absolute_importN)Set) iteritems)FormattedException)resolve_username_and_doc_root)CP_NAMEdocroot)NoDomain NotSupported IncorrectData) exec_utility) clselectctl) clpassenger) ClUserSelectClSelect ClExtSelect)APP_STARTED_CONSTENABLED_STATUSDISABLED_STATUSBaseSelectorError)validate_env_vars)format_summaryAPI_1ClSelectExcept)NodeJSConfigError)Website) NodeManager)PythonAppFormatVersionget_venv_rel_path) PythonManager) Environment)mkdir_p file_read file_writeget_using_realpath_keys get_abs_reldelete_using_realpath_keys)get_perm)_set_ui_configUIConfigExceptionceZdZdS)rN)__name__ __module__ __qualname__M/opt/cloudlinux/venv/lib64/python3.11/site-packages/clselector/selectorlib.pyrrHsDr3rceZdZdZdS)ClSelectDomainNotFoundzK Custom exception in case if user doesn't have the specific domain N)r/r0r1__doc__r2r3r4r6r6Ls Dr3r6statusokc zeZdZdZdZdZedQdZedZedZ edRdZ edQd Z ed Z edRd Z d Zed ZdZdZedZedZdZdRdZedZdRdZedZdZdQdZdZdZdZdZdZdZ dZ!d Z"d!Z#dRd"e$d#e%dzd$e&fd%Z'd&Z(d'Z)dRd(e&e$e$fd"e$d#e%dzd$e&fd)Z*dRd*Z+d+Z, dSd,Z-ed-Z.dRd.Z/dRd/Z0ed0Z1dTd2Z2dUd4Z3d5Z4d6Z5d7Z6d8Z7ed9Z8d:Z9ed;Z:d<Z;d=ZZ=dRd?Z>dQd@Z?dAZ@edBZAdVdCZBdDZCdEZDdFZEdGZFdRdHZGdIZHdJZIdKZJedLZKedMZLeMdNZNdOZOdPZPdS)WCloudlinuxSelectorLibcl||_d|_d|_d|_d|_d|_d|_d|_d|_d|_ d|_ d|_ |j|jkrLdd l m }||_ t|_tj|_ tj|_ dS|j|jkrLdd lm }||_ t'|_tj|_ tj|_ dS|j|jkrdd lm}||_dSdS) Nz/usr/bin/selectorctlz+/usr/share/l.v.e-manager/utils/dynamicui.py/usr/sbin/cloudlinux-selectornodejspythonrubyphpr)ApplicationsManager) PhpManager) interpreter_SELECTORCTL_UTILITYDYNAMIC_UI_CTL_CMDCLOUDLINUX_SELECTOR_UTILITYNODEJS_INTERPRETERPYTHON_INTERPRETERRUBY_INTERPRETERPHP_INTERPRETERselector_manager apps_managerselector_user_libselector_old_lib$clselect.clselectnodejs.apps_managerrBr clselectclselectnodejsuserclselectctlnodejsuser$clselect.clselectpython.apps_managerr#clselectpythonuserclselectctlpython clselect.clselectphp.php_managerrC)selfrDrBrCs r4__init__zCloudlinuxSelectorLib.__init__Ws[&$:!"O+J("*"* &$ !% !% $  t6 6 6 P P P P P P 3 3 5 5D $/MMD !%-%@D "$,$BD ! ! !  !8 8 8 P P P P P P 3 3 5 5D $1OOD !%-%@D "$,$>D ! ! !  !5 5 5 C C C C C C$.JLLD ! ! !6 5r3cf|j|jkrdS|jjdS)za Checks that selector is able to work on current os environment :return: N)rDrKrL cl_select_libcheck_requirementsrXs r4check_selector_is_availablez1CloudlinuxSelectorLib.check_selector_is_availableys:  t3 3 3 F +>>@@@@@r3cn|j||}|||\}}|S)z7Get doc_root from application config or raise exception)rMget_app_domain$safely_resolve_username_and_doc_root)rXusernameapp_rootdomain_doc_roots r4safely_resolve_doc_root_for_appz5CloudlinuxSelectorLib.safely_resolve_doc_root_for_apps8"11(HEE??&QQ 8r3Nc t||\}}ng#t$rt|dnd||ddt$rt ddt idt $rt d ||ddwxYw||fS) a8 Safely resolve username and doc_root by domain, or resolve document root by username, or resolve document root and username by effective uid :param user: str -> name of unix user :param domain: str -> domain of panel user :return: tuple -> user, doc_root userrdNzNo such domain: %(domain)szNo such user: %(user)s)rdrjmessagecontextz+Nodejs selector not supported for %(panel)spanelz3Domain %(domain)s is not owned by the user %(user)s)r r r6r rr r)rjrd result_userresult_doc_roots r4raz:CloudlinuxSelectorLib.safely_resolve_username_and_doc_roots" +H,,, (K   () <;/G"( $         L      T"( $    O++s A$A;cd}t\}}|d}nHt|tsd}n0|d |dd}n|dkr |dkrd}n|ddkrd}|S) z Check whether selector should be run through "su - user" :param opts: dict of parsed cli params :return: True if should be run through su or False if not TNF--user--domainr --interpreterrA)r+ isinstancedict)optsresulteuidegids r4should_be_runned_as_userz.CloudlinuxSelectorLib.should_be_runned_as_usersZZ d <FFD$'' FF (^ #Z(8(@FF QYY4199FF / "e + +F r3c\|ddko |dduotjdkS)NrtrArrr)osgeteuid)rws r4should_run_user_without_cagefsz4CloudlinuxSelectorLib.should_run_user_without_cagefss8O$-!H~T)!z||q  !r3c.tj|}|S)z Resolves user eigher with passed username or with getting current user ID :param user: str or None -> username to be resolved :return: obj -> pwd user object )pwdgetpwnam)rjuserdatas r4_get_user_pwd_dataz(CloudlinuxSelectorLib._get_user_pwd_datas<%%r3c6||tdiddSdS)z Check if user and domain are None :param user: name of unix user :param domain: domain of panel user :return: None NBUser or domain parameter must be specified if current user is rootrkrris r4user_and_domain_checkerz-CloudlinuxSelectorLib.user_and_domain_checkers: B?"C88 DDc>ddi}tjrd|d<|SNrFT)r rress r4get_nodejs_selector_statusz0CloudlinuxSelectorLib.get_nodejs_selector_status.s+!5) == ) +&*C" # r3c:d|jjrtntiS)N PHPSelector)rLrrrr]s r4get_php_selector_statusz-CloudlinuxSelectorLib.get_php_selector_status5s1F1Wl~~]lmmr3c |j}|||S#t$r}||cYd}~Sd}~wwxYwN)rL get_summaryrget_selector_statusrr)rXrrs r4rz!CloudlinuxSelectorLib.get_summary8s )'3355C JJt//11 2 2 2J  ) ) )%%a(( ( ( ( ( ( ( )sAA A-A("A-(A-c>ddi}tjrd|d<|Sr)r#rrs r4get_python_selector_statusz0CloudlinuxSelectorLib.get_python_selector_status@s+!5) ?? + +&*C" # r3ct tj|jS#t$rt ddiwxYw)NrlzNo such user: `%(user)s`)rrpw_dirKeyErrorr)rjs r4 get_user_homez#CloudlinuxSelectorLib.get_user_homeGsR <%%, ,    5"  s7ct}|||Sr)r rrr)rXrs r4get_nodejs_summaryz(CloudlinuxSelectorLib.get_nodejs_summaryPs:mm'')) 4++--... r3c$||}|j|jkr|j|||d}n<|j|jkr|j|||d}nt |g}|j|jkr|d|||:|j|jkr|d||| |||}|S)aD Runs script to execute other script inside user app environment :param user: str -> owner of application :param app_root: str -> application directory :param script_name: str -> name of script :param script_args: list of str -> arguments for the script :return: dict npmr?z run-scriptNz--) rrDrHrMget_binary_pathrINotImplementedErrorappendextend_run_interpreter) rXrjrc script_name script_args user_homeinterpreter_pathcmdrxs r4 run_scriptz CloudlinuxSelectorLib.run_scriptUs%&&t,,  t6 6 6#0@@h 5 2 2    !8 8 8#0@@h 8 5 5  &'' '   t6 6 6 JJ| $ $ $ ;  "4#::: 4   JJ{ # # #&&sIx@@ r3c:tj|tj||tjtjd} |\}}n'#t$r}td||ddd}~wwxYwd |j | | }td||fDrKtj }d |d } tj| } |d | d | d z }dt#j|i} | ddi|j dkr d|j | d<| S)z Run interpreter in users environment :param cmd: list -> command to execute :param user_home: -> user home directory :param app_root: -> app path :return: dict T)argscwdstdoutstderrtextz6run-script call: `%(args)s` failed with error: %(err)s)rrrkNz%returncode: {} stdout: {} stderr: {} c3BK|]}d|vVdS)z out of memoryN)lower).0outputs r4 z9CloudlinuxSelectorLib._run_interpreter..s/PPV&,,..0PPPPPPr3z/proc/z/limitsaD Out of memory error may be caused by hitting LVE limits or "Max data size", "Max address space" or "Max resident set" process limits Please check LVE limits and process limits. Readjust them if necessary More info: https://docs.cloudlinux.com/shared/cloudlinux_os_components/#known-restrictions-and-issues process limits "z":  datar8successrzScript exit code: warning) subprocessPopenr}pathjoinPIPE communicateOSErrorrr returncodestripanygetpidpathlibPath read_textbase64 b64encodeencodedecoder) rrrcprrr output_stringpidproc_limits_pathprocess_limitsrxs r4rz&CloudlinuxSelectorLib._run_interpreterrs  "',,y(;;?:? G G G ]]__NFFF    2$'22""    & L LLNN LLNN    PP?OPPP P P )++C4444 $\*:;;EEGGN P(8 PP>L PPP M&*=+?+?+A+ABBIIKKL x+,,, <1   CQ\ C CF9  s A%% B /BB c|j|jkr|j|S|j|jkr|jSdSNwebsite)rDrKrLrrH)rXrs r4get_fullzCloudlinuxSelectorLib.get_fulls[  t3 3 3(44W4EE E  t6 6 6(4466 6 7 6r3ct}tj}t |D]\}}||xxdz cc<|D]}||d|d<|S)a_ Add selector usage statistics (amount of domains that use some version, etc) Fist parameter is an array with such format: [{'version': '5.6'}, {'version': '7.6'}] Output is an array with such format: [{'version': '5.6', 'users': 10}, ...] :type versions_list: list :rtype: list version total_users)rget_user_version_map collectionsCounterr) versions_listuser_version_mapversion_user_maprjritems r4_add_statistics_fieldz+CloudlinuxSelectorLib._add_statistics_fields(>>>>@@&.00&'788 + +MD' W % % % * % % % %! D DD"24 ?"CD  r3c^|j|jkrSt|jd}t |dt }t j|}n#|j|j}ni}| ddkr d|di}n|}|S)zG Retrieves supported versions list and default version Fjson)r api_versionNr8ERRORrl) rDrKrrrrrloadsrLget)rXr json_dataselectorctl_resultrxs r4get_supported_versionsz,CloudlinuxSelectorLib.get_supported_versionss  t3 3 3D,--99%@@D&tFNNNI!%I!6!6    " .!%!6!B!B!D!D  !#   ! !( + +w 6 6 29 =>FF'F r3c|r|gnd}|j|jkr|j||S|dS)z3 Retrives current version for user NzSupported only by php selector)rDrKrLget_current_versionr)rXrjrds r4rz)CloudlinuxSelectorLib.get_current_versionsS'vv4  t3 3 3(<'(9:OO > > >I%%)))I*>?????")9=====  > "?33s)A AAc|j|jkr|S|j|jkr|S|j|jkr|SdSr)rDrHrrIrrKrr]s r4rz)CloudlinuxSelectorLib.get_selector_statusss  t6 6 62244 4  !8 8 82244 4  !5 5 5//11 16 5r3c|jj SrrLrr]s r4php_selector_is_disabledz.CloudlinuxSelectorLib.php_selector_is_disableds(999r3c|jjSrrr]s r4php_selector_is_enabledz-CloudlinuxSelectorLib.php_selector_is_enableds$55r3c|j|jkrdS ddlm}m}n#t $rYdSwxYw|rQ|s=|}|r1 |d}|dsdSn#t$rYnwxYwdS)z Returns True when MultiPHP system default PHP version is alt-php and PHP Selector is NOT disabled For details please see LVEMAN-1170 Fr)is_ea4_enabledread_cpanel_ea4_php_confdefaultzea-phpT) rDrKclcagefslib.selector.configurer r  ImportErrorr startswithr)rXr r conf default_phps r4check_multiphp_system_defaultz3CloudlinuxSelectorLib.check_multiphp_system_defaults  t3 3 35  _ _ _ _ _ _ _ _ _   55  >   D$A$A$C$C ++--D "&y/K&11(;;$#t$Dus ++A99 BBc |j|j|jfvrqt|D]Z\}} |||}n.#t $r!}||cYd}~cSd}~wwxYw|tkr|cS[tS|} |d}n5#t$r(|d|j d|jcYSwxYwd|D}t| |z r^|dd t| |z d|j d|jd Sd } g} t|D]u\}} | r5t|jt!|n4t|jt!|| d z } v| t%|krtS| d kr&d d | t%|| iS|d| S)Navailable_versionszcorrupted answer from z --json --summary --interpreter ch|] }|d Srr2)rxs r4 z?CloudlinuxSelectorLib.set_supported_versions..s I I I!9 I I Ir3zinvalid alternative versions (z, z), see z --summary --interpreter z for valid versionsrrr8z>WARNING: only {} of {} commands was successful. Errors was: {}z&All commands were failedErrors was: {})rDrHrIrset_version_statusrrrrrrEsetkeysrrenable_versionstrdisable_versionrr) rXversionsrenable_disablerxrralternatives_listalternatives_versionsr errors_list to_enables r4set_supported_versionsz,CloudlinuxSelectorLib.set_supported_versions s   79PR R R+4X+>+> " "'1!44^WMMFF(111--a00000000001[((!MMM) //11  > )*> ?   > > >%%%)))4+;+;'=>> > > > >!J I7H I I I x}}  "7 7 '%%%IIc(--//225JJKKKKTMfMfMf$$$&'' '  "+H"5"5   GY I)**99#g,,GGGG)**::3w<<HHH qLGG c(mm # #  q[[++16'3x==++V+V  %%'77=vk7J7JLL Ls/A A- A( A-(A-B%%/CCcB |j|j|nv#tjjj$rt dd|idtjjtf$r,}|t|cYd}~Sd}~wwxYwtSNNo such php version: %(ver)sverrk) rLswitch_default_versionrQclselectexceptrNoSuchAlternativeVersionBaseClSelectExceptionrrrr)rXrrs r4set_default_versionz)CloudlinuxSelectorLib.set_default_version8s :$0%<   79PRVRfg g g//77 7 h gr3ctjs&tjstjrKt |jdgd\}}}|dkr)|d||SdS)Nz--sync-conf=allT)rrz"Can not sync UI with reason: {} {})detect is_cpanelis_pleskis_darrFrr)rXretcodeoutrs r4rzCloudlinuxSelectorLib.update_uiqs     K!2!2 Kflnn K ,'*;),;;GZY`;aa(MM$'''*@ > > >55c!ff======== >M 4 3s4A B 4!BB B c|j|jkrb |j|||nC#tjj$r,}|t|cYd}~Sd}~wwxYwtSr) rDrKrL set_optionsrQr,r.rrr)rXoptionsrrrs r4rFz!CloudlinuxSelectorLib.set_optionss  t3 3 3 >%11'7G1TTTT*@ > > >55c!ff======== >s0A0!A+%A0+A0c>||dd}||dkr'td|j|j|jkr@t jd|}|stdd|id|d S|St|ttfr;|j|jkrtt|St|S|d krtd d|id|S) a3 Attempts to get or verify version to be passed to external program Currently supported version is one digit (6 or 8). If version is None, return a default version :param version: str or None -> version to be verified or found :return: str -> digit as string Nrz{} default version not definedz(?P\d+)z#Incorrect selector version: %(ver)sr*rkrnativezUnsupported version: %(ver)s) rrrrrDrHrematchgroupruintfloatr)rXrrms r4resolve_versionz%CloudlinuxSelectorLib.resolve_versionsO ?"6688<<=NPRSSO&/R*?*?$%E%L%LTM]%^%^___4#:::H0/BBP(5Z6;_5M*O*OPPPwwy)))&& gU| , , $4#:::3w<<(((7||# h   -K.3W-="?"?@@ @r3c |||||}|!ttj|}|||\}} |j|jkr+|j ||||| |||| |j |  no|j|j kr%tj ||||| n:|j|jkr*|j ||||| |||||j |  nD#tjj$r-} |t%| cYd} ~ Sd} ~ wwxYwt&S)a Creates application for specified user, interpreter and version If user is None we hope that the external application resolves a user Currently NodeJS supported only :param domain: str -> domain of the application :param app_root: str -> app path relative to user home :param app_uri: str -> URI path of the application :param version: str or None -> version of the interpreter :param user: str or None -> username of user who owns the app :param app_mode: str or None -> application mode (development or production) :param startup_file: str or None -> main application file :param env_vars: json_string or None -> enviroment variables for application :param entry_point: Application entry point (used only for python interpreter). :param passenger_log_file: Passenger log filename :return: dict N)rfenv_vars startup_file domain_name entry_pointrMpassenger_log_filerf)rrfapp_moderSrTrUrMrW)rx)rrQrrrrarDrIrOcreaterMrJrQclselectctlrubyrHr,r.rrr) rXrcapp_urirrjrdrYrTrSrVrWrfrs r4 create_appz CloudlinuxSelectorLib.create_apps$ $$T6222&&w//  (H)=)=>>HBB4PPh A4#:::%,,T8WgX`6>\9?[:>:K`r-tttt!T%:::(//h[c/dddd!T%<<<%,,(GWx%| &T5F[m- &< A A A11Q1@@ @ @ @ @ @ @ As)B*DE("E EEctj|j|}tj|}tj|j}||tjzs||krtdd|idtj|stdd|id|S)z Resolve app root to absolute path and checks if it exists :param app_root: str -> relative a user homedir app path :param userdata: obj -> pwd user object :return: str -> absolute path to app zNo such application: %(app)sapprk) r}rrrrealpathrseprisdir)rcrapp_path real_app_path real_homes r4_get_application_pathz+CloudlinuxSelectorLib._get_application_paths7<<::((22 G$$X_55 '' BF(:;; A QZ@Z@Z -K.3X->"@"@AA Aw}}]++ A -K.3X->"@"@AA Ar3c t}||d||}||| t jt j |}t j|j }| |t j zstdd|id|j r|j ||nd} fd|r|dpgngD} | r|| vrtdd|idt j|stdd|id t#|d5} | } |dt)j| idddn #1swxYwY|S#t.$r.} |t3| d d cYd} ~ Sd} ~ wwxYw) a  Reads file and returns its content as Base64 string :param app_root: str -> path to app relative to user home :param user: str -> username to resolve app path :param config_path: str -> file to be read (relative to app path) :return: dict Nz&Configuration file not found: %(path)srrkch|]?}tjtj|@Sr2r}rr`rrfrcs r4rz8CloudlinuxSelectorLib.read_app_config..I    G  RW\\(A66 7 7   r3 config_filesrbrstrerrorrI)rrCrrrfr}rr`rrrrarrMget_app_configrexistsopenreadrrrr Exceptionrgetattr)rXrc config_pathrjrxrfull_config_pathre app_configregistered_pathsrkrrrcs @r4read_app_configz%CloudlinuxSelectorLib.read_app_configs!!## $$T4000**400--hAA7++BGLL;,O,OPPG$$X_55 **9rv+=>>  G & 4  JNIZdT&55dHEEE`d     @JRz~~n55;PR      08H H H G & 4  w~~.//  G &(89   N&-- Ivvxx vv'7'='='D'D'F'FGHHH I I I I I I I I I I I I I I IM N N N11'!Z2L2LMM M M M M M M NsC HAG8, H8G<<H?G<H H=#H82H=8H=c ||d||}||| tjtj |}tj|j}||tj zstdd|id|j r|j ||nd} fd|r| dpgngD} | r|| vrtdd|id t|d5} | t!j|dddn #1swxYwYt$S#t&$r.} |t+| dd cYd} ~ Sd} ~ wwxYw) a Saves data passed as Base64 string to specified file :param content: data for saving in app's config :param app_root: str -> path to app relative to user home :param user: str -> username to resolve app path :param config_path: str -> file to be read (relative to app path) :param content: str -> Base64-encoded string :return: dict Nz)Invalid configuration file path: %(path)srrkch|]?}tjtj|@Sr2rirjs r4rz8CloudlinuxSelectorLib.save_app_config..:rlr3rmwbrorI)rrrfr}rr`rrrrarrMrprrrwriter b64decoderrtrru) rXrcrvcontentrjrrwrerxryrkrrcs @r4save_app_configz%CloudlinuxSelectorLib.save_app_config#sL $$T4000**400--hAA7++BGLL;,O,OPPG$$X_55 **9rv+=>>  J & 4  JNIZdT&55dHEEE`d     @JRz~~n55;PR      08H H H J & 4   N&-- 3(11222 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3  N N N11'!Z2L2LMM M M M M M M NsBF(F8 FFF F F G #G G Gct|}||d|gn)||d|gntd|S)Nrsrrr)listrr)rjrdr result_argss r4_add_user_or_domainz)CloudlinuxSelectorLib._add_user_or_domainNsf4jj      F3 4 4 4 4     $/ 0 0 0 0 !eff fr3FcZ||||j|jkrtdd|jid |D]}|j||| t S#tjj $r,}| t|cYd}~Sd}~wwxYw)an Uninstall described modules for user's webapp :param app_root: directory with webapp :param modules: comma-separated list of modules to uninstall :param user: name of unix user :param domain: domain of user :param skip_web_check: skip check web application after changing its properties :return: None zJUninstall command is available only for python interpreter, not %(interp)sinterprkN) rrDrIrrO uninstallrrQr,r.rr)rXrcmodulesrjrdskip_web_checkmodulers r4uninstall_modulesz'CloudlinuxSelectorLib.uninstall_modulesYs $$T6222  t6 6 6 gd.""   ! H H%//hGGGG H  &< : : :11#a&&99 9 9 9 9 9 9 :s!A**B*>!B%B*%B*r2c ||||j|jkrn |j||||jt S#tjj $r,}| t|cYd}~Sd}~wwxYw|j|j kr |r+|D]'}|j|||d||j(n?|r&|j||d|||jnd} | | St S#tjj $r,}| t|cYd}~Sd}~wwxYwtdd|jid)a Install described modules for user's webapp :type domain: domain of user :param user: name of unix user :param app_root: directory with webapp :param skip_web_check: skip check web application after change it's properties :param spec_file: file containing modules and their versions to install :param modules: list of installed modules :return: None )rrMNz9Please, specify modules or requirements file with modulesUnknown interpreter: %(interp)srrk)rrDrHrOinstallrMrrQr,r.rrrIr) rXrcrjrdr spec_filerrrrs r4install_modulesz%CloudlinuxSelectorLib.install_modulesss $$T6222  t6 6 6 #%--dH^;?;L.NNN #"*@ > > >55c!ff======== > !8 8 8 # ?")VV-55dHfdcqCGCT6VVVVV?)11$$ AO^b^o2qqqqVC99#>>>#"*@ > > >55c!ff======== > !<d."" s<#AB&!B B B&A+DE-!EEEcj||d |j|jkr!tj||n |||}n3#t$rtj dd|it$rd}YnwxYw|j|j |j fvr$|j ||||jntjdd|jinC#tjj$r,}|t'|cYd}~Sd}~wwxYwt(S)z Destroy specified application root directory and user name :param app_root: Application directory :param user: name of unix user :return: dict Nz\No such application or it's broken. Unable to find app-root folder by this path %(app_root)srcrk)rfrMrr)rrDrJrQr[destroyrg TypeErrorClSelectExceptions WrongDatar6rHrIrOrMInterpreterErrorr,r.rrrrXrcrjrfrs r4 destroy_appz!CloudlinuxSelectorLib.destroy_apps $$T4000 :4#888(00x@@@@ $#CCD(SSHH ,6!['!.$$$#HHH$#(?AX'YYY)11$8?C?P2RRRR-= A!)4+; <>>>>&< : : :11#a&&99 9 9 9 9 9 9 :sB1C+ A! C+!-BC+BAC++D+?!D& D+&D+c||d |||}|j|j|jfvr#|j||||jntj dd|jitS#tj j $r,}|t|cYd}~Sd}~wwxYw)z Start specified application root directory and user name :param app_root: Application directory :param username: name of unix user :return: dict Nrrrk)rrgrDrHrIrOstartrMrrrrQr,r.rrrXrcrbrfrs r4 start_appzCloudlinuxSelectorLib.start_apps $$Xt444 :;;HhOOHD$;T=T#UUU%++Hh$J[\\\\(9=%t'78:::: &< : : :11#a&&99 9 9 9 9 9 9 :sA1B C !C?C C c||d |||}|j|jkr#|j||||jnP|j|jkr#|j||||jntj dd|jitS#tj j $r,}|t|cYd}~Sd}~wwxYw)z Destroy specified application root directory and user name :param app_root: Application directory :param username: name of unix user :return: dict Nrrrk)rrgrDrHrOrestartrMrIrrrrQr,r.rrrs r4 restart_appz!CloudlinuxSelectorLib.restart_apps $$Xt444 :;;HhOOH4#:::%--h(DL]^^^^!T%<<<%--h(DL]^^^^(9=%t'78:::: &< : : :11#a&&99 9 9 9 9 9 9 :BB88C8 !C3-C83C8c||d |||}|j|jkr#|j||||jnP|j|jkr#|j||||jntj dd|jitS#tj j $r,}|t|cYd}~Sd}~wwxYw)z Start specified application root directory and user name :param app_root: Application directory :param user: name of unix user :return: dict Nrrrk)rrgrDrHrOstoprMrIrrrrQr,r.rrrs r4stop_appzCloudlinuxSelectorLib.stop_apps $$T4000 :;;D(KKH4#:::%**48TEVWWWW!T%<<<%**48TEVWWWW(9=%t'78:::: &< : : :11#a&&99 9 9 9 9 9 9 :rc d|zdz}d|zdz}tjtj|dddD]}tj|s t |d}||vs||vra|||}|||} t|| d#t$rYtj \} } } tj ttj| YwxYwdS) z Replace old prompt and env_var in binaries in new environment Working with bytes here, because of python binary (:*binrn)moder}N)rglobr}rrrbr&replacer'IOErrorsysexc_inforr~r tracebackprint_tb) new_envold_envnew_relold_rel old_prompt new_prompt venv_bin_file old_activate _new_activate new_activatere traceback_s r46_replace_old_env_and_prompt_in_binaries_in_environmentzLCloudlinuxSelectorLib._replace_old_env_and_prompt_in_binaries_in_environmentsxGmc)1133 Gmc)1133 !Yrw||GS%'M'MNN J JM7==// JJ#,]#F#F#FL~~''<77:;U;U(4(<(> C  C cLtj|s&t|tj||dStj|D]5}t jtj|||6tj |dS)z Move all items from old directory of application to new directory :param old_directory: full real path to old directory of applicaton :param new_directory: full real path to new directory of applicaton N) r}rrqr%renamelistdirshutilmoverrmdir) old_directory new_directoryrs r4_move_app_from_old_dir_to_newz3CloudlinuxSelectorLib._move_app_from_old_dir_to_newAsw~~m,, $ M " " " Im] 3 3 3 3 3 =11 N N BGLL==}MMMM H] # # # # #r3c  |j|} t|||}n%#t$rt jd|zwxYwt ||\}}t ||\}} tj| n3#t$r&} t j t| d} ~ wwxYw| ||| } t|| | t j |#t$rYnwxYw| |||} t||| } n%#t$rt j d|zwxYw| d}| d}|j||| |j}|j|jkrPt'||\}}t ||\}}t |t'|||d\}}n|j|jkrt |t*j|jjj|\}}t |t*j|jjj| \}}nt7t*j|d}t*j|d}t*j|}t*j|st+j|t?j |||!|||j|jkr|"||| ||j|jkrt'||\}}n:|j|jkr|j#||}nt7|jj$|||}|j%}t|||d }|tLkrmtOj(||||)d d}tOj*||||j|||d | tOj+||tY||||||<|j-||dS) a Move user's application from directory to new_directory :param user: application owner. unix like user name :param old_directory: current directory with application :param new_directory: new directory for application :return: None 8No such application (or application not configured) "%s"Nr r app_summaryrrrI app_statusrWrTrfrTrW).rMget_user_config_datar(rrNoSuchApplicationr)rcheck_directory ValueErrorrrr AppRootBusyrO_get_environmentnamerDrIr"rHr}rrrN environmentsDEFAULT_PREFIXrdirnamerqmakedirsrrrr _get_prefixr$rrr unconfigurer configurerr*write_full_user_config_data)rXrjrr full_configrxold_absrnew_absrrnew_user_summaryold_user_summaryold_user_app_summaryrfrenv_namer*rel_venv_old_envre_new_envrr new_env_dirprefix environmentrrpassenger_log_file_to_sets r4 _relocatezCloudlinuxSelectorLib._relocateSs<'<0?@@ @ @( 2$W-(99 --=m-L:NNNR   t6 6 6-dMBBMC%h  KHa&'mSIII!LNNKHaa  !8 8 8%dBGLL&3BG-M-MNNKHa&dBGLL&3BG-M-MNNKHaa&'' '',,x,,',,x,,gooh// w~~k** % K $ $ $ GW%%% **7G<<<  t6 6 6  G GQXZacj k k k  t6 6 6)$ >>IAvv  !8 8 8*66t]KKFF%'' ',9EEhPTV\]] ((**1,T=+NN|\ * * *  #D- 8 8 8(3M(B(F(FG[]a(b(b %  !$ ud>NPVai/9./I5N P P P P  m 4 4 4 #4 DDD%/ M" 55dKHHHHHs?."A:B B?!B::B?C?? D  D 'D99"EcX |j|j|jfvr||||n2|j|jkr"t j|||dnC#t jj $r,}| t|cYd}~Sd}~wwxYwtS)a= Call selectorctl to relocate application from old_app_root to new_app_root :param user: application owner :param old_app_root: current application directory (current application name) :param new_app_root: new application directory (new application name) :return: json N) rDrIrHrrJrQr[relocater,r.rrr)rXrj old_app_root new_app_rootrs r4rzCloudlinuxSelectorLib.relocates :D$;T=T#UUUt\<@@@@!T%:::(11$ lTXYYY&< : : :11#a&&99 9 9 9 9 9 9 :sAA""B"6!BB"B"cd}tj|||}tj|||}tj|tj|krdStj|}tj|stj|tj||dS)a :param old_doc_root: path to old doc root of application :param old_alias: old alias (uri) of application :param new_doc_root: path to new doc root of application :param new_alias: new alias (uri) of application :return: None rN) r}rrr`rrbrrrC) old_doc_root old_alias new_doc_root new_aliasrold_htaccess_filenew_htaccess_filenew_htaccess_paths r4_transit_htaccess_filez,CloudlinuxSelectorLib._transit_htaccess_filesGLLy(KKGLLy(KK 7  - . .7##$566 7 7 FGOO,=>>w}}.// + K) * * * %'899999r3c |j|} t|||}n5#t$r(t jd|wxYw||||} t|||} n5#t$r(t jd|wxYw| d} | d} || ntj |} |j ||||} | j}||dtkru||dd}t#j||| |j |dd ||d | t#j||| | | | t#j||n|| }|| | || | |d <|||d<|j||dS)a Change application URI :param user: application owner. unix like user name :param directory: directory with application. (app-root) :param alias: new alias (app-uri) for application or None if change only the domain :param new_doc_root: NEW doc_root to transit application to :param new_domain: NEW domain to transit application to :return: None z8No such application (or application not configured) "{}"rr NrrrWTtransitrTr)rrr\rd)rMrr(rrrrrrr get_aliasrOrrDrrrrrrrrr)rXrjrr new_domainrrrx apps_summaryold_app_summaryrrrrrrs r4_transitzCloudlinuxSelectorLib._transitsf'<(B(BCWY](^(^ %  !$ 9d>NPVX\^g%J~4N#< > > > >  T9iQ]lx y y y y  i 0 0 0 0#+  ' ' iy Y Y Y ) 9  !#-Jx  55dKHHHHHs.2A ;B 2B?c |d}n|||\}}|j|j|jfvr||||||nB|j|jkr$t j||||ntnC#t j j $r,}| t|cYd}~Sd}~wwxYwtS)aV Call selectorctl to transit application to new_app_uri :param user: application owner :param app_root: application directory (application name) :param new_app_uri: new uri or None if change only the domain :param new_domain: new domain or None if change only the app_uri :return: json NrX)rarDrIrHr rJrQr[rrr,r.rrr)rXrjrc new_app_urirrrers r4rzCloudlinuxSelectorLib.transit(s :!# "&"K"KDR\"]"]<D$;T=T#UUU dHlJ TTTT!T%:::(00xWc0dddd)+++&< : : :11#a&&99 9 9 9 9 9 9 :sBBC&!C C Ccd}|r, ||}n#tj$rYnwxYw|j||j||dkrtjddS)z Install nodejs extensions to new nodejs environment and change symlink //node_modules to new environment. Raise exception `WebAppError` if npm will return non-zero code rz tjdd}tjjd|tj djz<jdS)NrWrTr %s_version)rrrrrDrrMr) rrrxrrrfrrXrjrs r4actionz5CloudlinuxSelectorLib._change_version..actions  #D) 4 4 4(3I(>(B(BCWY](^(^ %  !$ 5$:JF]e/9./I5N P P P P  i 0 0 0FMK "<$2B#B C   9 9$ L L L L Lr3)rdrr z,An error occured during changing version. %sN)rMrr(rrrrOrrrDas_dict_create_environment_ensure_version_enabledrr8rIrrHrrsummaryr_get_info_about_webappcheck_response_from_webappr)rXrjrrrold_environmentnew_environmentinstalled_extensionsuser_summary_datar app_domainr rrrxrrfrs```` @@@@@r4_change_versionz%CloudlinuxSelectorLib._change_versionos'<R S S S S  !8 8 8  , ,T9oOc d d d(/55-dI?PQQ y) ,,..5 1HHVZ[[z M M M M M M M M M M M M M  k%@@%!A &1 k k k(45cfi5ijjj k FHHHHHs!7"A<GH*HHc4 |j|j|jfvrt|j|jkrM|j||dtj}|tjkrddiS|j ||tkr| ||||n| |||tS#tjj$r,}|t%|cYd}~Sd}~wwxYw)ax Call selectorctl to change current interpreter version to new_version for application :param user: application owner :param app_root: application directory (application name) :param new_version: new nodejs interpreter version :param skip_web_check: skip check web application after change it's properties :return: json app_versionr8zThis application was created by too old version of python selector and we cannot change version without migration to the new application format. To do that you can use `cloudlinux-selector migrate` command or just click button in web UI.)rN)rDrHrIrrMrprr!LEGACYget_app_statusrr,_change_version_for_stopped_apprrQr,r.rr)rXrjrc new_versionrr.rs r4change_versionz$CloudlinuxSelectorLib.change_versions> :(?AX'YYY))4#:::"/>>tXNNRR!#9#@BB "8"??? #L //h??CTTT$$T8[Q_$````44T8[QQQ &< : : :11#a&&99 9 9 9 9 9 9 :s%A8C;ACD+!D DDc$|j|jks|j|jkro|||} |j||||dS#t $r,}tjd |d}~wwxYwdS)NzRUnable to set environment variables in htaccess file for the application.Error: {}) rDrIrHrgrMadd_env_vars_for_htaccessrtrrr)rXrjrcrSrfrs r4set_variables_for_litespeedz1CloudlinuxSelectorLib.set_variables_for_litespeeds  t6 6 6$:JdNe:e:e;;D(KKH !;;D(HV^_____   (4 &s   ;f:esA B !'BB c |j|} t||| } n%#t$rt jd|zwxYw|j|jkr8|6| d|kr*| dtj krt j d||| d<||| d<||| d<||| d<||| d ks|j|g|| d krN|| d <|j|jkr9|j |||} |j ||| || |d krdn|| d <|j ||} t!j|} t||| }|d }| j}|d }|d}t!j||6| d !t!j||||j|||n4t!j||||j||| d |t!j|||j|| ||||dS)al Set application mode, environment variables and startup_file for application :param config_files: names of config files (such as requirements.txt or etc) :param entry_point: the specified entrypoint for application :param user: application owner. unix like user name :param directory: directory with application :param app_mode: expected application mode :param env_vars: dict with environment variables for application :param startup_file: main file for application :param passenger_log_file: Passenger log filename :return: None rNrSr.zUnable to set environment variables. Application was created too long time ago. Please, migrate your application to newer version before changing interpreter versionrYrVrmrTrIrWrr r)r)rfrWr)rMrr(rrrrDrIr!r/rrrO_get_full_path_to_startup_file setup_wsgirrr$r _unconfigurerrrr6)rXrjrrYrSrTrVrmrWrapp_config_datastartup_file_full_pathenv user_summaryuser_app_summaryrrrf htaccess_paths r4_set_variablesz$CloudlinuxSelectorLib._set_variabless.'</#t'>>>-1-B-a-a!$..*)44T9F\^ijjj!-ASVX@X@X^p 45'88yIIC&.t44L6tY UU $W-E__&&-F' 2H,Z8M  $m < < < <#(;(;N(K(K(S%dIud>NPVai9KMMMMM%dIud>NPVai3B3F3F~3V3V9KMMMM D),,, 55dKHHH ((y(CCCCCs ."Ac "|O ttj|} n.#ttf$r|dcYSwxYwd} |j|j|jfvrA|j ||tkr| |||| ||||n| |||| ||||tS#tjj$r,} |t%| cYd} ~ Sd} ~ wwxYw)ak Call selectorctl to set variables for application :param config_files: names of config files (such as requirements.txt or etc) (only for python) :param entry_point: the specified entrypoint for application (only for python) :param user: application owner :param app_root: application directory (application name) :param app_mode: application mode :param env_vars: json_string with environment variables for application :param startup_file: main file for application :param passenger_log_file: Passenger log filename :return: json Nz/wrong json format for environment variable list)rrrrrrrDrHrIrMr0rrA_set_variables_for_stopped_apprrQr,r.r) rXrjrcrYrSrTrVrmrWenv_dictrs r4 set_variablesz#CloudlinuxSelectorLib.set_variables8s`   i,TZ-A-ABBz* i i i556ghhhhh iH :D$;T=T#UUU%44T8DDHYYY##D(Hh Vaco$6888833D(HhXd4?Oaccc &< : : :11#a&&99 9 9 9 9 9 9 :s.!&&AAA8CD"!D D Dc |j|}|S#t$r}|j|jdcYd}~Sd}~wwxYw)z Retrieves info about all installed interpreters and user(s) applictions :param user: User name for read applictions. If None all users will be processed :return: Dict with info )rxrmN)rMget_applications_users_inforrlrm)rXrj result_dictrs r4get_apps_users_infoz)CloudlinuxSelectorLib.get_apps_users_infoZsc  ?+GGMMK   ? ? ?iAI>> > > > > > > ?s A<AAc||j|s!tj||ddS)z Check whether particular interpreter version is enabled and raises exception if not :param username: user to include in exception :param new_version: new interpreter version zversion is not enabledN)rLis_version_enabledrQrUnableToSetAlternative)rXr2rbs r4r#z-CloudlinuxSelectorLib._ensure_version_enabledfsF$77 DD r)@@;Xpqq q r rr3c"||||j||}|j|||d}t |}|j|||d}|D]7} ||#tj j j $rY4wxYw|j |} || |d|j z<|j|| dS)z Changes version for stopped application :param username: application owner :param app_root: application directory (application name) :param new_version: new nodejs interpreter version :return: None Nr)r#rMget_interpreter_version_for_apprOr"rr8rrQr,rrrrDr) rXrbrcr2 old_versionr'rr(rrxs r4r1z5CloudlinuxSelectorLib._change_version_for_stopped_appps* $$[(;;;'GGRZ[[ /CCHhXceijj_7799::/CCHhXceijj'  I 11)<<<<*9O    &;;HEE @K 8\D,<<= 55h KKKKKsB((CCc |j|} |r || |d<|r || |d<|r*|| |dkr || |d<|r || |d<|r || |d<||dkr || |d<n d| |d<|j|| ||||dS) a Sets new app_mode, environment variables and startup file for stopped NodeJS application :param config_files: names of config files (such as requirements.txt or etc) (only for python) :param entry_point: the specified entrypoint for application (only for python) :param str username: application owner :param str app_root: application directory (application name) :param str app_mode: New application mode, can be None :param dict env_vars_dict: New environment variables, can be None :param startup_file: New startup file, can be None :param passenger_log_file: Passenger log filename :return: None rYrSrTrVrmNrIrW)rMrrrr6) rXrbrcrY env_vars_dictrTrVrmrWrxs r4rCz4CloudlinuxSelectorLib._set_variables_for_stopped_apps&;;HEE  8/7Jx  ,  =/2=Jx  /  @3?Jx  0  ).@B.F.F9KJx !5 6 69=Jx !5 6 55h KKK ((8]KKKKKr3cltt|ddS)z Retrieves major version from full. If already short, return it with no difference :param version: Full/short :return: Short version as string .r)rrNsplitrs r4get_major_version_from_shortz2CloudlinuxSelectorLib.get_major_version_from_shorts+3w}}S))!,--...r3cttd}t }|D]}||dS)z Replace mysqli extension to nd_mysqli for defaults. Warning: only for PHP. See LVEMAN-1399 for details :return: rAN)rrget_all_alternatives_datarrlist_extensions)alt_php_versions_list cl_ext_select alt_php_vers r4replace_mysqliz$CloudlinuxSelectorLib.replace_mysqlisi!%Xe__%N%N%P%P%U%U%W%W X X# 0 7 7K  ) )+ 6 6 6 6 7 7r3ctjddgtjddgtjgdtjdg|dS)zf Setup php selector for work (suggested to use after native php is installed) cagefsctlz--force-updatez --remount-all)r=zmake-defaults-configz--jsonrtrAz//usr/share/l.v.e-manager/utils/cache_phpdata.pyN)r check_outputr\)clss r4setup_selectorz$CloudlinuxSelectorLib.setup_selectors .> ?@@@o >???!C!C!C D D D!R STTT r3c|j|jkrttjrt S |jt S#t$r,}| t|cYd}~Sd}~wwxYw)zn Scan users home dirs for .htaccess files and import applications to new config file. N) rDrIrr<r?rrM$import_legacy_applications_to_configrtrr)rXrs r4run_import_applicationsz-CloudlinuxSelectorLib.run_import_applicationss  t6 6 6% % \^^   :   B B D D D  : : :11#a&&99 9 9 9 9 9 9 :sA B !B>B B c|j|jkrtd|j||t S)z_ Convert applications created in older selector versions to new format z/Migration is only available for python selector)rDrIrrMmigrate_applicationr)rXrjrcs r4run_migrate_applicationz-CloudlinuxSelectorLib.run_migrate_applicationsM  t6 6 6%'<== = --dH===r3)NNr)NNNNNNN)NNF)NNFNr2)NF)Qr/r0r1rYr^rg staticmethodrar{rrrrrrrrrrrrrrrrrrrrrr rr&r/rr4rrrvr7r:rrDrFrQr]rfrzrrrrrrrrrrrrrrr rrrr,r3r6rArErIr#r1rCrUr\ classmethodrardrgr2r3r4r;r;Vs[ 1 1 1D A A A .,.,.,\.,`\.!!\! \   \ \    \ """H\ nnn)))\ \ :**\*X7777 \**HHHH 4 4 4222:::6660*L*L*LX            gn PT    888  c3h # PWZ^P^ jn    BHLim****X\$3N3N3N3Nj)N)N)N)NV\4****X"""H:::(:::,:::,JJ\J,%%%N$$\$"pIpIpId(::\:23I3I3I3Ij0qqq&\6AAAAF":":":H   UDUDUDn : : :D ? ? ? ?rrrLLL6LLLB//\/ 7 7\ 7  [ :::     r3r;)Z __future__rrrrrrrr}rrrKrrrrtypingr future.utilsr cldetectlibr<clselect.clselectctlnodejsuserrQclselect.clselectexceptclselect.clselectctlpythonclselect.clselectctlrubyclselect.clselectpythonuserclselect.clselectnodejsuserclcommon.clexceptionrclcommon.clpwdr clcommon.cpapir r clcommon.cpapi.cpapiexceptionsr r r cllimits.librrrrrrclselect.baseclselectrrrrrclselect.clselectctlphprrrrclselect.clselectnodejsrclselect.modelsr$clselect.clselectnodejs.node_managerr rTr!r"&clselect.clselectpython.python_managerr#(clselect.clselectpythonuser.environmentsr$PythonEnvironment(clselect.clselectnodejsuser.environmentsNodeJsEnvironmentclselect.utilsr%r&r'r(r)r*secureior+clconfig.ui_config_libr,r-r6robjectr;r2r3r4rs&%%%%%&&&&&&    """"""%%%%!!!!""""""""333333888888++++++++PPPPPPPPPP%%%%%% 8888888888gggggggggggg<<<<<<99999999HHHHHH555555######<<<<<<A@@@@@UUUUUUUUUUUUDDDDDDDD     '        ^    UUUUUFUUUUUr3