
Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­
<!DOCTYPE html>
<html>
3
Ö;j _  ã            .   @   s   d Z ddlZddlZddlZddlZddlZddlmZmZm	Z	m
Z
mZmZmZmZmZ ddlmZ ddlmZmZmZ dZdZdZd	Zd
ZdZdZdZdZdÂZdÃZ dÄZ!G dd„ de	j"ƒZ#G dd„ de$ƒZ%dd„ Z&dd„ Z'd d!„ Z(d"d#„ Z)G d$d%„ d%e$ƒZ*d&d'„ Z+d(d)„ Z,dÅd+d,„Z-d-d.„ Z.ej/d/d0„ ƒZ0d1d2„ Z1d3d4„ Z2d5d6„ Z3d7d8„ Z4d9d:„ Z5d;d<„ Z6d=d>„ Z7d?d@„ Z8dAdB„ Z9dCdD„ Z:dEdF„ Z;dGdH„ Z<dIdJ„ Z=dKdL„ Z>e*dMe.ƒe*dNe-dOgdPdQ�ƒe*dRe0ƒe*dSe1ƒe*dTe2ƒe*dUe-dUgƒƒe*dVe3ƒe*dWe+dXƒƒe*dYe+dZƒƒe*d[e+d\ƒƒe*d]e+d^ƒƒe*d_e+d`ƒƒe*dae+dbƒƒe*dce+ddƒƒe*dee+dfƒƒe*dge+dhƒƒe*die,djdkƒƒe*dle4ƒe*dme,dndoƒƒe*dpe5ƒe*dqe6ƒgZ?e&drdsj@eƒƒe&dtdtƒe&dudvj@eƒƒe&dwdxƒe'dydzƒe&d{d|ƒe(d}d~ƒe(dd€ƒe(d�d‚ƒe(dƒd„ƒe(d…d†ƒe(d‡dˆƒe(d‰dŠƒe(d‹dŒƒe(d�dŽƒe'd�d�ƒe(d‘d’ƒe'd“eƒe(d”d•ƒe&d–d—ƒe&d˜d™ƒe&dšdšƒe&d›d›ƒe)dœe7ƒe&d�džƒe'dŸd ƒe)d¡e9ƒe&d¢d£ƒe&d¤d¥ƒe)d¦e:ƒe'd§d¨ƒe&d©dªƒe)d«e;ƒe&d¬d­j@eƒƒe'd®eƒe'd¯d°ƒe)d±e<ƒe)d²e=ƒe&d³d´ƒe&dµdµƒe&d¶d·ƒe)d¸e>ƒe&d¹dºƒe&d»d¼ƒg,ZAejBejCd½�d¾d¿„ ƒZDdÆdÀdÁ„ZEdS )ÇaO  Doctor 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.
é    N)	ÚauthÚconfigÚdelivery_kitÚ
http_utilsÚkcareÚ	log_utilsÚplatform_utilsÚserveridÚutils)Úrun_command)Ú	HTTPErrorÚURLErrorÚhttplibz2.0-1z/boot/grub2/grub.cfgz/etc/kdump.confz/var/log/dpkg.logz/etc/apt/sources.list*z/etc/yum.repos.d/*z/var/log/libcare/*.logi'  z/sysúenable*únr_*úmax_*ú*cnt*ú /sys/kernel/debug/tracing/eventsú/sys/kernel/tracing/eventsú/sys/devicesú
[0-9]*.logúkmsg*logc               @   s    e Zd ZdZdZedd„ ƒZdS )ÚKcarectlDoctorPackagezkcarectl-doctorz/upload/kcarectl-doctor/c             C   s   t jS )N)r   ÚDOCTOR_REPORT_MAX_SIZE_BYTES)Úself© r   ú,/usr/libexec/kcare/python/kcarectl/doctor.pyÚmax_size;   s    zKcarectlDoctorPackage.max_sizeN)Ú__name__Ú
__module__Ú__qualname__Ú	data_typeÚ
upload_uriÚpropertyr   r   r   r   r   r   7   s   r   c               @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚCollectionSpeczé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.
    c             C   s   || _ || _d S )N)ÚarcnameÚ_collect)r   r%   Úcollectr   r   r   Ú__init__L   s    zCollectionSpec.__init__c             C   sN   y| j || jƒ W n6 tk
rH } z|jdj| j|ƒƒ W Y d d }~X nX d S )Nzfailed to collect {0}: {1})r&   r%   Ú	ExceptionÚ	log_errorÚformat)r   Údata_packageÚer   r   r   ÚapplyQ   s    zCollectionSpec.applyN)r   r   r    Ú__doc__r(   r.   r   r   r   r   r$   D   s   r$   c                s   ‡ fdd„}t | |ƒS )z4`run "<cmd>"` kcdoctor.sh helper (no shell features)c                s   | j |ˆ ƒ d S )N)Ú
add_stdout)r,   r%   )Úcmdr   r   r'   ]   s    zrun_spec.<locals>.collect)r$   )r%   r1   r'   r   )r1   r   Úrun_specY   s    r2   c                s   ‡ fdd„}t | |ƒS )z4`dump "<path>"` kcdoctor.sh helper for regular filesc                s   | j |ˆ d� d S )N)Úsrc_path)Úadd_file)r,   r%   )Úpathr   r   r'   h   s    zdump_spec.<locals>.collect)r$   )r%   r5   r'   r   )r5   r   Ú	dump_specd   s    r6   c                s   ‡ fdd„}t | |ƒS )z·`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).
    c                sL   t jjˆ ƒs | jdjˆ ƒƒ d S tˆ dƒ�}| j||jƒ d� W d Q R X d S )Nzfile not found: {0}Úrb)Ú
data_bytes)Úosr5   Úexistsr*   r+   Úopenr4   Úread)r,   r%   Úf)r5   r   r   r'   w   s
    zproc_dump_spec.<locals>.collect)r$   )r%   r5   r'   r   )r5   r   Úproc_dump_speco   s    	r>   c             C   s
   t | |ƒS )N)r$   )r%   Úfnr   r   r   Úcallable_specƒ   s    r@   c               @   s    e Zd ZdZdd„ Zdd„ ZdS )Ú	FieldSpecz÷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).
    c             C   s   || _ || _d S )N)Úkeyr&   )r   rB   r'   r   r   r   r(   “   s    zFieldSpec.__init__c             C   sX   y| j ƒ }W n4 tk
r@ } z|jdj| j|ƒƒ d S d }~X nX |d k	rT||| j< d S )Nzfailed to collect {0}: {1})r&   r)   r*   r+   rB   )r   r,   ÚreportÚvaluer-   r   r   r   r.   ˜   s    zFieldSpec.applyN)r   r   r    r/   r(   r.   r   r   r   r   rA   ‹   s   rA   c                s   ‡ fdd„}|S )z·`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).
    c           
      s:   t jjˆ ƒsd S tˆ dƒ�} | jƒ jddƒjƒ S Q R X d S )Nr7   zutf-8Úreplace)r9   r5   r:   r;   r<   ÚdecodeÚstrip)r=   )r5   r   r   r'   ¬   s    zread_field.<locals>.collectr   )r5   r'   r   )r5   r   Ú
read_field¤   s    rH   c                s"   t jtj|ƒƒ‰‡ ‡fdd„}|S )zÒ`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.
    c           
      sD   t jjˆ ƒsd S tˆ dƒ�} | jƒ jƒ }W d Q R X ‡fdd„|D ƒS )Nr7   c                s"   g | ]}ˆ j |ƒr|jd dƒ‘qS )zutf-8rE   )ÚsearchrF   )Ú.0Úline)Úregexr   r   ú
<listcomp>È   s    z/grep_field.<locals>.collect.<locals>.<listcomp>)r9   r5   r:   r;   r<   Ú
splitlines)r=   Úlines)r5   rL   r   r   r'   À   s
    zgrep_field.<locals>.collect)ÚreÚcompiler
   Úbstr)r5   Úpatternr'   r   )r5   rL   r   Ú
grep_field·   s    
rT   Fc                s   ‡ ‡fdd„}|S )z@`run "<cmd>"` captured as a doctor.json field instead of a file.c                 s0   t ˆ ddd�\} }} |pdjƒ }ˆr,|jƒ S |S )NT)Úcatch_stdoutÚcatch_stderrÚ )r   rG   rN   )Ú_ÚstdoutÚtext)ÚargvÚas_linesr   r   r'   Ñ   s    zcmd_field.<locals>.collectr   )r[   r\   r'   r   )r[   r\   r   Ú	cmd_fieldÍ   s    r]   c               C   s   t S )N)ÚDOCTOR_VERSIONr   r   r   r   Úcollect_doctor_versionÚ   s    r_   c              C   s<   y"t jtjdƒƒ} tj| jƒ ƒjƒ S  tk
r6   dS X dS )z’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.
    ZmyipZNAN)r   Úurlopenr
   Úget_patch_server_urlÚnstrr<   rG   r)   )Úresponser   r   r   Úget_main_ipß   s
    rd   c              C   s$   t jƒ } | stƒ jddƒ} tj| ƒS )NÚ.rX   )r	   Úget_serveridrd   rE   r
   rb   )Ú	server_idr   r   r   Úcollect_server_idî   s    rh   c               C   s   t jƒ S )N)r   Úget_kernel_hashr   r   r   r   Úcollect_kernel_idø   s    rj   c              C   sB   i } x8dD ]0}t dd| gddd	�\}}}|p0d
jƒ | |< q
W | S )NÚaÚrÚmÚpÚoÚunameú-T)rU   rV   rW   )rk   rl   rm   rn   ro   )r   rG   )ÚresultÚflagrX   rY   r   r   r   Úcollect_unameÿ   s
    
rt   c           
   C   sH   t jjtƒsdS ttdƒ�} | jƒ jddƒ}W dQ R X dd„ |jƒ D ƒS )z7`grep vmlinuz /boot/grub2/grub.cfg | sed 's/root=.*//'`Nr7   zutf-8rE   c             S   s"   g | ]}d |krt jdd|ƒ‘qS )Zvmlinuzzroot=.*rW   )rP   Úsub)rJ   rK   r   r   r   rM     s    z)collect_grub2_entries.<locals>.<listcomp>)r9   r5   r:   Ú	GRUB2_CFGr;   r<   rF   rN   )r=   rZ   r   r   r   Úcollect_grub2_entries	  s
    rw   c               C   s   t tjtƒƒS )N)ÚsortedÚglobÚYUM_REPOS_GLOBr   r   r   r   Úcollect_yum_repos  s    r{   c              C   s   dd„ t jD ƒ} | t jƒ dœS )z8presence-only port of the kcdoctor.sh detect_cp() probesc             S   s   g | ]\}}|ƒ r|‘qS r   r   )rJ   ÚnameÚprober   r   r   rM     s    z)collect_control_panel.<locals>.<listcomp>)ÚcpZsoftaculous)r   ÚCONTROL_PANEL_PROBESÚhas_softaculous)Zpanelsr   r   r   Úcollect_control_panel  s    r�   c             C   s@   t ddgddd�\}}}| j|tj|p(djddƒdd	�d
� dS )z`ipcs -m | sed -e s/-/=/g`Úipcsz-mT)rU   rV   rW   rq   ú=zutf-8)Úencoding)r8   N)r   r4   r
   rR   rE   )r,   r%   rX   rY   r   r   r   Úcollect_ipcs%  s    r…   c             C   sh   t jjtƒs | jdjtƒƒ dS ttdƒ�}dd„ |jƒ jƒ D ƒ}W dQ R X | j	|dj
