
    f`3                     .   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jD                   ejF                  e$            Z%ejL                   G d dejN                               Z( G d de      Z) G d de      Z* G d de      Z+ G d de      Z,de	e+   fdZ-de	e.   de	e(   fdZ/ G d dej`                        Z1de	e(   fdZ2de.de.de.d e.de
e3e	e3   f   f
d!Z4de.de.de.d e.d"e	e j                      de	e(   fd#Z5 ed$      de(fd%       Z6	 d/d&e.d'e	ee7      ddfd(Z8	 	 	 d0d)e	e.   d*e	e.   d'e	ee7      ddfd+Z9d,e.de	e.   fd-Z:de3fd.Z;y)1    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                   R    e Zd Z e       Z e       Z e       Z e       Z e       Zy)LivepatchSupportN)	__name__
__module____qualname__object	SUPPORTEDKERNEL_UPGRADE_REQUIRED
KERNEL_EOLUNSUPPORTEDUNKNOWN     4/usr/lib/python3/dist-packages/uaclient/livepatch.pyr   r       s&    I$hJ(KhGr    r   c                   X    e Zd Z ededd       ededd      gZdee   dee	   fdZ
y)	LivepatchPatchFixStatusnameFNamerequireddict_keypatchedPatchedc                      || _         || _        y N)r$   r)   )selfr$   r)   s      r!   __init__z LivepatchPatchFixStatus.__init__/   s    
 	r    N)r   r   r   r   r   r   fieldsr   strboolr.   r   r    r!   r#   r#   )   sD    foGiKF
sm $r    r#   c                       e Zd Z ededd       ed ee      dd       ededd      gZdee	   dee
e      dee	   fd	Zy
)LivepatchPatchStatusstateFStater&   fixesFixesversionVersionc                 .    || _         || _        || _        y r,   )r4   r6   r8   )r-   r4   r6   r8   s       r!   r.   zLivepatchPatchStatus.__init__D   s     

