
Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­
<!DOCTYPE html>
<html>
3
Ö;j+  ã               @   sœ   d dl Z d dl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 d dl	m
Z
mZmZmZmZmZ d dlmZ dd„ ZG dd„ deƒZG d	d
„ d
eƒZdS )é    N)ÚNamedTemporaryFile)ÚauthÚconfigÚ
http_utilsÚipv6_supportÚ	log_utilsÚutils)Úrun_commandc             C   s<   t | ƒ}x(dD ] }|dk r&dj||ƒS |d }qW dj|ƒS )	zBRender a byte count as a short human-readable string for the logs.ÚBÚKiBÚMiBÚGiBg      �@z{0:.1f} {1}z{0:.1f} TiB)r
   r   r   r   )ÚfloatÚformat)Z	num_bytesÚsizeZunit© r   ú2/usr/libexec/kcare/python/kcarectl/delivery_kit.pyÚformat_size   s    
r   c               @   s¸   e Zd ZdZdZdZdd„ Zedd„ ƒZedd„ ƒZ	d	d
„ Z
d(dd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zejejd!�d"d#„ ƒZd$d%„ Zd&d'„ ZdS ))ÚDataPackagezúGeneric archive package for the patch server uploads pipeline.

    Based on DataPackage from eportal (delivery_kit.py). Subclasses
    supply the manifest `data_type`, the `upload_uri` to PUT the
    archive to and the `max_size` payload limit.
    Ú c             C   s   d | _ g | _d| _d S )Nr   )Ú_tarÚ_errors_bufferÚ_total_payload_size)Úselfr   r   r   Ú__init__-   s    zDataPackage.__init__c             C   s   t ‚d S )N)ÚNotImplementedError)r   r   r   r   Úmax_size3   s    zDataPackage.max_sizec             C   s   | j ƒ }t|jƒS )N)Ú_ensure_tar_createdÚstrÚname)r   Útarr   r   r   Úarchive_path8   s    zDataPackage.archive_pathc             C   sŒ   d }d }yt tj|ƒddd�\}}}W n* tk
rP } zt|ƒ}W Y d d }~X nX |rh| jdj||ƒƒ |d k	rˆ| j|tj	|dd�d� d S )NT)Úcatch_stdoutÚcatch_stderrz!failed to dump stdout of {0}:
{1}zutf-8)Úencoding)Ú
data_bytes)
r	   ÚshlexÚsplitÚ	Exceptionr   Ú	log_errorr   Úadd_filer   Úbstr)r   ÚarcnameÚcmdÚstdoutÚstderrÚ_Úer   r   r   Ú
add_stdout>   s    zDataPackage.add_stdoutNFc       	      C   sh  |d kr|d krt dƒ‚| jƒ }d}|d k	rZtjj|ƒsL| jdj|ƒƒ d S tjj|ƒ}nt|ƒ}| j	|ƒs€| jdj|ƒƒ d S | r¼| j
|ƒ r¼| jdj|t|ƒt| jƒt| jƒƒƒ d S yp|rÒ|j||d� n"tj|ƒ}||_|j|tj|ƒƒ |�s*|  j|7  _tjdj|t|ƒt| jƒƒdd	� W n6 tk
�rb } z| jd
j||ƒƒ W Y d d }~X nX d S )Nz"No src_path or data_bytes providedr   zfile not found: {0}z no available space to store: {0}zPskipping {0}: {1} would exceed the {2} report size limit (already collected {3}))r,   z%collected {0}: {1} (report total {2})F)Ú	print_msgzfailed to store {0}: {1})Ú
ValueErrorr   ÚosÚpathÚexistsr)   r   ÚgetsizeÚlenÚ_check_required_spaceÚ_check_total_payload_limitÚlog_warningr   r   r   ÚaddÚtarfileÚTarInfor   ÚaddfileÚioÚBytesIOr   Úloginfor(   )	r   r,   Úsrc_pathr%   Úskip_limit_checkr    Ú
entry_sizeÚinfor1   r   r   r   r*   N   sJ    


