o
    S¯KjS;  ã                   @   sT  d dl Z d dlZ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	 d dl
mZmZmZmZmZmZmZmZ d dl
mZ d dl
mZmZ d dl
mZ d dl
mZmZmZ d dlmZmZmZm Z  d d	l!m"Z"m#Z# d d
l$m%Z%m&Z&m'Z'm(Z(m)Z) e *¡ Z+e ,e -e.¡¡Z/dZ0dZ1dej2dej3de j fdd„Z4	d8dej2deej5 dej3de j de6f
dd„Z7	d8dej2de8de6de6ddf
dd„Z9	d9dej2dej:ddfdd„Z;dd ddd!œdej2d"e8d#e6d$e8de6d%e	ee8  fd&d'„Z<ddd(œdej2d)e	e8 d*e6fd+d,„Zd-e8ddfd.d/„Z=	d:d-e8d0e	ee>  ddfd1d2„Z?dej2fd3d4„Z@dej2d5e8fd6d7„ZAdS );é    N)ÚListÚOptional)ÚapiÚcloudsÚconfigÚcontractÚentitlementsÚevent_loggerÚ
exceptionsÚ	livepatch)Úlog)ÚmessagesÚsecret_manager)Ústatus)ÚsystemÚtimerÚutil)ÚAPPARMOR_PROFILESÚCLOUD_BUILD_INFOÚDEFAULT_CONFIG_FILEÚDEFAULT_LOG_PREFIX)Úmachine_tokenÚnotices)ÚAttachmentDataÚattachment_data_fileÚmachine_id_fileÚonly_series_check_marker_fileÚtimer_jobs_state_file)zapt-news.servicezesm-cache.servicezua-timer.servicezua-timer.timerzua-auto-attach.pathzua-auto-attach.servicezua-reboot-cmds.servicezubuntu-advantage.serviceé
   ÚcfgÚcontract_clientÚattached_atc                 C   s<   ddl m} t t|d�¡ tj| d� || ƒ | ¡  d S )Nr   ©Úupdate_motd_messages©r!   ©r   )Úuaclient.timer.update_messagingr#   r   Úwriter   Ú	ua_statusr   Úupdate_activity_token)r   r    r!   r#   © r*   ú2/usr/lib/python3/dist-packages/uaclient/actions.pyÚ_handle_partial_attach9   s
   r,   FÚservices_to_be_enabledÚsilentc              
   C   sD  d}g }g }z'|D ]"}t | |j|j|d�\}	}
||	M }|	s$| |j¡ q	tj|jd� q	W nJ tjyH } zt |j¡ t	| ||ƒ |‚d }~w tj
yY   | |j¡ d}Y n tyw } zd}| |j¡ | |¡ W Y d }~nd }~ww |s t	| ||ƒ t |¡ |r•tjdd„ t||ƒD ƒd�‚tjdd„ |D ƒd�‚d S )	NT)r   ÚnameÚvariantr.   )ÚserviceFc                 S   s,   g | ]\}}|t jjt|ƒt ¡ d �f‘qS ))Ú	error_msgÚlog_path)r   ÚUNEXPECTED_ERRORÚformatÚstrÚpro_logÚget_user_or_root_log_file_path)Ú.0r/   Ú	exceptionr*   r*   r+   Ú
<listcomp>r   s    úþþÿz,_enable_default_services.<locals>.<listcomp>)Úfailed_servicesc                 S   s   g | ]}|t jf‘qS r*   )r   Ú!E_ATTACH_FAILURE_DEFAULT_SERVICES)r9   r/   r*   r*   r+   r;   �   s    ÿÿ)Úenable_entitlement_by_namer/   r0   ÚappendÚeventÚservice_processedr
   ÚConnectivityErrorÚservice_failedr,   ÚUbuntuProErrorÚ	ExceptionÚservices_failedÚAttachFailureUnknownErrorÚzipÚAttachFailureDefaultServices)r   r-   r    r!   r.   Úretr<   Úunexpected_errorsÚenable_by_default_serviceÚent_retÚreasonÚexcÚer*   r*   r+   Ú_enable_default_servicesF   s^   
üô€€ý
ÿøÿþÿërQ   ÚtokenÚallow_enableÚreturnc              
   C   sÔ  ddl m} ddlm} tj |¡ t | ¡}t	 
| ¡}tjjtjjd�}|j||d�}	t ¡ j}
|	 di ¡ di ¡}tdd	„ | d
g ¡D ƒƒ}| di ¡ di ¡ dd¡}|r�zt |¡}W n
 tjyi   Y n&w t |
