o
    thI,                     @   st  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Zddlm	Z	m
Z
mZ ddl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 dd
lmZmZ ddlmZ eeZ dZ!d$ddZ"G dd dej#Z$G dd de$Z%de%ej&fiZ'dd Z(dede)fddZ*deddfddZ+d%ddZ,dede-fdd Z.d!d" Z/ed#kre" 0 Z1e/e!e1 dS dS )&z)Handle reconfiguration on hotplug events.    N)	reportingstagesutil)install_hotplug)
EventScope	EventType)loggers)read_sys_net_safe)parse_net_config_data)events)
DataSourceDataSourceNotFoundException)Initzhotplug-hookc                 C   s   | s	t jttd} t| _| jdddddgd | jdd	d
}d|_|jddd |jddd}|jdddddd |jdddddgd |jddd | S )a  Build or extend an arg parser for hotplug-hook utility.

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

    @returns: ArgumentParser with proper argument configuration.
    )progdescriptionz-sz--subsystemTzsubsystem to act onnet)requiredhelpchoiceszHotplug Actionhotplug_action)titledestqueryz0Query if hotplug is enabled for given subsystem.)r   handlezHandle the hotplug event.z-dz	--devpathPATHzSysfs path to hotplugged device)r   metavarr   z-uz--udevactionzSpecify action to take.addenablez%Enable hotplug for a given subsystem.)	argparseArgumentParserNAME__doc__r   add_argumentadd_subparsersr   