|ƒd d� dS )z$`grep ' install ' /var/log/dpkg.log`zfile not found: {0}Nr7   c             S   s   g | ]}d |kr|‘qS )s	    install r   )rJ   rK   r   r   r   rM   4  s    z,collect_dpkg_install_log.<locals>.<listcomp>ó   
)r8   )r9   r5   r:   ÚDPKG_LOGr*   r+   r;   r<   rN   r4   Újoin)r,   r%   r=   rO   r   r   r   Úcollect_dpkg_install_log,  s     r‰   c             C   s†   t jjdƒst jjdƒrd}nXt jjdƒrrd}yt| dƒ W qv tk
rn } z| jdj|ƒƒ W Y d d }~X qvX nd}| j||ƒ d S )	Nz/usr/bin/rpmz/bin/rpmzFrpm -q -a --queryformat="%{N}|%{V}-%{R}|%{arch}|%{INSTALLTIME:date}\n"z/usr/bin/dpkgzJ/usr/bin/dpkg-query -W -f "${binary:Package}|${Version}|${Architecture}\n"zdpkg.logzfailed to collect dpkg.log: {0}zecho "unknown package manager")r9   r5   r:   r‰   r)   r*   r+   r0   )r,   r%   Úpackages_cmdr-   r   r   r   Úcollect_packages9  s    $r‹   c       
         sF  t jdƒ‰g }xdttjtƒƒD ]R}tjj|ƒrfx@tj|ƒD ]&\‰}}|j	‡fdd„t|ƒD ƒƒ q:W q|j
