HEX
Server: Apache
System: Linux md-ht-3.webhostbox.net 4.19.286-203.ELK.el7.x86_64 #1 SMP Wed Jun 14 04:33:55 CDT 2023 x86_64
User: kbinf747 (2664)
PHP: 8.3.32
Disabled: NONE
Upload Files
File: //usr/libexec/kcare/python/kcarectl/doctor.pyo
�
�;jc.@sdZddlZddlZddlZddlZddlZddlmZmZm	Z	m
Z
mZmZm
Z
mZmZddlmZddlmZmZmZer�ddlmZmZmZmZmZndZdZd	Zd
Z dZ!dZ"d
Z#dZ$dZ%d�Z&d�Z'd�Z(de	j)fd��YZ*de+fd��YZ,d�Z-d�Z.d�Z/d �Z0d!e+fd"��YZ1d#�Z2d$�Z3ed%�Z4d&�Z5ej6d'��Z7d(�Z8d)�Z9d*�Z:d+�Z;d,�Z<d-�Z=d.�Z>d/�Z?d0�Z@d1�ZAd2�ZBd3�ZCd4�ZDd5�ZEe1d6e5�e1d7e4d8gd9eF��e1d:e7�e1d;e8�e1d<e9�e1d=e4d=g��e1d>e:�e1d?e2d@��e1dAe2dB��e1dCe2dD��e1dEe2dF��e1dGe2dH��e1dIe2dJ��e1dKe2dL��e1dMe2dN��e1dOe2dP��e1dQe3dRdS��e1dTe;�e1dUe3dVdW��e1dXe<�e1dYe=�gZGe-dZd[jHe$��e-d\d\�e-d]d^jHe$��e-d_d`�e.dadb�e-dcdd�e/dedf�e/dgdh�e/didj�e/dkdl�e/dmdn�e/dodp�e/dqdr�e/dsdt�e/dudv�e.dwdx�e/dydz�e.d{e�e/d|d}�e-d~d�e-d�d��e-d�d��e-d�d��e0d�e>�e-d�d��e.d�d��e0d�e@�e-d�d��e-d�d��e0d�eA�e.d�d��e-d�d��e0d�eB�e-d�d�jHe$��e.d�e�e.d�d��e0d�eC�e0d�eD�e-d�d��e-d�d��e-d�d��e0d�eE�e-d�d��e-d�d��g,ZIejJd�ejK�d���ZLed��ZMdS(�sODoctor v2 vitals collector (KPT-5984).

Python port of the kcdoctor.sh (1.0-8) vitals collection: gathers the
same data set into a DataPackage-based archive processed by the patch
server generic uploads pipeline.

