o
    x[hN7  ã                   @   sˆ  d 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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 ddl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 eej e !e"¡ƒZ#G d
d„ deƒZ$e$ddƒe$ddƒe$ddƒgZ%e$ddƒe$ddƒe$ddƒe$ddƒe$ddƒe$ddƒe$ddƒe$d d!ƒe$d"d#ƒe$d$d%ƒe$d&d%ƒe$d'd(ƒgZ&	dcd)eej' d*ej'fd+d,„Z(d-ee) d.ej*d/e)d*ee) fd0d1„Z+d-ee) d.ej*d/e)d*dfd2d3„Z,d4ej*d5ej*d6e-d*dfd7d8„Z.d9ej*d6e-d*dfd:d;„Z/d9ej*d*dfd<d=„Z0d9ej*d6e-d*dfd>d?„Z1d@ee)ef d*eej* fdAdB„Z2e *dC¡fdDej*d*eej* fdEdF„Z3dGej*d*eej* fdHdI„Z4dJej*d*eej* fdKdL„Z5d9ej*d@ee)ef dJej*dGej*d6e-d*dfdMdN„Z6e *dO¡e *dP¡dQfdRe)d@ee)ef dJej*dGej*d6e-d*dfdSdT„Z7dUe8d*dfdVdW„Z9		Q	XdddRe)dUe8dYe-dZe-d*df
d[d\„Z:d]e)d^ej;d*e8fd_d`„Z<e"dak�rÂe =e<dbe(ƒ  >¡ ƒ¡ dS dS )ezGDefine 'collect-logs' utility and handler to include in cloud-init cmd.é    N)ÚdatetimeÚtimezone)ÚAnyÚDictÚIteratorÚListÚ
NamedTupleÚOptionalÚcast)Úloggers)ÚInit)ÚProcessExecutionErrorÚsubp)Útempdir)ÚcopyÚget_config_logfilesÚ
write_filec                   @   s   e Zd ZU eed< eed< dS )Ú
ApportFileÚpathÚlabelN)Ú__name__Ú
__module__Ú__qualname__ÚstrÚ__annotations__© r   r   ú:/usr/lib/python3/dist-packages/cloudinit/cmd/devel/logs.pyr      s   
 r   z(/var/log/installer/autoinstall-user-dataÚAutoInstallUserDataz/autoinstall.yamlÚAutoInstallYAMLz'/etc/cloud/cloud.cfg.d/99-installer.cfgÚInstallerCloudCfgz//var/log/installer/ubuntu_desktop_installer.logÚUdiLogz-/var/log/installer/subiquity-server-debug.logÚSubiquityServerDebugz-/var/log/installer/subiquity-client-debug.logÚSubiquityClientDebugz%/var/log/installer/curtin-install.logÚ	CurtinLogz0/var/log/installer/subiquity-curtin-install.confÚCurtinInstallConfigz8/var/log/installer/curtin-install/subiquity-initial.confÚCurtinConfigInitialz:/var/log/installer/curtin-install/subiquity-curthooks.confÚCurtinConfigCurtHooksz8/var/log/installer/curtin-install/subiquity-extract.confÚCurtinConfigExtractz=/var/log/installer/curtin-install/subiquity-partitioning.confÚCurtinConfigPartitioningz(/var/log/installer/curtin-error-logs.tarÚCurtinErrorz$/var/log/installer/curtin-errors.tarz(/var/log/installer/block/probe-data.jsonÚ	ProbeDataÚparserÚreturnc                 C   sh   | s	t jddd�} | jdddddd	d
� | jddddd� | jddddddd� | jdddddd� | S )a2  Build or extend and arg parser for collect-logs utility.

    @param parser: Optional existing ArgumentParser instance representing the
        collect-logs subcommand which will be extended to support the args of
        this utility.

    @returns: ArgumentParser with proper argument configuration.
    zcollect-logsz)Collect and tar all cloud-init debug info)ÚprogÚdescriptionz	--verbosez-vÚcountr   Ú	verbosityzBe more verbose.)ÚactionÚdefaultÚdestÚhelpz	--tarfilez-tzcloud-init.tar.gzzOThe tarfile to create containing all collected logs. Default: cloud-init.tar.gz)r2   r4   z--include-userdataz-uFÚ
store_trueÚuserdataz?DEPRECATED: This is default behavior and this flag does nothing)r2   r1   r3   r4   z--redact-sensitivez-rz€Redact potentially sensitive data from logs. Sensitive data may include passwords or keys in user data and root read-only files.)r2   r1   r4   )ÚargparseÚArgumentParserÚadd_argument)r+   r   r   r   Ú
get_parserO   sF   þúû	ù
úr:   ÚcmdÚ	file_pathÚmsgc              
   C   s‚   |j jddd� zt| ƒj}W n" ty1 } zt|t|ƒƒ t d|¡ d}W Y d}~|S d}~ww t||ƒ t d||j	¡ |S )zCHelper which runs a command and writes output or error to filename.T©ÚparentsÚexist_okúcollecting %s failed.Núcollected %s to file '%s')
ÚparentÚmkdirr   Ústdoutr   r   r   ÚLOGÚdebugÚstem)r;   r<   r=   ÚoutputÚer   r   r   Ú_write_command_output_to_fileˆ   s   €ù
rK   c              
   C   s¤   |j jddd� z| d¡�}tj| ||d� W d  ƒ n1 s!w   Y  W n  tyG } zt|t|ƒƒ t 	d|¡ W Y d}~dS d}~ww t 	d||j
¡ dS )zÐHelper which runs a command and writes output or error to filename.

    `subprocess.call` is invoked directly here to stream output to the file.
    Otherwise memory usage can be high for large outputs.
    Tr>   Úw)rE   ÚstderrNrA   rB   )rC   rD   ÚopenÚ
subprocessÚcallÚOSErrorr   r   rF   rG   rH   )r;   r<   r=   ÚfrJ   r   r   r   Ú_stream_command_output_to_file›   s   ÿ€€þrS   r   Úout_dirÚinclude_sensitivec                 C   sd   |   ¡ r*|s|  ¡ jtj@ r"|jddd� t| |ƒ t d| ¡ dS t d| ¡ dS t d| ¡ dS )z-Collect a file into what will be the tarball.Tr>   zcollected file: %sz#sensitive file %s was not collectedzfile %s did not existN)	Úis_fileÚstatÚst_modeÚS_IROTHrD   r   rF   rG   Útrace)r   rT   rU   r   r   r   Ú_collect_file®   s   
r[   Úlog_dirc                 C   s|   t D ]}t | |jdd… ¡j}tt |j¡|dd� q|r:tD ]}t | |jdd… ¡j}tt |j¡|dd� q dS dS )z'Obtain subiquity logs and config files.é   NT)rU   )ÚINSTALLER_APPORT_FILESÚpathlibÚPathr   rC   r[   Ú INSTALLER_APPORT_SENSITIVE_FILES)r\   rU   Úsrc_fileÚdestination_dirr   r   r   Ú_collect_installer_logs½   s"   
ý
ýýrd   c                 C   s@   t ddg| d dd�}t g d¢| d dd�}|s|pd	}d
S d
S )z8Include cloud-init version and dpkg version in the logs.ú
cloud-initz	--versionÚversionzcloud-init --version©r;   r<   r=   )z
dpkg-queryz--showz-f=${Version}
re   zdpkg-versionzdpkg versionznot-availableN)rK   )r\   rf   Údpkg_verr   r   r   Ú_collect_version_infoÒ   s   ýýÿri   c                 C   sL   |rt dg| d dd� t g d¢| d dd� t g d¢t | d	¡d
d� dS )z0Include dmesg and journalctl output in the logs.Údmesgz	dmesg.txtzdmesg outputrg   )Ú
journalctlz--boot=0ú-oúshort-precisezjournal.txtzsystemd journal of current boot)rk   z	--boot=-1rl   rm   zjournal-previous.txtz systemd journal of previous bootN)rS   r_   r`   )r\   rU   r   r   r   Ú_collect_system_logsâ   s    ýý

