o
    ÙKÕiy8  ã                   @   sº   d dl Z d dlmZmZmZmZ d dlmZmZm	Z	m
Z
mZmZmZmZmZ d dlmZmZ d dlmZ d dlmZ ddgZd	d
dœZe ¡ Ze  e e¡¡ZG dd„ deƒZdd„ Z dS )é    N)ÚAnyÚDictÚOptionalÚTuple)	ÚapiÚevent_loggerÚ
exceptionsÚhttpÚ	livepatchÚmessagesÚsnapÚsystemÚutil)ÚEntitlementWithMessageÚUAEntitlement)ÚApplicationStatus)ÚStaticAffordanceg      à?g      ð?z)Invalid Auth-Token provided to livepatch.z2Your running kernel is not supported by Livepatch.)zUnknown Auth-Tokenzunsupported kernelc                       sL  e Zd ZejjZdZejZ	ej
ZejZdZdZdZdZedeedf fdd„ƒZedeedf fdd	„ƒZdefd
d„Zdefdd„Zdejdefdd„Z		d#dejdededefdd„Zdejfdd„Z dee!e"ej# f fdd„Z$deee"ej# f fdd„Z%dd„ Z&		d$de'e(e)f de'e(e)f ded edef
‡ fd!d"„Z*‡  Z+S )%ÚLivepatchEntitlementr
   FTÚreturn.c                 C   s0   ddl m} ddlm} t|tjƒt|tjƒfS )Nr   ©ÚFIPSEntitlement)ÚRealtimeKernelEntitlement)Úuaclient.entitlements.fipsr   Úuaclient.entitlements.realtimer   r   r   ÚLIVEPATCH_INVALIDATES_FIPSÚREALTIME_LIVEPATCH_INCOMPATIBLE)Úselfr   r   © r   úA/usr/lib/python3/dist-packages/uaclient/entitlements/livepatch.pyÚincompatible_services,   s   ÿþüz*LivepatchEntitlement.incompatible_servicesc                    s\   ddl m} || jd�}t| ¡ d tjkƒ‰ tjj	| j
d�dd„ dftj‡ fdd„dffS )	Nr   r   )Úcfg)Útitlec                   S   s   t  ¡ p	t  ¡ dkS )NÚwsl)r   Úis_containerÚget_virt_typer   r   r   r   Ú<lambda>K   s    z9LivepatchEntitlement.static_affordances.<locals>.<lambda>Fc                      s   ˆ S ©Nr   r   ©Úis_fips_enabledr   r   r%   Q   s    )r   r   r    ÚboolÚapplication_statusr   ÚENABLEDr   Ú"SERVICE_ERROR_INSTALL_ON_CONTAINERÚformatr!   Ú!LIVEPATCH_ERROR_WHEN_FIPS_ENABLED)r   r   Úfips_entr   r'   r   Ústatic_affordances;   s    ÿÿú	
ý÷z'LivepatchEntitlement.static_affordancesc                 C   ó   dS )Né   r   ©r   r   r   r   Úenable_stepsV   ó   z!LivepatchEntitlement.enable_stepsc                 C   r1   )Né   r   r3   r   r   r   Údisable_stepsY   r5   z"LivepatchEntitlement.disable_stepsÚprogressc              
   C   sº  |  tj¡ t ¡ s| dtjjdd�¡ t ¡  t 	¡ sU| dtjjdd�¡ zt 
d¡ W n% tjyT } ztjd|d� | dtjjdd�¡ W Y d	}~nd	}~ww t |¡ zt d¡ W n$ tjy… } ztjd
|d� t tjjdd�¡ W Y d	}~nd	}~ww t d| jjtj¡}t d| jjtj¡}tj||tjd� t ¡ sÏ| dtjjdd�¡ zt 
d¡ W n tjyÎ } ztjt |ƒd�‚d	}~ww t !||¡ | j"|ddd�S )zYEnable specific entitlement.

        @return: True on success, False otherwise.
        ÚinfoÚsnapd)Úpackagesz
