o
    K&b<                     @   s   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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mZ d dlmZ d dlmZ dZe ZG dd dejZdS )	    N)AnyDictListOptionalTupleUnion)aptcontractevent_logger
exceptionsmessagesstatusutil)base)ApplicationStatusz-32768c                	       sb  e Zd ZdZdZdZdZedee	e
df fddZedefdd	Zedee
 fd
dZdefddZeejde
fddZd+dedefddZd+ddZd+dedd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 		 	 d,d!ee
 d"ed#eddfd$d%Z!d+deddfd&d'Z"	d-d(edefd)d*Z#  Z$S ).RepoEntitlementz*/etc/apt/sources.list.d/ubuntu-{name}.listz$/etc/apt/preferences.d/ubuntu-{name}NFreturnc                 C      d S N selfr   r   </usr/lib/python3/dist-packages/uaclient/entitlements/repo.pyrepo_pin_priority%      z!RepoEntitlement.repo_pin_priorityc                 C   s   dS )NFr   r   r   r   r   disable_apt_auth_only*   r   z%RepoEntitlement.disable_apt_auth_onlyc                 C   sH   g }| j j| ji di }|r"|di }t|dg }|}|S )zdebs to install on enablemententitlement
directivesadditionalPackages)cfgentitlementsgetnamecopy)r   packagesr   r   Zadditional_packagesr   r   r   r$   .   s   
zRepoEntitlement.packagesc                 C   s    t jt| jd}t| |S )z%Check if system needs to be rebooted.)Zinstalled_pkgs)r   Zshould_rebootsetr$   eventZneeds_reboot)r   Zreboot_requiredr   r   r   _check_for_rebootA   s   
z!RepoEntitlement._check_for_rebootc                 C   r   r   r   r   r   r   r   repo_key_fileG   s   zRepoEntitlement.repo_key_filesilentc                 C   s:   | j |d |   ttjj| jd | jdd dS )zEnable specific entitlement.

        @return: True on success, False otherwise.
        @raises: UserFacingError on failure to install suggested packages
        r)   titleinstall)Z	operationT)	setup_apt_configinstall_packagesr&   infor   ZENABLED_TMPLformatr,   Z_check_for_reboot_msgr   r)   r   r   r   _perform_enableL   s
   zRepoEntitlement._perform_enablec                 C   s"   t | dr	|   | j|d dS )Nremove_packagesr*   T)hasattrr4   _cleanupr2   r   r   r   _perform_disableZ   s   
z RepoEntitlement._perform_disablec                 C   s   | j |d dS )z4Clean up the entitlement without checks or messagingr*   N)remove_apt_configr2   r   r   r   r6   `   s   zRepoEntitlement._cleanupc                 C   s   | j j| ji }|di di }|d}|s%tjtjj| j	dfS |
d\}}tddgtjj}td||}|rS|d	tkrStjtjj| j	dfS tjtjj| j	dfS )
Nr   r   aptURLr+   z://z	apt-cachepolicyz(?P<pin>(-)?\d+) {}/ubuntuZpin)r   r    r!   r"   r   DISABLEDr   ZNO_APT_URL_FOR_SERVICEr1   r,   splitr   Zrun_apt_commandZAPT_POLICY_FAILEDmsgresearchgroupAPT_DISABLED_PINZENABLEDZSERVICE_IS_ACTIVEZSERVICE_NOT_CONFIGURED)r   Zentitlement_cfgr   repo_urlZprotocolZ	repo_pathr:   matchr   r   r   application_statusd   s.   

z"RepoEntitlement.application_statusc                 C   sP   | j j| jd}tdd t| dD rdS |sdS t|t|v S )zCheck if apt url delta should be applied.

        :param apt_url: string containing the apt url to be used.

        :return: False if apt url is already found on the source file.
                 True otherwise.
        r"   c                 s   s    | ]}| d V  qdS )#N)
startswith).0liner   r   r   	<genexpr>   s
    
z<RepoEntitlement._check_apt_url_is_applied.<locals>.<genexpr>
FT)	repo_list_file_tmplr1   r"   allr   Z	load_filestripr<   bool)r   Zapt_urlZapt_filer   r   r   _check_apt_url_is_applied   s   z)RepoEntitlement._check_apt_url_is_appliedorig_accessdeltasallow_enablec                    s
  t  |||r
dS |di }|di }|d}|d}| jd}|r/|r/|  }	n|  \}	}
|	tjj	kr=dS | 
|sptd| j |di }|di d}|rh| jj| jd	}t|| |   |   |rtd
d| | j|d 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.
        Tr   r   r9   r   zstatus-cacheFz5Updating '%s' apt sources list on changed directives.rE   z-Installing packages on changed directives: {}, )package_list)superprocess_contract_deltasr!   r   Z
read_cacheZ"_check_application_status_on_cacherD   r   r   r;   rP   loggingr0   r"   rL   r1   r   remove_auth_apt_repor8   r.   joinr/   )r   rQ   rR   rS   Zdelta_entitlementZdelta_directivesZdelta_apt_urlZdelta_packagesZstatus_cacherD   _Zorig_entitlementZold_urlrepo_filename	__class__r   r   rW      s@   



z'RepoEntitlement.process_contract_deltasTrU   cleanup_on_failureverbosec                 C   s   |s| j }|s	dS | jdg }t|sdS |r#tdj| jd | j	r/ddi}g d}ni }g }zt
jj| jd}tj|||j|d W dS  tjyW   |rV|    w )	a)  Install contract recommended packages for the entitlement.

        :param package_list: Optional package list to use instead of
            self.packages.
        :param cleanup_on_failure: Cleanup apt files if apt install fails.
        :param verbose: If true, print messages to stdout
        NZpre_installzInstalling {title} packagesr+   ZDEBIAN_FRONTENDZnoninteractive)z--allow-downgradesz$-o Dpkg::Options::="--force-confdef"z$-o Dpkg::Options::="--force-confold")r$   apt_optionsZ	error_msgenv)r$   Z	messagingr!   r   Zhandle_message_operationsr&   r0   r1   r,   apt_noninteractiver   ENABLED_FAILEDr   run_apt_install_commandr=   r   UserFacingErrorr6   )r   rU   r_   r`   Zmsg_opsrb   ra   r=   r   r   r   r/      s6   

