U
    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                       s2  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eedf dddZeeedf ddd	Zedd
dZedddZejedddZd ejeeedddZejdddZ ee!e"ej# f dddZ$eee"ej# f dddZ%dd Z&d!e'e(e)f e'e(e)f eed fddZ*  Z+S )"LivepatchEntitlementr
   FT.)returnc                 C   s0   ddl m} ddlm} t|tjt|tjfS )Nr   FIPSEntitlement)RealtimeKernelEntitlement)uaclient.entitlements.fipsr   Zuaclient.entitlements.realtimer   r   r   ZLIVEPATCH_INVALIDATES_FIPSZ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 )NZwsl)r   is_containerZget_virt_typer   r   r   r   <lambda>K   s   z9LivepatchEntitlement.static_affordances.<locals>.<lambda>Fc                      s    S Nr   r   Zis_fips_enabledr   r   r    Q       )r   r   r   boolapplication_statusr   ENABLEDr   Z"SERVICE_ERROR_INSTALL_ON_CONTAINERformatr   Z!LIVEPATCH_ERROR_WHEN_FIPS_ENABLED)r   r   Zfips_entr   r"   r   static_affordances;   s     	
z'LivepatchEntitlement.static_affordancesc                 C   s   dS )N   r   r   r   r   r   enable_stepsV   s    z!LivepatchEntitlement.enable_stepsc                 C   s   dS )N   r   r*   r   r   r   disable_stepsY   s    z"LivepatchEntitlement.disable_steps)progressr   c              
   C   s  | tj t s2|dtjjdd t  t	 s|dtjjdd zt
d W nH tjk
r } z(tjd|d |dtjjdd W 5 d	}~X Y nX t| ztd W nH tjk
r } z&tjd
|d ttjjdd W 5 d	}~X Y nX 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 n6 tjk
r } ztjt |dW 5 d	}~X Y nX t!|| | j"|dddS )zYEnable specific entitlement.

        @return: True on success, False otherwise.
        infoZsnapd)Zpackagesz
snapd snapz!Failed to install snapd as a snapexc_infozsnap install snapdZcommandNzFailed to refresh snapd snapzsnap refresh snapdr	   Zhttps)
http_proxyhttps_proxyZretry_sleepszcanonical-livepatch snapzcanonical-livepatchZ	error_msgT)process_directivesprocess_token)#r.   r   ZINSTALLING_LIVEPATCHr   Zis_snapd_installedemitZINSTALLING_PACKAGESr'   Zinstall_snapdZis_snapd_installed_as_a_snapZinstall_snapr   ProcessExecutionErrorLOGZwarningZEXECUTING_COMMAND_FAILEDZrun_snapd_wait_cmdZrefresh_snapeventr/   r	   Zvalidate_proxyr   r3   ZPROXY_VALIDATION_SNAP_HTTP_URLr4   ZPROXY_VALIDATION_SNAP_HTTPS_URLZconfigure_snap_proxyZSNAP_INSTALL_RETRIESr
   is_livepatch_installedZErrorInstallingLivepatchstrZconfigure_livepatch_proxysetup_livepatch_config)r   r.   er3   r4   r   r   r   _perform_enable\   s     
    
"  z$LivepatchEntitlement._perform_enable)r.   r6   r7   r   c              
   C   s  | tj | j | j}|rzt| W nV tj	k
r } z6t
jt||d |dtjjt|d W Y dS d}~X Y nX |r|d}|st
d| j | jjd }|  \}}|tjkr8t
d	 |dtj zttjd
g W n> tj	k
r6 } zt
jt||d W Y dS d}~X Y nX ztjtjd|gdd W n tj	k
r } zdtj}	t D ]&\}
}|
t|krv|	|7 }	 qqv|	tjkr|	t|7 }	|d|	 W Y dS d}~X Y nX 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.
        r0   r/   r5   FNresourceTokenzHNo specific resourceToken present. Using machine token as %s credentialsZmachineTokenz&Disabling livepatch before re-enablingdisableenableTZcapture)r.   r   ZSETTING_UP_LIVEPATCHZmachine_token_fileZentitlementsgetnameprocess_config_directivesr   r9   r:   errorr=   r8   ZLIVEPATCH_UNABLE_TO_CONFIGUREr'   debugr   Zmachine_tokenr%   r   DISABLEDr/   ZLIVEPATCH_DISABLE_REATTACHr   subpr
   LIVEPATCH_CMDZLIVEPATCH_UNABLE_TO_ENABLEERROR_MSG_MAPitems)r   r.   r6   r7   Zentitlement_cfgr?   Zlivepatch_tokenr%   Z_detailsmsgZerror_messageZprint_messager   r   r   r>      sb    




