o
    w7e,                     @   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mZ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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%e$j&e$j'e$j(gZ)G dd deZ*dZ+d!ddZ,de-fddZ.dee$e/f fddZ0dee# fddZ1d!dee de*fddZ2dd Z3e4d kre3  dS dS )"zFDefine 'status' utility and handler as part of cloud-init commandline.    N)gmtimesleepstrftime)AnyDictList
NamedTupleOptionalTupleUnion)safeyamlsubp)read_cfg_paths)uses_systemd)Paths)get_cmdline	load_file	load_jsonz/etc/cloud/cloud-init.disabledc                   @   s$   e Zd ZdZdZdZdZdZdZdS )UXAppStatusz=Enum representing user-visible cloud-init application status.znot runrunningdoneerrordisabledN)	__name__
__module____qualname____doc__NOT_RUNRUNNINGDONEERROR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ZdZdZ	dZ
d	S )
UXAppBootStatusCodez<Enum representing user-visible cloud-init boot status codes.zdisabled-by-generatorzdisabled-by-kernel-cmdlinezdisabled-by-marker-filezenabled-by-generatorzenabled-by-kernel-cmdlinezenabled-by-sysvinitunknownN)r   r   r   r   DISABLED_BY_GENERATORDISABLED_BY_KERNEL_CMDLINEDISABLED_BY_MARKER_FILEENABLED_BY_GENERATORENABLED_BY_KERNEL_CMDLINEENABLED_BY_SYSVINITUNKNOWNr"   r"   r"   r#   r$   '   s    r$   c                   @   sF   e Zd ZU eed< eed< eed< ee ed< eed< ee ed< dS )StatusDetailsstatusboot_status_codedescriptionerrorslast_update
datasourceN)	r   r   r   r   __annotations__r$   strr   r	   r"   r"   r"   r#   r-   =   s   
 r-   z@boot_status_code: {boot_code}
{last_update}detail:
{description}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.
    r.   zReport run status of cloud init)progr0   z--format)jsontabularyamlr8   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)actionr<   r=   z-wz--waitz'Block waiting on cloud-init to complete)argparseArgumentParseradd_argumentr5   parserr"   r"   r#   
get_parserL   s4   	
rE   returnc                 C   s^  t  }t|}|jr4|jtjtjfv r4|jdkr#tj	
d tj	  t|}td |jtjtjfv s|j|jj|jj|j|j|jd}dt|i|d< d|d< |jdkr|jr\dnd	}t| d
|jj  |jr|jrwd|j d}nd	}ttj||jj|j|d n|jdkrttj|dddd n|jdkrtt| |jtjkrdS dS )z4Handle calls to 'cloud-init status' as a subcommand.r8   .g      ?)r3   r/   r.   detailr1   r2   1schemas_schema_version
 zstatus: zlast_update: )prefix	boot_coder0   r2   r7      T),z: )indent	sort_keys
separatorsr9      r   )r   get_status_detailswaitr.   r   r   r   formatsysstdoutwriteflushr   r3   r/   valuer0   r1   r2   copydeepcopyprintlongTABULAR_LONG_TMPLr7   dumpsr   r    )nameargspathsdetailsdetails_dictrN   r2   r"   r"   r#   handle_status_argst   sX   




ri   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 tjtj|jdrRtj}d}||fS tjtj|jd	rgtj}d
}||fS tj}d}||fS )a  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.
    @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}zcloud-init=disabledz;Cloud-init disabled by kernel parameter 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$   r+   r*   ospathexistsr(   rX   r'   joinrun_dirr&   r)   r,   )disable_filerf   cmdline_partsbootstatus_codereasonr"   r"   r#   get_bootstatus   s8   


ru   c                  C   s   dD ]X} t  ddd| gj}tdd | D }|d ds+|d d	ks+tj  S |d
 dkrE|d dkr8q|d dkrE|d dkrEq|d
 dksQ|d dkrVtj  S tj  S dS )zGet status from systemd.

    Using systemd, we can get more fine-grained status of the
    individual unit. Determine if we're still
    running or if there's an error we haven't otherwise detected
    )zcloud-final.servicezcloud-config.servicezcloud-init.servicezcloud-init-local.service	systemctlshowz5--property=ActiveState,UnitFileState,SubState,MainPIDc                 S   s    g | ]}d d | dD qS )c                 S   s   g | ]}|  qS r"   )strip).0xr"   r"   r#   
<listcomp>   s    z2_get_systemd_status.<locals>.<listcomp>.<listcomp>=)rk   )ry   rr"   r"   r#   r{      s     z'_get_systemd_status.<locals>.<listcomp>UnitFileStaterj   staticActiveStateactiveSubStateexitedr   MainPID0failedN)r   rZ   dict
splitlines
startswithr   r    r   )servicerZ   statesr"   r"   r#   _get_systemd_status   s4   


r   rf   c                 C   s  | pt  } tj}g }d}i }tj| jd}tj| jd}tt| \}}|t	v r,tj
}tj|rEtj|s;tj}tt|di }d}	t| D ]c\}
}|
dkr`|r_tj}d|}qM|
dkr~|d	u rk|}qM|}|d
\}}}| dd}qMt|tr||dg  |dpd}|dpd}|dkr|dkrtj}t||}||	kr|}	qM|rtj}d|}n|tjkr|	dkrtj}t r|tjtj
fvrt }|r|}|	rtdt|	nd}t ||||||S )zReturn a dict with status, details and errors.

    @param paths: An initialized cloudinit.helpers.paths object.

    Values are obtained from parsing paths.run_dir/status.json.
    rM   zstatus.jsonzresult.jsonv1r   stagezRunning in stage: {0}r3   N r1   startfinishedrL   z%a, %d %b %Y %H:%M:%S %z)!r   r   r   rl   rm   ro   rp   ru   CLOUDINIT_DISABLED_FILEDISABLED_BOOT_CODESr!   rn   r   r   r   getsorteditemsrX   	partitionlowerreplace
isinstancer   extendmaxr    r   r   r   r   r   r-   )rf   r.   r1   r3   	status_v1status_fileresult_filer/   r0   latest_eventkeyr]   ds_r   r   
event_timesystemd_statusr2   r"   r"   r#   rV      sv   



rV   c                  C   s   t  } ttd|   dS )z$Tool to report status of cloud-init.r.   N)rE   rY   exitri   
parse_argsrC   r"   r"   r#   mainD  s   r   __main__)N)5r   r@   r^   enumr7   rl   rY   timer   r   r   typingr   r   r   r   r	   r
   r   	cloudinitr   r   cloudinit.cmd.develr   cloudinit.distrosr   cloudinit.helpersr   cloudinit.utilr   r   r   r   uniqueEnumr   r$   	frozensetr&   r'   r(   r   r-   rb   rE   intri   r5   ru   r   rV   r   r   r"   r"   r"   r#   <module>   sH   $
		
(2!4I
