o
    ϴfh3                     @   sV  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
 d dlmZmZmZmZmZ d dlmZmZmZmZmZmZ d dlmZ d dlmZ dZd	Zd
ZdZe  Z!e"e#e$Z%ej&G dd dej'Z(G dd deZ)G dd deZ*G dd deZ+G dd deZ,de	e+ fddZ-de	e. de	e( fddZ/G dd dej0Z1de	e( fddZ2d e.d!e.d"e.d#e.de
e3e	e3 f f
d$d%Z4d e.d!e.d"e.d#e.d&e	e j  de	e( fd'd(Z5edd)de(fd*d+Z6	d9d,e.d-e	ee7  ddfd.d/Z8			d:d0e	e. d1e	e. d-e	ee7  ddfd2d3Z9d4e.de	e. fd5d6Z:de3fd7d8Z;dS );    N)	lru_cache)ListOptionalTuple)event_logger
exceptionsmessagessystemutil)BoolDataValue
DataObjectFieldIncorrectTypeErrorStringDataValue	data_list)state_files)serviceclientz
http-proxyzhttps-proxyz/snap/bin/canonical-livepatchz/v1/api/kernels/supportedc                   @   s*   e Zd Ze Ze Ze Ze Ze ZdS )LivepatchSupportN)	__name__
__module____qualname__object	SUPPORTEDKERNEL_UPGRADE_REQUIRED
KERNEL_EOLUNSUPPORTEDUNKNOWN r   r   4/usr/lib/python3/dist-packages/uaclient/livepatch.pyr       s    
r   c                   @   sF   e Zd ZededddededddgZdee dee	 fddZ
d	S )
LivepatchPatchFixStatusnameFNamerequireddict_keypatchedPatchedc                 C   s   || _ || _d S N)r    r%   )selfr    r%   r   r   r   __init__/   s   
z LivepatchPatchFixStatus.__init__N)r   r   r   r   r   r   fieldsr   strboolr)   r   r   r   r   r   )   s    r   c                   @   sd   e Zd ZededddedeedddededddgZdee	 dee
e  dee	 fd	d
ZdS )LivepatchPatchStatusstateFStater"   fixesFixesversionVersionc                 C      || _ || _|| _d S r'   )r.   r0   r2   )r(   r.   r0   r2   r   r   r   r)   D      
zLivepatchPatchStatus.__init__N)r   r   r   r   r   r   r   r*   r   r+   r   r)   r   r   r   r   r-   8   s"    
r-   c                   @   s\   e Zd ZededddededddededddgZdee dee dee fd	d
Z	dS )LivepatchStatusStatuskernelFKernelr"   	livepatch	Livepatch	supported	Supportedc                 C   r4   r'   )r7   r9   r;   )r(   r7   r9   r;   r   r   r   r)   `   r5   zLivepatchStatusStatus.__init__N)
r   r   r   r   r   r-   r*   r   r+   r)   r   r   r   r   r6   O   s,    r6   c                   @   s8   e Zd ZedeedddgZdeee  fddZ	dS )LivepatchStatusstatusFStatusr"   c                 C   s
   || _ d S r'   )r>   )r(   r>   r   r   r   r)   u   s   
zLivepatchStatus.__init__N)
r   r   r   r   r   r6   r*   r   r   r)   r   r   r   r   r=   k   s    	
r=   returnc               
   C   s*  t  s
td d S zttddddg\} }W n( tjy@ } zd|jv r3t	|j W Y d }~d S tj	d|d |d }~ww zt
| }W n t
jyd } ztj	d	| |d W Y d }~d S d }~ww zt|}W n ty|   t	d
|  Y d S w |jd u st|jdk rtd d S |jd S )Nz$canonical-livepatch is not installedr>   z	--verbosez--formatjsonzMachine is not enabledz;canonical-livepatch returned error when checking status:
%s)exc_infozPJSONDecodeError while parsing livepatch status, returning None. output was: "%s"z<canonical-livepatch status returned unexpected structure: %s   z!canonical-livepatch has no statusr   )is_livepatch_installedLOGdebugr	   subpLIVEPATCH_CMDr   ProcessExecutionErrorstderrwarningrA   loadsJSONDecodeErrorr=   	from_dictr   r>   len)out_estatus_jsonstatus_rootr   r   r   r>   |   sT   

	

r>   
status_strc                 C   sJ   | dkrt jS | dkrt jS | dkrt jS | dkrt jS | dkr#t jS d S )Nr;   zkernel-upgrade-requiredzkernel-end-of-lifeunsupportedunknown)r   r   r   r   r   r   )rU   r   r   r   (_convert_str_to_livepatch_support_status   s   rX   c                   @   s<   e Zd ZdZdededededeej dee fdd	Zd
S )UALivepatchClientlivepatch_urlr2   flavorarchcodename
build_dater@   c              
   C   s   |||||d ur|  ndd}|  }z