Scalar and short values are consolidated into a single ``doctor.json``
(the eportal doctor precedent), one field each, instead of a tiny
archive entry per value; bulk data (logs, command dumps, package lists,
sysfs tunables, crash artifacts) stays as separate archive entries. The
1:1 inventory of collected items lives in
docs/features/KPT-5984-doctor-v2/parity-inventory.md.
i����N(	tauthtconfigtdelivery_kitt
http_utilstkcaret	log_utilstplatform_utilstserveridtutils(trun_command(t	HTTPErrortURLErrorthttplib(tAnytCallabletDicttListtOptionals2.0-1s/boot/grub2/grub.cfgs/etc/kdump.confs/var/log/dpkg.logs/etc/apt/sources.list*s/etc/yum.repos.d/*s/var/log/libcare/*.logi's/syssenable*snr_*smax_*s*cnt*s /sys/kernel/debug/tracing/eventss/sys/kernel/tracing/eventss/sys/devicess
[0-9]*.logskmsg*logtKcarectlDoctorPackagecBs#eZdZdZed��ZRS(skcarectl-doctors/upload/kcarectl-doctor/cCstjS(N(RtDOCTOR_REPORT_MAX_SIZE_BYTES(tself((s,/usr/libexec/kcare/python/kcarectl/doctor.pytmax_size;s(t__name__t
__module__t	data_typet
upload_uritpropertyR(((s,/usr/libexec/kcare/python/kcarectl/doctor.pyR7stCollectionSpeccBs eZdZd�Zd�ZRS(s�A single bulk vitals item ported from kcdoctor.sh.

    Collection failures are recorded in errors.log and never abort the
    report: an unhandled exception inside the package context manager
    would remove the whole archive.
    cCs||_||_dS(N(tarcnamet_collect(RRtcollect((s,/usr/libexec/kcare/python/kcarectl/doctor.pyt__init__Ls	cCsMy|j||j�Wn/tk
rH}|jdj|j|��nXdS(Nsfailed to collect {0}: {1}(RRt	Exceptiont	log_errortformat(Rtdata_packagete((s,/usr/libexec/kcare/python/kcarectl/doctor.pytapplyQs(RRt__doc__RR%(((s,/usr/libexec/kcare/python/kcarectl/doctor.pyRDs	cs�fd�}t||�S(s4`run "<cmd>"` kcdoctor.sh helper (no shell features)cs|j|��dS(N(t
add_stdout(R#R(tcmd(s,/usr/libexec/kcare/python/kcarectl/doctor.pyR]s(R(RR(R((R(s,/usr/libexec/kcare/python/kcarectl/doctor.pytrun_specYscs�fd�}t||�S(s4`dump "<path>"` kcdoctor.sh helper for regular filescs|j|d��dS(Ntsrc_path(tadd_file(R#R(tpath(s,/usr/libexec/kcare/python/kcarectl/doctor.pyRhs(R(RR,R((R,s,/usr/libexec/kcare/python/kcarectl/doctor.pyt	dump_specdscs�fd�}t||�S(s�`dump "<path>"` for /proc and /sys files.

    tar reports them as 0-size so they are first read into memory
    (see the same approach in anomaly.prepare_kernel_anomaly_report).
    csatjj��s,|jdj���dSt�d�� }|j|d|j��WdQXdS(Nsfile not found: {0}trbt
data_bytes(tosR,texistsR!R"topenR+tread(R#Rtf(R,(s,/usr/libexec/kcare/python/kcarectl/doctor.pyRws
(R(RR,R((R,s,/usr/libexec/kcare/python/kcarectl/doctor.pytproc_dump_specos	cCs
t||�S(N(R(Rtfn((s,/usr/libexec/kcare/python/kcarectl/doctor.pyt
callable_spec�st	FieldSpeccBs eZdZd�Zd�ZRS(s�A single doctor.json field ported from kcdoctor.sh.

    Collection failures are recorded in errors.log and never abort the
    report; a collector returning None omits the field (e.g. a
    distro-specific source file absent on this system).
    cCs||_||_dS(N(tkeyR(RR9R((s,/usr/libexec/kcare/python/kcarectl/doctor.pyR�s	cCscy|j�}Wn0tk
rB}|jdj|j|��dSX|dk	r_|||j<ndS(Nsfailed to collect {0}: {1}(RR R!R"R9tNone(RR#treporttvalueR$((s,/usr/libexec/kcare/python/kcarectl/doctor.pyR%�s(RRR&RR%(((s,/usr/libexec/kcare/python/kcarectl/doctor.pyR8�s	cs�fd�}|S(s�`dump "<path>"` as a doctor.json string field.

    Read in binary (non-utf8 safe) and decoded leniently; an absent
    distro-specific source file simply omits the field (None).
    csNtjj��sdSt�d��#}|j�jdd�j�SWdQXdS(NR.sutf-8treplace(R0R,R1R:R2R3tdecodetstrip(R4(R,(s,/usr/libexec/kcare/python/kcarectl/doctor.pyR�s((R,R((R,s,/usr/libexec/kcare/python/kcarectl/doctor.pyt
read_field�scs.tjtj|�����fd�}|S(s�`grep <pattern> <path>` as a doctor.json list-of-lines field.

    Match on bytes (like collect_apt_sources) so a non-utf8 byte cannot
    lose a line; the matched lines are decoded leniently for the JSON.
    csrtjj��sdSt�d��}|j�j�}WdQXg|D]'}�j|�rG|jdd�^qGS(NR.sutf-8R=(	R0R,R1R:R2R3t
splitlinestsearchR>(R4tlinestline(R,tregex(s,/usr/libexec/kcare/python/kcarectl/doctor.pyR�s
(tretcompileRtbstr(R,tpatternR((R,REs,/usr/libexec/kcare/python/kcarectl/doctor.pyt
grep_field�s
cs��fd�}|S(s@`run "<cmd>"` captured as a doctor.json field instead of a file.csGt�dtdt�\}}}|p*dj�}�rC|j�S|S(Ntcatch_stdouttcatch_stderrt(R	tTrueR?RA(t_tstdoutttext(targvtas_lines(s,/usr/libexec/kcare/python/kcarectl/doctor.pyR�s!((RRRSR((RRRSs,/usr/libexec/kcare/python/kcarectl/doctor.pyt	cmd_field�scCstS(N(tDOCTOR_VERSION(((s,/usr/libexec/kcare/python/kcarectl/doctor.pytcollect_doctor_version�scCsNy5tjtjd��}tj|j��j�SWntk
rIdSXdS(s�the public IP of the machine as seen by the patch server.

    Cached: the main_ip and server_id fields share one HTTP roundtrip
    per run.
    tmyiptNAN(RturlopenRtget_patch_server_urltnstrR3R?R (tresponse((s,/usr/libexec/kcare/python/kcarectl/doctor.pytget_main_ip�s

cCs7tj�}|s*t�jdd�}ntj|�S(Nt.RO(Rtget_serveridR]R=RR[(t	server_id((s,/usr/libexec/kcare/python/kcarectl/doctor.pytcollect_server_id�scCs
tj�S(N(Rtget_kernel_hash(((s,/usr/libexec/kcare/python/kcarectl/doctor.pytcollect_kernel_id�scCs\i}xOdD]G}tdd|gdtd	t�\}}}|pGd
j�||<q
W|S(Ntatrtmtptotunamet-RKRLRM(RdReRfRgRh(R	RNR?(tresulttflagRORP((s,/usr/libexec/kcare/python/kcarectl/doctor.pyt
collect_uname�s

+cCs~tjjt�sdSttd��}|j�jdd�}WdQXg|j�D]'}d|krSt	j
dd|�^qSS(s7`grep vmlinuz /boot/grub2/grub.cfg | sed 's/root=.*//'`R.sutf-8R=Ntvmlinuzsroot=.*RM(R0R,R1t	GRUB2_CFGR:R2R3R>RARFtsub(R4RQRD((s,/usr/libexec/kcare/python/kcarectl/doctor.pytcollect_grub2_entries	s
cCsttjt��S(N(tsortedtglobtYUM_REPOS_GLOB(((s,/usr/libexec/kcare/python/kcarectl/doctor.pytcollect_yum_reposscCsCgtjD]\}}|�r
|^q
}i|d6tj�d6S(s8presence-only port of the kcdoctor.sh detect_cp() probestcptsoftaculous(RtCONTROL_PANEL_PROBESthas_softaculous(tnametprobetpanels((s,/usr/libexec/kcare/python/kcarectl/doctor.pytcollect_control_panels+cCs_tddgdtdt�\}}}|j|dtj|pBdjdd�d	d
��dS(s`ipcs -m | sed -e s/-/=/g`tipcss-mRKRLR/RMRjt=tencodingsutf-8N(R	RNR+RRHR=(R#RRORP((s,/usr/libexec/kcare/python/kcarectl/doctor.pytcollect_ipcs%s'cCs�tjjt�s,|jdjt��dSttd��8}g|j�j�D]}d|krQ|^qQ}WdQX|j	|ddj
|�d�dS(s$`grep ' install ' /var/log/dpkg.log`sfile not found: {0}NR.s	 install R/s
(R0R,R1tDPKG_LOGR!R"R2R3RAR+tjoin(R#RR4RDRC((s,/usr/libexec/kcare/python/kcarectl/doctor.pytcollect_dpkg_install_log,s7cCs�tjjd�s$tjjd�r-d}n^tjjd�r�d}yt|d�Wq�tk
r�}|jdj|��q�Xnd}|j||�dS(	Ns/usr/bin/rpms/bin/rpmsFrpm -q -a --queryformat="%{N}|%{V}-%{R}|%{arch}|%{INSTALLTIME:date}\n"s
/usr/bin/dpkgsJ/usr/bin/dpkg-query -W -f "${binary:Package}|${Version}|${Architecture}\n"sdpkg.logsfailed to collect dpkg.log: {0}secho "unknown package manager"(R0R,R1R�R R!R"R'(R#Rtpackages_cmdR$((s,/usr/libexec/kcare/python/kcarectl/doctor.pytcollect_packages9s$	c
s�tjd��g}x�ttjt��D]n}tjj|�r�xStj|�D]2\�}}|j	�fd�t|�D��qSWq+|j
|�q+W|s�|jdjt��dSg}x�|D]�}y(t
|d��}|j�}WdQXWn/tk
r)}	|jdj||	��q�nXtjdj|�dd	��|j	��fd
�|j�D��q�W|j|ddj|�d�dS(
s/`grep -rE '^(deb|URIs)' /etc/apt/sources.list*`s^(deb|URIs)c3s$|]}tjj�|�VqdS(N(R0R,R�(t.0Rz(troot(s,/usr/libexec/kcare/python/kcarectl/doctor.pys	<genexpr>Ussfile not found: {0}NR.sfailed to read {0}: {1}s{0}:R�sutf-8c3s(|]}�j|�r�|VqdS(N(RB(R�RD(tprefixRE(s,/usr/libexec/kcare/python/kcarectl/doctor.pys	<genexpr>jsR/s
(RFRGRrRstAPT_SOURCES_GLOBR0R,tisdirtwalktextendtappendR!R"R2R3R RRHRAR+R�(
R#RtfilesR,ROtnamesRCR4tcontentR$((R�RER�s,/usr/libexec/kcare/python/kcarectl/doctor.pytcollect_apt_sourcesLs**
*c	Cs
ttjt��}|s5|jdjt��dSg}x�|D]�}y3t|d��}|j�j�t}WdQXWn/t	k
r�}|jdj||��qBnXt
jdj|�dd�}|j|dj
|��qBW|j|d	dj
|�d�dS(
s%`tail -n10000 /var/log/libcare/*.log`sfile not found: {0}NR.sfailed to read {0}: {1}s==> {0} <==
R�sutf-8s
R/(RrRstLIBCARE_LOGS_GLOBR!R"R2R3RAtLOG_TAIL_LINESR RRHR�R�R+(	R#RtpathstchunksR,R4RCR$theader((s,/usr/libexec/kcare/python/kcarectl/doctor.pytcollect_libcare_logsos
!cs�tjjtj�sdS|j|djtj��x�tjtj�D]�\}}}x|t|�D]n�t	�fd�t
D��rdtjj|��}tjj|tj�}|j
dj|�d|�qdqdWqHWdS(s3crashreporter artifacts from /var/cache/kcare/dumpsNs
ls -lR {0}c3s!|]}tj�|�VqdS(N(tfnmatch(R�RI(Rz(s,/usr/libexec/kcare/python/kcarectl/doctor.pys	<genexpr>�sscrashreporter/{0}R*(R0R,R�Rt
KDUMPS_DIRR'R"R�RrtanytCRASH_DUMP_PATTERNSR�trelpathR+(R#RR�ROR�R,trel_path((Rzs,/usr/libexec/kcare/python/kcarectl/doctor.pytcollect_crash_dumps�s"cCs�tjjt�sdStj�}tjj|�s8dS|j|dj|��x{t	t
j
tjj|d���D]U}tjj|�s�qvn|jdjtjj
|��dtjj|d��qvWdS(Ns
ls -lR {0}t*skdump/{0}/vmcore-dmesg.txtR*svmcore-dmesg.txt(R0R,R1t
KDUMP_CONFRtget_kdump_rootR�R'R"RrRsR�R+tbasename(R#Rt
kdump_roottevt((s,/usr/libexec/kcare/python/kcarectl/doctor.pyt
collect_kdump�s+c	sg}x�tjt�D]�\}}}|jt�rAg|(qnx�t|�D]��t�fd�tD��rNtjj	|��}y(t
|d��}|j�}WdQXWntk
r�d}nX|j
tjdj|��|d�qNqNWqW|j|ddj	|��dS(sGtunables gathered by the kcdoctor.sh get_sysfs_info() `find /sys` callsc3s!|]}tj�|�VqdS(N(R�(R�RI(Rz(s,/usr/libexec/kcare/python/kcarectl/doctor.pys	<genexpr>�sR.NRMscat {0}
s
R/(R0R�t
SYSFS_ROOTt
startswithtSYSFS_EXCLUDE_PREFIXESRrR�tSYSFS_NAME_PATTERNSR,R�R2R3R R�RRHR"R+(	R#RR�R�tdirsR�R,R4R�((Rzs,/usr/libexec/kcare/python/kcarectl/doctor.pytcollect_sysfs_config�s

2tdoctor_versiont	virt_whats/usr/libexec/kcare/virt-whatRStmain_ipR`t	kernel_idtdateRitredhat_releases/etc/redhat-releasetdebian_versions/etc/debian_versiont
os_releases/etc/os-releasetissues
/etc/issuetsysconfig_kernels/etc/sysconfig/kerneltproc_uptimes/proc/uptimetproc_loadavgs
/proc/loadavgtproc_cmdlines
/proc/cmdlinetproc_versions
/proc/versiontdefault_grubs/etc/default/grubtDEFAULTt
grub2_entriest	sshd_ports/etc/ssh/sshd_configtPorttyum_repos_dt
control_paneltsyslogstail -n{0} /var/log/syslogtdmesgtmessagesstail -n{0} /var/log/messagestls_var_cache_kcaresls -lR /var/cache/kcare/s
kcare.confs/etc/sysconfig/kcare/kcare.conftcpuinfoscat /proc/cpuinfotproc_vmstats/proc/vmstattproc_devicess
/proc/devicestproc_diskstatss/proc/diskstatstproc_mdstats/proc/mdstattproc_meminfos
/proc/meminfot
proc_swapss/proc/swapstproc_filesystemss/proc/filesystemstproc_mountss/proc/mountstproc_interruptss/proc/interruptss	grub.confs/boot/grub/grub.conftproc_moduless
/proc/moduless	grub2.cfgt
proc_zoneinfos/proc/zoneinfotls_boot_configss:ls /etc/grub.conf /boot/grub/grub.conf /boot/grub/menu.lsttls_bootsls -l /boottprintenvt	dmidecodeR~tsysctls	sysctl -assysctl.confs/etc/sysctl.confs
packages.listtlspcis	lspci -vvtdpkg_lsdpkg -ltapt_sourcessyum.confs
/etc/yum.conftyum_repolistsyum repolisttlibcare_logsskcarectl.logs tail -n{0} /var/log/kcarectl.logs
kdump.confs
kcare-crons/etc/cron.d/kcare-cronscrashreporter/lsskdump/lst	aa_statuss	aa-statustsestatustkprobes_lists"cat /sys/kernel/debug/kprobes/listtsysfs_configtlsblkslsblk -ftdfsdf -htloggercCsot�}|�Zi}xtD]}|j||�qW|jd|�xtD]}|j|�qNWWdQX|S(Nsdoctor.json(RtFIELD_SPECSR%tadd_jsont
FILE_SPECS(R#R;tfieldtspec((s,/usr/libexec/kcare/python/kcarectl/doctor.pytprepare_doctor_reports	

c	CsB|stjrH|rdnd}tjdj|�dt�|�dStj�dkrxtjddt�|�dSt	�}|dkr�tj
d�|�dSz�yB|j�}tjdj|�dt�tj
d	j|��WnBtttjtjfk
r.}tj
d
j|��|�nXWd|j�XdS(s�Collect and upload the doctor report via the generic uploads proxy.

    PUTs the archive to ``/upload/kcarectl-doctor/`` -- the same modern
    pipeline as ``kernel-anomaly`` -- which ePortal proxies transparently
    to the patch server, so no ePortal change is required. Any 2xx reply
    is success, including the ``REDUCED_REPORT`` ``204`` where the proxy
    intentionally drops the report (``send()`` returns without raising, so
    we do not fall back).

    Falls back to the legacy ``kcdoctor.sh`` flow (``fallback``) when:

    * ``force_fallback`` (the ``--doctor --fallback`` CLI flag) or
      ``config.FORCE_DOCTOR_FALLBACK`` is set -- the rollout kill-switch.
      ``--fallback`` is the one-off, per-invocation form; the config knob
      is settable per host in kcare.conf or pushed fleet-wide via the
      ``KC-Flag-Force-Doctor-Fallback`` feature flag. Either forces the
      legacy flow on every host, registered or not, before the new path
      is even considered;
    * the host is not registered, i.e. there is no auth string (OQ-4: the
      proxy upload requires auth, so the new path is not even attempted);
    * report collection failed (``prepare_doctor_report`` returned None);
    * the new route is unavailable on an older patch server / ePortal --
      a 404 / 405 / 403, surfaced as ``HTTPError``, or a connection-level
      failure. ``send()`` drives ``http_utils.upload_file`` (raw
      ``httplib``, not ``urllib``), so transport failures surface as an
      ``OSError`` subclass -- ``socket.timeout``, ``ConnectionRefused``,
      ``socket.gaierror`` (DNS), ``ssl.SSLError`` -- or an
      ``httplib.HTTPException``, *not* ``URLError``; all of these mean the
      new path is unusable. ``upload_file`` raises only on status >= 400,
      so a redirect is not treated as a failure; the proxy and patch
      server never redirect uploads.

    :param fallback: legacy ``kcdoctor.sh`` runner, injected by the caller
        (KPT-6065) to keep this module free of an ``__init__`` import cycle.
    :param force_fallback: when True (``--doctor --fallback``), skip the v2
        path and run ``fallback`` directly; the per-invocation form of
        ``config.FORCE_DOCTOR_FALLBACK``.
    s--fallback requestedsFORCE_DOCTOR_FALLBACK is sets.doctor: {0}; using the legacy kcdoctor.sh flowt	print_msgNsAdoctor: host is not registered; using the legacy kcdoctor.sh flowsCdoctor: report collection failed; using the legacy kcdoctor.sh flowsdoctor: report uploaded as {0}s,Please provide this filename to support: {0}sJdoctor: report upload unavailable ({0}); using the legacy kcdoctor.sh flow(RtFORCE_DOCTOR_FALLBACKRtloginfoR"tFalseRtget_http_auth_stringR:R�tlogwarntsendRt
print_wrapperR
RRt
HTTPExceptiontsocketterrortremove_archive(tfallbacktforce_fallbacktsrcR#tupload_nameterr((s,/usr/libexec/kcare/python/kcarectl/doctor.pytsend_doctor_report-s6)	
!(senable*snr_*smax_*s*cnt*(s /sys/kernel/debug/tracing/eventss/sys/kernel/tracing/eventss/sys/devices(s
[0-9]*.logskmsg*log(NR&R�RsR0RFR�tkcarectlRRRRRRRRRtkcarectl.process_utilsR	t
kcarectl.py23R
RRR�ttypingR
RRRRRURoR�R�R�RtR�R�R�R�R�R�tDataPackageRtobjectRR)R-R5R7R8R@RJRTRVtcachedR]RaRcRmRqRuR}R�R�R�R�R�R�R�R�RNR�R"R�tcatch_errorsR�R�R�(((s,/usr/libexec/kcare/python/kcarectl/doctor.pyt<module>s�@+
						
		
		
			
		
		#