add_parser)parser
subparsersparser_handle r(   B/usr/lib/python3/dist-packages/cloudinit/cmd/devel/hotplug_hook.py
get_parser   sL   r*   c                   @   s`   e Zd Zdd Zejdd Zeejdd Zejde	fdd	Z
d
d Zdd Zdd ZdS )UeventHandlerc                 C   s"   || _ || _|| _|| _|| _d S N)id
datasourcedevpathaction
success_fn)selfr-   r.   r/   r0   r1   r(   r(   r)   __init__R   s
   
zUeventHandler.__init__c                 C      t  r,   NotImplementedErrorr2   r(   r(   r)   applyY      zUeventHandler.applyc                 C   r4   r,   r5   r7   r(   r(   r)   config]   s   zUeventHandler.configreturnc                 C   r4   r,   r5   r7   r(   r(   r)   device_detectedb   r9   zUeventHandler.device_detectedc                 C   s@   d }| j dkr
d}ntd| j  ||  krtd| j d S )Nr   TzUnknown action: %sz'Failed to detect %s in updated metadata)r0   
ValueErrorr<   RuntimeErrorr-   )r2   detect_presencer(   r(   r)   detect_hotplugged_devicef   s   
z&UeventHandler.detect_hotplugged_devicec                 C   s   |   S r,   )r1   r7   r(   r(   r)   successr   s   zUeventHandler.successc                 C   s,   | j tjg}|std| j tjf |S )Nz&Datasource %s not updated for event %s)r.   update_metadata_if_supportedr   HOTPLUGr>   )r2   resultr(   r(   r)   update_metadatau   s   
zUeventHandler.update_metadataN)__name__
__module____qualname__r3   abcabstractmethodr8   propertyr:   boolr<   r@   rA   rE   r(   r(   r(   r)   r+   Q   s    
r+   c                       s>   e Zd Z fddZdd Zedd Zdefdd	Z  Z	S )

NetHandlerc                    s*   t tj|d}t ||||| d S )Naddress)r	   ospathbasenamesuperr3   )r2   r.   r/   r0   r1   r-   	__class__r(   r)   r3      s   zNetHandler.__init__c                 C   sZ   | j jj| jdd tj| j}| j j }| j	dkr)|
|s+td| jd S d S )NF)bring_upr   zFailed to bring up device: {})r.   distroapply_network_configr:   rO   rP   rQ   r/   network_activatorr0   bring_up_interfacer>   format)r2   interface_name	activatorr(   r(   r)   r8      s   


zNetHandler.applyc                 C   s   | j jS r,   )r.   network_configr7   r(   r(   r)   r:      s   zNetHandler.configr;   c                    s<   t  j} fdd| D }td j| t|dkS )Nc                    s    g | ]}| d  jkr|qS )mac_address)getr-   ).0ifacer7   r(   r)   
<listcomp>   s
    z.NetHandler.device_detected.<locals>.<listcomp>zIfaces with ID=%s : %sr   )r
   r:   iter_interfacesLOGdebugr-   len)r2   netstatefoundr(   r7   r)   r<      s   

zNetHandler.device_detected)
rF   rG   rH   r3   r8   rK   r:   rL   r<   __classcell__r(   r(   rS   r)   rM      s    
rM   r   c              
   C   sR   zt | d }W n ty } ztd||d }~ww tj| j| jtj	|dS )N   z4hotplug-hook: cannot handle events for subsystem: {})r.   cfgevent_source_typescope)
SUBSYSTEM_PROPERTIES_MAPKeyErrorr>   rZ   r   update_event_enabledr.   rk   r   rC   )hotplug_init	subsystemrm   er(   r(   r)   
is_enabled   s$   rt   rq   rr   c                 C   sR   t d | jdd}|tjgst d| d S t| |s't d| d S |S )NzFetching datasourcetrustexistingz*hotplug not supported for event of type %sz(hotplug not enabled for event of type %s)rd   re   fetchget_supported_eventsr   rC   rt   )rq   rr   r.   r(   r(   r)   initialize_datasource   s   

rz   r;   c                 C   s   t | |}|s	d S t| d }td| ||||| jd}t }|jjs.t||| d S t | |jj	k rVt||| td t
|jj t | |jj	k s8d S d S )Nr   zCreating %s event handler)r.   r/   r0   r1   z>Gathering network configuration again due to IMDS limitations.)rz   rn   rd   re   _write_to_cachetimehotplug_retry_settingsforce_retrytry_hotplugsleep_totalsleepsleep_period)rq   r/   rr   
udevactionr.   handler_clsevent_handlerstartr(   r(   r)   handle_hotplug   s,   
r   c                 C   s   g d}t d}t|D ]X\}}td| |t| z+td |  |js0td |  td |  td |	  W  d S  t yd } ztd| t
| |}W Y d }~qd }~ww |)	N)rj         
      z#Bug while processing hotplug event.z!subsystem=%s update attempt %s/%szRefreshing metadataz$Detecting device in updated metadatazApplying config changezUpdating cachez,Exception while processing hotplug event. %s)	Exception	enumeraterd   re   rf   rE   skip_hotplug_detectr@   r8   rA   r|   r   )rr   r   r.   
wait_timeslast_exceptionattemptwaitrs   r(   r(   r)   r      s6   




r   c                 C   s   | j dd}|s
dS t| d }tj|tjg|t v }|s-td| tj	d dS t
| j}|j|d v rGtd| d	tj	d d
S |d |j t
j| jdt|ddd t|d
| jd d
S )Nru   rv   Frj   z#hotplug not supported for event of )filescopesz)Not installing hotplug for event of type z. Reason: Already done.Tzhotplug.enabledwi  )omodemode)network_hotplug_enabledrk   )rx   rn   r   rC   ry   r_   setprintsysstderrr   read_hotplug_enabled_filepathsvalueappend
write_file	get_cpathjsondumpsr   rk   )rq   rr   r.   rm   hotplug_supportedhotplug_enabled_filer(   r(   r)   enable_hotplug   s<   

r   c              	   C   s  t j| tdd}tg |d}|  t|j d|jv r&t	|j
d td| |j|jd|v r5|jnd d|v r=|jnd  |w za|jdkrmzt||j}W n tyc   td	 td
 Y nw t|ridnd n6|jdkr~t||j|j|jd n%t dkrtjd td
 t||jdstd
 td|j  W n ty   td  w W d    n1 sw   Y  td t  d S )NT)reporting_enabled)ds_depsreporterr   zh%s called with the following arguments: {hotplug_action: %s, subsystem: %s, udevaction: %s, devpath: %s}r   r/   r   z9Unable to determine hotplug state. No datasource detectedrj   enableddisabledr   )rq   r/   rr   r   r   z9Root is required. Try prepending your command with sudo.
)rq   rr   z)Enabled cloud-init hotplug for subsystem=z*Received fatal exception handling hotplug!zExiting hotplug handler)r   ReportEventStackr!   r   read_cfgr   setup_loggingrk   r   update_configurationr_   rd   re   r   rr   r   r/   rz   r   r   r   exitr   rO   getuidr   writer   r   	exceptionflush_events)nameargshotplug_reporterrq   r.   r(   r(   r)   handle_args   sx   







)r   __main__r,   )r;   N)2r!   rI   r   r   loggingrO   r   r|   	cloudinitr   r   r   #cloudinit.config.cc_install_hotplugr   cloudinit.eventr   r   cloudinit.logr   cloudinit.netr	   cloudinit.net.network_stater
   cloudinit.reportingr   cloudinit.sourcesr   r   cloudinit.stagesr   	getLoggerrF   rd   r    r*   ABCr+   rM   NETWORKrn   rt   strrz   r   r   rL   r   r   
parse_argsr   r(   r(   r(   r)   <module>   sD   

60
#
#E
