
Ke2              
   @   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 j    Z! e j" e j# e$   Z% e j& Gd d   d e j'   Z( Gd d   d e  Z) Gd d   d e  Z* Gd d   d e  Z+ Gd d   d e  Z, e	 e+ d d d    Z- e	 e. e	 e( d d d    Z/ Gd d   d e j0  Z1 e	 e( d d d    Z2 e. e. e. e. e
 e3 e	 e3 f d  d! d"    Z4 e. e. e. e. e	 e  j  e	 e( d# d$ d%    Z5 e d& d  e( d d' d(     Z6 d e. e	 e e7 d d) d* d+   Z8 d d d e	 e. e	 e. e	 e e7 d d, d- d.   Z9 e. e	 e. d/ d0 d1    Z: e3 d d2 d3    Z; d S)4    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 d e d e d d d d g Z e e e e	 d d	 d
    Z
 d S)LivepatchPatchFixStatusnamerequiredFdict_keyNamepatchedZPatched)r    r$   c             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            	   @   s   e  Z d  Z e d e d d d d e d e e  d d d d e d e d d d d	 g Z e e	 e e
 e e e	 d
 d d    Z d S)LivepatchPatchStatusstater!   Fr"   ZStatefixesZFixesversionZVersion)r+   r,   r-   c             C   s   | |  _  | |  _ | |  _ d  S)N)r+   r,   r-   )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            	   @   s   e  Z d  Z e d e d d d d e d e d d d d e d e d d d d	 g Z e e e e e e d
 d d    Z	 d S)LivepatchStatusStatuskernelr!   Fr"   ZKernel	livepatchZ	Livepatch	supported	Supported)r/   r0   r1   c             C   s   | |  _  | |  _ | |  _ d  S)N)r/   r0   r1   )r%   r/   r0   r1   r   r   r   r&   `   s    		zLivepatchStatusStatus.__init__N)
r   r   r   r   r   r*   r'   r   r(   r&   r   r   r   r   r.   O   s   r.   c               @   sQ   e  Z d  Z e d e e  d d d d g Z e e e d d d    Z	 d	 S)
LivepatchStatusstatusr!   Fr"   ZStatus)r4   c             C   s   | |  _  d  S)N)r4   )r%   r4   r   r   r   r&   u   s    zLivepatchStatus.__init__N)
r   r   r   r   r   r.   r'   r   r   r&   r   r   r   r   r3   k   s   r3   )returnc           !   C   s?  t    s t j d  d  Sy( t j t d d d d g  \ }  } Wn& t j k
 rj t j d  d  SYn Xy t	 j
 |   } WnB t	 j k
 r } z t j d |  d | d  SWYd  d  } ~ Xn Xy t j |  } Wn& t k
 r t j d	 |   d  SYn X| j d  k s#t | j  d
 k  r4t j d  d  S| j d S)Nz$canonical-livepatch is not installedr4   z	--verbosez--formatjsonz7canonical-livepatch returned error when checking statuszPJSONDecodeError while parsing livepatch status, returning None. output was: "%s"exc_infoz<canonical-livepatch status returned unexpected structure: %s   z!canonical-livepatch has no statusr   )is_livepatch_installedLOGdebugr	   subpLIVEPATCH_CMDr   ZProcessExecutionErrorwarningr6   loadsZJSONDecodeErrorr3   Z	from_dictr   r4   len)out_Zstatus_jsoneZstatus_rootr   r   r   r4   |   s8    	"		$r4   )
status_strr5   c             C   sc   |  d k r t  j S|  d k r& t  j S|  d k r9 t  j S|  d k rL t  j S|  d k r_ t  j Sd  S)Nr1   zkernel-upgrade-requiredzkernel-end-of-lifeZunsupportedunknown)r   r   r   r   r   r   )rD   r   r   r   (_convert_str_to_livepatch_support_status   s    rF   c            	   @   sE   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_dater5   c             C   s(  d | d | d | d | d | d  k	 r3 | j    n d i } |  j   } y |  j t d | d | } WnC t k
 r }	 z# t j d	  t j |	  d  SWYd  d  }	 ~	 Xn X| j d
 k r t j d  t j | j  d  S| j	 j
 d  }
 |
 d  k s
t |
 t  r|
 rt j St j St |
  S)Nzkernel-versionZflavourZarchitecturerJ   z
