o
    m[h}F  ã                   @   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mZ ddlm	Z	m
Z
mZ ddlmZmZmZmZmZmZ ddlmZmZ ddlmZ ddlmZ dd	lmZ dd
lmZmZmZ dZ ej!G dd„ dej"ƒƒZ#ej!G dd„ dej"ƒƒZ$ej!G dd„ dej"ƒƒZ%e&e%j'e%j(e%j)e%j*gƒZ+G dd„ deƒZ,dZ-dee. de/de.fdd„Z0d@dd„Z1de#de$dee.e.f fdd„Z2d e,fd!d"„Z3de4fd#d$„Z5de/fd%d&„Z6dee%e.f fd'd(„Z7de/fd)d*„Z8de/de/fd+d,„Z9de/fd-d.„Z:de#fd/d0„Z;de.fd1d2„Z<d3d4„ Z=d5d6„ Z>deeef fd7d8„Z?	9dAd:ee de/de,fd;d<„Z@d=d>„ ZAeBd?k�r,eAƒ  dS dS )BzGDefine 'status' utility and handler as part of cloud-init command line.é    N)Údeepcopy)ÚgmtimeÚsleepÚstrftime)ÚAnyÚDictÚListÚ
NamedTupleÚOptionalÚTuple)ÚsafeyamlÚsubp)Úread_cfg_paths)Úuses_systemd)ÚPaths)Úget_cmdlineÚ	load_jsonÚload_text_filez/etc/cloud/cloud-init.disabledc                   @   s    e Zd ZdZdZdZdZdZdS )ÚRunningStatusz=Enum representing user-visible cloud-init application status.znot startedÚrunningÚdoneÚdisabledN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚNOT_STARTEDÚRUNNINGÚDONEÚDISABLED© r    r    ú6/usr/lib/python3/dist-packages/cloudinit/cmd/status.pyr      s    r   c                   @   s   e Zd ZdZdZdZdZdS )ÚConditionStatusz;Enum representing user-visible cloud-init condition status.ÚerrorÚdegradedÚhealthyN)r   r   r   r   ÚERRORÚDEGRADEDÚPEACHYr    r    r    r!   r"   %   s
    r"   c                   @   s0   e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
S )ÚEnabledStatusz<Enum representing user-visible cloud-init boot status codes.zdisabled-by-generatorzdisabled-by-kernel-command-linezdisabled-by-marker-filez disabled-by-environment-variablezenabled-by-generatorzenabled-by-kernel-command-linezenabled-by-sysvinitÚunknownN)r   r   r   r   ÚDISABLED_BY_GENERATORÚDISABLED_BY_KERNEL_CMDLINEÚDISABLED_BY_MARKER_FILEÚDISABLED_BY_ENV_VARIABLEÚENABLED_BY_GENERATORÚENABLED_BY_KERNEL_CMDLINEÚENABLED_BY_SYSVINITÚUNKNOWNr    r    r    r!   r)   .   s    r)   c                   @   sr   e Zd ZU eed< eed< eed< eed< ee ed< e	eee f ed< eed< e
e ed< e	eef ed	< d
S )ÚStatusDetailsÚrunning_statusÚcondition_statusÚboot_status_codeÚdescriptionÚerrorsÚrecoverable_errorsÚlast_updateÚ
datasourceÚv1N)r   r   r   r   Ú__annotations__r"   r)   Ústrr   r   r
   r   r    r    r    r!   r3   F   s   
 r3   z›extended_status: {extended_status}
boot_status_code: {boot_code}
{last_update}detail: {description}
errors:{errors}
recoverable_errors:{recoverable_errors}Úsystemctl_argsÚwaitÚreturnc                C   s@   	 zt   dg| ¢¡j ¡ W S  t jy   |s‚ tdƒ Y nw q)z-Query systemd with retries and return output.TÚ	systemctlç      Ð?)r   ÚstdoutÚstripÚProcessExecutionErrorr   )r?   r@   r    r    r!   Úquery_systemctlZ   s   ýýrG   c                 C   sV   | s	t jddd�} | jdtg d¢ddd� | jd	d
dddd� | jdddddd� | S )a%  Build or extend an arg parser for status utility.

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

    @returns: ArgumentParser with proper argument configuration.
    ÚstatuszReport run status of cloud init)Úprogr7   z--format)ÚjsonÚtabularÚyamlrK   z5Specify output format for cloud-id (default: tabular))ÚtypeÚchoicesÚdefaultÚhelpz-lz--longÚ