z RepoEntitlement.install_packagesc                 C   s  t d| jjt j}t d| jjt j}tj||d | j	j
| jd}| jj| j}|d di }|d di }|d}|sl| jjd	 }	|d
sat| j}
|
|	| j}|ra|d}|sl|	}td| j |d}|s|td
| j|d}|st| j|d}|std
| j| jj| jr| jstd
| jtjj
| jdj| jj
| jd}| jdkrt||| j| j nt j!"|rt #| g }t j!"tj$s|%d t j!"tj&s|%d |r|st'(d
d)| ztj*|d W n tjy   | +   w t,||||| j- |s+t'(tj. zt/  W dS  tjyB   | j+dd  w )zSetup apt config based on the resourceToken and directives.
        Also sets up apt proxy if necessary.

        :raise UserFacingError: on failure to setup any aspect of this apt
           configuration
        ZhttpZhttps)
http_proxyhttps_proxyrE   r   r   obligationsZresourceTokenZmachineTokenZenableByDefaultzWNo resourceToken present in contract for service %s. Using machine token as credentialsaptKeyz<Ubuntu Advantage server provided no aptKey directive for {}.r9   Zsuitesz%Empty {} apt suites directive from {}z:Cannot setup apt pin. Empty apt repo origin value '{}'.
{}r+   neverzapt-transport-httpszca-certificateszInstalling prerequisites: {}rT   )r$   F)run_apt_updateN)0r   Zvalidate_proxyr   Zapt_http_proxyZPROXY_VALIDATION_APT_HTTP_URLZapt_https_proxyZPROXY_VALIDATION_APT_HTTPS_URLr   Zsetup_apt_proxyrL   r1   r"   r    r!   machine_tokenr	   ZUAContractClientZrequest_resource_machine_accessrX   Zwarningr,   r   rf   MissingAptURLDirectiveZcontract_urlr   originr   rd   r=   repo_pref_file_tmpladd_ppa_pinningospathexistsunlinkZAPT_METHOD_HTTPS_FILEappendZCA_CERTIFICATES_FILEr&   r0   rZ   re   r8   Zadd_auth_apt_repor(   APT_UPDATING_LISTSrun_apt_update_command)r   r)   rg   rh   r\   Zresource_cfgr   ri   tokenrm   ZclientZmachine_accessrj   rB   Zrepo_suitesrepo_pref_fileZprerequisite_pkgsr   r   r   r.     s   










z RepoEntitlement.setup_apt_configrl   c           	      C   s   t  d }| jj| jd}| jj| j di }|di }|d}|s,t	| j| j
r:t| t| nt||| j t|| | jrn| jj| jd}| jdkrct||| j| j ntj|rnt| |r~|sxttj t  dS dS )zRemove any repository apt configuration files.

        :param run_apt_update: If after removing the apt update
            command after removing the apt files.
        seriesrE   r   r   r9   rk   N)r   Zget_platform_inforL   r1   r"   r   r    r!   r   rn   r   r   Zremove_repo_from_apt_auth_fileZrestore_commented_apt_list_filerY   r(   Zremove_apt_list_filesr   rp   rq   ro   rr   rs   rt   ru   r&   r0   r   rw   rx   )	r   rl   r)   r{   r\   r   Zaccess_directivesrB   rz   r   r   r   r8   y  s<   



z!RepoEntitlement.remove_apt_config)F)NTT)TF)%__name__
__module____qualname__rL   rp   ro   rc   propertyr   intstrr   rO   r   r   r$   r'   abcabstractmethodr(   r3   r7   r6   r   r   r   r   ZNamedMessagerD   rP   r   r   rW   r/   r.   r8   __classcell__r   r   r]   r   r      sf    



?
3nr   )r   r#   rX   rr   r>   typingr   r   r   r   r   r   Zuaclientr   r	   r
   r   r   r   r   Zuaclient.entitlementsr   Zuaclient.statusr   rA   Zget_event_loggerr&   ZUAEntitlementr   r   r   r   r   <module>   s     $	