
Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­
<!DOCTYPE html>
<html>
3
ôn»jWa  ã            .   @   s4  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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j0d/d0„ ƒZ1d1d2„ Z2d3d4„ Z3d5d6„ Z4d7d8„ Z5d9d:„ Z6d;d<„ Z7d=d>„ Z8d?d@„ Z9dAdB„ Z:dCdD„ Z;dEdF„ Z<dGdH„ Z=dIdJ„ Z>dKdL„ Z?dMdN„ Z@e+dOe/ƒe+dPe.dQgdRdS�ƒe+dTe1ƒe+dUe2ƒe+dVe3ƒe+dWe.dWgƒƒe+dXe4ƒ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,djƒƒe+dke-dldmƒƒe+dne5ƒe+doe-dpdqƒƒe+dre6ƒe+dse7ƒe+dte8ƒgZAe'dudvjBeƒƒe'dwdwƒe'dxdyjBeƒƒe'dzd{ƒ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”d•ƒe(d–eƒe)d—d˜ƒe'd™dšƒe'd›dœƒ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«ƒe'd¬d­ƒe*d®e=ƒe'd¯d°jBeƒƒ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,ZCejDejEdÀ�dÁdÂ„ ƒZFdÉdÃdÄ„ZGd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Úconfig_handlersÚ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_sizeF   s    zKcarectlDoctorPackage.max_sizeN)Ú__name__Ú
__module__Ú__qualname__Ú	data_typeÚ
upload_uriÚpropertyr   r   r   r   r   r   B   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__W   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   Úapply\   s    zCollectionSpec.applyN)r   r    r!   Ú__doc__r)   r/   r   r   r   r   r%   O   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(   h   s    zrun_spec.<locals>.collect)r%   )r&   r2   r(   r   )r2   r   Úrun_specd   s    r3   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(   s   s    zdump_spec.<locals>.collect)r%   )r&   r6   r(   r   )r6   r   Ú	dump_speco   s    r7   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)Úosr6   Úexistsr+   r,   Úopenr5   Úread)r-   r&   Úf)r6   r   r   r(   ‚   s
    zproc_dump_spec.<locals>.collect)r%   )r&   r6   r(   r   )r6   r   Úproc_dump_specz   s    	r?   c             C   s
   t | |ƒS )N)r%   )r&   Úfnr   r   r   Úcallable_specŽ   s    rA   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   rC   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,   rC   )r   r-   ÚreportÚvaluer.   r   r   r   r/   £   s    zFieldSpec.applyN)r   r    r!   r0   r)   r/   r   r   r   r   rB   –   s   rB   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 )Nr8   zutf-8Úreplace)r:   r6   r;   r<   r=   ÚdecodeÚstrip)r>   )r6   r   r   r(   ·   s    zread_field.<locals>.collectr   )r6   r(   r   )r6   r   Ú
read_field¯   s    rI   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 )Nr8   c                s"   g | ]}ˆ j |ƒr|jd dƒ‘qS )zutf-8rF   )ÚsearchrG   )Ú.0Úline)Úregexr   r   ú
<listcomp>Ó   s    z/grep_field.<locals>.collect.<locals>.<listcomp>)r:   r6   r;   r<   r=   Ú
splitlines)r>   Úlines)r6   rM   r   r   r(   Ë   s
    zgrep_field.<locals>.collect)ÚreÚcompiler   Úbstr)r6   Úpatternr(   r   )r6   rM   r   Ú
grep_fieldÂ   s    
rU   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   rH   rO   )Ú_Ú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=   rH   r*   )Úresponser   r   r   Úget_main_ipê   s
    re   c              C   s$   t jƒ } | stƒ jddƒ} tj| ƒS )NÚ.rY   )r
   Úget_serveridre   rF   r   rc   )Ú	server_idr   r   r   Úcollect_server_idù   s    ri   c               C   s   t jƒ S )N)r   Úget_kernel_hashr   r   r   r   Úcollect_kernel_id  s    rk   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)rV   rW   rX   )rl   rm   rn   ro   rp   )r   rH   )ÚresultÚflagrY   rZ   r   r   r   Úcollect_uname
  s
    