snapd snapz!Failed to install snapd as a snap©Úexc_infozsnap install snapd©ÚcommandNzFailed to refresh snapd snapzsnap refresh snapdr	   Úhttps)Ú
http_proxyÚhttps_proxyÚretry_sleepszcanonical-livepatch snapzcanonical-livepatch©Ú	error_msgT)Úprocess_directivesÚprocess_token)#r8   r   ÚINSTALLING_LIVEPATCHr   Úis_snapd_installedÚemitÚINSTALLING_PACKAGESr-   Úinstall_snapdÚis_snapd_installed_as_a_snapÚinstall_snapr   ÚProcessExecutionErrorÚLOGÚwarningÚEXECUTING_COMMAND_FAILEDÚrun_snapd_wait_cmdÚrefresh_snapÚeventr9   r	   Úvalidate_proxyr    rA   ÚPROXY_VALIDATION_SNAP_HTTP_URLrB   ÚPROXY_VALIDATION_SNAP_HTTPS_URLÚconfigure_snap_proxyÚSNAP_INSTALL_RETRIESr
   Úis_livepatch_installedÚErrorInstallingLivepatchÚstrÚconfigure_livepatch_proxyÚsetup_livepatch_config)r   r8   ÚerA   rB   r   r   r   Ú_perform_enable\   s~   ÿþÿþ€þ
	ÿÿ€þÿÿýÿþ€ÿÿz$LivepatchEntitlement._perform_enablerF   rG   c              
   C   sÊ  |  tj¡ | j ¡  | j¡}|rBzt|ƒ W n* tj	yA } zt
jt|ƒ|d� | dtjjt|ƒd�¡ W Y d}~dS d}~ww |rã| d¡}|sXt
 d| j¡ | jjd }|  ¡ \}}|tjkr—t
 d	¡ | dtj¡ z
t tjd
g¡ W n tj	y– } zt
jt|ƒ|d� W Y d}~dS d}~ww ztjtjd|gdd� W dS  tj	yâ } z0tj}	t ¡ D ]\}
}|
t|ƒv rÅ|	|7 }	 nqµ|	tjkrÑ|	t|ƒ7 }	| d|	¡ W Y d}~dS d}~ww dS )a  Processs configuration setup for livepatch directives.

        :param process_directives: Boolean set True when directives should be
            processsed.
        :param process_token: Boolean set True when token should be
            processsed.
        r<   r9   rD   NFÚresourceTokenzHNo specific resourceToken present. Using machine token as %s credentialsÚmachineTokenz&Disabling livepatch before re-enablingÚdisableÚenableT©Úcapture)r8   r   ÚSETTING_UP_LIVEPATCHÚmachine_token_fileÚentitlementsÚgetÚnameÚprocess_config_directivesr   rO   rP   Úerrorr]   rJ   ÚLIVEPATCH_UNABLE_TO_CONFIGUREr-   Údebugr!   Úmachine_tokenr*   r   ÚDISABLEDr9   ÚLIVEPATCH_DISABLE_REATTACHr   Úsubpr
   ÚLIVEPATCH_CMDÚLIVEPATCH_UNABLE_TO_ENABLEÚERROR_MSG_MAPÚitems)r   r8   rF   rG   Úentitlement_cfgr`   Úlivepatch_tokenr*   Ú_detailsÚmsgÚerror_messageÚprint_messager   r   r   r_   ¢   sr   ÿþ€ø	
ýÿ

€þ
þöþ
€÷
z+LivepatchEntitlement.setup_livepatch_configc                 C   sB   t  ¡ sdS t jdg}| tjjd |¡d�¡ tj	|dd� dS )zYDisable specific entitlement

        @return: True on success, False otherwise.
        Trd   ú r>   rf   )
r
   r[   ru   r8   r   ÚEXECUTING_COMMANDr-   Újoinr   rt   )r   r8   Úcmdr   r   r   Ú_perform_disableã   s   
ÿz%LivepatchEntitlement._perform_disablec              
   C   s€   t jd f}t ¡ st jtjfS zt ¡ }W n tj	y3 } zt j
tjj|jd�fW  Y d }~S d }~ww |d u r>t jtjfS |S )N)Úlivepatch_error)r   r+   r
   r[   rr   r   ÚLIVEPATCH_NOT_ENABLEDÚstatusr   rO   ÚWARNINGÚ LIVEPATCH_CLIENT_FAILURE_WARNINGr-   ÚstderrÚ+LIVEPATCH_APPLICATION_STATUS_CLIENT_FAILURE)r   r†   Úlivepatch_statusr`   r   r   r   r*   ñ   s$   
ÿþ€ÿþz'LivepatchEntitlement.application_statusc                 C   sz   t  ¡ }|t jjkrt ¡ }dtjj|j	|j
d�fS |t jjkr0t ¡ }dtjj|j	|j
d�fS |t jjkr;dtjfS dS )NT)ÚversionÚarch)FN)r
   Úon_supported_kernelÚLivepatchSupportÚUNSUPPORTEDr   Úget_kernel_infor   ÚLIVEPATCH_KERNEL_NOT_SUPPORTEDr-   Úuname_releaseÚuname_machine_archÚ
