jWddlmZddlmZddlmZddlZddlZddlZddlmZddlm Z ddl m Z dd l mZmZdd lmZdd lmZGd d eZdS))absolute_import)print_function)divisionN)glob)map) configparser)ClSelectExceptBaseClSelectException)clprint)clcagefsceZdZejrdndZedZedZdZedZ edZ edZ d Z d Z d Zd Ze ezZeezZd Ze ezZeezZedZedZd3dZdZdZdZdZdZdZd4dZdZ dZ!dZ"dZ#d4dZ$dZ%d5d!Z&d"Z'ee'Z'd#Z(ee(Z(d$Z)ee)Z)d6d&Z*d'Z+d(Z,d)Z-d*Z.d+Z/d7d,Z0d7d-Z1d.Z2d5d/Z3d0Z4d4d1Z5d7d2Z6d S)8ClSelectz/etc/cl.selector.conf.dz/etc/cl.selectorz/selector.confz /defaults.cfgz /usr/bin/phpz /native.confz /user.confz/php.extensions.d/z/usr/sbin/cagefsctlz/var/lvez/var/lve/php.dat.dz /php%s.datz/php_native_ver.datctjrdS ddlm}m}n#t $rt dwxYw|s|st ddSdS)Nr!multiphp_system_default_is_ea_phpselector_modules_must_be_usedzCageFS not installed.zesystem default PHP version is alt-php. PHP Selector is disabled. Use cPanel MultiPHP manager instead.)r in_cagefsclcagefslib.selector.configurerr ImportErrorr rs H/opt/cloudlinux/venv/lib64/python3.11/site-packages/clselect/clselect.py%check_multiphp_system_default_versionz.ClSelect.check_multiphp_system_default_version/s      F A w w w w w w w w w A A A'(?@@ @ A1022 ;X;X;Z;Z 'w     s :cTtjtjSN)ospathexistsr USER_CONFrwork_without_cagefszClSelect.work_without_cagefs>sw~~h0111r phpc||_||_i|_i|_t |_d|_t |_ | dSr) _item_get_default_config_handler_dh_selector_contents_native_contentsset_hidden_extensions_native_versionrr!without_cagefs_load_config_files)selfitems r__init__zClSelect.__init__Bsl 3355"$ ""%%%#&::<< !!!!!r cfdtjdffdtjfg}|D]\}}|r|dS)NchtjdS)Ncli)rrr_get_native_pathr.srz-ClSelect.check_requirements..Ps#t'<'.Ss(T''))KRW^^DN-K-Kr )r NativeNotInstalledr4MissingCagefsPackage)r. utilities predicateerrors` rcheck_requirementszClSelect.check_requirementsLsEDDD1$2G2G2N2NOO L K K K^MpMrMr s  !*   Iuy{{ K  r cttj|jdD]}||dS)Nz*.cfg)rrrjoin CONFIGS_DIR_load_config_file)r.filenames rr-zClSelect._load_config_files[sMRW\\$*:GDDEE - -H  " "8 , , , , - -r ctjdd} ||n=#tj$r+}t j|dt |zd}~wwxYw |j| dd ddS#tj tj f$rYdSwxYw)NF interpolationstrictzConfig is malformed, error: %smessage extensionshide_extensions,) ConfigParserSafeConfigParserreadErrorr FileProcessErrorstrr*updategetsplitNoSectionError NoOptionError)r.filepathdhes rrCzClSelect._load_config_file_s  *e L L L o GGH    ! o o o 1(DdgjklgmgmDmnnn n o   # * *266,@Q+R+R+X+XY\+]+] ^ ^ ^ ^ ^+\-GH    DD s'.A(&A##A(,AB//C Cc,|}g}t|D]N} ||||d||d|jf?#t $rYKwxYwt |S)zM Returns alternatives summary as tuple :rtype: tuple versiondata)get_all_alternatives_datasortedkeysappendr$KeyErrortuple)r. alternativeslist_of_alternativesalts rlist_alternativeszClSelect.list_alternativesls 5577 !,++--..  C $++S,s2CI2NP\]`PabhPijnjtPu,vwwww    )***s;A77 BBc|js9 |n##tjtjf$ricYSwxYw|jS)a Returns dict of all selector config contents. If no data loads them :return: {'4.4': {'version': '4.4.9', 'data': {'lsphp': '/opt/alt/php44/usr/bin/lsphp', 'php.ini': '/opt/alt/php44/etc/php.ini', 'php': '/opt/alt/php44/usr/bin/php-cgi', 'php-cli': '/opt/alt/php44/usr/bin/php'}}} :rtype: dict )r'_load_alternatives_configr ConfigNotFoundWrongConfigFormatr5s rr_z"ClSelect.get_all_alternatives_data{sa&  ..0000"1>3ST     &&s >>c|js| ||j|iS#t$rtj|wxYw)z Returns selector config contents of certain version as dict. If no data loads them @param version: string, selector version @return: dict )r'rjrcr NoSuchAlternativeVersionr.r]s rget_alternatives_datazClSelect.get_alternatives_datasj& -  * * , , , CT4W=> > C C C 9'BB B Cs ,A Fc|} |jd|j}|||d||d|jfS#tjt f$r||cYSwxYw)z/ Gets default selector version versionsr]r^)r_r&rUr$rNrWrc_compose_native_info)r.show_native_versionrer]s r get_versionzClSelect.get_versions5577  Bhll:tz::G\'29=|G?TU[?\]a]g?hi i+X6 B B B,,-@AA A A A BsAA+B  B c|}|||||jd|j|j|f}|d||jdS)z/ Sets default selector version )rr N)r__check_alternative_process_ini_file DEFAULTS_PATH_add_or_change_optionr$_write_to_filerAr.r]redefaults_contentss r set_versionzClSelect.set_versions5577  666 22   t/IDJX_K`   DII&788$:LMMMMMr c|}|||||j|j|f|jd}|d||jdS)z5 Removes disabled state from version staterwN)r_rxryrzr$_remove_optionr|rAr}s renable_versionzClSelect.enable_versions5577  666 22  W 5t7JG   DII&788$:LMMMMMr c |jd|j}n##tjtjf$rd}YnwxYw||krt jd|d|}| ||| |j |j|f|j d}| d||j dS)z- Marks a vesrion as disabled rrnativez$Cannot disable the default version 'z/'. Please set another version as default first.)rdisabledrwN)r&rUr$rNrWrXr VersionModificationBlockedr_rxryrzr{r|rA)r.r]default_versionrer~s rdisable_versionzClSelect.disable_versions '"hll:tzBBOO+\-GH ' ' '&OOO ' o % % ;owooo 5577  666 22  W 5t7QSh   DII&788$:LMMMMMs #AAcL|j|j|d S)z Method that allows you to check if some version is enabled in config. E.g. is_version_enabled('5.4') -> True :rtype: bool r)r& has_optionr$ros ris_version_enabledzClSelect.is_version_enableds* 8&&WW'EwOOOOr cL|}||}ddddi}t|dgz}|D]4}||vri||<||||d<d||d<5 |jd|j}n##tj tj f$rd}YnwxYw d||d<n"#t$rtj |wxYw|d||d<|d||dt#t%|D]+}||} | || d|| dff||<,t'|S) zl Returns state of alternatives @return: tuple[version, tuple[isEnabled, isDefault]] rTF)enableddefaultrrrrr)r_rsr`rarr&rUr$rNrWrXrcr rnpopremoverbrangelenrd) r.rtre native_infosummary alt_versionsr]ridxvs r get_summaryzClSelect.get_summarys 5577 //0CDD %@@Al//1122hZ? # 0 0Gg%%#% *.*A*A'*J*JGG Y '*/GG Y ' ' '"hll:tzBBOO+\-GH ' ' '&OOO ' K26GO $Y / / K K K 9/JJ J K")++h"7"7 AH%%%KN+++\**++ T TCS!A!"WQZ %:GAJycZ t|j}|D]}|}|dkr|\}}}}|j|vr@||jvr i|j|<||j|d<d|j|vri|j|d<||j|d|<|jst jdddS#ttf$r'}t jd|jd|d dd}~wt$rt j |jwxYw) a Parses selector config file and fills an instance config dict. Example: {'4.4': {'version': '4.4.9', 'data': {'lsphp': '/opt/alt/php44/usr/bin/lsphp', 'php.ini': '/opt/alt/php44/etc/php.ini', 'php': '/opt/alt/php44/usr/bin/php-cgi', 'php-cli': '/opt/alt/php44/usr/bin/php'}}} :raises ClSelectExcept.ConfigNotFound: :raises ClSelectExcept.WrongConfigFormat: r]r^Nzalt-php packages not foundrIz Cannot read z: z . Native used) open CONFIG_PATHstriprVr$r'r rkOSErrorIOError ValueErrorrl) r.fline stripped_liner/ short_version long_version item_pathr[s rrjz"ClSelect._load_alternatives_configs ET%&&A Q Q $  B&&ANATATAVAV>}lI:T)) (???=?D+M:DP' 6yA!8!GGGEGD+M:6BGP' 6v>tDD* `$3DB^____ ` `!    //595E5E5EqqqISo  E E E 243CDD D EsC CD*!"D'D*Nctjdd}t|_|r||n||j|S)z: Gets ConfigParser handler for future use NFrF)rNrS optionxformrPrz)r.rrZs rr%z$ClSelect._get_default_config_handlersS &T% H H H  ( GGDMMMM GGD& ' ' ' r cF|dkr||vrtj|dSdS)Nr)r rn)r]res rrxzClSelect._check_alternative#s6 h  7,#>#> 9'BB B  #>#>r c^dddgt|zz}||zS)z Gets section header data tuple and returns ini section header string @param section_info: tuple @return: string z[%s]rz%s)rAr) section_info section_fmts r_make_section_headerzClSelect._make_section_header)s4 rwwvL0A0A'ABBB \))r cttd|}|r |ddkr|d|S)zN Removes empty lines from list and appends newline if missing c|dkS)Nrr)is rr6z'ClSelect._smooth_data..8s a2gr rw)listfilterrb)r^s r _smooth_datazClSelect._smooth_data4sLF--5566 tBx4'' KK    r Tc fg}g}g} d} d} d} ||} t|}|D]}|}|dr_d} d|vrd} | |krd} t |dkr||g}|||| |||g} | r| ||||||| |||n#ttf$rYnwxYw| s(d| vr$dd|j zdg}|||}| s | d}n#tj $rYnwxYw|d kr:|||| d d |zg||n`|d kr8|||||| g||n"|||| g|||S) z Parses ini file by sections, calls supplied callable to modify section is question, returns file as list of strings F[Tz [versions]rz %s = nativerrdisable_extentionsz modules = rMenable_extentions)rrr startswithrextendrbcloserrr$ _get_builtinsr UnableToGetExtensionsrA)r.rrfunctionr^traceactioncontentsno_section_contentssection in_sectionfound has_defaultsection_headerrrrbuild_ins rryzClSelect._process_ini_file?s    22<@@ T A 5 5zz||??3'' !%J#t++&* %-- $.//144 (;<<<.0+OOHH\7D%$P$PQQQ#fG5NN4(((('..t4444 OOHH\7D%HH I I I GGIIII!    D  |>AA#]TZ%?DG NN8 $ $ $H W --h77!7    ---H\NL388T\K]K]<]+^`dfkll... H%%%7Gu U UVVVV7Gu U UVVVs$C>D""D65D6&E<<F Fcd|jz}|} ||d|}n&#t$r|d}YnwxYw|S)z Retrives path to php binary for supplied version :param version: php version to retrive path :return: path to php binary. If alternative version not found native php binary path returned z%s-clir^r3)suffix)r$r_rcr4)r.r]r/rers r_get_php_binary_pathzClSelect._get_php_binary_pathxsv $*$5577  7(06DD 7 7 7(((66DDD 7 s5 AAc|}d|di}|D]}||||<|S)a Retrives paths to php binary for all versions :return: Dictionary version -> path. Example: { '5.2': '/opt/alt/php52/usr/bin/php', '5.3': '/opt/alt/php53/usr/bin/php', 'native': '/usr/bin/php' } r)r_rra)r.re paths_dictr]s rget_all_php_binaries_pathsz#ClSelect.get_all_php_binaries_pathssk5577  9 9( C CD #((** E EG"&";";G"D"DJw  r c(tjS)zF Check if running inside CageFS :return: bool )r rr5s rr8zClSelect._is_in_cagefss !###r c|r |j|z}n |j|z}t|d5}|cdddS#1swxYwYdS)z Retrives contents of cache file for supplied php version :param version: PHP version to read file :return: file contents rN)r8CACHEFILE_CAGEFS_PATTERNCACHEFILE_PATTERNrrP)r.r]rDrs r_read_php_cache_filezClSelect._read_php_cache_files      84w>HH-7H (C  A6688                  sAA"Acdg} ||}n)#ttf$rtj|wxYwd\}}||||}}|dkrdn|t |z}|||}tjd} | dD]p} | | sd tj d| } | |j vr|| q|S)z Gets php extensions from the /var/lve/phpX.X.dat cache file, which contains list of modules that are either compiled-in or enabled in /opt/alt/phpXX/etc/php.ini config file )z [PHP Modules]z[Zendrrz\wrw_z\s+)rrrr rfindrrecompilerVmatchrAlowerr*rb) r.r]builtinsoutput start_pattern end_pattern start_index end_index modules_listmodule_patternextmodules rrzClSelect._get_builtinssE  @..w77FF! @ @ @ 6w?? ? @ &>" {!']!;!;V[[=U=UY &",,aa+M@R@R2R k)34 E**%%d++ ( (C!'',, XXbhuciikk::;;FT444'''s &Ac||}t|dks ||dkr|S|tt fd|S)z Adds 'modules' option to section or extends it @param section_info: tuple (item and version) @param section: list @param data: string @return: list rc0| Sr)r)rr^s rr6z)ClSelect._remove_option..sALL.sr N) r NATIVE_CONFrrrrVr(DEFAULT_PHP_PATHrrr)r.valuerrr/rs rrzClSelect._load_native_contentss  AT%&&A 3 3??3''$$d??!#':':TZZ__"M"MNN d.2%d++D111/3/D%e, GGIIIII! A A A+/+@D !% ( ( ( ( AsB#B'' C  C c|sdd|fS|d}|r+d|ddd|dd|fSdd|fS)NrF)verboseznative (r)r )r4get_native_version)r. show_versionnative_versions rrszClSelect._compose_native_infos ?Xt'<'<'>'>> >000??  y y%3A%6%6%688>Z[K\K\K\:^`d`u`u`w`wx x4#8#8#:#:::r c"|jr|jStjd} t|jd}|}|nF#ttf$r2}|r%tj ddt|dYd}~dSd}~wwxYw| D]R}| |}|r9|d|d} }|| f|_|| fcSSdS)Nz(PHP\s+(?P(?P\d+\.\d+)\.\d+)rtextERROR)statusrJshortfull)r+rrrCACHEFILE_NATIVE_VER_PATTERNrPrrrr print_diagrS splitlinesrgroup) r.rversion_patternrr^r[rmr r s rrzClSelect.get_native_version$s1   (' '*%PQQ T6<A]*]'  \ 22\2""""   ---    + + +'''$ C C C B B B B N N N N N NNNN&PPP####< E E ED    CCC&&899***(<(<== < --L7777r      $$$   : \ \ \ \****. @ @ @1111 AAA,;;;;r r) __future__rrrrrsysrrr future.movesrrNclselectexceptr r clselectprintr clcommonr objectrrr rr$s'&&&&&%%%%%% 555555AAAAAAAA""""""^^^^^v^^^^^r