|ƒ qW |sŒ| jdjtƒƒ dS g }x˜|D ]�}y"t|dƒ�}|jƒ }W dQ R X W n6 tk
rò }	 z| jdj||	ƒƒ w–W Y dd}	~	X nX tjdj|ƒd	d
�‰ |j	‡ ‡fdd„|jƒ D ƒƒ q–W | j|dj|ƒd d� dS )z/`grep -rE '^(deb|URIs)' /etc/apt/sources.list*`s   ^(deb|URIs)c             3   s   | ]}t jjˆ |ƒV  qd S )N)r9   r5   rˆ   )rJ   r|   )Úrootr   r   ú	<genexpr>U  s    z&collect_apt_sources.<locals>.<genexpr>zfile not found: {0}Nr7   zfailed to read {0}: {1}z{0}:zutf-8)r„   c             3   s    | ]}ˆj |ƒrˆ | V  qd S )N)rI   )rJ   rK   )ÚprefixrL   r   r   r�   j  s    r†   )r8   )rP   rQ   rx   ry   ÚAPT_SOURCES_GLOBr9   r5   ÚisdirÚwalkÚextendÚappendr*   r+   r;   r<   r)   r
   rR   rN   r4   rˆ   )
r,   r%   Úfilesr5   rX   ÚnamesrO   r=   Úcontentr-   r   )rŽ   rL   rŒ   r   Úcollect_apt_sourcesL  s*    
"
"r—   c       	      C   sä   t tjtƒƒ}|s&| jdjtƒƒ dS g }xœ|D ]”}y0t|dƒ�}|jƒ jƒ t d… }W dQ R X W n6 t	k
rš } z| jdj||ƒƒ w0W Y dd}~X nX t
jdj|ƒdd�}|j|dj|ƒ ƒ q0W | j|dj|ƒd d	� dS )
z%`tail -n10000 /var/log/libcare/*.log`zfile not found: {0}Nr7   zfailed to read {0}: {1}z==> {0} <==
zutf-8)r„   r†   )r8   )rx   ry   ÚLIBCARE_LOGS_GLOBr*   r+   r;   r<   rN   ÚLOG_TAIL_LINESr)   r
   rR   r“   rˆ   r4   )	r,   r%   ÚpathsÚchunksr5   r=   rO   r-   Úheaderr   r   r   Úcollect_libcare_logso  s    
