o
    ÙKÕih3  ã                   @   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 s‰t|jƒdk r�t 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ÿ
þ/ÿÿÿÿ
þÿþýüû
ú%<ÿÿ
ÿ
þýÿþ
ý
ü%