o
    Jh7                     @   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  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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<   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_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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   delta_entitlementprocess_enable_defaultenable_success_r*   delta_directivessupported_deltasrF   rG   	__class__r   r   r   4  sB   
z,LivepatchEntitlement.process_contract_deltas)TT)F),__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      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={}Trf   r    /zremote-server={})rk   r   rt   r
   ru   r-   endswith)r    r   ca_certsremote_serverr   r   r   rm   m  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     ,  Q