o
    ϴf7                     @   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                	       sF  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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  S N)r   is_containerr   r   r   r   <lambda>K   s    z9LivepatchEntitlement.static_affordances.<locals>.<lambda>Fc                      s    S r"   r   r   is_fips_enabledr   r   r$   P   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_stepsU      z!LivepatchEntitlement.enable_stepsc                 C   r/   )N   r   r1   r   r   r   disable_stepsX   r3   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)#r6   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eventr7   r	   validate_proxyr    r?   PROXY_VALIDATION_SNAP_HTTP_URLr@   PROXY_VALIDATION_SNAP_HTTPS_URLconfigure_snap_proxySNAP_INSTALL_RETRIESr
   is_livepatch_installedErrorInstallingLivepatchstrconfigure_livepatch_proxysetup_livepatch_config)r   r6   er?   r@   r   r   r   _perform_enable[   s~   
	z$LivepatchEntitlement._perform_enablerD   rE   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rt
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:   r7   rB   NFresourceTokenzHNo specific resourceToken present. Using machine token as %s credentialsmachineTokenz&Disabling livepatch before re-enablingdisableenableTcapture)r6   r   SETTING_UP_LIVEPATCHmachine_token_fileentitlementsgetnameprocess_config_directivesr   rM   rN   errorr[   rH   LIVEPATCH_UNABLE_TO_CONFIGUREr+   debugr!   machine_tokenr(   r   DISABLEDr7   LIVEPATCH_DISABLE_REATTACHr   subpr
   LIVEPATCH_CMDLIVEPATCH_UNABLE_TO_ENABLEERROR_MSG_MAPitems)r   r6   rD   rE   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.
        Trb    r<   rd   )
r
   rY   rs   r6   r   EXECUTING_COMMANDr+   joinr   rr   )r   r6   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
   rY   rp   r   LIVEPATCH_NOT_ENABLEDstatusr   rM   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_DESCRIPTIONr1   r   r   r   status_description_override*  s   z0LivepatchEntitlement.status_description_overrideorig_accessdeltasallow_enablec                    s   t  |||r
dS |di }|di dd}|r'| t \}}|S |  \}}|tjkr4dS |di }	t	ddg}
t
|
|	}t
|d	d}t||grotd
 ttjj| jd | jt ||dS dS )a1  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.

        :return: True when delta operations are processed; False when noop.
        TentitlementobligationsenableByDefaultF
directivescaCertsremoteServerr`   zANew livepatch directives or token. running setup_livepatch_config)service)r6   rD   rE   )superprocess_contract_deltasri   rc   r   ProgressWrapperr(   r   rp   setr'   intersectionanyrN   r7   rS   r   #SERVICE_UPDATING_CHANGED_DIRECTIVESr+   rj   r]   )r   r   r   r   delta_entitlementprocess_enable_defaultenable_success_r(   delta_directivessupported_deltasrD   rE   	__class__r   r   r   3  sB   
z,LivepatchEntitlement.process_contract_deltas)TT)F),__name__
__module____qualname__r   urlsLIVEPATCH_HOME_PAGEhelp_doc_urlrj   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   r.   intr2   r5   r   r   r'   r_   r]   r   r   r   NamedMessager(   r   r   r   r[   r   r   __classcell__r   r   r   r   r      s\    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={}Trd   r    /zremote-server={})ri   r   rr   r
   rs   r+   endswith)r    r   ca_certsremote_serverr   r   r   rk   l  s0   



rk   )!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_RETRIESru   get_event_loggerrS   	getLoggerreplace_top_level_logger_namer   rN   r   rk   r   r   r   r   <module>   s     ,  P