jddlmZddlmZddlmZddlZddlZddlZddlZddlm Z ddl Z ddl Z ddl Z ddl Z ddlZddlmZddlmZddlmZddlmZdd lmZdd lmZdd lmZdd lmZdd lm Z m!Z!m"Z"ddl#m$Z$m%Z%ddl&m'Z'm(Z(ddl)m*Z*ddl+m,Z,ddl-m.Z.ddl/m0Z0ddl1m2Z2ddl3m4Z4ddl5m6Z6m7Z7m8Z8ddl5m9Z9ddl:m;Z;mm?Z?ddl@m=ZAdZBdZCGddeDZEdS) )print_function)absolute_import)divisionN)AnyStr) iteritems)ClPwd)FormattedException) MailHelper)is_ascii_string)CloudlinuxLicenseLib) clselectctl) get_abs_relmkdir_prun_process_in_cagefs)BaseSelectorErrorAcquireApplicationLockError)print_dictionaryreplace_params) CONFIG_DIR) PkgManager)is_clpassenger_active) defaultdict)MIMEText)mkstemp)NODEJSPYTHONPHP)parse_cloudlinux_selector_opts)CloudlinuxSelectorLib OK_RES_DICTClSelectExcept)Website)r"z.lockc"t||SN)open) file_namemodes M/opt/cloudlinux/venv/lib64/python3.11/site-packages/clselector/cl_selector.py_openr*<s  4  ceZdZdZdZ d1dZdZdZedZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZd2dZedZd3dZe d Z!e d!Z"d"Z#e$j%d#Z&d$Z'd%Z(d&Z)d'Z*d(Z+d)Z,d*Z-d+Z.d,Z/d-Z0d.Z1ed/Z2d0S)4CloudlinuxSelectorcd|_i|_d|_tjdk|_d|_d|_d|_d|_ tj td|_ dS)NFrz --backgroundzcloudlinux-selector_bkg.pid)_is_json_opts _selector_libosgeteuid _is_root_user_lock_is_bkg_option_present _bkg_option_nj_ver_move_frompathjoinr_pid_file_nameselfs r)__init__zCloudlinuxSelector.__init__Bsi  !Z\\Q. &+#)!# gll:7TUUr+c|jdttfvrdSt|jd|jdgrdSt|jd|jd|jd|jd|jd |jd |jd |jd |jd |jd|jd|jd|jd|jd|jdgrdSdS)zx Check if cloudlinux-selector called with application operations :return: True if lock is need --interpreterFchange-version-multiplecreatestartrestartdestroymigratestopinstall-modulesuninstall-modules run-script --app-mode --env-vars--new-app-root --new-domain --new-app-uri --new-version--startup-fileT)r1rranyr=s r)is_app_lock_neededz%CloudlinuxSelector.is_app_lock_neededNs :o &vv.> > >5  45tz(7KL M M 5  Jw  Jy ! Jy ! Jy ! Jv  J( ) J* + J| $ J| $ J| $ J' ( J~ & J ' J ' J' (* + +  4ur+Fc|sdS|jd|jd}}|jj||| | \}}t j|sdSt j|t} t|d|_ tj |j tjtjzdS#t"$r<}|jt$jkrd} t)|| t)|d}~wwxYw)z[ Acquire lock for application if this lock is needed :return: None N--user --app-root) chk_app_rootchk_envza+z6Disk quota exceeded. Please, free space and try again.)reason)rTr1r2 apps_managerget_app_foldersr3r:existsr;LOCKr&r6fcntlflockfilenoLOCK_EXLOCK_NBIOErrorerrnoEDQUOTr) r>ignore_missing_app_rootignore_missing_doc_rootusernameapp_root_app_venv lock_fileerZs r)acquire_app_lock_if_neededz-CloudlinuxSelector.acquire_app_lock_if_neededls5&&((  F!Z14:l3K((5EE h1H-H//F11 8w~~h''  FGLL400  8i..DJ K ))++U]U]-J K K K K K 8 8 8w%,&&Q1(6JJJJ-h77 7  8s AC:: E7D;;Ec^|jr#|jdr|dSdSdS)NrQ)r5r1send_notificationr=s r)send_notification_if_neededz.CloudlinuxSelector.send_notification_if_neededsG   %$*_"= %  " " $ $ $ $ $ % % % %r+cdSr%) rr1cpapicpinfor sendmail IndexErrorKeyErrorcpapiexceptions NotSupported)r>MSG_TEMPmsgme cp_userinfouser_data_email mailhelpers r)rqz$CloudlinuxSelector.send_notifications  r+cl|sdSd|dDS)Ncg|]}||Srr).0modules r) z4CloudlinuxSelector.parse_modules..sRRR66RRRRr+,)stripsplit)modules_optionss r) parse_modulesz CloudlinuxSelector.parse_moduless= 2RR_%:%:%<%<%B%B3%G%GRRRRr+c Jd|v|_|j|v|_|jr||j t }|sGd|_|ddi|jr" tj|jS#YSxYwS| ||_ t|j d|_ |j |j |j r|5t!|j d|j j|}|d}||d|d d d n #1swxYwY||jr" tj|jS#YSxYwS|j |j rd d |j d|j jg|z}|5t+j|i }||d d d n #1swxYwY|j|jr" tj|jS#YSxYwS||j d |j d |j drc||j d|j d\}}|dkr ||j d<n#|t7||j dr|n|j dr|n|j dr|n|j dr|n`|j d r| n=|j dr|!n|j dr|"n|j dr|#n|j dr|$n|j dr|%n|j dr|&nk|j dr|'nH|j ds |j dr|(n|j ds |j d r|)n|j d!r]|*|j +|j d|j d"|j d#|j d$n|j d%r|,n]|j d&r|j -n6|j d'r|.n|/n!#t`j1t`j2t`j3f$r;} |t7ti| Yd } ~ nd } ~ wt`j5t`j6f$rU} |j d&s.|t7| j7| j8(tsd)Yd } ~ nWd } ~ wt`j:$r.} |t7| Yd } ~ nd } ~ wtv$rt} | j<r5|t7| j7| j8| j<*n.|t7| j7| j8(Yd } ~ nd } ~ wtz$r} t}j?} t}j@t| | } t| trd+D| } n| } |t7| | ,Yd } ~ nd } ~ wwxYw|jr" tj|jn6#Yn2xYwn.#|jr" tj|jw#YwxYwwxYwd)S)-z$ Run command action --jsonTresultzCloudlinux license isn't validrArV returncodeoutputNz /usr/bin/sudoz-u)envrF)rgrh--passenger-log-fileOKrsetrGimport-applicationsrCrDrErHz read-configz save-configrIrJinstall-versionzuninstall-versionenable-versionzdisable-versionrKrWz --script-namez rBzmake-defaults-configsetuprcontextr)rrdetails )rr)Er0r8r7remover get_license_status_error_and_exitr3r< _parse_argsr1r r2check_selector_is_availableshould_be_runned_as_user_lock_interpreter_if_neededrCLOUDLINUX_SELECTOR_UTILITY_print_raw_datarrshould_run_user_without_cagefs subprocessPopen communicaterro!_passenger_log_filename_validatordictrun_setrun_migrate_applicationrun_import_applications run_create run_destroy run_start run_restartrun_stoprun_read_configrun_save_configrun_install_modulesrun_uninstall_modulesrun_manage_versionrun_disable_or_enable_version _print_data run_script_start_change_all_apps_versionsreplace_mysqli run_setuprun_getClSelectExcept_oldConfigNotFound WrongDataNoSuchAlternativeVersionstrNativeNotInstalledMissingCagefsPackagemessagerexitFileProcessErrorr r Exception traceback format_excformat_exception_onlytype isinstancelistr;)r>argvlicencerr user_run_cmdprocessr log_filenamernerrr| list_err_msgerr_msgs r)runzCloudlinuxSelector.runs !D( &*&6$&>#  & * KK( ) ) ){ *,,G--// Z $ ++X7W,XYYd* Id12222D  _))$//DJ!6tz/7R!S!SD    : : < < <!::4:FF *5577772 8,*FF "( !5J(()9:::44666777777777777777"B* Id12222D  A#BB4:NN * /tz(7K $ 2 N PRV W 557777(.|DDDG'')))44666777777777777777)r* Id12222D  o  + +(, 9(=(, 9(= ,    z01 ?(,(N(NtzZbOcOSzZpOq)s)s%d??9EDJ566((W)=)=)=>>>z% *  I&( ,,....12& ,,....H%$ !!!!I&"   """"G$     I&   """"F#  M* $$&&&&M* $$&&&&-. ((****/0 **,,,,-. $*=P2Q '')))),- a5aa5a--a15b >bb bb c`|jd:||j|jddS|jdF||j|jd|jddS|jdrF||j|jd|jddS|jd:||j|jddS|jd:||j|jddS|jd l|jd_||j|jd |jd|j ddS|jd l|jd_||j |jd |jd|j ddS|j s|j r| |jd |jd |jd |jd|jd|jd|jd|jd|jd|jd|jd|jd|jd dSdS)Nz--default-versionz--current-version--domainz--reset-extensions --version --websitez--selector-statusz--supported-versionsz --extensionsz --optionsrVrWrLrMrNrOrPrQrR--skip-web-check --entry-pointz--config-filesr)r1rr2set_default_versionset_current_versionreset_extensionsset_selector_statusset_supported_versionsset_extensionsget set_options _is_nodejs _is_python run_changer=s r)rzCloudlinuxSelector.run_set9sL :) * 6   T/CCDJObDcdd e e e e e Z+ , 8   "66tzBU7VX\XbcmXnoo     Z, - @   T/@@KAXZ^ZdepZqrr s s s s s Z+ , 8   T/CCDJObDcdd e e e e e Z. / ;   T/FFtzRhGijj k k k k k Z ' 3 ;8O8[   T/>>tz.?Y[_[efq[rtxt~uCuCDOuPuPQQ R R R R R Z $ 0TZ 5L5X   T/;;DJ{  @ @ @ @ @ @ @r+c8|jdSr%)r2setup_selectorr=s r)rzCloudlinuxSelector.run_setupTs ))+++++r+c ||ddi|e|j|||}|}|ddkr)||t jd||d|j||||}|ddkr)||t jdt||| | | du| dufr| d| dD} |j ||||| | | | }|ddkr)||t jd|d|j |||| }|ddkr)||t jd|idS) a Call selectorctl to change application parameter :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 main directory (application name) :param app_mode: application mode :param env_vars: dict with environment variables :param new_app_root: new application main directory (new application name) :param new_domain: new application domain :param new_app_uri: new application uri :param new_version: new version for nodejs interpreter :param startup_file: new startup file for application :param skip_web_check: skip check web application after change it's properties :param passenger_log_file: Passenger log filename :return: None NrzERROR: User is not specifiedstatusrrcg|] }|dk| S)r/r)ritems r)rz1CloudlinuxSelector.run_change..sWWWDTVJJJJJr+r) rr2relocateupperrsysrtransitrSr set_variableschange_version)r>userrjapp_modeenv_vars new_app_root new_domain new_app_uri new_version startup_fileskip_web_check entry_point config_filespassenger_log_filers r)rzCloudlinuxSelector.run_changeWs(( <  8": ; ; ;  #"++D(LIIA#H{  ""d**  ###  "j&<"**4; SSA{  ""d**  ### (L+|SW?W"$.0 1 1 'WW1C1CC1H1HWWW "00x81={LZlnnA{  ""d**  ###  ""11$+~^^A{  ""d**  ###  r+c^||jdSr%)rr2rr=s r)rz*CloudlinuxSelector.run_import_applicationss+ +CCEEFFFFFr+c||j|jd|jddS)NrVrW)rr2rr1r=s r)rz*CloudlinuxSelector.run_migrate_applicationsL +CC Jx $*\":<< = = = = =r+c|jdr.||jdS|jdr.||jdS|jdr.||jdS|jdrF||j|jd|jddS|jdtkrG||j|j ddSd ti}|jdtkr^| |j |jd|\}}| | ||d <||d <nN|jdtkr8| |j |jdd |vr|||d  dS||dS)Nz--get-default-versionz--get-selector-statusz--get-supported-versionsz--get-current-versionrVrrArpassenger_activeremaining_apps_counttotal_apps_countrr)r1rr2get_default_versionget_selector_statusget_supported_versionsget_current_versionrget_fullrrrupdateget_apps_users_info_get_apps_count_from_pid_filer)r>resr r s r)rzCloudlinuxSelector.run_getsc :- . &   T/CCEE F F F F F Z/ 0 &   T/CCEE F F F F F Z2 3 &   T/FFHH I I I I I Z/ 0 &   T/CCDJxDXDHJzDZ\\ ] ] ] ] ] Z (C / /   T/88 9T9TUU V V V V V%'<'>'>?Cz/*f44 4-AA$*XBVWWXXX9=9[9[9]9]6$&6'38H8T2FC./.>C*+O,66 4-AA$*XBVWWXXX3  S] ;;;;;  %%%%%r+c^||jdr%|dd|jdidts5|jdtkrd}nd}|dd |id||j|jd |jd |jd|jd |jd |jd|jd|jd|jd|jd dS)NrzTCan't create application: Nodejs version %(version)s is locked by background processversionrrAz9https://docs.cloudlinux.com/python_selector/#installationz8https://docs.cloudlinux.com/index.html?installation.htmlz`Application creation not allowed, Phusion Passenger seems absent, please see %(url)s for detailsurlrWz --app-urirVrrLrRrMrr)(_is_version_locked_by_background_processr1rrrrr2 create_app)r>rs r)rzCloudlinuxSelector.run_createsU  8 8K9P Q Q   q%tz+'>?""   %&& z/*f44QP  [3""       ) ) <( ;' ;' 8$ :& <( +, <( ?+ 12       r+c||j|jd|jddSNrWrV)rr2 destroy_appr1r=s r)rzCloudlinuxSelector.run_destroyS +77 <8P8< 88LNN O O O O Or+c||j|jd|jddSr)rr2 start_appr1r=s r)rzCloudlinuxSelector.run_startsS +55dj6N6:j6JLL M M M M Mr+c||j|jd|jddSr)rr2 restart_appr1r=s r)rzCloudlinuxSelector.run_restartrr+c||j|jd|jddSr)rr2stop_appr1r=s r)rzCloudlinuxSelector.run_stopsS +44TZ 5M59Z5IKK L L L L Lr+c||j|jd|jd|jddS)NrW --config-filerV)rr2read_app_configr1r=s r)rz"CloudlinuxSelector.run_read_configsX    . . <( ?+ 8$ & & ' ' ' ' 'r+c ||j|jd|jd|jd|jddS)NrWr$z --contentrV)rr2save_app_configr1r=s r)rz"CloudlinuxSelector.run_save_configsb    . . <( ?+ ;' 8$  & & ' ' ' ' 'r+c ||j|jd|jd|jd|jd|jd||jddS)NrWrVrrz--requirements-file --modules)rdomainr spec_filemodules)rr2install_modulesr1rr=s r)rz&CloudlinuxSelector.run_install_moduless    . . <(Z)z*-#z*<=*%:;**4:k+BCC /   r+c ||j|jd||jd|jd|jd|jddS)NrWr)rVrr)r,rr*r)rr2uninstall_modulesr1rr=s r)rz(CloudlinuxSelector.run_uninstall_moduless    0 0 <(**4:k+BCCZ)z*-#z*<= 1       r+c|jd}|jd} ||j||dS#t$r/}|dt |iYd}~dSd}~wwxYw)zM Disable or enable interpreter version :return: None rrrN)r1rr2set_version_statusrrr)r>rtarget_version_statusrns r)rz0CloudlinuxSelector.run_disable_or_enable_version s *[) $ +; <    T/BBCXZabb c c c c c      #a&&"          s.A B$BBct|jd} |jdr |jj|}n|jj|}n&#t $r}t|}Yd}~nd}~wwxYw||tdSt|tr| |dS| d|idS)Nrrr) rr1r2selector_managerinstall_versionuninstall_versionrrr!rrr)r>verrrns r)rz%CloudlinuxSelector.run_manage_versions$*[)** z+, Q(9II#NN(9KKCPP   a&&CCCCCC  ;   [ ) ) ) ) ) T " " 2   % % % % %  (C 1 1 1 1 1sA A)) B 3BB c Bt||j|j\}}|s"|t ||ddkr|drX t }||dn-#t j$rtdd|didwxYwd}|d rT tj |d|d \}}|r||d<t|d | }n#t$rYnwxYw||d <|Stj d s(|d s|dr|dddtj |d|d \|d<}dD]} || st!|d|| \}} t#j| nG#t&$r:} |t)t+| Yd} ~ nd} ~ wwxYw| || <|S)z% Parse CLI arguments ) as_from_rootrAphprVzNo such user (%s)r)rrNr)r*docrootrz/usr/local/cpanelrrGsuccessz?Import/migrate of Python Selector applications is not supported)rwarning)rWrNr)rr0r5rrrget_pw_by_nameNoSuchUserExceptionr"r $safely_resolve_username_and_doc_rootr#r3r:isdirrrr check_directory ValueErrorrr) r>rrdatapwdwebsite resolved_userdoc_rootrk app_root_arg directoryrns r)rzCloudlinuxSelector._parse_args+s6 $-d.@BBB  7  !5!5 6 6 6  E ) )H~  ''C&&tH~66660(': &X(GJ  .C.hXZ(8/:/:+M8%7)6X%T*-=xPPPGG%D!(D K w}}011 qt> D  D =G H0HHrcd|vr|d|d<|d=|jr9|dtjit|dn] t t |d|dizn"#t$rt d|zYnwxYwtj |dS)z Print error and exit :param dict message: Dictionary with keys "result" as string and optional "context" as dict rr timestampTrz Error: %sN) r0rtimerprintrrrxrr)r>r error_codes r)rz"CloudlinuxSelector._error_and_exitts w   ' 1GH ! = - NNK5 6 6 6 Wd + + + + -c'(+,,w{{9b/I/IIJJJJ - - -kG+,,,,, - s9BB-,B-c$t|dS)z Print raw data. Function should be used in case if you want to print a json string as an output from other utilities N)rN)rDs r)rz"CloudlinuxSelector._print_raw_datas d r+r<c,t|tr|}d|vr#t|dtr|d}|d||ddkr:d|d<|jdt kr|jrd|d<nd|vrd|vr |d|d<|d=| d tj it||j p|d S) z Output data wrapper :param: `dict` data - data for output to stdout :param: `bool` force_json - always output json format rDrokr<rrAzbMultiPHP system default PHP version is alt-php. PHP Selector does not work and should be disabled!r=rLN) rrcopy setdefaultlowerr1rr2check_multiphp_system_defaultrrMrr0)r>rD force_jsonrs r)rzCloudlinuxSelector._print_datas dD ! ! 499;;D~~*T&\4"@"@~F| OOHf - - -H~##%%--!*X:o.#55$:L:j:j:l:l5'[DO%%(d*:*:!%hXX KKdikk2 3 3 3t}: ;;;;;r+cR|jdtkSNrA)r1rUrr=s r)rzCloudlinuxSelector._is_nodejs z/*0022f<rs r)_is_interpreter_lock_neededz.CloudlinuxSelector._is_interpreter_lock_neededs: :o &66*: : :*_5K $$ $ur+c#K|rK|jj}||jd5dVddddS#1swxYwYdSdVdS)z{ Wrapper over contextmanager of PkgManager in order not to try acquire lock when it is not needed. rQN)r^r2r[acquire_interpreter_lockr1)r>mgrs r)rz.CloudlinuxSelector._lock_interpreter_if_neededs  + + - - $1C--dj.IJJ                     EEEEEsAAAc|jd}|jd}|j|}|j|}||kr|ddi||fS)z Retrives NodeJS versions from arguments and converts them to major versions :return: Cortege (from_version, to_version) z--from-versionrQrz4--from-version and --new-version should be different)r1r2get_major_version_from_shortr)r> from_version to_versions r)_get_nj_versionsz#CloudlinuxSelector._get_nj_versionssy z"23 Z0 )FF|TT 'DDZPP : % %  (,b!c d d dZ''r+c|\}}t}|j}||vr|dd|id|js+|r|ddi||fS)z Checks arguments and environment before start group applications move :return: Cortege (from_version, to_version) zXCan't move NodeJS applications to Nodejs version %(version)s. No such version installed.rrrz+Another background process already started.)rfrinstalled_versionsrr7&_is_background_process_already_running)r>rdre pkg_managerinstalled_nj_versionss r) _check_environment_for_move_appsz3CloudlinuxSelector._check_environment_for_move_appss $(#8#8#:#: j ll + > 2 2 2  u%z2""    * \t/Z/Z/\/\ \  (,Y!Z [ [ [Z''r+c|\}}|jsP|jjd|d|d|jd}t j|dd|tdS| |\}}|r|d krdS| |||| |||dS) zM Change all applications all users versions :return: zD change-version-multiple --json --interpreter=nodejs --from-version=z --new-version= z >/dev/null &Tz /bin/bash)shell executableNr) rlr7r2rr8rrrr!_get_all_apps_by_version_write_pid_file_move_apps_by_list)r>rdrecommandusers_apps_listr s r)rz2CloudlinuxSelector._start_change_all_apps_versionss $(#H#H#J#J j*  )EEE|||U_U_U_aeaqaqaqsG N7$; G G G G   [ ) ) ) F-1,I,I,,W,W)) "2a"7"7 F \:7GHHH =MNNNNNr+c t|D]|\}}|D]t}|jjdddtd|d|d|g }t j|}||dz}||tj du}d S) a Move applications from list from one NodeJS version to another :type dict :param apps_dict: Application list. List example: {'cltest1': [u'modjsapp_root'], 'cltest2': [u'app2', u'main_app']} :param to_version: Move applications to this version :param total_apps_count: Total applications count for move :return: None rrrArVrWrQrN) rr2rrrrr_change_pid_filerMsleep) r> apps_dictrer  user_name user_app_listrjcmdrs r)rsz%CloudlinuxSelector._move_apps_by_list s)2)(<(<   $I})  *FxYhjp )\8_V`c$*3//##%%% A% %%&6777 2   r+ctt}|jj}d}t |D]\}} |jj|j|j|j }t |D]1\}} | d|kr || ||dz }2x#ttttf$rYwxYw||fS)aB Retrives list of all NodeJS applications for all users, which uses supplied version of NodeJS :param from_version: Required NodeJS version :return: Cortege: (application_list, application_count). Example: ({'cltest1': [u'modjsapp_root'], 'cltest2': [u'app2', u'main_app']}, 3) rnodejs_versionr)rrr2r[get_users_dictrread_user_selector_config_jsonpw_dirpw_uidpw_gidappendr TypeErrorrxAttributeError) r>rdusers_apps_dict user_infor r{ user_pw_entry user_app_datarjapp_infos r)rqz+CloudlinuxSelector._get_all_apps_by_version s&d++&3BBDD (1)(<(<   $I}  $ 2 ? ^ ^!(!(!(!! +4M*B*B..&Hh 01\AA' 299(CCC(A-( . &y(NK     000s A1B<<CCc tjt|jd}|d|_dS#YnxYwdS)z] Determine is background process already working :return: True|False rrdTF)jsonloadr*r<r9)r>rDs r)riz9CloudlinuxSelector._is_background_process_already_running@sH  9U4#6<<==D%).%9D "4  Dus48<c|jdtkrdS|j|}|j|}|}|r ||jkrdSdS)z Checks if NodeJS version blocked by background operation :param nj_version: NodeJS version to check :return: True - version is locked, False - not locked rAFT)r1rr2resolve_versionrcrir9)r> nj_versionis_bkg_process_presents r)rz;CloudlinuxSelector._is_version_locked_by_background_processNsx :o && 0 05'77 CC 'DDZPP !%!L!L!N!N ! jD4J&J&J4ur+c *tjtjt |t |||t t jdt|jdtj |jddS)a Creates pid file for background process move version from version to version :param from_version: Move from NJ version :param to_version: Move to NJ version :param total_apps_count: Total application count to move :return: None )pidrdrer r rMwN) rdumpr3getpidrfloatrMr*r<chmod)r>rdrer s r)rrz"CloudlinuxSelector._write_pid_file^s 9;; --j// 0$4$)++&&    $c * * , , , $e,,,,,r+ct|jd}tj|}||S)zc Reads pid file and returns it's content as dictionary :return: Dictionary r)r*r<rrcloser>fpid_datas r)_read_pid_filez!CloudlinuxSelector._read_pid_fileqs5 $%s + +9Q<<  r+cT |}||d<tt\}}tj|t |dt j||jt j |jddS#tttf$rYdSwxYw)z Creates pid file for background process move version from version to version :param remaining_apps_count: Remaining application count to move :return: None r )dirrrN) rrrrrr*r3renamer<rOSErrorrdrx)r>r rrktemp_file_names r)rxz#CloudlinuxSelector._change_pid_file{s **,,H/CH+ , 'J 7 7 7 A~ Ihnc : : ; ; ; Ind&9 : : : HT(% 0 0 0 0 0(+    66 sBB B'&B'c t|jd}tj|}||d|dfS#t t tf$rYdSwxYw)z Retrieves application counts from pid file :return: Cortege (remaining_apps_count, total_apps_count) If no background process started, returns None, None rr r )NN)r*r<rrrrrdrxrs r)rz0CloudlinuxSelector._get_apps_count_from_pid_filess  d)3//Ay||H GGIII23X>P5QQ Q(+   :: sA AA*)A*ct}||} t|sdStj|rdS|tjjs tj||}tj |}||tjzrQtj |}tj |st|d|fSn2#ttf$r}dt|zdfcYd}~Sd}~wwxYwdS)a Validates passenger log file name :param username: User's name :param log_filename: passenger log file name to validate :return: tuple: (message, log_filename). message: "OK" - filename is valid, any other string - invalid, error text log_filename: corrected log filename - simlink dereferencing, appends user's homedir for relative paths, etc )zAERROR: Passenger log filename should contain only english lettersN)zDERROR: Passenger log file should be a filename, not a directory nameNrz%sN)z9ERROR: Passenger log file should be placed in user's homeN)r get_homedirr r3r:rA startswithsepr;realpathdirnamer]rrrdr)rirrE user_homedir log_realpathrexcs r)rz4CloudlinuxSelector._passenger_log_filename_validatorsPggx00  )"<00 a``w}}\** dcc**27;77 H!w||L,GG 7++L99L&&|BF':;; *'//,77w~~g..%G$$$\))  * ! ) ) )#c((?D( ( ( ( ( ( ( )PPs)D.D.CD..E?EEEN)FF)r)Fr<)3__name__ __module__ __qualname__r?rTrorrrq staticmethodrrrrrrrrrrrrrrrrrrrrrrrpropertyrrr^ contextlibcontextmanagerrrfrlrrsrqrirrrrrxrrrr+r)r-r-@s8 V V V@%*$)88888%%%@SS\S EEEN@@@6,,,777rGGG===&&&8!!!FOOOMMMOOOLLL''''''           222 GGGR$\<<<<:==X===X=    ( ( (((($OOO8,111@    ---&$   QQ\QQQr+r-)F __future__rrrr_rrMreclcommon.cpapirtrrr3rrtypingr future.utilsrclcommonrclcommon.clexceptionr clcommon.mail_helperr clcommon.clfuncr cllicenser clselectr clselect.utilsrrrclselect.baseclselectrr cli_utilsrrclselect.clselectnodejsr"clselect.clselectnodejs.pkgmanagerr clselector.clpassenger_detectlibr collectionsremail.mime.textrtempfilercl_selector_arg_parserrrr selectorlibr r!r"clselect.modelsr#clselect.clselectexceptrr^r*objectr-rr+r)rs&%%%%%&&&&&&  """"""333333++++++++++++****** FFFFFFFFFFPPPPPPPP66666666......999999BBBBBB######$$$$$$6666666666AAAAAAKKKKKKKKKK######HHHHHH!!!v Qv Qv Qv Qv Qv Qv Qv Qv Qv Qr+