$r�   c                s    t jjtjƒsdS | j|djtjƒƒ xtt jtjƒD ]d\}}}xXt|ƒD ]L‰ t	‡ fdd„t
D ƒƒrHt jj|ˆ ƒ}t jj|tjƒ}| jdj|ƒ|d� qHW q4W dS )z3crashreporter artifacts from /var/cache/kcare/dumpsNz
ls -lR {0}c             3   s   | ]}t j ˆ |ƒV  qd S )N)Úfnmatch)rJ   rS   )r|   r   r   r�   ’  s    z&collect_crash_dumps.<locals>.<genexpr>zcrashreporter/{0})r3   )r9   r5   r�   r   Ú
KDUMPS_DIRr0   r+   r‘   rx   ÚanyÚCRASH_DUMP_PATTERNSrˆ   Úrelpathr4   )r,   r%   rŒ   rX   r•   r5   Zrel_pathr   )r|   r   Úcollect_crash_dumps‰  s    r£   c             C   s”   t jjtƒsd S tjƒ }t jj|ƒs(d S | j|dj|ƒƒ xTt	t
j
t jj|dƒƒƒD ]8}t jj|ƒsfqT| jdjt jj|ƒƒt jj|dƒd� qTW d S )Nz
ls -lR {0}Ú*zkdump/{0}/vmcore-dmesg.txtzvmcore-dmesg.txt)r3   )r9   r5   r:   Ú
KDUMP_CONFr   Úget_kdump_rootr�   r0   r+   rx   ry   rˆ   r4   Úbasename)r,   r%   Ú
kdump_rootZevtr   r   r   Úcollect_kdump›  s    r©   c       	         sÞ   g }xÀt jtƒD ]²\}}}|jtƒr2g |dd…< qxŽt|ƒD ]‚‰ t‡ fdd„tD ƒƒr<t jj	|ˆ ƒ}y"t
|dƒ�}|jƒ }W dQ R X W n tk
rž   d}Y nX |jtjdj|ƒƒ| d ƒ q<W qW | j|dj	|ƒd� dS )	zGtunables gathered by the kcdoctor.sh get_sysfs_info() `find /sys` callsNc             3   s   | ]}t j ˆ |ƒV  qd S )N)rž   )rJ   rS   )r|   r   r   r�   ¾  s    z'collect_sysfs_config.<locals>.<genexpr>r7   ó    zcat {0}
r†   )r8   )r9   r‘   Ú
SYSFS_ROOTÚ
startswithÚSYSFS_EXCLUDE_PREFIXESrx   r    ÚSYSFS_NAME_PATTERNSr5   rˆ   r;   r<   r)   r“   r
   rR   r+   r4   )	r,   r%   r›   rŒ   Údirsr•   r5   r=   r–   r   )r|   r   Úcollect_sysfs_config´  s    

