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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 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fddZ%dd Z&edkre ' Z(e&ee( dS dS )z)Handle reconfiguration on hotplug events.    N)log	reportingstages)
EventScope	EventType)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dg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remove)	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   sF   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-   r.   r/   r&   r&   r'   __init__J   s
   
zUeventHandler.__init__c                 C      t  r*   NotImplementedErrorr0   r&   r&   r'   applyQ      zUeventHandler.applyc                 C   r2   r*   r3   r5   r&   r&   r'   configU   s   zUeventHandler.configreturnc                 C   r2   r*   r3   r5   r&   r&   r'   device_detectedZ   r7   zUeventHandler.device_detectedc                 C   sP   d }| j dkr
d}n| j dkrd}ntd| j  ||  kr&td| j d S )Nr   Tr   FzUnknown action: %sz'Failed to detect %s in updated metadata)r.   
ValueErrorr:   RuntimeErrorr+   )r0   detect_presencer&   r&   r'   detect_hotplugged_device^   s   

z&UeventHandler.detect_hotplugged_devicec                 C   s   |   S r*   )r/   r5   r&   r&   r'   successl   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<   )r0   resultr&   r&   r'   update_metadatao   s   
zUeventHandler.update_metadataN)__name__
__module____qualname__r1   abcabstractmethodr6   propertyr8   boolr:   r>   r?   rC   r&   r&   r&   r'   r)   I   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superr1   )r0   r,   r-   r.   r/   r+   	__class__r&   r'   r1   |   s   zNetHandler.__init__c                 C   s   | j jj| jdd tj| j}| j j }| j	dkr+|
|s)td| jd S | j	dkr=||s?td| jd S d S )NF)bring_upr   zFailed to bring up device: {}r   zFailed to bring down device: {})r,   distroapply_network_configr8   rM   rN   rO   r-   network_activatorr.   bring_up_interfacer<   formatbring_down_interface)r0   interface_name	activatorr&   r&   r'   r6      s&   





zNetHandler.applyc                 C   s   | j jS r*   )r,   network_configr5   r&   r&   r'   r8      s   zNetHandler.configr9   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ifacer5   r&   r'   
<listcomp>   s
    z.NetHandler.device_detected.<locals>.<listcomp>zIfaces with ID=%s : %sr   )r   r8   iter_interfacesLOGdebugr+   len)r0   netstatefoundr&   r5   r'   r:      s   

zNetHandler.device_detected)
rD   rE   rF   r1   r6   rI   r8   rJ   r:   __classcell__r&   r&   rQ   r'   rK   {   s    
rK   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_PROPERTES_MAPKeyErrorr<   rX   r   update_event_enabledr,   rj   r   rA   )hotplug_init	subsystemrl   er&   r&   r'   
is_enabled   s$   rs   rp   rq   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)rc   rd   fetchget_supported_eventsr   rA   rs   )rp   rq   r,   r&   r&   r'   initialize_datasource   s   

rx   c                 C   s
  t | |}|s	d S t| d }td| ||||| jd}g d}td}t|D ]X\}	}
td||	t| z+td |  |j	sNtd |
  td	 |  td
 |  W  d S  ty } ztd| t|
 |}W Y d }~q*d }~ww |)Nr   zCreating %s event handler)r,   r-   r.   r/   )ri         
      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)rx   rm   rc   rd   _write_to_cache	Exception	enumeratere   rC   skip_hotplug_detectr>   r6   r?   timesleep)rp   r-   rq   
udevactionr,   handler_clsevent_handler
wait_timeslast_exceptionattemptwaitrr   r&   r&   r'   handle_hotplug   sL   





r   c              	   C   sB  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  |L z6|jdkrmzt||j}W n tyc   td	 td
 Y nw t|ridnd nt||j|j|jd 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 detectedri   enableddisabled)rp   r-   rq   r   z*Received fatal exception handling hotplug!zExiting hotplug handler)r	   ReportEventStackr   r   read_cfgr   setupLoggingrj   r   update_configurationr^   rc   rd   r   rq   r   r-   rx   r   printsysexitr   r~   	exceptionflush_events)nameargshotplug_reporterrp   r,   r&   r&   r'   handle_args   sZ   




r   __main__r*   ))r   rG   r   rM   r   r   	cloudinitr   r   r   cloudinit.eventr   r   cloudinit.netr   cloudinit.net.network_stater   cloudinit.reportingr	   cloudinit.sourcesr
   r   cloudinit.stagesr   	getLoggerrD   rc   r   r(   ABCr)   rK   NETWORKrm   rs   strrx   r   r   
parse_argsr   r&   r&   r&   r'   <module>   s8   

22
((5
