U
    2d3                     @   s.  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,e	e+ dddZ-e	e. e	e( dddZ/G dd dej0Z1e	e( dddZ2e.e.e.e.e
e3e	e3 f d d!d"Z4e.e.e.e.e	e j  e	e( d#d$d%Z5edd&e(dd'd(Z6d4e.e	ee7  dd)d*d+Z8d5e	e. e	e. e	ee7  dd,d-d.Z9e.e	e. d/d0d1Z:e3dd2d3Z;dS )6    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                   @   sD   e Zd ZededddededddgZee ee	 ddd	Z
d
S )LivepatchPatchFixStatusnameFNameZrequiredZdict_keypatchedZPatchedr    r#   c                 C   s   || _ || _d S Nr$   )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                   @   s`   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ee	 ee
e  ee	 d	d
dZdS )LivepatchPatchStatusstateFStater"   fixesZFixesversionZVersionr,   r.   r/   c                 C   s   || _ || _|| _d S r%   r0   )r&   r,   r.   r/   r   r   r   r'   D   s    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                   @   sX   e Zd ZededddededddededddgZee ee ee d	d
dZ	dS )LivepatchStatusStatuskernelFZKernelr"   	livepatchZ	Livepatch	supported	Supportedr2   r3   r4   c                 C   s   || _ || _|| _d S r%   r6   )r&   r2   r3   r4   r   r   r   r'   `   s    zLivepatchStatusStatus.__init__N)
r   r   r   r   r   r+   r(   r   r)   r'   r   r   r   r   r1   O   s$   r1   c                   @   s8   e Zd ZedeedddgZeee  dddZ	dS )	LivepatchStatusstatusFZStatusr"   r8   c                 C   s
   || _ d S r%   r9   )r&   r8   r   r   r   r'   u   s    zLivepatchStatus.__init__N)
r   r   r   r   r   r1   r(   r   r   r'   r   r   r   r   r7   k   s   
r7   )returnc                  C   s<  t  std d S zttddddg\} }W n6 tjk
rf   t	  t
d W 5 Q R X Y d S X zt| }W nD tjk
r   t	  t
tjjd| dj W 5 Q R X Y d S X zt|}W n< tk
r   t	  t
d	|  W 5 Q R X Y d S X |jd ks$t|jd
k r2td d S |jd S )Nz$canonical-livepatch is not installedr8   z	--verbosez--formatjsonz7canonical-livepatch returned error when checking statuszcanonical-livepatch status)sourceoutz<canonical-livepatch status returned unexpected structure: {}   z!canonical-livepatch has no statusr   )is_livepatch_installedLOGdebugr	   subpLIVEPATCH_CMDr   ZProcessExecutionErrorr
   disable_log_to_consolewarningr;   loadsZJSONDecodeErrorr   ZJSON_PARSER_ERRORformatmsgr7   Z	from_dictr   r8   len)r=   _Zstatus_jsonZstatus_rootr   r   r   r8   |   sL    


 

r8   )
status_strr:   c                 C   sJ   | dkrt jS | dkrt jS | dkr*t jS | dkr8t jS | dkrFt jS d S )Nr4   zkernel-upgrade-requiredzkernel-end-of-lifeZunsupportedunknown)r   r   r   r   r   r   )rK   r   r   r   (_convert_str_to_livepatch_support_status   s    rM   c                   @   s2   e Zd ZdZeeeeeej ee dddZdS )UALivepatchClientZlivepatch_urlr/   flavorarchcodename
build_dater:   c                 C   s   |||||d k	r|  ndd}|  }z| jt||d}W nP tk
r }	 z2t  td t|	 W 5 Q R X W Y d S d }	~	X Y nX |j	dkrt  td t|j
 W 5 Q R X d S |jd}
|
d kst|
tr|
rtjS tjS t|
S )NrL   )zkernel-versionZflavourZarchitecturerR   z
build-date)query_paramsheadersz4error while checking livepatch supported kernels API   z0livepatch supported kernels API was unsuccessfulr5   )Z	isoformatrU   Zrequest_url"LIVEPATCH_API_V1_KERNELS_SUPPORTED	Exceptionr
   rD   r@   rE   codeZbodyZ	json_dictget
isinstancer*   r   r   r   rM   )r&   r/   rP   rQ   rR   rS   rT   rU   ZresponseeZapi_supported_valr   r   r   is_kernel_supported   sB    	
	