&r°   Zdoctor_versionZ	virt_whatz/usr/libexec/kcare/virt-whatT)r\   Zmain_iprg   Z	kernel_idÚdaterp   Zredhat_releasez/etc/redhat-releaseZdebian_versionz/etc/debian_versionZ
os_releasez/etc/os-releaseZissuez
/etc/issueZsysconfig_kernelz/etc/sysconfig/kernelZproc_uptimez/proc/uptimeZproc_loadavgz/proc/loadavgZproc_cmdlinez/proc/cmdlineÚproc_versionz/proc/versionZdefault_grubz/etc/default/grubÚDEFAULTZgrub2_entriesZ	sshd_portz/etc/ssh/sshd_configZPortZyum_repos_dZcontrol_panelÚsyslogztail -n{0} /var/log/syslogÚdmesgÚmessagesztail -n{0} /var/log/messagesÚls_var_cache_kcarezls -lR /var/cache/kcare/z
kcare.confz/etc/sysconfig/kcare/kcare.confÚcpuinfozcat /proc/cpuinfoZproc_vmstatz/proc/vmstatZproc_devicesz/proc/devicesZproc_diskstatsz/proc/diskstatsZproc_mdstatz/proc/mdstatZproc_meminfoz/proc/meminfoZ
proc_swapsz/proc/swapsZproc_filesystemsz/proc/filesystemsZproc_mountsz/proc/mountsZproc_interruptsz/proc/interruptsz	grub.confz/boot/grub/grub.confÚproc_modulesz/proc/modulesz	grub2.cfgZproc_zoneinfoz/proc/zoneinfoZls_boot_configsz:ls /etc/grub.conf /boot/grub/grub.conf /boot/grub/menu.lstZls_bootzls -l /bootZprintenvZ	dmidecoder‚   Úsysctlz	sysctl -azsysctl.confz/etc/sysctl.confzpackages.listZlspciz	lspci -vvZdpkg_lzdpkg -lZapt_sourceszyum.confz/etc/yum.confZyum_repolistzyum repolistZlibcare_logszkcarectl.logz tail -n{0} /var/log/kcarectl.logz
kdump.confz
kcare-cronz/etc/cron.d/kcare-cronzcrashreporter/lszkdump/lsZ	aa_statusz	aa-statusZsestatusZkprobes_listz"cat /sys/kernel/debug/kprobes/listZsysfs_configZlsblkzlsblk -fZdfzdf -h)Úloggerc              C   s\   t ƒ } | �H i }xtD ]}|j| |ƒ qW | jd|ƒ xtD ]}|j| ƒ q<W W d Q R X | S )Nzdoctor.json)r   ÚFIELD_SPECSr.   Úadd_jsonÚ
FILE_SPECS)r,   rC   ÚfieldÚspecr   r   r   Úprepare_doctor_report  s    