ýrn   Úlog_cfgc                 c   s    � t | ƒD ]}t |¡V  qdS )z7Get paths for cloud-init.log and cloud-init-output.log.N)r   r_   r`   )ro   r   r   r   r   Ú_get_cloudinit_logsø   s   €ÿrp   z
/etc/cloudÚetc_cloud_dirc                 #   s6   � | d | d dg‰ ‡ fdd„|   d¡D ƒE dH  dS )zÂGet paths for all files in /etc/cloud.

    Excludes:
      /etc/cloud/keys because it may contain non-useful sensitive data.
      /etc/cloud/templates because we already know its contents
    ÚkeysÚ	templatesz99-installer.cfgc                 3   s(   � | ]}|j ˆ vr|jˆ vr|V  qd S ©N)ÚnamerC   )Ú.0r   ©Úignorer   r   Ú	<genexpr>  s   € þýz!_get_etc_cloud.<locals>.<genexpr>z**/*N©Úglob)rq   r   rw   r   Ú_get_etc_cloud   s   €
ü
þr|   Ú	cloud_dirc              	   C   s:   t  |  d¡|  d¡|  d¡dd„ |  d¡D ƒ|  d¡¡S )zkGet paths for files in /var/lib/cloud.

    Skip user-provided scripts, semaphores, and old instances.
    zdata/*z
handlers/*zseed/*c                 s   s   � | ]	}|  ¡ r|V  qd S rt   )rV   )rv   Úpr   r   r   ry     s   € z%_get_var_lib_cloud.<locals>.<genexpr>z
instance/*zinstance/handlers)Ú	itertoolsÚchainr{   ©r}   r   r   r   Ú_get_var_lib_cloud  s   ûr‚   Úrun_dirc                 C   s
   |   d¡S )zÀGet all paths under /run/cloud-init except for hook-hotplug-cmd.

    Note that this only globs the top-level directory as there are currently
    no relevant files within subdirectories.
    Ú*rz   ©rƒ   r   r   r   Ú_get_run_dir$  s   
r†   c                 C   sŒ   t | ƒ t| |ƒ t| |ƒ t|ƒD ]}t|| t |¡j d¡ dƒ qt	 
tƒ t|d�t|d�¡D ]}t|| t |¡j d¡ |ƒ q2dS )z8Collect all cloud-init logs into the provided directory.ú/Tr�   r…   N)ri   rn   rd   rp   r[   r_   r`   rC   Úrelative_tor   r€   r|   r‚   r†   )r\   ro   rƒ   r}   rU   Úlogfiler   r   r   Ú_collect_logs_into_tmp_dir-  s(   

ýýýûrŠ   z/run/cloud-initz/var/lib/cloudTÚtarfilec                 C   s    t j | ¡} t tj¡ ¡  d¡}t	|d��*}t
 ||¡}t|||||d� tdd| d|t|ƒ |› d�d¡gƒ W d	  ƒ n1 sCw   Y  t d