KERNEL_EOLÚLIVEPATCH_KERNEL_EOLÚKERNEL_UPGRADE_REQUIREDÚ!LIVEPATCH_KERNEL_UPGRADE_REQUIRED)r   ÚsupportÚkernel_infor   r   r   Úenabled_warning_status  s,   þþþþþz+LivepatchEntitlement.enabled_warning_statusc                 C   s"   t  ¡ t jjkrt ¡ stjS d S r&   )r
   rŽ   r�   r�   r   r#   r   Ú*LIVEPATCH_KERNEL_NOT_SUPPORTED_DESCRIPTIONr3   r   r   r   Ústatus_description_override+  s   ÿþz0LivepatchEntitlement.status_description_overrideÚorig_accessÚdeltasÚallow_enableÚverbosec                    sê   t ƒ j||||d�rdS | di ¡}| di ¡ dd¡}|r)|  t ¡ ¡\}}|S |  ¡ \}	}|	tjkr6dS | di ¡}
t	dd	gƒ}t
| |
¡ƒ}t
| d
d¡ƒ}t||gƒrst d¡ |rit tjj| jd�¡ | jt ¡ ||d�S dS )ak  Process any contract access deltas for this entitlement.

        :param orig_access: Dictionary containing the original
            resourceEntitlement access details.
        :param deltas: Dictionary which contains only the changed access keys
        and values.
        :param allow_enable: Boolean set True if allowed to perform the enable
            operation. When False, a message will be logged to inform the user
            about the recommended enabled service.
        :param verbose: If True, display output to stdout

        :return: True when delta operations are processed; False when noop.
        )r¡   TÚentitlementÚobligationsÚenableByDefaultFÚ
directivesÚcaCertsÚremoteServerrb   zANew livepatch directives or token. running setup_livepatch_config)Úservice)r8   rF   rG   )ÚsuperÚprocess_contract_deltasrk   re   r   ÚProgressWrapperr*   r   rr   Úsetr)   ÚintersectionÚanyrP   r9   rU   r   Ú#SERVICE_UPDATING_CHANGED_DIRECTIVESr-   rl   r_   )r   rž   rŸ   r    r¡   Údelta_entitlementÚprocess_enable_defaultÚenable_successÚ_r*   Údelta_directivesÚsupported_deltasrF   rG   ©Ú	__class__r   r   rª   4  sH   ÿÿ
ÿÿÿÿýz,LivepatchEntitlement.process_contract_deltas)TT)FT),Ú__name__Ú
__module__Ú__qualname__r   ÚurlsÚLIVEPATCH_HOME_PAGEÚhelp_doc_urlrl   ÚLIVEPATCH_TITLEr!   ÚLIVEPATCH_DESCRIPTIONÚdescriptionÚLIVEPATCH_HELP_TEXTÚ	help_textÚ#affordance_check_kernel_min_versionÚaffordance_check_kernel_flavorÚaffordance_check_seriesÚaffordance_check_archÚpropertyr   r   r   r   r0   Úintr4   r7   r   r«   r)   ra   r_   rƒ   r   r   ÚNamedMessager*   r›   r�   r   r]   r   rª   Ú__classcell__r   r   r¶   r   r      sb    Iüþýü
ûA
þ
þ û
þ
ýüûúr   c                 C   s�   | sdS |   di ¡  di ¡}|  d¡}|r#tjtjdd |¡gdd� |  d	d
¡}| d¡r4|dd… }|rFtjtjdd |¡gdd� dS dS )a˜  Process livepatch configuration directives.

    We process caCerts before remoteServer because changing remote-server
    in the canonical-livepatch CLI performs a PUT against the new server name.
    If new caCerts were required for the new remoteServer, this
    canonical-livepatch client PUT could fail on unmatched old caCerts.

    @raises: ProcessExecutionError if unable to configure livepatch.
    Nr¢   r¥   r¦   Úconfigzca-certs={}Trf   r§   Ú ú/éÿÿÿÿzremote-server={})rk   r   rt   r
   ru   r-   Úendswith)r    r¥   Úca_certsÚremote_serverr   r   r   rm   s  s0   

ýú
ý
úÿrm   )!ÚloggingÚtypingr   r   r   r   Úuaclientr   r   r   r	   r
   r   r   r   r   Úuaclient.entitlements.baser   r   Ú(uaclient.entitlements.entitlement_statusr   Úuaclient.typesr   ÚLIVEPATCH_RETRIESrw   Úget_event_loggerrU   Ú	getLoggerÚreplace_top_level_logger_namer¸   rP   r   rm   r   r   r   r   Ú<module>   s     ,þ  W