z%UALivepatchClient.is_kernel_supportedN)	r   r   r   Zcfg_url_base_attrr)   r   datetimer   r]   r   r   r   r   rN      s   rN   c                  C   s   t  } | d krd S t| jS r%   )r8   rM   r4   )Z	lp_statusr   r   r   _on_supported_kernel_cli   s    r_   )r/   rP   rQ   rR   r:   c              	   C   s   zt j }W n tk
r&   d}Y nX |dk	rtjtjjtjdd }t	|j
|k|j| k|j|k|j|k|j|kgr|jdkrt  td W 5 Q R X d|jfS dS )zOCheck local cache of kernel support

    :return: (is_cache_valid, result)
    N   )Zdaysz-livepatch kernel support cache has None valueT)FN)r   livepatch_support_cachereadrX   r^   nowtimezoneutcZ	timedeltaall	cached_atr/   rP   rQ   rR   r4   r
   rD   r@   rE   )r/   rP   rQ   rR   Z
cache_dataZone_week_agor   r   r   _on_supported_kernel_cache   s2    

	


rh   rO   c                 C   s   t  j| ||||d}d }|tjkr*d}n|tjkr8d}tjtj| ||||t	j	
t	jjd |d krt  td W 5 Q R X |S )N)r/   rP   rQ   rR   rS   TF)r/   rP   rQ   rR   r4   rg   z3livepatch kernel support API response was ambiguous)rN   r]   r   r   r   r   ra   writeZLivepatchSupportCacheDatar^   rc   rd   re   r
   rD   r@   rE   )r/   rP   rQ   rR   rS   r4   Zcache_supportedr   r   r   _on_supported_kernel_api  s4    	


rj   )maxsizec                  C   s   t  } | dk	rtd | S t }|jdksB|jdksB|jdkrRtd t	j
S t|j}t j}dj|j|jd}t||j||\}}|rtd |dkrt	j
S |rt	jS |st	jS td t||j|||j}|dkrt	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)r_   r@   rA   r	   Zget_kernel_inforP   rl   rm   rE   r   r   r
   Zstandardize_arch_nameZuname_machine_archZget_release_infoZseriesrG   rh   r   r   rj   rS   )Zcli_saysZkernel_inforQ   rR   Zlp_api_kernel_verZis_cache_validZ
cache_saysZapi_saysr   r   r   on_supported_kernel:  s\    

    

rn   )protocol_typeretry_sleepsr:   c                 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=rp   )r?   r	   rB   rC   rG   )ro   rp   r   r   r   unconfigure_livepatch_proxyv  s    rs   )
http_proxyhttps_proxyrp   r:   c                 C   sj   ddl m} | s|r*ttjj|jd | rHtj	t
dd| g|d |rftj	t
dd|g|d 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)servicerq   zhttp-proxy={}rr   zhttps-proxy={}N)Zuaclient.entitlementsrv   eventinfor   ZSETTING_SERVICE_PROXYrG   titler	   rB   rC   )rt   ru   rp   rv   r   r   r   configure_livepatch_proxy  s"    r{   )keyr:   c                 C   s\   t tdg\}}td| |tj}|r6|dnd}|rLtdd|}|rX|	 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
    rq   z
^{}: (.*)$r>   Nz\"(.*)\"z\g<1>)
r	   rB   rC   researchrG   	MULTILINEgroupsubstrip)r|   r=   rJ   matchvaluer   r   r   get_config_option_value  s    r   c                   C   s   t td k	S r%   )r	   ZwhichrC   r   r   r   r   r?     s    r?   )N)NNN)<r^   enumr;   Zloggingr}   	functoolsr   typingr   r   r   Zuaclientr   r   r   r	   r
   Zuaclient.data_typesr   r   r   r   r   r   Zuaclient.filesr   Zuaclient.httpr   ZHTTP_PROXY_OPTIONZHTTPS_PROXY_OPTIONrC   rW   Zget_event_loggerrx   Z	getLoggerZreplace_top_level_logger_namer   r@   uniqueEnumr   r   r+   r1   r7   r8   r)   rM   ZUAServiceClientrN   r_   r*   rh   rj   rn   floatrs   r{   r   r?   r   r   r   r   <module>   sx    -3   #&<  
   
%