¡}|j|jkr~tj|j|jd�‚tjtjj|j|jd� t  !|¡ | !|	¡ z|| ƒ W n tj"y­ } z| #¡  |‚d}~ww tj$ %¡  |	 di ¡ dt $| ¡¡}t& !|¡ |rØt	 '| | (¡ ¡}t)| ||||d� t* !t+|d�¡ || ƒ t, -¡  dS )aC  
    Common functionality to take a token and attach via contract backend
    :raise ConnectivityError: On unexpected connectivity issues to contract
        server or inability to access identity doc from metadata service.
    :raise ContractAPIError: On unexpected errors when talking to the contract
        server.
    r   )Ú+check_entitlement_apt_directives_are_uniquer"   )Útz)Úcontract_tokenÚattachment_dtÚmachineTokenInfoÚcontractInfoc                 s   s,   � | ]}|  d ¡dkr|  d ¡|fV  qdS )ÚtypeÚsupportN)Úget)r9   rP   r*   r*   r+   Ú	<genexpr>¦   s   € þýz$attach_with_token.<locals>.<genexpr>ÚresourceEntitlementsr\   ÚaffordancesÚ
onlySeriesN)ÚreleaseÚseries_codenameÚ	machineId)r   r-   r    r!   r.   r$   ).Úuaclient.entitlementsrU   r&   r#   r   ÚsecretsÚ
add_secretr   Úget_machine_token_filer   ÚUAContractClientÚdatetimeÚnowÚtimezoneÚutcÚadd_contract_machiner   Úget_release_infoÚseriesr]   ÚdictÚget_distro_infor
   ÚMissingSeriesInDistroInfoFileÚeolÚAttachFailureRestrictedReleaserb   rc   r   ÚaddÚNoticeÚLIMITED_TO_RELEASEr   r'   Ú%EntitlementsAPTDirectivesAreNotUniqueÚdeleteÚget_machine_idÚcache_clearr   Úget_enabled_by_default_servicesr   rQ   r   r   r   Ústart)r   rR   rS   r.   rU   r#   Úmachine_token_filer    r!   Únew_machine_tokenÚcurrent_seriesrZ   Úsupport_resourceÚonly_seriesÚallowed_releaseÚcurrent_releaserP   Ú
machine_idr-   r*   r*   r+   Úattach_with_tokenˆ   s‚   

ÿ
ÿ
þ
ýý
þý

€þ

ÿ
ÿûr‡   TÚcloudc                 C   s   |  | ¡}t| ||d� dS )a\  
    :raise ConnectivityError: On unexpected connectivity issues to contract
        server or inability to access identity doc from metadata service.
    :raise ContractAPIError: On unexpected errors when talking to the contract
        server.
    :raise NonAutoAttachImageError: If this cloud type does not have
        auto-attach support.
    )rR   rS   N)Úacquire_pro_tokenr‡   )r   rˆ   rS   rR   r*   r*   r+   Úauto_attachç   s   
rŠ   Ú )Úaccess_onlyr0   r.   Ú
extra_argsr/   rŒ   r0   r�   c          	      C   sf   t j| ||||d�}|st tjj|jd�¡ | t	 
¡ ¡\}}|r/|s/t tjj|jd�¡ ||fS )zè
    Constructs an entitlement based on the name provided. Passes kwargs onto
    the entitlement constructor.
    :raise EntitlementNotFoundError: If no entitlement with the given name is
        found, then raises this error.
    )r   r/   r0   rŒ   r�   )Útitle)r   Úentitlement_factoryr@   Úinfor   ÚENABLING_TMPLr5   rŽ   Úenabler   ÚProgressWrapperÚENABLED_TMPL)	r   r/   rŒ   r0   r.   r�   ÚentitlementrM   rN   r*   r*   r+   r>   ø   s   ûr>   )Úsimulate_with_tokenÚshow_allr–   r—   c                C   s:   |rt j| ||d�\}}||fS t j| |d�}d}||fS )z6
    Construct the current Pro status dictionary.
    )r   rR   r—   ©r   r—   r   )r(   Úsimulate_statusr   )r   r–   r—   r   rJ   r*   r*   r+   r     s   	
ý	ýr   Úfilenamec              
   C   sº   g d¢}d}d}z	t  |¡\}}W n' tjy8 } zt dt|ƒ¡ t  d | ¡t|ƒ¡ W Y d}~dS d}~ww |r[g }| 	d¡D ]}t
 ||¡rO| |¡ qBt  | d |¡¡ dS dS )z…
    Helper which gets ubuntu_pro apparmor logs from the kernel from the last
    day and writes them to the specified filename.
    )Ú
journalctlz-bz-kz--since=1 day agoz7apparmor=\".*(profile=\"ubuntu_pro_|name=\"ubuntu_pro_)Nz!Failed to collect kernel logs:
%sú{}-errorÚ
)r   Úsubpr
   ÚProcessExecutionErrorÚLOGÚwarningr6   Ú
write_filer5   ÚsplitÚreÚsearchr?   Újoin)rš   ÚcmdÚapparmor_reÚkernel_logsÚ_rP   Úapparmor_logsÚkernel_liner*   r*   r+   Ú_write_apparmor_logs_to_file0  s$   $€þ
€úr­   Úreturn_codesc              
   C   sr   zt j|  ¡ |d�\}}W n tjy, } zt  d |¡t|ƒ¡ W Y d}~dS d}~ww t  |d ||¡¡ dS )zCHelper which runs a command and writes output or error to filename.)Úrcsrœ   Nzstdout:
{}