rÁ   c             C   s  |s
t jr4|rdnd}tjdj|ƒdd� | ƒ  dS tjƒ dkrXtjddd� | ƒ  dS tƒ }|dkrztjdƒ | ƒ  dS zzy0|j	ƒ }tjd	j|ƒdd� t
jd
j|ƒƒ W nD tttjtjfk
rð } ztjdj|ƒƒ | ƒ  W Y dd}~X nX W d|jƒ  X dS )aµ  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``.
    z--fallback requestedzFORCE_DOCTOR_FALLBACK is setz.doctor: {0}; using the legacy kcdoctor.sh flowF)Ú	print_msgNzAdoctor: host is not registered; using the legacy kcdoctor.sh flowzCdoctor: report collection failed; using the legacy kcdoctor.sh flowzdoctor: report uploaded as {0}z,Please provide this filename to support: {0}zJdoctor: report upload unavailable ({0}); using the legacy kcdoctor.sh flow)r   ÚFORCE_DOCTOR_FALLBACKr   Úloginfor+   r   Úget_http_auth_stringrÁ   ÚlogwarnÚsendr
   Úprint_wrapperr   r   r   ÚHTTPExceptionÚsocketÚerrorÚremove_archive)ÚfallbackÚforce_fallbackÚsrcr,   Úupload_nameÚerrr   r   r   Úsend_doctor_report-  s4    )

rÒ   )r   r   r   r   )r   r   r   )r   r   )F)F)Fr/   rž   ry   r9   rP   rÊ   Úkcarectlr   r   r   r   r   r   r   r	   r
   Zkcarectl.process_utilsr   Zkcarectl.py23r   r   r   r^   rv   r¥   r‡   r�   rz   r˜   r™   r«   r®   r­   r¡   ÚDataPackager   Úobjectr$   r2   r6   r>   r@   rA   rH   rT   r]   r_   Úcachedrd   rh   rj   rt   rw   r{   r�   r…   r‰   r‹   r—   r�   r£   r©   r°   r¼   r+   r¾   Úcatch_errorsrÆ   rÁ   rÒ   r   r   r   r   Ú<module>   sæ   ,  



#