| ¡ d	S )a¤  Collect all cloud-init logs and tar them up into the provided tarfile.

    :param tarfile: The path of the tar-gzipped file to create.
    :param log_cfg: The cloud-init base configuration containing logging cfg.
    :param run_dir: The path to the cloud-init run directory.
    :param cloud_dir: The path to the cloud-init cloud directory.
    :param include_sensitive: Boolean, true means include sensitive data.
    zcloud-init-logs-%Y-%m-%d)Údir)r\   ro   rƒ   r}   rU   ÚtarÚczfz-Cr‡   Ú NzWrote %s)Úosr   Úabspathr   Únowr   ÚutcÚdateÚstrftimer   r_   r`   rŠ   r   r   ÚreplacerF   Úinfo)r‹   ro   rƒ   r}   rU   Údir_nameÚtmp_dirr\   r   r   r   Úcollect_logsN  s.   ÿûúÿ÷rš   r0   c                 C   s^   t  ¡  | dkrtj}n| dkrtj}nt j}t |¡ t ¡ }| 	t 
d¡¡ t |¡ dS )z�Set up the logger for CLI use.

    The verbosity controls which level gets printed to stderr. By default,
    DEBUG and TRACE are hidden.
    r   r]   z%(message)sN)r   Úreset_loggingÚloggingÚINFOÚDEBUGÚTRACErF   ÚsetLevelÚStreamHandlerÚsetFormatterÚ	FormatterÚ
addHandler)r0   ÚlevelÚhandlerr   r   r   Ú_setup_loggerw  s   
r§   FÚredact_sensitiveÚinclude_userdatac                 C   s|   t |ƒ t ¡ dkrtdƒ‚|rt d¡ tg d�}| ¡  t| |j	t
 |jj¡t
 |jj¡| d� |s<t d¡ dS dS )z:Handle calls to 'cloud-init collect-logs' as a subcommand.r   z!This command must be run as root.z;The --include-userdata flag is deprecated and does nothing.)Úds_deps)r‹   ro   rƒ   r}   rU   z¹WARNING:
Sensitive data may have been included in the collected logs.
Please review the contents of the tarball before sharing or
rerun with --redact-sensitive to redact sensitive data.N)r§   r�   ÚgetuidÚRuntimeErrorrF   Úwarningr   Úread_cfgrš   Úcfgr_   r`   Úpathsrƒ   r}   )r‹   r0   r¨   r©   Úinitr   r   r   Úcollect_logs_cliŠ  s*   ÿ
ûÿÿr²   Ú_nameÚargsc              
   C   s^   t ƒ  ¡ }zt|j|j|j|jd� W dS  ty. } zt|t	j
d� W Y d}~dS d}~ww )z}Handle the CLI interface to the module.

    Parse CLI args, redirect all exceptions to stderr, and return an exit code.
    )r0   r‹   r¨   r©   r   )ÚfileNr]   )r:   Ú
parse_argsr²   r0   r‹   r¨   r6   Ú	ExceptionÚprintÚsysrM   )r³   r´   rJ   r   r   r   Úhandle_collect_logs_args«  s   
ü€þrº   Ú__main__r�   rt   )r   TF)?Ú__doc__r7   r   rœ   r�   r_   rW   rO   r¹   r   r   Útypingr   r   r   r   r   r	   r
   Úcloudinit.logr   Úcloudinit.stagesr   Úcloudinit.subpr   r   Úcloudinit.temp_utilsr   Úcloudinit.utilr   r   r   ÚCustomLoggerTypeÚ	getLoggerr   rF   r   ra   r^   r8   r:   r   r`   rK   rS   Úboolr[   rd   ri   rn   rp   r|   r‚   r†   rŠ   rš   Úintr§   r²   Ú	Namespacerº   Úexitr¶   r   r   r   r   Ú<module>   sJ  $ÿû	ÿÿþþþþþß&ÿÿ
þ9ÿþý
üÿÿÿ
þÿÿÿ
þÿÿ
þÿÿ
þ
ÿ
þ	ÿÿ
þ	ÿ
þýüû
ú$ûÿ
þýüû
ú)üÿþýü
û!
ÿ