store_trueFzJReport long format of statuses including run stage name and error messages)ÚactionrO   rP   z-wz--waitz'Block waiting on cloud-init to complete)ÚargparseÚArgumentParserÚadd_argumentr>   ©Úparserr    r    r!   Ú
get_parseri   s4   	ÿûú
ûrX   r   Ú	conditionc                 C   s^   |t jkrd|j› d| j› �fS |t jkr)| tjtjfv r)| j|j› d| j› �fS | j| jfS )zžTranslate running and condition status to human readable strings.

    Returns (status, extended_status).
    Much of this is for backwards compatibility
    r#   z - ú )r"   r&   Úvaluer'   r   r   r   )r   rY   r    r    r!   Útranslate_status‘   s   
	þr\   Údetailsc           
   
   C   s`  t |j|jƒ\}}|j|jj|||j|j|j|j	dœ|j
¥}dt|ƒi|d< d|d< | jdkrŽd}|d }t|› d|› �ƒ | jrŒ| d	¡rOd
|d	 › d�}nd}|d r^dd |d ¡ nd}|d rtdd dd„ |d  ¡ D ƒ¡ nd}	ttj|d ||d |d |||	d�ƒ dS dS | jdkr ttj|dddd�ƒ dS | jdkr®tt |¡ƒ dS dS )zPrint status out to the CLI.)r;   r6   rH   Úextended_statusÚdetailr8   r9   r:   Ú1ÚschemasÚ_schema_versionrK   Ú rH   zstatus: r:   zlast_update: Ú
r8   ú
	- z []r9   c                 S   s.   g | ]\}}|› d �d  dd„ |D ƒ¡ ‘qS )z:
	- re   c                 S   s   g | ]}|  d d¡‘qS )rd   rZ   )Úreplace)Ú.0Úir    r    r!   Ú
<listcomp>Î   s    z+print_status.<locals>.<listcomp>.<listcomp>)Újoin)rg   ÚkÚvr    r    r!   ri   Ì   s    þÿÿz print_status.<locals>.<listcomp>z {}r^   r6   r_   )r^   ÚprefixÚ	boot_coder7   r:   r8   r9   rJ   é   T)ú,z: )ÚindentÚ	sort_keysÚ
separatorsrL   N)r\   r4   r5   r;   r6   r[   r7   r8   r9   r:   r<   r   ÚformatÚprintÚlongÚgetrj   ÚitemsÚTABULAR_LONG_TMPLrJ   Údumpsr   )
Úargsr]   rH   r^   Údetails_dictrm   Ústater:   Úerrors_outputÚrecoverable_errors_outputr    r    r!   Úprint_status¥   sv   ÿø	÷

ÿýø
ýÿÿ	öùÿê
!ÿÿ
ÿr€   c                 C   sž   t ƒ }t||jƒ}|jr8|jtjtjfv r8|jdkr%tj	 
d¡ tj	 ¡  t||jƒ}tdƒ |jtjtjfv st||ƒ |jtjkrEdS |jtjkrMdS dS )z4Handle calls to 'cloud-init status' as a subcommand.rK   Ú.rC   é   r   )r   Úget_status_detailsr@   r4   r   r   r   rt   ÚsysrD   ÚwriteÚflushr   r€   r5   r"   r&   r'   )Únamer{   Úpathsr]   r    r    r!   Úhandle_status_argsê   s,   þ

øþ

r‰   c                 C   s8   zt dg| d�}W d|v S  tjy   d}Y d|v S w )z?Return whether cloud-init is disabled via environment variable.zshow-environment©r@   rc   úcloud-init=disabled)rG   r   rF   )r@   Úenvr    r    r!   Ú_disabled_via_environment  s   þþr�   c                 C   s  t ƒ  ¡ }tƒ stj}d}||fS d|v rtj}d}||fS tj | ¡r0tj	}d 
| ¡}||fS d|v r=tj}d}||fS dtj dd¡v sNtƒ rWt|d	�rWtj}d
}||fS tj tj |jd¡¡rltj}d}||fS tj tj |jd¡¡r�tj}d}||fS tj}d}||fS )aX  Report whether cloud-init current boot status

    @param disable_file: The path to the cloud-init disable file.
    @param paths: An initialized cloudinit.helpers.Paths object.
    @param wait: If user has indicated to wait for cloud-init to complete.
    @returns: A tuple containing (code, reason) about cloud-init's status and
    why.
    zCloud-init enabled on sysvinitzcloud-init=enabledz<Cloud-init enabled by kernel command line cloud-init=enabledzCloud-init disabled by {0}r‹   z;Cloud-init disabled by kernel parameter cloud-init=disabledÚKERNEL_CMDLINErc   rŠ   zNCloud-init disabled by environment variable KERNEL_CMDLINE=cloud-init=disabledr   z+Cloud-init disabled by cloud-init-generatorÚenabledz2Cloud-init enabled by systemd cloud-init-generatorz'Systemd generator may not have run yet.)r   Úsplitr   r)   r1   r0   ÚosÚpathÚexistsr-   rt   r,   Úenvironrw   r�   r.   rj   Úrun_dirr+   r/   r2   )Údisable_filerˆ   r@   Úcmdline_partsÚbootstatus_codeÚreasonr    r    r!   Úget_bootstatus  sJ   
	æé
ìïÿÿÿ÷úþrš   c                   C   s   t tƒ ƒjtvS ©N)rƒ   r   r6   ÚDISABLED_BOOT_CODESr    r    r    r!   Úis_cloud_init_enabled8  s   
ÿÿr�   c                 C   sü   dD ]y}zt dd|g| d�}W n  tjy/ } ztd|j› �tjd� W Y d}~ dS d}~ww td	d
„ | ¡ D ƒƒ}|d  d¡sK|d dksK dS |d dkrj|d dkrXq|d dkrg|d dkrg dS  dS |d dksv|d dkry dS  dS dS )z2Return if systemd units report a cloud-init error.)zcloud-final.servicezcloud-config.servicezcloud-init.servicezcloud-init-local.serviceÚshowz5--property=ActiveState,UnitFileState,SubState,MainPIDrŠ   z^Failed to get status from systemd. Cloud-init status may be inaccurate. Error from systemctl: )ÚfileNFc                 S   s    g | ]}d d„ |  d¡D ƒ‘qS )c                 S   s   g | ]}|  ¡ ‘qS r    )rE   )rg   Úxr    r    r!   ri   Z  s    z-systemd_failed.<locals>.<listcomp>.<listcomp>ú=)r�   )rg   Úrr    r    r!   ri   Z  s     z"systemd_failed.<locals>.<listcomp>ÚUnitFileStater�   ÚstaticTÚActiveStateÚactiveÚSubStateÚexitedr   ÚMainPIDÚ0Úfailed)	rG   r   rF   ru   Ústderrr„   ÚdictÚ
splitlinesÚ
startswith)r@   ÚservicerD   ÚeÚstatesr    r    r!   Úsystemd_failed?  sH   ý
úþü€ø	ÿÿûr³   c                 C   s   t j | ¡ot j |¡ S )z%Return True if cloud-init is running.)r‘   r’   r“   )Ústatus_fileÚresult_filer    r    r!   Ú
is_runningy  s   r¶   c                 C   s2   |t v rtjS t| |ƒrtjS |dkrtjS tjS )z(Return the running status of cloud-init.r   )rœ   r   r   r¶   r   r   r   )r´   rµ   r6   Úlatest_eventr    r    r!   Úget_running_status~  s   
r¸   c                 C   s4   |   dd¡}|r| d¡\}}}| ¡  dd¡}|S )zyGet the datasource from status.json.

    Return a lowercased non-prefixed version. So "DataSourceEc2" becomes "ec2"
    r;   rc   rZ   )rw   Ú	partitionÚlowerrf   )Ú	status_v1r;   ÚdsÚ_r    r    r!   Úget_datasourceŒ  s
   r¾   c                 C   s.   |   d¡}|r	|S |   d¡rd| d › �S |S )z¼Return a description of the current status.

    If we have a datasource, return that. If we're running in a particular
    stage, return that. Otherwise, return the boot_description.
    r;   ÚstagezRunning in stage: )rw   )r»   Úboot_descriptionr;   r    r    r!   Úget_description˜  s   

rÁ   c                 C   s@   d}|   ¡ D ]}t|tƒrt|| d¡pd| d¡pdƒ}q|S )z,Return the latest event time from status_v1.r   ÚstartÚfinished)ÚvaluesÚ
isinstancer­   Úmaxrw   )r»   r·   Ú
stage_infor    r    r!   Úget_latest_event§  s   
ý€rÈ   c                 C   sˆ   g }i }t |  ¡ ƒD ]5\}}t|tƒr?| | dg ¡¡ | di ¡}| ¡ D ]}||vr5t|| ƒ||< q&||  || ¡ q&q
||fS )z>Return a list of errors and recoverable_errors from status_v1.r8   r9   )Úsortedrx   rÅ   r­   Úextendrw   Úkeysr   )r»   r8   r9   Ú_keyrÇ   Úcurrent_recoverable_errorsÚerr_typer    r    r!   Ú
get_errors´  s$   
ÿ
ÿÿ€rÏ   Frˆ   c              
   C   s  t j}| ptƒ } tj | jd¡}tj | jd¡}tt| |ƒ\}}i }tj 	|¡r2t
t|ƒƒ di ¡}t|ƒ}t||ƒ}	t|ƒ}
|
rHtdt|
ƒƒnd}t|ƒ\}}|rVt j}n|r[t j}t||||
ƒ}|tjkr|tƒ r|t|d�r|tj}t j}d}	| d¡ | d	d
¡ t||||	|||||ƒ	S )a  Return a dict with status, details and errors.

    @param paths: An initialized cloudinit.helpers.paths object.
    @param wait: If user has indicated to wait for cloud-init to complete.

    Values are obtained from parsing paths.run_dir/status.json.
    zstatus.jsonzresult.jsonr<   z%a, %d %b %Y %H:%M:%S %zrc   rŠ   z"Failed due to systemd unit failurez‹Failed due to systemd unit failure. Ensure all cloud-init services are enabled, and check 'systemctl' or 'journalctl' for more information.r;   N)r"   r(   r   r‘   r’   rj   r•   rš   ÚCLOUDINIT_DISABLED_FILEr“   r   r   rw   r¾   rÁ   rÈ   r   r   rÏ   r&   r'   r¸   r   r   r   r³   r   ÚappendÚpopr3   )rˆ   r@   r5   r´   rµ   r6   rÀ   r»   r;   r7   r·   r:   r8   r9   r4   r    r    r!   rƒ   Ì  s`   

ÿ
ÿýÿ
ÿþÿ÷rƒ   c                  C   s   t ƒ } t td|  ¡ ƒ¡ dS )z$Tool to report status of cloud-init.rH   N)rX   r„   Úexitr‰   Ú
parse_argsrV   r    r    r!   Úmain  s   rÕ   Ú__main__r›   )NF)Cr   rS   ÚenumrJ   r‘   r„   Úcopyr   Útimer   r   r   Útypingr   r   r   r	   r
   r   Ú	cloudinitr   r   Úcloudinit.cmd.develr   Úcloudinit.distrosr   Úcloudinit.helpersr   Úcloudinit.utilr   r   r   rÐ   ÚuniqueÚEnumr   r"   r)   Ú	frozensetr+   r,   r-   r.   rœ   r3   ry   r>   ÚboolrG   rX   r\   r€   Úintr‰   r�   rš   r�   r³   r¶   r¸   r¾   rÁ   rÈ   rÏ   rƒ   rÕ   r   r    r    r    r!   Ú<module>   sŽ    	üÿ
ÿý
ü
(ÿÿ

þE	*:
þÿÿÿ
þG

ÿ