U
    Ld,                     @   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,e-dddZ.ee$e/f dddZ0ee# dddZ1d"ee e*dddZ2dd Z3e4d kr~e3  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runningZ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   sX   | st jddd} | jdtdddg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)progr/   z--formatjsontabularyamlz5Specify 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_argumentr4   parserr!   r!   r"   
get_parserL   s6    	 
rD   )returnc                 C   sX  t  }t|}|jrX|jtjtjfkrX|jdkrFtj	
d tj	  t|}td q|j|jj|jj|j|j|jd}dt|i|d< d|d< |jdkr|jrdnd	}t| d
|jj  |jrB|jrd|j d}nd	}ttj||jj|j|d n>|jdkr(ttj|dddd n|jdkrBtt| |jtjkrTdS dS )z4Handle calls to 'cloud-init status' as a subcommand.r7   .g      ?)r2   r.   r-   Zdetailr0   r1   1ZschemasZ_schema_version
 zstatus: zlast_update: )prefixZ	boot_coder/   r1   r6      T),z: )indentZ	sort_keysZ
separatorsr8      r   )r   get_status_detailswaitr-   r   r   r   formatsysstdoutwriteflushr   r2   r.   valuer/   r0   r1   copydeepcopyprintZlongTABULAR_LONG_TMPLr6   dumpsr   r   )nameargspathsZdetailsZdetails_dictrJ   r1   r!   r!   r"   handle_status_argst   sZ    


   r_   c                 C   s   t   }t stj}d}nd|kr0tj}d}ntj| rNtj	}d
| }nfd|krbtj}d}nRtjtj|jdrtj}d}n.tjtj|jd	rtj}d
}n
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'   rQ   r&   joinrun_dirr%   r(   r+   )Zdisable_filer^   Zcmdline_partsZbootstatus_codereasonr!   r!   r"   get_bootstatus   s,    
rh   c                  C   s   dD ]} t  ddd| gj}tdd | D }|d dsV|d d	ksVtj  S |d
 dkr|d dkrrqn|d dkr|d dkrq|d
 dks|d dkrt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.serviceZ	systemctlZ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>=)ra   )rj   rr!   r!   r"   rl      s     z'_get_systemd_status.<locals>.<listcomp>ZUnitFileStater`   ZstaticZActiveStateZactiveZSubStateZexitedr   ZMainPID0ZfailedN)r   rS   dict
splitlines
startswithr   r   r   )servicerS   Zstatesr!   r!   r"   _get_systemd_status   s2    



rt   )r^   rE   c                 C   s  | pt  } tj}g }d}i }tj| jd}tj| jd}tt| \}}|t	krXtj
}tj|rtj|svtj}tt|di }d}	t| D ]\}
}|
dkr|rtj}d|}q|
dkr|d	kr|}q|}|d
\}}}| dd}qt|tr||dg  |dp&d}|dp6d}|dkrR|dkrRtj}t||}||	kr|}	q|rtj}d|}n|tjkr|	dkrtj}t r|tjtj
fk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.
    rI   zstatus.jsonzresult.jsonZv1r   ZstagezRunning in stage: {0}r2   N r0   startfinishedrH   z%a, %d %b %Y %H:%M:%S %z)!r   r   r   rb   rc   re   rf   rh   CLOUDINIT_DISABLED_FILEDISABLED_BOOT_CODESr    rd   r   r   r   getsorteditemsrQ   	partitionlowerreplace
isinstancerp   extendmaxr   r   r   rt   r   r   r,   )r^   r-   r0   r2   Z	status_v1Zstatus_fileZresult_filer.   r/   Zlatest_eventkeyrV   Zds_rv   rw   Z
event_timeZsystemd_statusr1   r!   r!   r"   rO      s~    
 


     rO   c                  C   s   t  } ttd|   dS )z$Tool to report status of cloud-init.r-   N)rD   rR   exitr_   
parse_argsrB   r!   r!   r"   mainD  s    r   __main__)N)N)5r   r?   rW   enumr6   rb   rR   timer   r   r   typingr   r   r   r   r	   r
   r   Z	cloudinitr   r   Zcloudinit.cmd.develr   Zcloudinit.distrosr   Zcloudinit.helpersr   Zcloudinit.utilr   r   r   rx   uniqueEnumr   r#   	frozensetr%   r&   r'   ry   r,   rZ   rD   intr_   r4   rh   rt   rO   r   r   r!   r!   r!   r"   <module>   sD   $
		
(2!4I