zDataPackage.add_filec             C   sb   yt jtj|dd�dd�}W n2 tk
rN } z| jdj||ƒƒ d S d }~X nX | j||d� d S )Né   )Úindentzutf-8)r$   zfailed to dump {0}:
{1})r%   )r   r+   ÚjsonÚdumpsÚ	TypeErrorr)   r   r*   )r   r,   Údatar%   r1   r   r   r   Úadd_json‰   s    zDataPackage.add_jsonc             C   s   t j| jƒ}|j|j |kS )N)r5   Ústatvfsr!   Úf_frsizeÚf_bfree)r   rF   rO   r   r   r   r:   “   s    z!DataPackage._check_required_spacec             C   s   | j | j| kS )N)r   r   )r   rF   r   r   r   r;   ™   s    z&DataPackage._check_total_payload_limitc             C   s   d| j ttjƒ ƒdœS )Né   )Zschema_versionÚtypeZtime_created)Ú	data_typeÚintÚtime)r   r   r   r   Úmake_manifestž   s    zDataPackage.make_manifestc             C   sN   t jtj| jƒ dd�dd�}| jƒ }tjdƒ}t|ƒ|_	|j
|tj|ƒƒ d S )NrH   )rI   zutf-8)r$   zmanifest.json)r   r+   rJ   rK   rW   r   r>   r?   r9   r   r@   rA   rB   )r   r%   r    rG   r   r   r   Ú_add_manifest¦   s
    

zDataPackage._add_manifestc             C   s&   |j ƒ }tj|dd� | jj|ƒ d S )NF)r3   )Ústripr   Úlogerrorr   Úappend)r   Z	error_msgr   r   r   r)   ³   s    zDataPackage.log_errorc             C   s&   |j ƒ }tj|dd� | jj|ƒ d S )NF)r3   )rY   r   Úlogwarnr   r[   )r   Zwarning_msgr   r   r   r<   ¹   s    zDataPackage.log_warningc             C   sô   xädD ]Ü}t dj|dd … ƒdd�}|jƒ  y6tjdj|jƒdd	� tj|j|d
d�| _| j	ƒ  | S  t
k
rà } zb| jd k	r¨y| jjƒ  W n t
k
r    Y nX d | _tjj|jƒrÂtj|jƒ t|tjƒsÐ‚ W Y d d }~X qX qW tjdƒ‚d S )Núw:xzúw:bz2úw:gzz.tar.{0}é   F)ÚsuffixÚdeletezCreating DataPackage: {0})r3   T)r   ÚmodeZdereferencez%No supported compression method found)r]   r^   r_   )r   r   Úcloser   rC   r   r>   Úopenr   rX   r(   r5   r6   r7   ÚunlinkÚ
isinstanceZCompressionError)r   Zcompression_modeZtmpfileÚerrr   r   r   Ú	__enter__Â   s(    

zDataPackage.__enter__c             C   sP   | j r,dj| j ƒd }| jdtj|ƒdd� | jrL| jjƒ  |rL| jƒ  dS dS )NÚ
z
errors.logT)r%   rE   F)r   Újoinr*   r   r+   r   rd   Úremove_archive)r   Úexc_typeZexc_valÚexc_tbÚerrorsr   r   r   Ú__exit__â   s    
zDataPackage.__exit__)Úloggerc             C   s$   | j r tjj| jƒr tj| jƒ d S )N)r   r5   r6   r7   r!   rf   )r   r   r   r   rl   ð   s    zDataPackage.remove_archivec             C   s   | j stdƒ‚| j S )Nz/DataPackage should be used as a context manager)r   ÚRuntimeError)r   r   r   r   r   ö   s    zDataPackage._ensure_tar_createdc             C   st   | j ƒ jƒ  tjj| jƒ}d|kr4||jdƒd… nd}ttj	ƒ ƒ| }t
jƒ | j | }tj| j|tjƒ d� |S )a  Send the package archive to the patch server.

        Upload errors propagate to the caller (see the eportal
        precedent): wrap with utils.catch_errors where a silent
        failure is acceptable.

        :return: Upload name (package identifier)
        Ú.Nr   )Ú
upload_urlZauth_string)r   rd   r5   r6   Úbasenamer!   Úfindr   ÚuuidZuuid4r   Úget_patch_serverÚ
upload_urir   Zupload_filer   Úget_http_auth_string)r   ru   ÚextÚupload_namert   r   r   r   Úsendü   s    zDataPackage.send)NNF)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rT   ry   r   Úpropertyr   r!   r2   r*   rN   r:   r;   rW   rX   r)   r<   ri   rp   r   Úcatch_errorsr   r\   rl   r   r}   r   r   r   r   r   "   s(   
;
	 r   c               @   s    e Zd ZdZdZedd„ ƒZdS )ÚKernelAnomalyPackagezkernel-anomalyz/upload/kernel-anomaly/c             C   s   t jS )N)r   Z$KERNEL_ANOMALY_REPORT_MAX_SIZE_BYTES)r   r   r   r   r     s    zKernelAnomalyPackage.max_sizeN)r~   r   r€   rT   ry   r‚   r   r   r   r   r   r„     s   r„   )rA   rJ   r5   r&   r>   rV   rw   Útempfiler   Úkcarectlr   r   r   r   r   r   Zkcarectl.process_utilsr	   r   Úobjectr   r„   r   r   r   r   Ú<module>   s     y