z+LivepatchEntitlement.setup_livepatch_config)r.   c                 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    r2   rD   )
r
   r<   rL   r.   r   ZEXECUTING_COMMANDr'   joinr   rK   )r   r.   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	k
rh } zt j
tjj|jdf W Y S d }~X Y nX |d kr~t jtjfS |S )N)Zlivepatch_error)r   r&   r
   r<   rJ   r   ZLIVEPATCH_NOT_ENABLEDstatusr   r9   ZWARNINGZ LIVEPATCH_CLIENT_FAILURE_WARNINGr'   stderrZ+LIVEPATCH_APPLICATION_STATUS_CLIENT_FAILURE)r   rT   Zlivepatch_statusr?   r   r   r   r%      s     
z'LivepatchEntitlement.application_statusc                 C   sz   t  }|t jjkr4t }dtjj|j	|j
dfS |t jjkr`t }dtjj|j	|j
dfS |t jjkrvdtjfS dS )NT)versionZarch)FN)r
   on_supported_kernelLivepatchSupportUNSUPPORTEDr   Zget_kernel_infor   ZLIVEPATCH_KERNEL_NOT_SUPPORTEDr'   Zuname_releaseZuname_machine_archZ
KERNEL_EOLZLIVEPATCH_KERNEL_EOLZKERNEL_UPGRADE_REQUIREDZ!LIVEPATCH_KERNEL_UPGRADE_REQUIRED)r   ZsupportZ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
   rW   rX   rY   r   r   r   Z*LIVEPATCH_KERNEL_NOT_SUPPORTED_DESCRIPTIONr*   r   r   r   status_description_override+  s    z0LivepatchEntitlement.status_description_override)orig_accessdeltasallow_enabler   c                    s   t  |||rdS |di }|di dd}|rN| t \}}|S |  \}}|tjkrhdS |di }	t	ddg}
t
|
|	}t
|d	d}t||grt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entitlementZobligationsZenableByDefaultF
directivescaCertsremoteServerrA   zANew livepatch directives or token. running setup_livepatch_config)service)r.   r6   r7   )superprocess_contract_deltasrE   rC   r   ProgressWrapperr%   r   rJ   setr$   intersectionanyr:   r/   r;   r   Z#SERVICE_UPDATING_CHANGED_DIRECTIVESr'   rF   r>   )r   r\   r]   r^   Zdelta_entitlementZprocess_enable_defaultZenable_success_r%   Zdelta_directivesZsupported_deltasr6   r7   	__class__r   r   re   4  sD     
z,LivepatchEntitlement.process_contract_deltas)TT)F),__name__
__module____qualname__r   ZurlsZLIVEPATCH_HOME_PAGEZhelp_doc_urlrF   ZLIVEPATCH_TITLEr   ZLIVEPATCH_DESCRIPTIONZdescriptionZLIVEPATCH_HELP_TEXTZ	help_textZ#affordance_check_kernel_min_versionZaffordance_check_kernel_flavorZaffordance_check_seriesZaffordance_check_archpropertyr   r   r   r   r(   intr+   r-   r   rf   r$   r@   r>   rS   r   r   ZNamedMessager%   rZ   r[   r   r=   r   re   __classcell__r   r   rk   r   r      sJ   I  A  

r   c                 C   s   | sdS |  di  di }| d}|rFtjtjdd|gdd | d	d
}|drh|dd }|rtjtjdd|gdd 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`   ra   Zconfigzca-certs={}TrD   rb    /zremote-server={})rE   r   rK   r
   rL   r'   endswith)r   r`   Zca_certsZremote_serverr   r   r   rG   m  s.    


rG   )!Zloggingtypingr   r   r   r   Zuaclientr   r   r   r	   r
   r   r   r   r   Zuaclient.entitlements.baser   r   Z(uaclient.entitlements.entitlement_statusr   Zuaclient.typesr   ZLIVEPATCH_RETRIESrM   Zget_event_loggerr;   Z	getLoggerZreplace_top_level_logger_namerm   r:   r   rG   r   r   r   r   <module>   s   ,  Q