stderr:
{})r   rž   r£   r
   rŸ   r¢   r5   r6   )r§   rš   r®   ÚoutÚerrrP   r*   r*   r+   Ú_write_command_output_to_fileI  s   $€ÿÿr²   c                    s,   ˆ j ptˆ jtjjtg‡ fdd„tjD ƒ¢S )Nc                 3   s(   � | ]}t |tjjƒr|ˆ ƒjV  qd S ©N)Ú
issubclassr   ÚrepoÚRepoEntitlementÚ	repo_file)r9   Úentitlement_clsr%   r*   r+   r^   ^  s   € ý
ÿz#_get_state_files.<locals>.<genexpr>)	Úcfg_pathr   Úlog_filer   Úua_fileÚpathr   r   ÚENTITLEMENT_CLASSESr%   r*   r%   r+   Ú_get_state_filesW  s   ü
þûr¾   Ú
output_dirc                 C   sÈ  t dd |¡ƒ t d tj¡d |¡ƒ t dd |¡ƒ t dd |¡ƒ t d	 d
 dd„ tD ƒ¡¡d |¡ƒ tD ]}t d |¡d ||¡ddgd� q9t| dd�\}}t d |¡t	j
|tjd�¡ t ¡ }t d |¡t	 
|¡¡ t| ƒ}t ¡ rƒt ¡ dt… nt ¡ g}t|ƒD ]D\}}	tj |	¡r�t d|	¡ qŒzt t |	¡¡}
t tj |d |¡¡|
¡ W qŒ tyÐ } zt d|	t|ƒ¡ W Y d}~qŒd}~ww |t td ¡ D ]L}tj  |¡�r&zt |¡}
W n t�y } zt d|t|ƒ¡ W Y d}~qÚd}~ww t |
¡}
t ¡ �rt ||
¡ t tj |tj !|¡¡|
¡ qÚt"d |¡ƒ t#D ]1}tj  |¡�r`z	t$ %||¡ W �q0 t�y_ } zt d|t|ƒ¡ W Y d}~�q0d}~ww �q0dS ) zG
    Write all relevant Ubuntu Pro logs to the specified directory
    zcloud-idz{}/cloud-id.txtz	{} statusz{}/livepatch-status.txtzsystemctl list-timers --allz{}/systemd-timers.txtzujournalctl --boot=0 -o short-precise -u cloud-init-local.service -u cloud-init-config.service -u cloud-config.servicez{}/cloud-init-journal.txtzjournalctl -o short-precise {}ú c                 S   s   g | ]}d |v rd  |¡‘qS )z.servicez-u {})r5   )r9   Úsr*   r*   r+   r;   �  s    z collect_logs.<locals>.<listcomp>z{}/pro-journal.txtzsystemctl status {}z	{}/{}.txtr   é   )r®   Fr˜   z{}/pro-status.json)Úclsz{}/environment_vars.jsonNz$Skipping symlinked user log file: %sz
user{}.logz&Failed to collect user log file: %s
%sÚ*zFailed to load file: %s
%sz{}/apparmor_logs.txtzFailed to copy file: %s
%s)&r²   r5   r   ÚLIVEPATCH_CMDr¦   ÚUA_SERVICESr   r   r¢   ÚjsonÚdumpsr   ÚDatetimeAwareJSONEncoderÚget_pro_environmentr¾   Úwe_are_currently_rootr7   Úget_all_user_log_filesÚUSER_LOG_COLLECTED_LIMITÚget_user_log_fileÚ	enumerateÚosr¼   Úislinkr    r¡   Úredact_sensitive_logsÚ	load_filerE   r6   Úglobr   ÚisfileÚbasenamer­   r   ÚshutilÚcopy)r   r¿   r1   Ú
pro_statusrª   Úenv_varsÚstate_filesÚuser_log_filesÚlog_file_idxrº   ÚcontentrP   Úfr*   r*   r+   Úcollect_logsf  s°   
ÿ
þþù	ÿÿú
ýþþÿýþ
ÿ€ÿ€û

ÿ€€þýÿrà   )F)Tr³   )Brj   rÔ   rÇ   ÚloggingrÐ   r¤   r×   Útypingr   r   Úuaclientr   r   r   r   r   r	   r
   r   r   r7   r   r   r   r(   r   r   r   Úuaclient.defaultsr   r   r   r   Úuaclient.filesr   r   Úuaclient.files.state_filesr   r   r   r   r   Úget_event_loggerr@   Ú	getLoggerÚreplace_top_level_logger_nameÚ__name__r    rÆ   rÍ   ÚUAConfigri   r,   ÚEnableByDefaultServiceÚboolrQ   r6   r‡   ÚAutoAttachInstancerŠ   r>   r­   Úintr²   r¾   rà   r*   r*   r*   r+   Ú<module>   sÀ    (
ÿþ
ýûÿþýü
ûFüÿþýü
ûbýÿþ
üùÿþüûú

ù%üÿý
üÿÿ
ÿ
þ