o
    i                  
   @   s  U 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	 ddl
mZ ddlmZ ddlmZ ddlmZ ddlmZ eZd	Zd
egedgdZeed< eeZdd Zdd Zdededededdf
ddZdd Z dd Z!d!ddZ"dd  Z#dS )"z&Power State Change: Change power state    N)subputil)Cloud)Config)
MetaSchema)ALL_DISTROS)PER_INSTANCE   cc_power_state_changepower_state)iddistros	frequencyactivate_by_schema_keysmetac                 C   st   z/t  r(tddt| g\}}| d }td|}|r%|dW S W d S t d|  W S  t	y9   Y d S w )Nprocstatz-c   z\d+ (\w|\.|-)+\s+(/\w.+)   z/proc/%s/cmdline)
r   
is_FreeBSDr   str
splitlinesresearchgroupload_text_fileIOError)pidoutput_errlinem r!   H/usr/lib/python3/dist-packages/cloudinit/config/cc_power_state_change.pygivecmdline%   s   r#   c              
   C   s   t | trtd|  | S d|  }z6tj| t | t d}|  |j}|dkr1td| W dS |dkr>td| W d	S t	d
|| W d	S  t
ya } zt	d|| W Y d }~d	S d }~ww )NzStatic Condition: %szcheck_condition command (%s): )shellr   z%sexited 0. condition met.Tr   z%sexited 1. condition not met.Fz*%sunexpected exit %s. do not apply change.z%sUnexpected error: %s)
isinstanceboolLOGdebug
subprocessPopenlistcommunicate
returncodewarning	Exception)condpreprocreter!   r!   r"   check_condition:   s*   
r5   namecfgcloudargsreturnc              
   C   s   zt ||j\}}}|d u rtd W d S W n ty2 } ztdt| W Y d }~d S d }~ww |du r>td d S t }t	|}	|	sOtd d S t
tjd}
td|d| tt||	||t||
g d S )	Nz&no power_state provided. doing nothingz%%s Not performing power state change!Fz3Condition was false. Will not perform state change.z5power_state: failed to get cmdline of current processwz#After pid %s ends, will execute: %s )load_power_statedistror'   r(   r/   r.   r   osgetpidr#   opendevnulljoinr   fork_cbrun_after_pid_goneexecmd)r6   r7   r8   r9   arg_listtimeout	conditionr4   mypidcmdline
devnull_fpr!   r!   r"   handleR   s<   


rM   c           	   
   C   s   |  d}|d u rdS t|tstdg d}| d}||jvr-tdd||f |j|| dd	| d
d}z
t| dd}W n ty[ } z	td|d  |d }~ww | dd}t|t	t
tfsntd|||fS )Nr   )NNNzpower_state is not a dict.)haltpoweroffrebootmodez<power_state[mode] required, must be one of: %s. found: '%s'.,delaynowmessage)rQ   rS   rU   rH   g      >@z(failed to convert timeout '%s' to float.rI   Tz2condition type %s invalid. must be list, bool, str)getr%   dict	TypeErrorshutdown_options_maprC   shutdown_commandfloat
ValueErrorr   r+   r&   )	r7   r>   pstatemodes_okrQ   r9   rH   r4   rI   r!   r!   r"   r=   v   s@   






r=   c                 C   s   t |  d S N)r?   _exit)sysexitr!   r!   r"   doexit   s   rb   c                 C   sV   d}zt j| t j|t jd}|| |j}W n ty$   tt Y nw t| d S )Nr   )stdinstdoutstderr)	r)   r*   PIPESTDOUTr,   r-   r/   rb   	EXIT_FAIL)exe_argsr   data_inr3   r2   r!   r!   r"   rF      s   

rF   c              
   C   sH  d }t  | }dd }tjtjf}		 t  |krd|  }nSzt| }
|
|kr/d| |
f }W nBW n: tyS } z|j|	v rCd|j }n|d|  W Y d }~n"d }~w tyj } z|d|  W Y d }~nd }~ww t d	 q|sw|d
 t	
| z	t|sW d S W n ty } z|d|  W Y d }~nd }~ww ||  d S )Nc                 S   s   t |  tt d S r_   )r'   r.   rb   rh   )msgr!   r!   r"   fatal   s   
z!run_after_pid_gone.<locals>.fatalTztimeout reached before %s endedz cmdline changed for %s [now: %s]zpidfile gone [%d]zIOError during wait: %szUnexpected Exception: %sg      ?z&Unexpected error in run_after_pid_gonez0Unexpected Exception when checking condition: %s)time	monotonicerrnoENOENTESRCHr#   r   r/   sleepr'   r(   r5   )r   
pidcmdlinerH   rI   funcr9   rk   end_timerl   known_errnosrK   ioerrr4   r!   r!   r"   rE      sL   


rE   )NN)$__doc__ro   loggingr?   r   r)   rm   	cloudinitr   r   cloudinit.cloudr   cloudinit.configr   cloudinit.config.schemar   cloudinit.distrosr   cloudinit.settingsr   r   rh   r   __annotations__	getLogger__name__r'   r#   r5   r   r+   rM   r=   rb   rF   rE   r!   r!   r!   r"   <module>   s8   
$&