ru   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=.*//'`Nr8   zutf-8rF   c             S   s"   g | ]}d |krt jdd|ƒ‘qS )Zvmlinuzzroot=.*rX   )rQ   Úsub)rK   rL   r   r   r   rN     s    z)collect_grub2_entries.<locals>.<listcomp>)r:   r6   r;   Ú	GRUB2_CFGr<   r=   rG   rO   )r>   r[   r   r   r   Úcollect_grub2_entries  s
    rx   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   )rK   ÚnameÚprober   r   r   rN   )  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 tjƒpdS )zÔthe kcare.conf options kcarectl refuses to run on, named with the reason.

    --doctor is exempt from that refusal so a stuck host can still be
    diagnosed; the field is omitted (None) on a usable config.
    N)Údictr   ÚINVALID_CONFIG_OPTIONSr   r   r   r   Úcollect_invalid_config_options-  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)rV   rW   rX   rr   ú=zutf-8)Úencoding)r9   N)r   r5   r   rS   rF   )r-   r&   rY   rZ   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}Nr8   c             S   s   g | ]}d |kr|‘qS )s	    install r   )rK   rL   r   r   r   rN   I  s    z,collect_dpkg_install_log.<locals>.<listcomp>ó   
)r9   )r:   r6   r;   ÚDPKG_LOGr+   r,   r<   r=   rO   r5   Újoin)r-   r&   r>   rP   r   r   r   Úcollect_dpkg_install_logA  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")r:   r6   r;   r�   r*   r+   r,   r1   )r-   r&   Úpackages_cmdr.   r   r   r   Úcollect_packagesN  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)r:   r6   rŒ   )rK   r}   )Úrootr   r   ú	<genexpr>j  s    z&collect_apt_sources.<locals>.<genexpr>zfile not found: {0}Nr8   zfailed to read {0}: {1}z{0}:zutf-8)rˆ   c             3   s    | ]}ˆj |ƒrˆ | V  qd S )N)rJ   )rK   rL   )ÚprefixrM   r   r   r‘     s    rŠ   )r9   )rQ   rR   ry   rz   ÚAPT_SOURCES_GLOBr:   r6   ÚisdirÚwalkÚextendÚappendr+   r,   r<   r=   r*   r   rS   rO   r5   rŒ   )
r-   r&   Úfilesr6   rY   ÚnamesrP   r>   Úcontentr.   r   )r’   rM   r�   r   Úcollect_apt_sourcesa  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}Nr8   zfailed to read {0}: {1}z==> {0} <==
zutf-8)rˆ   rŠ   )r9   )ry   rz   ÚLIBCARE_LOGS_GLOBr+   r,   r<   r=   rO   ÚLOG_TAIL_LINESr*   r   rS   r—   rŒ   r5   )	r-   r&   ÚpathsÚchunksr6   r>   rP   r.   Úheaderr   r   r   Úcollect_libcare_logs„  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)rK   rT   )r}   r   r   r‘   §  s    z&collect_crash_dumps.<locals>.<genexpr>zcrashreporter/{0})r4   )r:   r6   r”   r   Ú
KDUMPS_DIRr1   r,   r•   ry   ÚanyÚCRASH_DUMP_PATTERNSrŒ   Úrelpathr5   )r-   r&   r�   rY   r™   r6   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)r4   )r:   r6   r;   Ú
KDUMP_CONFr   Úget_kdump_rootr”   r1   r,   ry   rz   rŒ   r5   Ú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¢   )rK   rT   )r}   r   r   r‘   Ó  s    z'collect_sysfs_config.<locals>.<genexpr>r8   ó    zcat {0}
rŠ   )r9   )r:   r•   Ú
SYSFS_ROOTÚ
startswithÚSYSFS_EXCLUDE_PREFIXESry   r¤   ÚSYSFS_NAME_PATTERNSr6   rŒ   r<   r=   r*   r—   r   rS   r,   r5   )	r-   r&   rŸ   r�   Údirsr™   r6   r>   rš   r   )r}   r   Úcollect_sysfs_configÉ  s    

&r´   Zdoctor_versionZ	virt_whatz/usr/libexec/kcare/virt-whatT)r]   Zmain_iprh   Z	kernel_idÚdaterq   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_panelZinvalid_config_optionsÚ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-   rD   Ú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_reportD  s4    )

rÖ   )r   r   r   r   )r   r   r   )r   r   )F)F)Hr0   r¢   rz   r:   rQ   rÎ   Úkcarectlr   r   r   r   r   r   r   r	   r
   r   Zkcarectl.process_utilsr   Zkcarectl.py23r   r   r   r_   rw   r©   r‹   r“   r{   rœ   r�   r¯   r²   r±   r¥   ÚDataPackager   Úobjectr%   r3   r7   r?   rA   rB   rI   rU   r^   r`   Úcachedre   ri   rk   ru   rx   r|   r‚   r…   r‰   r�   r�   r›   r¡   r§   r­   r´   rÀ   r,   rÂ   Úcatch_errorsrÊ   rÅ   rÖ   r   r   r   r   Ú<module>   sê   0  


#