a 'Dg{7@s4dZddlZddlZddlZddlZddlZddlZddlZddlZddl m Z m Z ddl m Z m Z mZmZmZmZmZddlmZddlmZddlmZmZddlmZdd lmZmZmZeej e!e"Z#Gd d d eZ$e$d d e$dde$ddgZ%e$dde$dde$dde$dde$dde$dde$dde$d d!e$d"d#e$d$d%e$d&d%e$d'd(g Z&d^eej'ej'd)d*d+Z(ee)ej*e)ee)d,d-d.Z+ee)ej*e)dd,d/d0Z,ej*ej*e-dd1d2d3Z.ej*e-dd4d5d6Z/ej*dd7d8d9Z0ej*e-dd4d:d;Z1e e)e feej*d<d=d>Z2e*d?fej*eej*d@dAdBZ3ej*eej*dCdDdEZ4ej*eej*dFdGdHZ5ej*e e)e fej*ej*e-ddIdJdKZ6e*dLe*dMdNfe)e e)e fej*ej*e-ddOdPdQZ7e8ddRdSdTZ9d_e)e8e-e-ddVdWdXZ:e)ej;e8dYdZd[ZdS)`zGDefine 'collect-logs' utility and handler to include in cloud-init cmd.N)datetimetimezone)AnyDictIteratorList NamedTupleOptionalcast)loggers)Init)ProcessExecutionErrorsubp)tempdir)copyget_config_logfiles write_filec@seZdZUeed<eed<dS) ApportFilepathZlabelN)__name__ __module__ __qualname__str__annotations__rr|d }tj|||dWdn1sB0YWn>ty}z&t|t|t d|WYd}~nd}~00t d||j dS)zHelper 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)r6stderrNr2r3) r4r5open subprocesscallOSErrorrrr7r8r9)r,r-r.fr;rrr_stream_command_output_to_files 2"rD)rout_dirinclude_sensitivercCs`|rP|s|jtj@rB|jdddt||td|q\td|n td|dS)z-Collect a file into what will be the tarball.Tr/zcollected file: %sz#sensitive file %s was not collectedzfile %s did not existN) is_filestatst_modeS_IROTHr5rr7r8Ztrace)rrErFrrr _collect_files rK)log_dirrFrcCsxtD]2}t||jddj}tt|j|ddq|rttD]2}t||jddj}tt|j|ddq@dS)z'Obtain subiquity logs and config files.NT)rF)INSTALLER_APPORT_FILESpathlibPathrr4rK INSTALLER_APPORT_SENSITIVE_FILES)rLrFZsrc_fileZdestination_dirrrr_collect_installer_logss  rR)rLrcCs<tddg|ddd}tgd|ddd}|s8|p6d }d S) z8Include cloud-init version and dpkg version in the logs. cloud-initz --versionversionzcloud-init --versionr,r-r.)z dpkg-queryz--showz-f=${Version} rSz dpkg-versionz dpkg versionz not-availableN)r<)rLrTZdpkg_verrrr_collect_version_infosrVcCsL|rtdg|dddtgd|dddtgdt|d d dd S) z0Include dmesg and journalctl output in the logs.Zdmesgz dmesg.txtz dmesg outputrU) journalctlz--boot=0-o short-precisez journal.txtzsystemd journal of current boot)rWz --boot=-1rXrYzjournal-previous.txtz systemd journal of previous bootN)rDrOrP)rLrFrrr_collect_system_logss  rZ)log_cfgrccst|D]}t|VqdS)z7Get paths for cloud-init.log and cloud-init-output.log.N)rrOrP)r[rrrr_get_cloudinit_logss r\z /etc/cloud) etc_cloud_dirrc#s4|d|ddgfdd|dDEdHdS)zGet 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 keysZ templatesz99-installer.cfgc3s&|]}|jvr|jvr|VqdSN)namer4).0rignorerr sz!_get_etc_cloud..z**/*Nglob)r]rrbr_get_etc_clouds  rg) cloud_dirrc Cs:t|d|d|ddd|dD|dS)zkGet paths for files in /var/lib/cloud. Skip user-provided scripts, semaphores, and old instances. zdata/*z handlers/*zseed/*css|]}|r|VqdSr_)rGraprrrrdz%_get_var_lib_cloud..z instance/*zinstance/handlers) itertoolschainrfrhrrr_get_var_lib_cloudsro)run_dirrcCsdd|dDS)zGet 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. css|]}|jdkr|VqdS)zhook-hotplug-cmdN)r`rirrrrd*rkz_get_run_dir..*rerprrr _get_run_dir$srs)rLr[rprhrFrcCst|t||t||t|D]"}t||t|jddq$t t t |dt |dD]"}t||t|jd|qddS)z8Collect all cloud-init logs into the provided directory./TrnrrN)rVrZrRr\rKrOrPr4 relative_torlrmrgrors)rLr[rprhrFZlogfilerrr_collect_logs_into_tmp_dir-s&   rvz/run/cloud-initz/var/lib/cloudT)tarfiler[rprhrFrc Cstj|}ttjd}t |dT}t ||}t |||||dt dd|d|t||ddgWd n1s0Ytd |d S) aCollect 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. zcloud-init-logs-%Y-%m-%d)dir)rLr[rprhrFtarZczfz-CrtNzWrote %s)osrabspathrZnowrZutcdatestrftimerrOrPrvrrreplacer7info)rwr[rprhrFZdir_nameZtmp_dirrLrrr collect_logsNs,   " r)r!rcCs^t|dkrtj}n|dkr(tj}ntj}t|t}| t dt |dS)zSet up the logger for CLI use. The verbosity controls which level gets printed to stderr. By default, DEBUG and TRACE are hidden. rrMz %(message)sN) r Z reset_loggingloggingINFODEBUGZTRACEr7ZsetLevelZ StreamHandlerZ setFormatterZ FormatterZ addHandler)r!levelZhandlerrrr _setup_loggerws rF)rwr!redact_sensitiveinclude_userdatarcCsxt|tdkrtd|r*tdtgd}|t||j t |j j t |j j| d|sttddS)z:Handle calls to 'cloud-init collect-logs' as a subcommand.rz!This command must be run as root.z;The --include-userdata flag is deprecated and does nothing.)Zds_deps)rwr[rprhrFzWARNING: 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)rr{getuid RuntimeErrorr7Zwarningr Zread_cfgrZcfgrOrPpathsrprh)rwr!rrinitrrrcollect_logs_clis(    r)_nameargsrc Csbt}zt|j|j|j|jdWdSty\}zt|t j dWYd}~dSd}~00dS)z}Handle the CLI interface to the module. Parse CLI args, redirect all exceptions to stderr, and return an exit code. )r!rwrrr)fileNrM) r+ parse_argsrr!rwrr' Exceptionprintsysr>)rrr;rrrhandle_collect_logs_argss r__main__rz)N)rTF)?__doc__r(rlrr{rOrHr@rrrtypingrrrrrr r Z cloudinit.logr Zcloudinit.stagesr Zcloudinit.subpr rZcloudinit.temp_utilsrZcloudinit.utilrrrZCustomLoggerTypeZ getLoggerrr7rrQrNr)r+rrPr<rDboolrKrRrVrZr\rgrorsrvrintrr Namespacerexitrrrrrs$    & :             $  ) !