build-daterE   query_paramsheadersz4error while checking livepatch supported kernels API   z0livepatch supported kernels API was unsuccessfulr2   )Z	isoformatrM   Zrequest_url"LIVEPATCH_API_V1_KERNELS_SUPPORTED	Exceptionr:   r>   codeZbodyZ	json_dictget
isinstancer)   r   r   r   rF   )r%   r-   rH   rI   rJ   rK   rL   rM   ZresponserC   Zapi_supported_valr   r   r   is_kernel_supported   s6    		z%UALivepatchClient.is_kernel_supportedN)	r   r   r   Zcfg_url_base_attrr(   r   datetimer   rT   r   r   r   r   rG      s   
rG   c              C   s&   t    }  |  d  k r d  St |  j  S)N)r4   rF   r1   )Z	lp_statusr   r   r   _on_supported_kernel_cli   s    	rV   )r-   rH   rI   rJ   r5   c             C   s   y t  j j   } Wn t k
 r- d } Yn X| d k	 r t j j t j j  t j d d  } t	 | j
 | k | j |  k | j | k | j | k | j | k g  r | j d k r t j d  d | j f Sd S)zOCheck local cache of kernel support

    :return: (is_cache_valid, result)
    NZdays   z-livepatch kernel support cache has None valueTF)FN)r   livepatch_support_cachereadrP   rU   nowtimezoneutcZ	timedeltaall	cached_atr-   rH   rI   rJ   r1   r:   r>   )r-   rH   rI   rJ   Z
cache_dataZone_week_agor   r   r   _on_supported_kernel_cache   s$    	r_   )r-   rH   rI   rJ   rK   r5   c             C   s   t    j d |  d | d | d | d |  } d  } | t j k rK d } n | t j k r` d } t j j t j d |  d | d | d | d | d	 t	 j	 j
 t	 j j    | d  k r t j d
  | S)Nr-   rH   rI   rJ   rK   TFr1   r^   z3livepatch kernel support API response was ambiguous)rG   rT   r   r   r   r   rX   writeZLivepatchSupportCacheDatarU   rZ   r[   r\   r:   r>   )r-   rH   rI   rJ   rK   r1   Zcache_supportedr   r   r   _on_supported_kernel_api	  s,    				ra   maxsizec              C   sR  t    }  |  d k	 r& t j d  |  St j   } | j d k s_ | j d k s_ | j d k rs t j d  t	 j
 St j | j  } t j   j } d j d | j d | j  } t | | j | |  \ } } | rt j d  | d k r t	 j
 S| rt	 j S| st	 j St j d  t | | j | | | j  } | d k rNt	 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)rV   r:   r;   r	   Zget_kernel_inforH   rc   rd   r>   r   r   r
   Zstandardize_arch_nameZuname_machine_archZget_release_infoZseriesformatr_   r   r   ra   rK   )Zcli_saysZkernel_inforI   rJ   Zlp_api_kernel_verZis_cache_validZ
cache_saysZapi_saysr   r   r   on_supported_kernel.  sF    		rf   )protocol_typeretry_sleepsr5   c             C   s6   t    s d St j t d d j |   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=rh   )r9   r	   r<   r=   re   )rg   rh   r   r   r   unconfigure_livepatch_proxyj  s
    	rj   )
http_proxyhttps_proxyrh   r5   c             C   s   d d l  m } |  s | r; t j t j j d | j   |  rf t j	 t
 d d j |   g d | | r t j	 t
 d d j |  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serviceri   zhttp-proxy={}rh   zhttps-proxy={}N)Zuaclient.entitlementsrm   eventinfor   ZSETTING_SERVICE_PROXYre   titler	   r<   r=   )rk   rl   rh   rm   r   r   r   configure_livepatch_proxy~  s    rr   )keyr5   c             C   s   t  j t d g  \ } } t j d j |   | t j  } | rQ | j d  n d } | rr t j d d |  } | r | j	   Sd 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
    ri   z
^{}: (.*)$r8   Nz\"(.*)\"z\g<1>)
r	   r<   r=   researchre   	MULTILINEgroupsubstrip)rs   rA   rB   matchvaluer   r   r   get_config_option_value  s    !r|   c               C   s   t  j t  d  k	 S)N)r	   Zwhichr=   r   r   r   r   r9     s    r9   )<rU   Zenumr6   Zloggingrt   	functoolsr   Z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_OPTIONr=   rO   Zget_event_loggerro   Z	getLoggerZreplace_top_level_logger_namer   r:   ZuniqueZEnumr   r   r*   r.   r3   r4   r(   rF   ZUAServiceClientrG   rV   r)   r_   ra   rf   floatrj   rr   r|   r9   r   r   r   r   <module>   sZ   (.)/#
<!