a hI@sddlmZddlmZgdZddlZddlZddlZddlm Z ddl Z ddl m Z ddl Z ddlZddlZddlZddlZddlZddlZddlZddlZddlZddlTddlZddlmZdd lmZmZdd lmZddlTd d Z d dZ!dZ"dZ#dZ$e%drdZ$ne%dr&dZ$dZ&e'Z(e)dZ*e)dZ+e)dZ,e)dZ-e)dZ.e)dZ/da0ej1a2ej3ej4ej1ej5ej6dZ7ddZ8ddZ9dd Z:d!d"Z;d#d$Zd)d*Z?dd+d,Z@d-d.ZAdd1d2ZBdd3d4ZCdd6d7ZDd8d9ZEd:d;ZFdd?ZHdeH_Id@dAZJdBdCZKdDdEZLieL_MdFdGZNieN_MzddHlOmPZPePZQWngZQYn0dIdJZRdKdLZSdMdNZTdOdPZUddRdSZVdTdUZWdVdWZXdXdYZYdZd[ZZd\d]Z[dd^d_Z\d`daZ]ddbdcZ^dddeZ_ddfdgZ`dhdiZaddjdkZbdldmZcdndoZddpdqZedrdsZfdtduZgejheji dvZjejkr`ejhejl dvZmnejZmemejZnehdZoejhdwdxZpGdydzdzejqZrGd{d|d|ejqZsGd}d~d~ZtGddde j Zue veudS))absolute_import)range)-audit_msg_decode merge_listspreextend_listfmt_objformat_elapsed_timeformat_2_column_name_value wrap_text format_msgremove_linebreaks default_textdefault_date_textis_standard_directoryget_standard_directoriesget_rpm_nvr_from_headerget_package_nvr_by_nameget_package_nvr_by_file_pathget_rpm_nvr_by_typeget_rpm_nvr_by_scontextget_rpm_source_packageget_store_rootis_hex split_rpm_nvr file_typesget_user_home_dirget_plugin_names load_pluginsget_os_environment find_program get_identity get_hostnamemake_database_filepathvalid_email_addresslaunch_web_browser_on_urlabstract log_debugget_error_from_socket_exception!assure_file_ownership_permissionsparse_datetime_offsetDATABASE_MAJOR_VERSIONDATABASE_MINOR_VERSIONdatabase_version_compatible syslog_trace TimeStampRetryPACKAGE_MANAGERN)SystemMessageBus)GObject)*) cmp_to_key) FunctionType MethodType) get_configcCs||k||kSNxyr9r97/usr/lib/python3.9/site-packages/setroubleshoot/util.py_r>cCs.z t|tWSty(t|tYS0dSr8) isinstanceZTypeType NameErrortypeobjr9r9r=is_typebs  rErpmdpkgdebz/etc/redhat-releasez \s*\n+\s*z^[A-Fa-f0-9]+$zz^([^\s@]+)@([^\s@]+)$z^\s*"([^"]+)"\s*$z\s*\(\s*type\s+([\w-]+)\s*\)\s*)ZCRITICALZERRORZWARNINGINFODEBUGcCs&tt|datdur"tjadS)Nlevel) log_levelsgetr7upper log_levelsyslog LOG_WARNING)sectionr9r9r=log_initsrTcCsttjkrttj|dSr8)rPrQ LOG_DEBUG)msgr9r9r=r&s r&cCs*|d}|D]}t|rt|qdS)N )splitlenrQ)ZtraceZ log_linesliner9r9r=r-s r-cCszd}}|d}t|dkr*t|d}t|dkrBt|d}|tkr`td|ttfdStd|ttfdSdS) N.rz=database version %s not compatible with current %d.%d versionFz9database version %s compatible with current %d.%d versionT)rXrYintr*r&r+)versionmajorminor componentsr9r9r=r,s     r,cCs|dur dSddl}||\}}t|}|d}||d}|d}||d}|d}||d}|r~d|||||fS|rd||||fS|rd|||fSd||S) NriQi<z%dd:%dh:%dm:%.3fsz %dh:%dm:%.3fsz %dm:%.3fsz%.3fs)mathZmodfr^)Z elapsed_timerdZfractionZwholedayshoursminutessecondsr9r9r=rs$   rcCst|rdSdSdSNTF)hex_rematchstrr9r9r=rs rcCsj|dur dSt|}|r&|d}n@z.tjddkrB|d}nt|d}Wn|}Yn0|S)Nr\rrFhexzutf-8)audit_decode_researchgroupsys version_infodecode bytearrayfromhex)rVrkZdecodedr9r9r=rs    rcCsH|s|S|s|Si}|D] }d||<q|D] }d||<q*t|}|S)z2return a list containing the unique members of a+bN)listkeys)abdimr9r9r=rs   rcs^|dur g}t|}||}|dkrZtrJ|fddt|Dn|g||S)Nrcsg|] }qSr9r9.0r;defaultr9r= r?z"preextend_list..)rYrEextendr)Zrequested_lengthZ_listrZ cur_lengthZdeltar9rr=rsrcsttjrStttfr:ddddDdSttrxt}|ddfdd|DdSt SdS) N[ cSsg|]}dt|qS)z%srr~r9r9r=rr?zfmt_obj..]{cs$g|]}dt|t|fqS)z%s=%sr)rkeyrCr9r=r r?}) r@six string_typesrwtuplejoindictrxsortrm)rDrxr9rCr=rs    rPcCsvt||kr"|d|dd}n|d|t|}|rB|rN||dS|t_d|t_|t_t|dSdS)Nrr\rrW)rYisspace text_wrapperinitial_indentsubsequent_indentwidthfill)namevalueZ value_indentZ page_widthrr9r9r=r s    r cCs(d|}|t_|t_|t_t|dS)NrrW)rrrrr)srindentprefixr9r9r=r s r cCsD|dur d}|}d|}|t_|t_dt_|dt|dS)NrrrWz )striprrrrr)titlerVrZ indentStringr9r9r=r &sr cCs$td|}|durdS|SdS)Nrr)fix_newline_resubr)rmZnew_strr9r9r=r 1sr cCs |durdtdd}t|S)N)_rm)valr9r9r=r 9sr cCs|durt|S|Sr8)r format)dater9r9r=r?srcCsL|dur dStj|}|r(tj|s,dStjdurBttt_|tjvS)z Check whether given path is a standard directory. >>> is_standard_directory('/etc') True >>> is_standard_directory('/etc/systemd/') False >>> is_standard_directory('/usr/bin/cat') False NF)ospathnormpathisabsrdatasetr)rr9r9r=rEs   rc Csg}zTtdkr.tjgddtjdd}tdkrVtjgddtjdd}Wn>tjy}z$ttjd t|j WYd }~n d }~00|S) zH >>> get_standard_directories() # doctest: +ELLIPSIS [...'/bin'...] rG)rGz-qlZ filesystemTuniversal_newlinesstderrrWrI)rHz-Lz base-fileszfailed to get list from {}: {}N) r0 subprocess check_outputPIPErstriprXCalledProcessErrorrQLOG_ERRrr)Zlster9r9r=rcs $.rcCs&|d}|d}|d}d|||fS)z6Given an RPM header return the package NVR as a stringrr_releasez%s-%s-%sr9)Zhdrrr_rr9r9r=rusrc Cs|dur dS|tjvr tj|Sd}zNtdkrJtjdd|gdtjd}tdkrptjddd |gdtjd}Wn@tjy}z&ttj d t||j fWYd}~n d}~00|tj|<|S) z? >>> get_package_nvr_by_name("coreutils")[0:9] 'coreutils' NrG-qTrrI dpkg-queryz(-f=${Package}-${Version}:${Architecture}z-Wz,failed to retrieve %s info for name '%s': %s) rcacher0rrrrrrQrr)rnvrrr9r9r=r~s   0 rc Cs|dur dStj|sdStj|}tj|s8dS|tjvrLtj|Sd}ztdkrvtj dd|gdtj d }tdkr>> get_package_nvr_by_file_path("/bin/ls")[0:9] 'coreutils' NrGz-qfTrrIrz-S)rr\rWz diversion by z: )maxsplitrz, z,failed to retrieve %s info for path '%s': %s)rrrrexistsrrr0rrrrrtr returncoderX startswithrrQrr)rrqueryZcperZZ package_namerr9r9r=rs@            0 r)get_all_file_typescCs6|d}|d}|d}d|dd}|||fS)N-)rXr)rrbrr_rr9r9r=rs  rcCstdurttdurdSt|d}|dur2dSt|}|dur||dd}d|d}t|}|dur||d7}t|}|S)a Finds an SELinux module which defines given SELinux type ##### arguments * `selinux_type(s)`: an SELinux type ##### return values * `nvr(s)`: nvr of rpm which ships module where `selinux_type` is defined ##### usage >>> get_rpm_nvr_by_type("sshd_t")[0:14] 'selinux-policy' >>> get_rpm_nvr_by_type("mysqld_log_t")[0:13] 'mysql-selinux' >>> get_rpm_nvr_by_type("spc_t")[0:17] 'container-selinux' N/rz/usr/share/selinux/packages/z.ppz.bz2)module_type_cachebuild_module_type_cacherNrrX)Z selinux_typerpackage module_namer9r9r=rs   rcCs"zt|WdSYdS0dSrir^rlr9r9r= __str_is_ints rc Cs"t\}}|dkrdSt}g}t}td||*}tdd|Dddd}Wdn1sj0Y|D]}td |||D]\}}} d | vrzfzt j d |d d } Wnt d |} Yn0| D] } t | } | r||| d<q| WqYq0qqx|adS)z Creates a dictionary with all types defined in the module store as keys and corresponding module paths as values. The dictionary is stored in "module_type_cache" to be used by "get_rpm_nvr_by_type" >>> build_module_type_cache() rNz{}/{}/active/modulescSs$g|]}|rt|jr|jqSr9)is_dirrrr~r9r9r=r7r?z+build_module_type_cache..cSst|Sr8r)r;r9r9r=r>7r?z)build_module_type_cache..rz{}/{}/active/modules/{}Zcilz{}/cilZrt)moder\)selinuxZselinux_getpolicytyperrrscandirrsortedwalkbz2opentypedef_regexprkrqcloser) ZretvalZ policytypeZmodule_type_dictZ prioritiesZ store_rootZ module_storedirdirpathdirnames filenamesfrZresultr9r9r=r"s0 8   rFcCsL|r(t}|dd}t|t|Stt|}ttt|SdS)a  Finds an SELinux module which defines given SELinux context ##### arguments * `scontext(s)`: an SELinux context ##### return values * `nvr(s)`: nvr of rpm which ships module where SELinux type used in `scontext` is defined ##### usage >>> get_rpm_nvr_by_scontext("system_u:system_r:syslogd_t:s0")[0:14] 'selinux-policy' >>> get_rpm_nvr_by_scontext("system_u:system_r:mysqld_log_t:s0")[0:13] 'mysql-selinux' >>> get_rpm_nvr_by_scontext("system_u:system_r:timedatex_t:s0", use_dbus=True)[0:14] 'selinux-policy' z*org.fedoraproject.SetroubleshootPrivilegedz+/org/fedoraproject/SetroubleshootPrivilegedN)r1Z get_proxyrmrrZ context_newrZcontext_type_get)ZscontextZuse_dbusZbusZ remote_objectcontextr9r9r=rUsrcCsd|dur dSd}z0ddl}|jdddd|gddd d d}Wnttjd |Yn0|S) a; Find a source package for `name` rpm >>> get_rpm_source_package("policycoreutils-python-utils") 'policycoreutils' >>> get_rpm_source_package("selinux-policy-targeted") 'selinux-policy' >>> get_rpm_source_package("selinux-policy-targeted-35.8-1.fc35.noarch") 'selinux-policy' NrrGrz--qfz %{SOURCERPM}T)rrr]z"failed to retrieve rpm info for %s)rrrsplitrQr)rsrcrr9r9r=rxs (rcCs6t}zt|}Wnty*YdS0|j}|Sr8)rgetuidpwdgetpwuidKeyErrorpw_dir)uidZpwZhome_dirr9r9r=rs rcCst|}|rdSdSdSri)name_at_domain_rerp)addressrkr9r9r=r#s r#cCs tdd}ttj|||dS)NZ helper_appsweb_browser_launcher)r7rspawnlP_NOWAIT)urlrr9r9r=r$s r$cCs6t|dd}|r"|d}|d}n t}t|}||fS)Nargsrr\)getattrZERR_SOCKET_ERRORZ get_strerror)rrerrnostrerrorr9r9r=r's  r'c Csd}tj|shzt|d}|Wn@tyf}z(d}ttjd||jfWYd}~n d}~00zt ||WnBt y}z*d}ttjd|||jfWYd}~n d}~00zbt |t r|}nt |d}|dur|}t |t r|}nddl} | |d}t|||Wnbt y}zHd}ddl} ttjd|t |d| |d|jfWYd}~n d}~00|S) NTwFzcannot create file %s [%s]zcannot chmod %s to %o [%s]r]rzcannot chown %s to %s:%s [%s])rrrrr ExceptionrQrrchmodOSErrorr@r^rgetpwnamgrpgetgrnamchownrgetgrgid) filepathrownerrqrrrrgidrr9r9r=r(s:   .0  Fr(cCs<ddl}||dd}|jj}td|||fdS)Nrr\rFz=%s must be implemented in subclass %s or ancestor class of %s)inspectZgetouterframesZ currentframe __class____name__NotImplementedError)rDrmethodsubclassr9r9r=r%s r%cCs|durd}ntdd|}tdd}g}ttj||dD]<}tj|}|dvr\qBtjtj|d}| |qB|S) Nr3z.py$rplugins plugin_dir.py)z __init__.pyr) rerr7globrrrbasenamesplitextappend) filter_globr plugin_namesp plugin_namer9r9r=rs   rcCs||Sr8)Z get_priorityr:r9r9r= sort_pluginssrc Csztdd}tj|s&td|gStj|}g}t|}td||}|tjvrz.t j ||d}t j |}|j |WnBty}z*ttjd|t|fgWYd}~Sd}~00|D]} d|| f}zDt j ||d| d }t j |}|j |||Wqtyb}z&ttjd | t|fWYd}~qd}~00q|jttd |S) Nrrz4plugin directory %s does not exist, no plugin loadedzload_plugins() names=%sz /__init__.pyz&failed to initialize plugins in %s: %sz%s.%srrzfailed to load %s plugin: %sr)r7rrisdirr&r rrrmodules importlibutilspec_from_file_locationmodule_from_specloader exec_modulerrQrrmr Zpluginrr4r) r rZ plugin_baserrrmod_specmodrrr9r9r=rs8          2rc Cs~zttd}Wn8zddl}d|}Wnd}Yn0Yn0t}|d}|d}d||f}||fS)Nrrunknownr]rz%s %s) rredhat_release_path readlinesrdistrorZlinux_distributionruname)Z myplatformrr Zkernel_releaseZcpuZos_descr9r9r=r s rcCs@|durt}zt|}Wnty2YdS0|d}|SNr)rrrrr)rZ pwd_entryusernamer9r9r=r 3s r c CsTzddl}|}|WStyN}z ttjd|WYd}~dSd}~00dS)Nrzcannot lookup hostname: %s)ZsocketZ gethostnamerrQr)ZSockethostnamerr9r9r=r!?sr!cCs\tj|r|Stj|}tddd}|D]&}tj||}tj|r0|Sq0dS)NZ fix_commandZprog_search_path:)rrrr r7rXrr)progr  search_pathr{rr9r9r=rIs    rcCs2tdd}tdd|}|d}tj||}|S)NZdatabase database_dirz\.xml$rz _database.xml)r7rrrrr)rr'filenamerr9r9r=r"Us  r"c Cs td}d}d}d}d}d}|}||D]}|r0d}t|d}|d} | dur0| dkrp||d 7}| d kr||d 7}| d kr||d 7}| dkr||7}| dkr||7}| dkr||7}| dkr0||7}q0|rtj||||d} td|| f| St t j d|dSdS)zThe time offset may be specified as a sequence of integer unit pairs. Units may be one of year,month,week,day,hour,minute,second and may optionally be plural. Example: '2 weeks 1 day' sets the threshold at 15 days. z0(\d+)\s*(year|month|week|day|hour|minute|second)FrTr\r]NyearimmonthZweekdayhourminutesecondrerfrgrhz)parse_datetime_offset(%s) = time delta %sz$could not parse datetime offset (%s)) rcompilelowerfinditerr^rqdatetime timedeltar&rQr) textZdatetime_offset_refoundrerfrgrhrkZquantityZunitZtdr9r9r=r)^sB      r)cCs~tdb}|D]L}z:|d\}}|dkrJ|WWdSWqYq0qWdn1sp0YdS)Nz/etc/selinux/semanage.conf=z store-rootz/var/lib/selinux)rrXr)rrZZparamrr9r9r=rs   &r)rhr\)rfc@s,eZdZddZddZddZddZd S) LocalTimezonecCs||rtStSdSr8)_isdst DSTOFFSET STDOFFSETselfdtr9r9r= utcoffsets zLocalTimezone.utcoffsetcCs||rtStSdSr8)r;DSTDIFFZEROr>r9r9r=dsts zLocalTimezone.dstcCstj||Sr8)timetznamer;r>r9r9r=rFszLocalTimezone.tznamec CsD|j|j|j|j|j|j|ddf }t|}t |}|j dkS)Nrr) r)r*r-r.r/r0weekdayrEmktime localtimetm_isdst)r?r@ttZstampr9r9r=r;s     zLocalTimezone._isdstN)r __module__ __qualname__rArDrFr;r9r9r9r=r:sr:c@s(eZdZdZddZddZddZdS)UTCcCs tdSr!r5r6r>r9r9r=rAsz UTC.utcoffsetcCsdS)NrNr9r>r9r9r=rFsz UTC.tznamecCs tdSr!rOr>r9r9r=rDszUTC.dstN)rrLrM__doc__rArFrDr9r9r9r=rNsrNc@seZdZeZeZdZdZd#ddZ ddZ dd Z d d Z d d Z ddZd$ddZddZddZddZd%ddZddZddZd&d!d"ZdS)'r.z%Y-%m-%dT%H:%M:%SZz%cNcCs|dur|jdd|_nft|tjr0||nNt|trNtj||j |_n0t|tjrb||_nt|t rv|j|_nt ddS)NFlocalz-must be string, float, datetime, or TimeStamp) now_dtr@rrparsefloatr5Z fromtimestamputc_tzr. TypeError)r?tr9r9r=__init__s      zTimeStamp.__init__cCs$t|tr|j|jkS|j|kSdSr8r@r.rTr?otherr9r9r=__lt__s  zTimeStamp.__lt__cCs$t|tr|j|jS|j|SdSr8r[r\r9r9r=__add__s  zTimeStamp.__add__cCs.t|tr|j|j7_n|j|7_|Sr8r[r\r9r9r=__iadd__s zTimeStamp.__iadd__cCs$t|tr|j|jS|j|SdSr8r[r\r9r9r=__sub__s  zTimeStamp.__sub__cCs.t|tr|j|j8_n|j|8_|Sr8r[r\r9r9r=__isub__s zTimeStamp.__isub__FcCs$|rtj|jStj|jSdSr8)r5rSlocal_tzrW)r?rRr9r9r=rSsz TimeStamp.nowcCs|j|jSr8)rTZ astimezonercr?r9r9r=rRszTimeStamp.localcCs|j|jddS)NFrQ)r iso8601_fmtrdr9r9r=__str__ szTimeStamp.__str__c CsBt||j\ }}}}}}}} } t||||||d|j|_|jSr!)rEstrptimerer5rWrT) r?rmr)r*r-r.r/r0rGZyeardayrDr9r9r=rU s  zTimeStamp.parsercCs |jtj||||d7_dS)Nr1)rTr5r6)r?rerfrgrhr9r9r=addsz TimeStamp.addcCs|}||jkrdSdSdSrirSrTr?rSr9r9r= in_futures zTimeStamp.in_futurecCs|}||jkrdSdSdSririrjr9r9r=in_pasts zTimeStamp.in_pastTcCs0|dur|j}|r ||S|j|SdSr8) locale_fmtrRstrftimerT)r?fmtrRr9r9r=r%s zTimeStamp.format)N)F)rrrr)NT)rrLrMrNrWr:rcrermrZr^r_r`rarbrSrRrfrUrhrkrlrr9r9r9r=r.s$   r.c@sheZdZdZdejjdejejffiZ dddZ ddZ ddd Z dd d Z d dZddZddZdS)r/al A class which schedules attempts until one succeeds. Intervals are expressed as floating point seconds. The retry attempt will be scheduled in the future based on the retry_interval which may be either a number of seconds or a callable object returning the number of seconds. The callable form of the retry_interval is useful when the interval should be adjusted based on prior history or other external factors, e.g. backing off the frequency of the retry attempts if initial attempts fail. The retry callback should return False if the attempt fails, in which case it will be scheduled again in the future based on the current value obtained from the retry_interval. If the retry callback returns True it indicates the retry attempt succeeded and no more attempts will be made. Retry's are started with the start() method and continues until the retry callback returns True or the stop() method is called. It is always safe to call stop() even if a retry is not pending. The retry callback, user_data and notify_interval may be specified in either the class init() or in the start() method for convenience. If notify_interval is set a 'pending_retry' signal will be emitted every time the notification interval elapses, this provides a countdown till the next retry attempt. The signature of the retry callback is: callback(retry_obj, user_data) The signature of the pending_retry signal handler is: callback(retry_obj, seconds_pending, user_data) The signature of the retry interval function is: interval(retry_obj, user_data) pending_retryNcCs:tj|||_||_||_d|_||_d|_d|_dSr!) r2rZcallbackretry_interval user_datafailed_attemptsnotify_interval trigger_time timeout_id)r?rqrrrsrur9r9r=rZZs zRetry.__init__cCs |jdurt|jd|_dSr8)rwZGLibZ source_removerdr9r9r=stopds  z Retry.stopcCsF|dur||_|dur||_|dur*||_|d|_|ddS)NrT)rrrsrurxrt_schedule_alarm)r?rrrsrur9r9r=startisz Retry.startFcCsht}|r|||_|j|}|jrH|d||jt|j|}n|}tt |d|j |_ dS)Nrpi) rE_get_retry_intervalrvruemitrsminr2Z timeout_addr^_alarm_callbackrw)r?Z new_retryrSseconds_pendingZ alarm_timer9r9r=ryus zRetry._schedule_alarmcCs6d|_t}|j|}|dkr*|n|dS)Ng{Gzt?F)rwrErv_attempt_retryry)r?rSrr9r9r=r~s  zRetry._alarm_callbackcCs4|||jr|n|jd7_|ddS)Nr\T)rqrsrxrtryrdr9r9r=rs zRetry._attempt_retrycCs"ttttfr|||jS|jSr8)r@Z interval_typer6r5rrrsrdr9r9r=r{szRetry._get_retry_interval)NN)NNN)F)rrLrMrPr2Z SignalFlagsZRUN_LASTZ TYPE_FLOATZ TYPE_PYOBJECTZ __gsignals__rZrxrzryr~rr{r9r9r9r=r/0s%  r/)NN)rr)rr)r)F)N)N)N)N)wZ __future__rZ six.movesr__all__rrr5Zdasbus.connectionr1r Z gi.repositoryr2rrrrshutilrrrrtextwraprEtypesrQ functoolsr4r5r6Zsetroubleshoot.configr7Zsetroubleshoot.errcodecmprEr*r+r0whichrZ TextWrapperrr2rrjZhref_rerrorrrRrPZLOG_CRITrZLOG_INFOrUrMrTr&r-r,rrrrrrr r r r r rrrrrrrrZsepolicyrrrrrrrrrr#r$r'r(r%rrrrr r!rr"r)rr6timezoner=daylightaltzoner<rBrCZHOURZtzinfor:rNr.r/Z type_registerr9r9r9r=s  1                  ;   23 #  *  $    -    fq