| jt||d}W n ty; }	 ztd t|	 W Y d }	~	d S d }	~	ww |jdkrNtd t|j d S |j	
d}
|
d u s]t|
tre|
rbtjS tjS t|
S )NrW   )zkernel-versionflavourarchitecturer]   z
build-date)query_paramsheadersz4error while checking livepatch supported kernels API   z0livepatch supported kernels API was unsuccessfulr<   )	isoformatrb   request_url"LIVEPATCH_API_V1_KERNELS_SUPPORTED	ExceptionrE   rK   codebody	json_dictget
isinstancer,   r   r   r   rX   )r(   r2   r[   r\   r]   r^   ra   rb   responserR   api_supported_valr   r   r   is_kernel_supported   s:   		




z%UALivepatchClient.is_kernel_supportedN)	r   r   r   cfg_url_base_attrr+   r   datetimer   ro   r   r   r   r   rY      s    rY   c                  C   s8   zt  } W n tjy   Y d S w | d u rd S t| jS r'   )r>   r   rI   rX   r;   )	lp_statusr   r   r   _on_supported_kernel_cli   s   

rs   r2   r[   r\   r]   c                 C   s   zt j }W n ty   d}Y nw |durLtjtjjtjdd }t	|j
|k|j| k|j|k|j|k|j|kgrL|jdu rGtd d|jfS dS )zOCheck local cache of kernel support

    :return: (is_cache_valid, result)
    N   )daysz-livepatch kernel support cache has None valueT)FN)r   livepatch_support_cachereadrg   rq   nowtimezoneutc	timedeltaall	cached_atr2   r[   r\   r]   r;   rE   rK   )r2   r[   r\   r]   
cache_dataone_week_agor   r   r   _on_supported_kernel_cache   s.   

	

r   r^   c                 C   sx   t  j| ||||d}d }|tjkrd}n|tjkrd}tjtj| ||||t	j	
t	jjd |d u r:td |S )N)r2   r[   r\   r]   r^   TF)r2   r[   r\   r]   r;   r}   z3livepatch kernel support API response was ambiguous)rY   ro   r   r   r   r   rv   writeLivepatchSupportCacheDatarq   rx   ry   rz   rE   rK   )r2   r[   r\   r]   r^   r;   cache_supportedr   r   r   _on_supported_kernel_api  s2   	


r   )maxsizec                  C   s   t  } | durtd | S t }|jdu s!|jdu s!|jdu r)td t	j
S t|j}t j}dj|j|jd}t||j||\}}|r_td |du rUt	j
S |rZt	jS |s_t	jS td t||j|||j}|du rut	j
S |S )z
    Checks CLI, local cache, and API in that order for kernel support
    If all checks fail to return an authoritative answer, we return None
    Nzusing livepatch cli for supportzHunable to determine enough kernel information to check livepatch supportz{major}.{minor})majorminorzusing livepatch support cachezusing livepatch support api)rs   rE   rF   r	   get_kernel_infor[   r   r   rK   r   r   r
   standardize_arch_nameuname_machine_archget_release_infoseriesformatr   r   r   r   r^   )cli_sayskernel_infor\   r]   lp_api_kernel_veris_cache_valid
cache_saysapi_saysr   r   r   on_supported_kernel:  sN   







r   protocol_typeretry_sleepsc                 C   s(   t  sdS tjtdd| g|d dS )a  
    Unset livepatch configuration settings for http and https proxies.

    :param protocol_type: String either http or https
    :param retry_sleeps: Optional list of sleep lengths to apply between
        retries. Specifying a list of [0.5, 1] tells subp to retry twice
        on failure; sleeping half a second before the first retry and 1 second
        before the second retry.
    Nconfigz	{}-proxy=r   )rD   r	   rG   rH   r   )r   r   r   r   r   unconfigure_livepatch_proxyv  s   
r   
http_proxyhttps_proxyc                 C   sn   ddl m} | s
|rttjj|jd | r$tj	t
dd| g|d |r5tj	t
dd|g|d dS dS )	a  
    Configure livepatch to use http and https proxies.

    :param http_proxy: http proxy to be used by livepatch. If None, it will
                       not be configured
    :param https_proxy: https proxy to be used by livepatch. If None, it will
                        not be configured
    :@param retry_sleeps: Optional list of sleep lengths to apply between
                               snap calls
    r   )LivepatchEntitlement)servicer   zhttp-proxy={}r   zhttps-proxy={}N)uaclient.entitlementsr   eventinfor   SETTING_SERVICE_PROXYr   titler	   rG   rH   )r   r   r   r   r   r   r   configure_livepatch_proxy  s$   
r   keyc                 C   s\   t tdg\}}td| |tj}|r|dnd}|r&tdd|}|r,|	 S dS )z
    Gets the config value from livepatch.
    :param key: can be any valid livepatch config option
    :return: the value of the livepatch config option, or None if not set
    r   z
^{}: (.*)$rC   Nz\"(.*)\"z\g<1>)
r	   rG   rH   researchr   	MULTILINEgroupsubstrip)r   rP   rQ   matchvaluer   r   r   get_config_option_value  s   r   c                   C   s   t td uS r'   )r	   whichrH   r   r   r   r   rD     s   rD   r'   )NNN)<rq   enumrA   loggingr   	functoolsr   typingr   r   r   uaclientr   r   r   r	   r
   uaclient.data_typesr   r   r   r   r   r   uaclient.filesr   uaclient.httpr   HTTP_PROXY_OPTIONHTTPS_PROXY_OPTIONrH   rf   get_event_loggerr   	getLoggerreplace_top_level_logger_namer   rE   uniqueEnumr   r   r-   r6   r=   r>   r+   rX   UAServiceClientrY   rs   r,   r   r   r   floatr   r   r   rD   r   r   r   r   <module>   s     0
/

%<



%