U
    Jhp:                  	   @   s  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Z1ej2ej3e j dddZ4d0ej2eej5 ej3e j e6dddZ7d1ej2e8e6e6ddddZ9d2ej2ej:ddddZ;dddddej2e8e6e8e6e	ee8  dddZ<ddd ej2e	e8 e6d!d"d#Ze8dd$d%d&Z=d3e8e	ee>  dd'd(d)Z?ej2d*d+d,Z@ej2e8d-d.d/ZAdS )4    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   Zupdate_activity_token)r   r    r!   r#    r)   2/usr/lib/python3/dist-packages/uaclient/actions.py_handle_partial_attach9   s
    r+   Fr   services_to_be_enabledr    r!   silentc              
   C   sT  d}g }g }zN|D ]D}t | |j|j|d\}	}
||	M }|	sH||j qtj|jd qW n tjk
r } z t|j t	| || |W 5 d }~X Y n` tj
k
r   ||j d}Y n< tk
r } zd}||j || W 5 d }~X Y nX |sPt	| || t| |r:tjdd t||D dn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 ))Z	error_msgZlog_path)r   ZUNEXPECTED_ERRORformatstrpro_logZget_user_or_root_log_file_path).0r/   Z	exceptionr)   r)   r*   
<listcomp>r   s   z,_enable_default_services.<locals>.<listcomp>)failed_servicesc                 S   s   g | ]}|t jfqS r)   )r   Z!E_ATTACH_FAILURE_DEFAULT_SERVICES)r5   r/   r)   r)   r*   r6      s   )enable_entitlement_by_namer/   r0   appendeventZservice_processedr
   ZConnectivityErrorZservice_failedr+   ZUbuntuProError	ExceptionZservices_failedZAttachFailureUnknownErrorzipZAttachFailureDefaultServices)r   r-   r    r!   r.   retr7   Zunexpected_errorsZenable_by_default_serviceent_retreasonexcer)   r)   r*   _enable_default_servicesF   sV    

 rB   )r   tokenallow_enabler.   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k
r   Y n,X t|
}|j|jkrtj|j|jdtjtjj|j|jd t !| |!|	 z||  W n2 tj"k
rl } z|#  |W 5 d}~X Y nX tj$%  |	di dt$| }t&!| |rt	'| |( }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"   )Ztz)Zcontract_tokenZattachment_dtZmachineTokenInfocontractInfoc                 s   s*   | ]"}| d dkr| d |fV  qdS )typesupportN)get)r5   rA   r)   r)   r*   	<genexpr>   s   z$attach_with_token.<locals>.<genexpr>ZresourceEntitlementsrI   ZaffordancesZ
onlySeriesN)releaseseries_codenameZ	machineIdr,   r$   ).Zuaclient.entitlementsrF   r&   r#   r   ZsecretsZ
add_secretr   Zget_machine_token_filer   UAContractClientdatetimeZnowtimezoneZutcZadd_contract_machiner   Zget_release_infoZseriesrJ   dictZget_distro_infor
   ZMissingSeriesInDistroInfoFileZeolZAttachFailureRestrictedReleaserL   rM   r   addZNoticeZLIMITED_TO_RELEASEr   r'   Z%EntitlementsAPTDirectivesAreNotUniquedeleteZget_machine_idcache_clearr   Zget_enabled_by_default_servicesr   rB   r   r   r   start)r   rC   rD   r.   rF   r#   Zmachine_token_filer    r!   Znew_machine_tokenZcurrent_seriesrG   Zsupport_resourceZonly_seriesZallowed_releaseZcurrent_releaserA   Z
machine_idr-   r)   r)   r*   attach_with_token   s    

 
 
  



 
 rV   T)r   cloudrE   c                 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.
    )rC   rD   N)Zacquire_pro_tokenrV   )r   rW   rD   rC   r)   r)   r*   auto_attach   s    
rX    )access_onlyr0   r.   
extra_args)r   r/   rZ   r0   r.   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   rZ   r[   )title)r   Zentitlement_factoryr:   infor   ZENABLING_TMPLr2   r\   enabler   ZProgressWrapperZENABLED_TMPL)	r   r/   rZ   r0   r.   r[   Zentitlementr>   r?   r)   r)   r*   r8      s    r8   )simulate_with_tokenshow_all)r   r_   r`   c                C   s4   |rt j| ||d\}}nt j| |d}d}||fS )z6
    Construct the current Pro status dictionary.
    )r   rC   r`   r   r`   r   )r(   Zsimulate_statusr   )r   r_   r`   r   r=   r)   r)   r*   r     s    	r   )filenamerE   c              
   C   s   ddddg}d}d}zt |\}}W nJ tjk
rp } z*tdt| t d| t| W 5 d}~X Y nBX |rg }|	d	D ]}t
||r|| qt | d	| dS )
z
    Helper which gets ubuntu_pro apparmor logs from the kernel from the last
    day and writes them to the specified filename.
    Z
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warningr3   
write_filer2   splitresearchr9   join)rb   cmdZapparmor_reZkernel_logs_rA   Zapparmor_logsZkernel_liner)   r)   r*   _write_apparmor_logs_to_file0  s    (rp   )rb   return_codesrE   c              
   C   sn   zt j|  |d\}}W n: tjk
rT } zt d|t| W 5 d}~X Y nX t |d|| dS )zCHelper which runs a command and writes output or error to filename.)Zrcsrc   Nzstdout:
{}

stderr:
{})r   re   rj   r
   rf   ri   r2   r3   )rn   rb   rq   outerrrA   r)   r)   r*   _write_command_output_to_fileI  s    ( 
rt   r%   c                    s,    j pt jtjjtf fddtjD S )Nc                 3   s&   | ]}t |tjjr| jV  qd S )N)
issubclassr   ZrepoZRepoEntitlementZ	repo_file)r5   Zentitlement_clsr%   r)   r*   rK   ^  s   z#_get_state_files.<locals>.<genexpr>)	Zcfg_pathr   log_filer   Zua_filepathr   r   ZENTITLEMENT_CLASSESr%   r)   r%   r*   _get_state_filesW  s    
rx   )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 qrt| dd\}}td|t	j
|tjd t }td|t	
| t| }t rt dt nt g}t|D ]r\}}	z0tt|	}
ttj|d||
 W n6 tk
r } ztd|	t| W 5 d}~X Y nX q|ttd  D ]}tj|rzt|}
W n@ tk
r  } z td|t| W Y qW 5 d}~X Y nX t|
}
t r"t||
 ttj|tj ||
 qt!d| t"D ]f}tj|rVzt#$|| W n@ tk
r } z td|t| W Y qVW 5 d}~X Y nX qVd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 |krd |qS )z.servicez-u {})r2   )r5   sr)   r)   r*   r6     s      z collect_logs.<locals>.<listcomp>z{}/pro-journal.txtzsystemctl status {}z	{}/{}.txtr      )rq   Fra   z{}/pro-status.json)clsz{}/environment_vars.jsonNz
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)%rt   r2   r   ZLIVEPATCH_CMDrm   UA_SERVICESr   r   ri   jsondumpsr   ZDatetimeAwareJSONEncoderZget_pro_environmentrx   Zwe_are_currently_rootr4   Zget_all_user_log_filesUSER_LOG_COLLECTED_LIMITZget_user_log_file	enumerateZredact_sensitive_logsZ	load_fileosrw   r;   rg   rh   r3   globr   isfilebasenamerp   r   shutilcopy)r   ry   r1   Z
pro_statusro   Zenv_varsZstate_filesZuser_log_filesZlog_file_idxrv   ZcontentrA   fr)   r)   r*   collect_logsf  s     
	
  

 r   )F)F)T)N)BrO   r   r   Zloggingr   rk   r   typingr   r   Zuaclientr   r   r   r   r   r	   r
   r   r   r4   r   r   r   r(   r   r   r   Zuaclient.defaultsr   r   r   r   Zuaclient.filesr   r   Zuaclient.files.state_filesr   r   r   r   r   Zget_event_loggerr:   Z	getLoggerZreplace_top_level_logger_name__name__rg   r   r   ZUAConfigrN   r+   ZEnableByDefaultServiceboolrB   r3   rV   ZAutoAttachInstancerX   r8   rp   intrt   rx   r   r)   r)   r)   r*   <module>   s   (
 F b 
%  
