IQgddlZddlmcmZddlZddlZddlmZddl m Z m Z m Z ddl mZddlmZddlmZmZGddZGd d eZGd d eZGd deZdZGddZdS)N) ExpatError)TupleOptionalDict)Version)FormattedException) run_commandExternalProgramFailedceZdZdZdZdZdS)GovernorStatusenablederrordisabledN)__name__ __module__ __qualname__ENABLEDERRORDISABLED/builddir/build/BUILD/imunify360-venv-2.5.0/opt/imunify360/venv/lib/python3.11/site-packages/clcommon/lib/mysql_governor_lib.pyr r sG EHHHrr ceZdZdS)MySQLGovExceptionN)rrrrrrrrsDrrc"eZdZdZfdZxZS)MySQLGovernorDisabledz< Exception raised when dbgovernor daemon is offline cVtddddddS)NzR%(util)s is disabled in the system. Please, run "%(command)s" to start the servicezMySQL governorzservice db_governor restart)utilcommandmessagecontextsuper__init__self __class__s rr%zMySQLGovernorDisabled.__init__%sK C)8        rrrr__doc__r% __classcell__r(s@rrr!sB          rrc"eZdZdZfdZxZS)MySQLGovernorAbsentz: Exception raised when dbgovernor isn't installed cTtdddiddS)Nz%(util)s not present in systemrGovernorr r#r&s rr%zMySQLGovernorAbsent.__init__5s> 7 +       rr)r,s@rr.r.1sB         rr.cdd|idS)NzInvalid %(param)s parameterparamr r)r2s r_get_exc_messager3<s0U#  rc VeZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zdd#e%e&de%e+fd)Z,d*e&d+e)fd,Z-d#e&d-e%ed.e%efd/Z.d#e&d-e%ed.e%efd0Z/ d=d#e&d-e%ed.e%efd1Z0d2Z1d3Z2d4Z3ed5e&d6e&fd7Z4ds1vv@..  &,,s-8 B AB B")B BBc|} t|dd5}tj|cdddS#1swxYwYdS#t t f$r/}d|_td|t|dd|d}~wt$r/}d|_td|t|dd|d}~wwxYw) Nrzutf-8)encodingTzNAn error occured while loading governor config from %(path)s. Error: %(error)s)r=rr zNAn error occured while parsing governor config from %(path)s. Error: %(error)s) _get_config_pathopenxml parseStringreadIOErrorOSErrorr;rrbr)r' config_pathfrcs rrLzMySQLGovernor._get_xml_configsc++--  k3999 1Qqvvxx00 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1!   &*D ##E%03q66BBDD      &*D ##E%03q66BBDD   sFA(&A A(AA("A#A((C9*B## C0*CCcvg} |dd}n'#t$r}tdddid|d}~wwxYw|d}|D]Z}|d}|d kr=|d r(||d [|S) z Loads information about igrored users :type governor_cfg: xml.Document :return: list of ignore users governorrzFMalformed mysql-governor config. Unable to find element '%(element)s'.elementr Nusermodeignorename)rMrOrrNappend)rPignore_users_listgov_datarcusers_data_list user_data user_modes r_load_ignore_users_from_xmlz)MySQLGovernor._load_ignore_users_from_xmls #88DDQGHH   #E%z2%%    #77??( M MI!..v66IH$$))&11M%,,Y-C-CF-K-KLLL  s A?Ac|dr|dz}d}n |}|dkrd}d}||t|dz|jz}||t|dz|jz}||fS)z Calculate db R/W IO limits based on governor version :param io: requested limits in MB/s :return: string values suitable to pass to "dbctl set ..." z1.2-17iz%sb,%sb,%sb,%sbz %s,%s,%s,%s)_is_governor_newer_then _percentageint IO_PERCENTS)r'io io_limits limits_tmplrkwrites r_calc_rw_io_limitsz MySQLGovernor._calc_rw_io_limitss  ' ' 1 1 (W I+KKIA~~ 'KT--c)q..A.A.2.>@@@d..s9>/B/B/3/?AAAU{rc|sdS tj|jdgd}|dd}|S#tjtf$rYdSwxYw)Nz --versionT)text r)r` subprocess check_output_GOVERNOR_BINARY_PATHstripsplitCalledProcessErrorrm)r'resversions rrCz"MySQLGovernor.get_governor_versions'')) 4 )4+E{*SZ^___Ciikk'',,Q/GN-w7   44 sA A$$A>=A>cX|j}|sdSt|t|kSr8)rDr)r'rcurrents rrz%MySQLGovernor._is_governor_newer_thens2( 5w''"2"222rc>d|DS)a Convert data line from dbctl to list :param line: Data line could be like: "default 400/380/350/300 953/791/724/562 953/791/724/562" or: "default 400/380/350/300 1000/830/760/590 1000/830/760/590" depending on --kb/mb/bb option passed to dbctl :return: list: ['default', '400/380/350/300', '953/791/724/562', '953/791/724/562'] cg|]}||Srr).0parts r z-MySQLGovernor._parse_line..s6666666rr)lines r _parse_linezMySQLGovernor._parse_lines 766666rcz|g}|D]'}|t||z(t|S)zX Calculate full list of governor limits by one value and percents koeff )rwrtuple)valuepercentsrks rrzMySQLGovernor._percentagesE g % %A JJs57|| $ $ $ $Szzrc|jS)z= Get governor presence flag :return: )r@rEs rr`z!MySQLGovernor.is_governor_presents ((rcD|||jvrdSdS)z Get MySQL governor status for supplied user :param username: Username for get status :return: Governor status: "watched"/"ignored" or None if error ignoredwatched)rar9r'usernames rget_governor_status_by_usernamez-MySQLGovernor.get_governor_status_by_usernames,  t3 3 39yrwith_package_markreturnc|||jvr|j|\}}}}n|jd\}}}}|r||f}n||f}|S)a Get MySQL governor limits for supplied user :param username: Username for read limits :param with_package_mark: False - without package limits difference mark (for compatibility with non-package governor, used in cloudlinux-top/cloudlinux-statistics), True - with package limits difference mark :return: Tuple (CPU limit, IO limit). Examples: (150, 3072) - with_package_mark == False ('*150', '3072') - with_package_mark == True ('*150', '*4096') - with_package_mark == True * - user has individual limits, differ from package limit MySQLGovException will be thrown if governor not present or error default)rar:)r'rruser_cpu_limituser_io_limit_kbuser_cpu_limit_markeduser_io_limit_markedlimits_for_returns rget_limits_by_userz MySQLGovernor.get_limits_by_user$s  t, , ,%h/ ZN,.CEYEY%i0 ZN,.CEY  C!68L M  !/1A B   rc||rdnd}|||g\}}}|s|rd||p|dd}t|dS)z Set MySQLGovernor status for single user :param: `str` username: Username for set status :param: `bool` status: True for "monitor", False for "ignore" :return: `bool`: operation status result monitorruz.Set governor status error(%(ret)s): %(output)sretrTr rrar[rr'rstatus status_cmdrrYrZ exc_messages rset_governor_status_for_userz*MySQLGovernor.set_governor_status_for_userAs "(6YYh $ 9 9:x:P Q QWg  1c 1&V.1W=O&P&PRRK#K00 0qrc||rdnd}|dvrd}|||g\}}}|s|rd||p|dd}t|dS) z Set user restricted with dbctl utility :param: `str` username: Username for set restricted status :param: `bool` status: True for "restricted", False for "unrestricted" :return: `bool`: operation status result restrict unrestrictrootadminrz,Set user restrict error(%(ret)s): %(output)srr rrrs rset_restricted_status_for_userz,MySQLGovernor.set_restricted_status_for_userQs #);ZZ| ( ( ( H $ 9 9:x:P Q QWg  1c 1&T.1W=O&P&PRRK#K00 0qrc||dg\}}}|s|rd||p|dd}t|dS)zi Set user restricted with dbctl utility :return: `bool`: operation status result zunrestrict-all:Set all users unrestrict status error(%(ret)s): %(output)srr rr)r'rrYrZrs r%set_unrestricted_status_for_all_usersz3MySQLGovernor.set_unrestricted_status_for_all_userscsu  $ 9 9;K:L M MWg  1c 1&b.1W=O&P&PRRK#K00 0qrcP||dvrd}||jvrdSdS)z Get MySQL governor status for supplied user :param username: Username for get status :return: Governor restricted status: "restricted"/"unrestricted" rr restricted unrestricted)ra_governor_restricted_usersrs rget_restrict_status_by_usernamez-MySQLGovernor.get_restrict_status_by_usernameps=  ( ( ( H t6 6 6<~rNc 0||dS|d|g}|t|trBdt t |||j}nttd| d||zt|tr| |\}}nttd| d|| d | | |\}}} n/#t$r"} tt | | d} ~ wwxYw| s|rd || p|d d } t| d|_dS) a Set MySQLGovernor limits for user :param: username `str`: username for set limits :param: `int`|`list` cpu: governor cpu limit. when it param int - calculate by percentage other params :param: `int`|`list` io: io value means that read and write limits similar :param: `int`|`list` read: read limit :param: `int`|`list` write: write limit :return: 0 Nrset,cpu--cpu=r--read=--write=rrr )ra isinstancerjoinmaprbr CPU_PERCENTSrr3rwrr[r r:) r'rrrcmdrkrrrYrZrcrs rset_limits_for_userz!MySQLGovernor.set_limits_for_user~s ;2:1 h ?#s## Ahhs3(8(8d>O(P(PQQRR'(8(?(?@@@ JJ~~~ & & & >"c"" @"55b99 ee'(8(>(>??? JJ''' ( ( ( JJ)%)) * * * 3$($=$=c$B$B !C''$ 3 3 3#CFF++ 2 3  1c 1&b.1W=O&P&PRRK#K00 0 $qs)E E/ E**E/ package_namec|r4|jdd|ddg}n |jdddg}t|d\}}}|dks|r(t d d ||d d  t j|}n@#t jf$r-}t d |jt|dd |d}~wwxYw|S) Retrieve MySQL Governor package limits :param package_name: Package name. If None, get all packages name :return: Dict with limits. Example: {'pack1': {'cpu': 100, 'io': 900}, 'pack2': {'cpu': 100, 'io': 900}} getz --package=zunicode-escapez --format=kbz--allTrRrz''%(cmd)s' failed, stderr is: %(stderr)srrstderrr z,%(util)s output invalid, error is: %(error)s)rrN) _PACKAGE_UTILITY_PATHencodedecoder rrjsonloadsJSONDecodeErrorrb)r'rcmd_listrXrYrZpackage_data_from_utilrcs r$_get_package_raw_limits_from_utilityz2MySQLGovernor._get_package_raw_limits_from_utilitys3  S2EU\%8%8%:%:%A%ABR%S%SUU%'HH2E7MRH%0d%S%S%S"'7 q==G=#D#&88H#5#5II%%  %)Z%8%8 " "$'   #I$($>QPP%%   &%sBC-(CCcpu_limits_listread_limits_listwrite_limits_listct|d|t|dt|dfS)a Calculate package limits from raw governor limits :param cpu_limits_list: CPU limits list :param read_limits_list: Read limits list :param write_limits_list: Write limits list :return: Tuple: (cpu_limit, io_limit) r)r_get_user_io_limitrb)r'rrrs r_calc_package_limits_from_rawz+MySQLGovernor._calc_package_limits_from_rawsK?1%&&(?(?DTUVDW@X@XZ]^opq^rZsZs(t(tttrc ||}n#t$rwxYwi}|D]9\}}||d|d|d\}}||d||<:|S)rrrkr)rr)rritemsr)r'rr packages_data pack_name pack_limits cpu_limitio_limits rget_package_limitsz MySQLGovernor.get_package_limitss %)%N%N|%\%\ " "       &<&B&B&D&D J J "I{"&"D"D[QVEWYdekYlEPQXEY#[#[ Ix/8'I'IM) $ $s $r limit_namescd|}|jdd|d|g}t|d\}}}|dks|r(tdd ||d d d S) z Reset users limits to default :param username: User name ro reset limits :param limit_names: Limit names list to reset rreset_individualz--user=z --limits=TrRrz*'%(cmd)s' is failed, stderr is: %(stderr)srrr N)rrr r)r'rr limits_stringrrX_rZs rreset_user_limits_to_defaultsz+MySQLGovernor.reset_user_limits_to_defaultss-- .0BDXhDXDX/ //1*8MMM!W q==G=#G#&88H#5#5II%%  =rrrc ddlm}m}d|} ||}n#ttf$rYdSwxYwt |dkrdSg}d} |D]} | dr|| d} t | dkrU|dkr|j } nt|} | d } | | kr| d | d d } | | d | d r||dkr|j }nt|}| d} t | dkr7| d }||kr| d|d d } t| | d | | | r|||ddSdS)z Set MySQL Governor to cPanel package file. If limits not changed, package file will not be written :param package_name: Package name :param cpu_limit: MySQL CPU limit to set :param io_limit: MySQL IO limit to set r)get_file_lineswrite_file_linesz/var/cpanel/packages/NF lve_mysql_cpu=rrzlve_mysql_cpu= T lve_mysql_ioz lve_mysql_io=w) clcommon.utilsrrrmrllen startswithrr _S_DEFAULTrbrw)r'rrrrr package_pathcpanel_package_lineslines_to_writeis_change_maderparts s_cpu_limits_old_cpu_limit s_io_limitrs r&_set_governor_limits_to_cpanel_packagez4MySQLGovernor._set_governor_limits_to_cpanel_packagesr DCCCCCCC=|==  #1>,#?#? #    FF  # $ $ ) ) F) , ,D// ,I4I **3//u::??>>"&/KK"%i..K"'(.."2"2"k11"))*J;*J*J*JKKK%)NN#))T+++666600 ,X5Iq==!%JJ!$XJ **3//u::??a((J&&"))*H**H*H*HIII%)NN#))T+++6666%%d++++  @  \>3 ? ? ? ? ? @ @s 00c`ddlm}|dkrdS||||dS)a& Apply all MySQL Governor packages limits to cpanel package file. In not cPanel, do nothing :param package_name: Package name to update :param cpu_limit: MySQL CPU limit to set, None - not change :param io_limit: MySQL IO limit to set, None - not change r) getCPNamecPanelN)clcommon.cpapirr)r'rrrrs r_apply_package_limits_to_cpanelz-MySQLGovernor._apply_package_limits_to_cpanelLsJ -,,,,, 9;;( " " F 33L)XVVVVVrc &|||td|d|d|d|jdd|g}|t|trBdt t |||j}nttd | d ||zt|tr| |\}}nttd | d || d |t|d\}} } |dks| r)tdd|| | dd| |||dS)z Set limits for Governor package :param package_name: Package name for set :param cpu_limit: MySQL CPU limit to set :param io_limit: MySQL CPU limit to set NzMySQLGovernor.set_package_limits arguments error: Package name and at least one limit should be provided. Current arguments: package name: z; cpu limit is z; IO limit is ;rz --packagerrrrrrTrRrzI'%(command)s' is failed, stdout is: '%(stdout)s', stderr is: '%(stderr)s'r)rstdoutrr )rrrrrrrbrrr3rwrr r) r'rrrrrrkrrXrYrZs rset_package_limitsz MySQLGovernor.set_package_limitsXs  9#49I#%Y\h%Y%Y5>%Y%YNV%Y%Y%YZZ Z .{LQ  )S)) Ghhs3(8(8DDU(V(VWWXX'(8(E(EFFF OONSNN + + +  (C(( F"55h?? ee'(8(D(DEEE OO,d,, - - - OO.u.. / / /%0d%S%S%S"'7 q==G=#f'*xx'9'9WX_``%%  ,,\9hOOOOOrcftj|jr|jS|jS)zN Get config path for mysql-governor; :rtype: str|None )r<r=r>_CONTAINER_PATH_V2_CONTAINER_PATHrEs rrgzMySQLGovernor._get_config_paths/ 7>>$1 2 2 +* *##rc |}|||_dS#t$rd|_d|_wxYw)z*Load ignore users list from container fileN)rLr}r9rr:)r' governor_xmls r_read_ignore_usersz MySQLGovernor._read_ignore_usersse //11L00>>  ( ( (    $(D !+/D (  s .2A c\|j |jdS|jsd|_t dd|jid}||\}}|dgd\}}}d| d d dD|_ | d }| ||||_d |jvr4d|_d|_d|_d d |jddd}t|dS)zL Loads users info from MySQL governor :return: None NTz%(utility)s output is invalidutilityr zlist-restrictedrWcBg|]}|dS)rr)rrs rrz,MySQLGovernor._load_info..s1+ + + $DJJLLO+ + + rrrrz'There is no %(what)s found in %(where)szdefault settingsz output)whatwhere)r9r:r@r;r.r?r!_run_dbctl_listr[rrr_parse_dbctl_data_linesr)r'utility_exc_messageis_kb_limits_ok gov_data_strrgov_restricted_strgov_data_linesrs rrazMySQLGovernor._load_infos  ' 38M8Y F( (&*D #%'' '*I+4d6H*IKK !!!)-(<(<(>(>%  % %'8&94 % P P ! q+ + (:(@(@(B(B(H(H(N(Nqrr(R+ + + '&++D11 $ < <^_^q r r D1 1 1&*D #$(D !+/D (D$6DDVA_A_A_``K$K00 0 2 1r read_limit write_limitc t|t|z}nH#t$r;||cxkrdkrnnd}n%|dkrt|}nt|}YnwxYw|S)z Calculates the io limit. Handles the situation when user's write or read io limit is less than 1mb/s (PTCLLIB-85). :type write_limit: str :type read_limit: str :rtype: int z<1r)r ValueError)r/r0 user_io_limits rrz MySQLGovernor._get_user_io_limits 1 OOc+.>.>>MM 1 1 1[0000D00000 ! $$ #J #K 0 0  1s"AA'&A'c|ddgd\}}}d}|sd|vr|dgd\}}}d}||fS)aW Executes dbctl list-marked --kb or dbctl list-marked :param _is_incorrect_syntax: True is emulate dbctl error. Only for testing! :return: Cortege (is_kb_limits_ok, stdout_str), where is_kb_limits_ok == True, if dbctl returned limits in KB, else - False stdout_str - dbctl stdout string z list-markedz--kbTr$zIncorrect syntaxrUF)r[)r'_is_incorrect_syntaxrXr,rr+s rr(zMySQLGovernor._run_dbctl_lists%)$=$= F #T%>%;%;!,  $#5#E#E!%!:!:$";"0"0 A|Q#O ,,rr+r*ci}|D]}|}|rd|vrt|}t|dkst|ddkr$d|_d|_d|_t||dd}|dd}|d d} t|dks&t|dkst| dkr$d|_d|_d|_t||d } t|d } | |d | d } |r| n| d z} |d}|d d kr d |d }n|d }|dd krd | }nt| }| | ||f|| <|S)a Converts data lines from dbctl stdout to dictionary :param data_lines_list: List of lines from dbctl stdout :param is_kb_limits_ok: Is limits already in KB/s :param utility_exc_message: Message dict for exception :return: Tuple(dict, dict) dbctl data dictionary. Example: {'default': (400, 1953124, '400', '1953124'), 'cltest1': (350, 2025138, '*350', '2025138') } zcpu(%)rTNr/ri+*) rr5rrr;r:r9rrrrrb)r'data_lines_listr+r*governor_limitsruser_limits_listrrr user_namerr3rmarksrrs rr)z%MySQLGovernor._parse_dbctl_data_liness(#, y, yD::<> #$$))S1A!1D-E-E-J-J*.'(,%/3,'(;<<<.q177< > ?##q((C0@,A,AQ,F,F#N_J`J`deJeJe*.'(,%/3,'(;<<<(+I !344N 334DQ4GIZ[\I]^^M0?W}}]SWEW %Q'EQx3(@OA,>(@(@%%(7(:%Qx3'=+;'='=$$'*+;'<'<$*8:JLacw)xOI & &r)F)NNrG)7rrrr*rrr?rrrrr r%rHrAr[r^r]rL staticmethodr}rrCrrrr`rboolrrrrrrrrrrbdictrrUrrrrrrrrgr!rarr(r)rrrr5r5Cs%K%L%MU39O=J===$###****,... - - -*!!\!22   333  7 7\ 7\)))   !!d!uUXZ]U]!!!!: $      BBBBH&#&SW&&&&8 uT uUY u9= uBGS/ u u u ux}QU&c&;@;@C=;@3- ;@;@;@;@z WC WHUXM Wemnqer W W W WPT59(P(Ps(Px}(P%-c](P(P(P(PT$$$   '1'1'1Rs\&----&99cg9lp999999rr5)r<xml.dom.minidomdomminidomrirrxml.parsers.expatrtypingrrrpackaging.versionrclcommon.clexceptionrclcommon.utils_cmdr r r rrr.r3r5rrrrMs  ((((((((((((((((%%%%%%333333AAAAAAAA      *         -         +   \ \ \ \ \ \ \ \ \ \ r