r    N)r   r   r   r   r   r   r#   r/   r   r0   r   r.   r   r    r!   r3   r3   8   su    gI-.		
 	i59M	F} 456 #	r    r3   c                   x    e Zd Z ededd       ededd       ededd      gZdee   dee   dee   fd	Z	y
)LivepatchStatusStatuskernelFKernelr&   	livepatch	Livepatch	supported	Supportedc                 .    || _         || _        || _        y r,   )r=   r?   rA   )r-   r=   r?   rA   s       r!   r.   zLivepatchStatusStatus.__init__`   s     ""r    N)
r   r   r   r   r   r3   r/   r   r0   r.   r   r    r!   r<   r<   O   sp    h%(K  		
 	 		
F ## 01# C=	#r    r<   c                   J    e Zd Z ed ee      dd      gZdeee      fdZ	y)LivepatchStatusstatusFStatusr&   c                     || _         y r,   )rF   )r-   rF   s     r!   r.   zLivepatchStatus.__init__u   s     r    N)
r   r   r   r   r   r<   r/   r   r   r.   r   r    r!   rE   rE   k   s;    +,		
F345r    rE   returnc                     t               st        j                  d       y 	 t        j                  t
        ddddg      \  } }	 t        j                  |       }	 t        j                  |      }|j                   t#        |j                         dk  rt        j                  d       y |j                   d   S # t        j                  $ rP}d|j                  v r$t        j                  |j                         Y d }~y t        j                  d|       |d }~ww xY w# t        j                  $ r"}t        j                  d	| |       Y d }~y d }~ww xY w# t        $ r t        j                  d
|        Y y w xY w)Nz$canonical-livepatch is not installedrF   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warningrK   loadsJSONDecodeErrorrE   	from_dictr   rF   len)out_estatus_jsonstatus_roots        r!   rF   rF   |   s\   !#		89Hk:vF
Q	jjo%//< !S););%<q%@		56a  I ++ 
 $qxx/KK!J 	 	
 
  	 	 	
   J	
 sG   !B8 D E 8D-D=DDE1EEE87E8
status_strc                     | 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 y )NrA   zkernel-upgrade-requiredzkernel-end-of-lifeunsupportedunknown)r   r   r   r   r   r   )r_   s    r!   (_convert_str_to_livepatch_support_statusrc      sm     [ )))..777))***]"+++Y'''r    c                   P    e Zd ZdZdededededeej                     dee   fdZy	)
UALivepatchClientlivepatch_urlr8   flavorarchcodename
build_daterI   c                 D   ||||||j                         ndd}| j                         }	 | j                  t        ||      }|j                  dk7  r5t
        j                  d       t
        j                  |j                         y |j                  j                  d      }
|
t        |
t              r"|
rt        j                  S t        j                  S t!        |
      S # t        $ r4}	t
        j                  d       t
        j                  |	       Y d }	~	y d }	~	ww xY w)Nrb   )zkernel-versionflavourarchitectureri   z
build-date)query_paramsheadersz4error while checking livepatch supported kernels API   z0livepatch supported kernels API was unsuccessfulrB   )	isoformatro   request_url"LIVEPATCH_API_V1_KERNELS_SUPPORTED	ExceptionrO   rU   codebody	json_dictget
isinstancer1   r   r   r   rc   )r-   r8   rg   rh   ri   rj   rn   ro   responser\   api_supported_vals              r!   is_kernel_supportedz%UALivepatchClient.is_kernel_supported   s    &  % %..0
 ,,.		''2) ( H ==CKKJKKK&$..22;?$
3Dd(K '111#///78IJJ#  	KKNOKKN	s   C" "	D+*DDN)	r   r   r   cfg_url_base_attrr0   r   datetimer   r|   r   r    r!   re   re      s_    ')K)K )K 	)K
 )K X../)K 
"	#)Kr    re   c                  z    	 t               } | y t        | j                        S # t        j                  $ r Y y w xY wr,   )rF   r   rS   rc   rA   )	lp_statuss    r!   _on_supported_kernel_clir      sD    H	 3I4G4GHH ++ s   
$ ::r8   rg   rh   ri   c                    	 t         j                  j                         }|t        j                  j                  t        j                  j                        t	        j                  d      z
  }t        |j                  |kD  |j                  | k(  |j                  |k(  |j                  |k(  |j                  |k(  g      r/|j                  t         j#                  d       d|j                  fS y# t        $ r d}Y w xY w)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readrt   r~   nowtimezoneutc	timedeltaall	cached_atr8   rg   rh   ri   rA   rO   rU   )r8   rg   rh   ri   
cache_dataone_week_agos         r!   _on_supported_kernel_cacher      s     88==?
 ((,,!!
A&' $$|3""g-!!V+4'##x/
 ##+KL*..//'  
s   C1 1C?>C?rj   c                    t               j                  | ||||      }d }|t        j                  k(  rd}n|t        j                  k(  rd}t
        j                  j                  t        j                  | ||||t        j                  j                  t        j                  j                                     |t        j                  d       |S )N)r8   rg   rh   ri   rj   TF)r8   rg   rh   ri   rA   r   z3livepatch kernel support API response was ambiguous)re   r|   r   r   r   r   r   writeLivepatchSupportCacheDatar~   r   r   r   rO   rU   )r8   rg   rh   ri   rj   rA   cache_supporteds          r!   _on_supported_kernel_apir     s     "#77 8 I O$...	&22	2''----%''++H,=,=,A,AB	
	 IJr    )maxsizec                  2   t               } | t        j                  d       | S t        j                         }|j
                  |j                  |j                  %t        j                  d       t        j                  S t        j                  |j                        }t        j                         j                  }dj!                  |j                  |j                        }t#        ||j
                  ||      \  }}|rKt        j                  d       |t        j                  S |rt        j$                  S |st        j&                  S t        j                  d       t)        ||j
                  |||j*                        }|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
    z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   rO   rP   r
   get_kernel_inforg   r   r   rU   r   r   r   standardize_arch_nameuname_machine_archget_release_infoseriesformatr   r   r   r   rj   )cli_sayskernel_inforh   ri   lp_api_kernel_veris_cache_valid
cache_saysapi_sayss           r!   on_supported_kernelr   :  sw    ()H		34 ((*K"$$&	
  '''%%k&D&DED&&(//H)00{'8'8 1 
 "<;--tX"NJ 		12#+++#---#/// II+,'H '''Or    protocol_typeretry_sleepsc                 t    t               syt        j                  t        ddj	                  |       g|       y)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   )rN   r
   rQ   rR   r   )r   r   s     r!   unconfigure_livepatch_proxyr   v  s1     "#
KK	+"4"4]"CD!r    
http_proxyhttps_proxyc                 P   ddl m} | s|r=t        j                  t        j
                  j                  |j                               | r-t        j                  t        ddj                  |       g|       |r.t        j                  t        ddj                  |      g|       yy)	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
   rQ   rR   )r   r   r   r   s       r!   configure_livepatch_proxyr     s     ;[

**11,22 2 	
 Ho&<&<Z&HI%	

 H&6&=&=k&JK%	
 r    keyc                 *   t        j                  t        dg      \  }}t        j                  dj                  |       |t        j                        }|r|j                  d      nd}|rt        j                  dd|      }|r|j                         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
^{}: (.*)$rM   Nz\"(.*)\"z\g<1>)
r
   rQ   rR   researchr   	MULTILINEgroupsubstrip)r   rZ   r[   matchvalues        r!   get_config_option_valuer     su     [[-23FCIIl))#.R\\BE#EKKNE{He4!5;;=+t+r    c                  8    t        j                  t              d uS r,   )r
   whichrR   r   r    r!   rN   rN     s    <<&d22r    r,   )NNN)<r~   enumrK   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_OPTIONrR   rs   get_event_loggerr   	getLoggerreplace_top_level_logger_namer   rO   uniqueEnumr   r#   r3   r<   rE   rF   r0   rc   UAServiceClientre   r   r1   r   r   r   floatr   r   r   rN   r   r    r!   <module>r      sk       	  ( ( E E  ' '  " /%@ "%%%'g:::8DE tyy  j : .#J #8j "-!./ -!` ,K55 ,K^I(+;"< I%(47
4$ >""" " 	"
 **+" "J 48- 8 8x ?C&.tE{&;	* !%!%*."
"
#"
 4;'"
 
	"
J, ,# ,3 3r    