U
    Ad#                     @   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"ee#dddZ$edddZ%dd Z&edkr$e ' Z(e&ee( 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   Z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_argumentZadd_subparsersr   Z
add_parser)parserZ
subparsersZ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e	d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   s
   t  d S r%   NotImplementedErrorr+   r!   r!   r"   applyQ   s    zUeventHandler.applyc                 C   s
   t  d S r%   r-   r/   r!   r!   r"   configU   s    zUeventHandler.configreturnc                 C   s
   t  d S r%   r-   r/   r!   r!   r"   device_detectedZ   s    zUeventHandler.device_detectedc                 C   sP   d }| j dkrd}n| j dkr$d}ntd| j  ||  krLtd| j d S )Nr   Tr   FzUnknown action: %sz'Failed to detect %s in updated metadata)r)   
ValueErrorr4   RuntimeErrorr&   )r+   Zdetect_presencer!   r!   r"   detect_hotplugged_device^   s    

z&UeventHandler.detect_hotplugged_devicec                 C   s   |   S r%   )r*   r/   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'   Zupdate_metadata_if_supportedr   HOTPLUGr6   )r+   resultr!   r!   r"   update_metadatao   s    
zUeventHandler.update_metadataN)__name__
__module____qualname__r,   abcabstractmethodr0   propertyr1   boolr4   r7   r8   r;   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eddd	Z  Z	S )

NetHandlerc                    s*   t tj|d}t ||||| d S )NZaddress)r   ospathbasenamesuperr,   )r+   r'   r(   r)   r*   r&   	__class__r!   r"   r,   |   s    zNetHandler.__init__c                 C   s|   | j jj| jdd tj| j}| j j }| j	dkrT|
|sxtd| jn$| j	dkrx||sxtd| jd S )NF)Zbring_upr   zFailed to bring up device: {}r   zFailed to bring down device: {})r'   ZdistroZapply_network_configr1   rD   rE   rF   r(   Znetwork_activatorr)   Zbring_up_interfacer6   formatZbring_down_interface)r+   Zinterface_nameZ	activatorr!   r!   r"   r0      s     





zNetHandler.applyc                 C   s   | j jS r%   )r'   Znetwork_configr/   r!   r!   r"   r1      s    zNetHandler.configr2   c                    s<   t  j} fdd| D }td j| t|dkS )Nc                    s    g | ]}| d  jkr|qS )Zmac_address)getr&   ).0Zifacer/   r!   r"   
<listcomp>   s   z.NetHandler.device_detected.<locals>.<listcomp>zIfaces with ID=%s : %sr   )r   r1   Ziter_interfacesLOGdebugr&   len)r+   Znetstatefoundr!   r/   r"   r4      s    

zNetHandler.device_detected)
r<   r=   r>   r,   r0   rA   r1   rB   r4   __classcell__r!   r!   rH   r"   rC   {   s
   
rC   r   c              
   C   s\   zt | d }W n2 tk
rB } ztd||W 5 d }~X Y nX tj| j| jtj	|dS )N   z4hotplug-hook: cannot handle events for subsystem: {})r'   cfgZevent_source_typescope)
SUBSYSTEM_PROPERTES_MAPKeyError	ExceptionrJ   r   Zupdate_event_enabledr'   rT   r   r9   )hotplug_init	subsystemrU   er!   r!   r"   
is_enabled   s     r\   )rY   rZ   c                 C   sR   t d | jdd}|tjgs4t d| d S t| |sNt d| d S |S )NzFetching datasourceZtrust)existingz*hotplug not supported for event of type %sz(hotplug not enabled for event of type %s)rN   rO   ZfetchZget_supported_eventsr   r9   r\   )rY   rZ   r'   r!   r!   r"   initialize_datasource   s    

r^   )rY   c                 C   s  t | |}|sd S t| d }td| ||||| jd}dddddg}td	}t|D ]\}	}
td
||	t| zZtd |  |j	std |
  td |  td |  W  qW qZ tk
r } ztd| t|
 |}W 5 d }~X Y qZX qZ|d S )Nr   zCreating %s event handler)r'   r(   r)   r*   rS         
      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)r^   rV   rN   rO   Z_write_to_cacherX   	enumeraterP   r;   Zskip_hotplug_detectr7   r0   r8   timesleep)rY   r(   rZ   
udevactionr'   Zhandler_clsZevent_handlerZ
wait_timesZlast_exceptionZattemptwaitr[   r!   r!   r"   handle_hotplug   sH    





rh   c              	   C   s8  t j| tdd}tg |d}|  t|j d|jkrLt	|j
d td| |j|jd|krj|jnd d|krz|jnd  | zn|jdkrzt||j}W n& tk
r   td	 td
 Y nX t|rdnd nt||j|j|jd W n" tk
r   td  Y nX W 5 Q R X td t  d S )NT)Zreporting_enabled)Zds_depsZreporterr   zh%s called with the following arguments: {hotplug_action: %s, subsystem: %s, udevaction: %s, devpath: %s}rf   r(   r   z9Unable to determine hotplug state. No datasource detectedrS   enabledZdisabled)rY   r(   rZ   rf   z*Received fatal exception handling hotplug!zExiting hotplug handler)r	   ZReportEventStackr   r   Zread_cfgr   ZsetupLoggingrT   r   Zupdate_configurationrK   rN   rO   r   rZ   rf   r(   r^   r   printsysexitrh   rX   Z	exceptionZflush_events)nameargsZhotplug_reporterrY   r'   r!   r!   r"   handle_args   sV      


 


ro   __main__)N))r   r?   r   rD   rk   rd   Z	cloudinitr   r   r   Zcloudinit.eventr   r   Zcloudinit.netr   Zcloudinit.net.network_stater   Zcloudinit.reportingr	   Zcloudinit.sourcesr
   r   Zcloudinit.stagesr   Z	getLoggerr<   rN   r   r#   ABCr$   rC   ZNETWORKrV   r\   strr^   rh   ro   
parse_argsrn   r!   r!   r!   r"   <module>   s6   

22( (5

