o
    x[h�  ã                
   @   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	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)Úsignal_handlerÚ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*   
€þr6   Ú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)   r0   r/   r   ÚosÚgetpidr$   ÚopenÚdevnullÚjoinr   Úfork_cbÚrun_after_pid_goneÚexecmd)r7   r8   r9   r:   Úarg_listÚtimeoutÚ	conditionr5   ÚmypidÚcmdlineÚ
devnull_fpr"   r"   r#   ÚhandleR   s<   
þ€þ

ùrN   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)rR   rT   rV   rI   g      >@z(failed to convert timeout '%s' to float.rJ   Tz2condition type %s invalid. must be list, bool, str)Úgetr&   ÚdictÚ	TypeErrorÚshutdown_options_maprD   Úshutdown_commandÚfloatÚ
ValueErrorr   r,   r'   )	r8   r?   ÚpstateÚmodes_okrR   r:   rI   r5   rJ   r"   r"   r#   r>   v   s@   



ÿÿ
ý
ÿþ€ÿ
r>   c                 C   s   t  | ¡ d S ©N)r@   Ú_exit)Úsysexitr"   r"   r#   Údoexitœ   s   rc   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.   r0   rc   Ú	EXIT_FAIL)Úexe_argsr   Údata_inr4   r3   r"   r"   r#   rG       s   ü

ÿrG   c              
   C   sr  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|ƒs„W d S W n ty� } z|d| ƒ W Y d }~nd }~ww t ¡ � ||Ž  W d   ƒ d S 1 s²w   Y  d S )Nc                 S   s   t  | ¡ ttƒ d S r`   )r(   r/   rc   ri   )Ú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   r0   Úsleepr(   r)   r6   r   Úsuspend_crash)r   Ú
pidcmdlinerI   rJ   Úfuncr:   rl   Úend_timerm   Úknown_errnosrL   Úioerrr5   r"   r"   r#   rF   °   sP   þ
€€ÿ
ë
ÿ€ÿ

"ÿrF   )NN)%Ú__doc__rp   Úloggingr@   r   r*   rn   Ú	cloudinitr   r   r   Úcloudinit.cloudr   Úcloudinit.configr   Úcloudinit.config.schemar   Úcloudinit.distrosr   Úcloudinit.settingsr	   r   ri   r   Ú__annotations__Ú	getLoggerÚ__name__r(   r$   r6   r   r,   rN   r>   rc   rG   rF   r"   r"   r"   r#   Ú<module>   s8   ü
$&
