3 \mer'@sdZddlZddlZddlZddlZddlZddlmZddlmZddl m Z ddl m Z ddl mZddlmZmZdd lmZdd lmZmZmZmZd d gZd ZGddde ZeddeddeddgZeddeddeddeddedded d!ed"d#ed$d%ed&d'ed(d)ed*d)ed+d,g Zed-d.d/Zed-d0d1Z dHd2d3Z!d4d5Z"d6d7Z#d8d9Z$d:d;Z%dd?Z'dIe(d@dAdBZ)dCdDZ*dEdFZ+e,dGkrej-e+dS)JzGDefine 'collect-logs' utility and handler to include in cloud-init cmd.N)datetime)Path) NamedTuple)read_cfg_paths)Paths)ProcessExecutionErrorsubp)tempdir)chdircopy ensure_dir write_filez/var/log/cloud-init.logz/var/log/cloud-init-output.logz/run/cloud-initc@seZdZUeedS) ApportFileN)__name__ __module__ __qualname__strpathZlabelrr/usr/lib/python3.6/logs.pyrs rz(/var/log/installer/autoinstall-user-dataZAutoInstallUserDataz/autoinstall.yamlZAutoInstallYAMLz'/etc/cloud/cloud.cfg.d/99-installer.cfgZInstallerCloudCfgz//var/log/installer/ubuntu_desktop_installer.logZUdiLogz-/var/log/installer/subiquity-server-debug.logZSubiquityServerDebugz-/var/log/installer/subiquity-client-debug.logZSubiquityClientDebugz%/var/log/installer/curtin-install.logZ CurtinLogz0/var/log/installer/subiquity-curtin-install.confZCurtinInstallConfigz8/var/log/installer/curtin-install/subiquity-initial.confZCurtinConfigInitialz:/var/log/installer/curtin-install/subiquity-curthooks.confZCurtinConfigCurtHooksz8/var/log/installer/curtin-install/subiquity-extract.confZCurtinConfigExtractz=/var/log/installer/curtin-install/subiquity-partitioning.confZCurtinConfigPartitioningz(/var/log/installer/curtin-error-logs.tarZ CurtinErrorz$/var/log/installer/curtin-errors.tarz(/var/log/installer/block/probe-data.jsonZ ProbeData)returncCst}|jdS)NZ userdata_raw)rZ get_ipath_cur)pathsrrr_get_user_data_fileNsrcCst}|jdS)Ndata)rZ get_cpath)rrrr_get_cloud_data_pathSsrcCs`|stjddd}|jdddddd d |jd d d ddt}|jddddddj|d|S)a2Build 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-vcountr verbosityzBe more verbose.)actiondefaultdesthelpz --tarfilez-tzcloud-init.tar.gzzOThe tarfile to create containing all collected logs. Default: cloud-init.tar.gz)r r"z--include-userdataz-uF store_trueuserdatazPOptionally include user-data from {0} which could contain sensitive information.)r rr!r")argparseArgumentParser add_argumentrformat)parseruser_data_filerrr get_parserXs4  r+cCs*dg}tjdkr&|jtijd|S)z>Return a list of files to ignore for /run/cloud-init directoryzhook-hotplug-cmdrZinstance_data_sensitive)osgetuidappendrZlookups)curdirfilesZ ignored_filesrrr_copytree_rundir_ignore_filess r1cCsttjj|yt|j}Wn@tk r^}z$t|t|t d|d|WYdd}~Xn Xt||t d|d||SdS)zCHelper which runs a command and writes output or error to filename.zcollecting %s failed. Nz collected %s ) r r,rdirnamerstdoutrr r_debug)cmdfilenamemsgroutputerrr_write_command_output_to_files" r;cCsttjj|y*t|d}tj|||dWdQRXWn@tk rz}z$t|t |t d|d|WYdd}~XnXt d|d|dS)zCHelper which runs a command and writes output or error to filename.w)r4stderrNzcollecting %s failed. r2z collected %s ) r r,rr3open subprocessZcallOSErrorr rr5)r6r7r8rfr:rrr_stream_command_output_to_files "rBcCs||krtjj|dS)N)sysr=write)r8levelrrrrr5sr5cCs<tjj|r(t||td|d|ntd|d|dS)Nzcollected file: %s r2zfile %s did not exist )r,risfiler r5)rZout_dirrrrr _collect_files  rHcCsxBtD]:}t||jj}|js.tt|t|jt||qW|rxBtD]:}t||jj}|jsvtt|t|jt||qNWdS)z'Obtain subiquity logs and config files.N) INSTALLER_APPORT_FILESrrparentexistsr rrH INSTALLER_APPORT_SENSITIVE_FILES)log_dirinclude_userdatarZsrc_fileZdestination_dirrrrcollect_installer_logss    rO)rNc #Cs|r tjdkr tjjddStjj|}tjj j d}t dd }tjj ||}t ddgtjj |d d |d }t d d ddgtjj |dd|d }|s|r|nd}td|td|d|tdgtjj |dd|d tddddgtjj |dd|d xtD]}t|||qW|r6t}t|||t|||tjj |d} t| tjjtrytjttjj | dtdWnFtjk r} z&tjjdtjjt| d WYd!d!} ~ XnXtd"td|ntd#td|tjjtjj td$r6tt} | jr6tjt| t|t| t|"t d%d&||j!|d'd(gWd!QRXWd!QRXtjjd)|dS)*zCollect all cloud-init logs and tar them up into the provided tarfile. @param tarfile: The path of the tar-gzipped file to create. @param include_userdata: Boolean, true means include user-data. rzMTo include userdata, root user is required. Try sudo cloud-init collect-logs r2zcloud-init-logs-%Y-%m-%dz/tmp)dirz cloud-initz --versionversionzcloud-init --version)r6r7r8rz dpkg-queryz--showz-f=${Version} z dpkg-versionz dpkg versionz not-availablez version: z!collected cloud-init version: %s Zdmesgz dmesg.txtz dmesg outputZ journalctlz--boot=0z-oz short-precisez journal.txtzsystemd journal of current bootZrun)ignorez(Failed collecting file(s) due to error:  Nzcollected dir %s zdirectory '%s' did not exist ZdisabledZtarZczvf/z Wrote %s )"r,r-rCr=rDrabspathrZutcnowZdateZstrftimer joinr;printr5rBCLOUDINIT_LOGSrHrrOr rKCLOUDINIT_RUN_DIRshutilZcopytreer1Errorrrrr rreplace) tarfilerNrrMZtmp_dirrQZdpkg_verlogr*Zrun_dirr:Zcloud_data_dirrrr collect_logss               &   0r`cCst|j|j|jS)z:Handle calls to 'cloud-init collect-logs' as a subcommand.)r`r^r$r)nameargsrrrhandle_collect_logs_argssrccCst}td|jS)z4Tool to collect and tar all cloud-init related logs.z collect-logs)r+rc parse_args)r)rrrmain"sre__main__)N)r).__doc__r%r,r[r?rCrZpathlibrZtypingrZcloudinit.cmd.develrZcloudinit.helpersrZcloudinit.subprrZcloudinit.temp_utilsr Zcloudinit.utilr r r r rYrZrrLrIrrrr+r1r;rBr5rHrOboolr`rcrerexitrrrrst         .  U