o
    fL+                     @   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ZddlZddlm	Z	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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e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util)install_hotplug)
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 |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remove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/   r0   r1   r2   r)   r)   r*   __init__Q   s
   
zUeventHandler.__init__c                 C      t  r-   NotImplementedErrorr3   r)   r)   r*   applyX      zUeventHandler.applyc                 C   r5   r-   r6   r8   r)   r)   r*   config\   s   zUeventHandler.configreturnc                 C   r5   r-   r6   r8   r)   r)   r*   device_detecteda   r:   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)r1   
ValueErrorr=   RuntimeErrorr.   )r3   detect_presencer)   r)   r*   detect_hotplugged_devicee   s   

z&UeventHandler.detect_hotplugged_devicec                 C   s   |   S r-   )r2   r8   r)   r)   r*   successs   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?   )r3   resultr)   r)   r*   update_metadatav   s   
zUeventHandler.update_metadataN)__name__
__module____qualname__r4   abcabstractmethodr9   propertyr;   boolr=   rA   rB   rF   r)   r)   r)   r*   r,   P   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superr4   )r3   r/   r0   r1   r2   r.   	__class__r)   r*   r4      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_configr;   rP   rQ   rR   r0   network_activatorr1   bring_up_interfacer?   formatbring_down_interface)r3   interface_name	activatorr)   r)   r*   r9      s&   





zNetHandler.applyc                 C   s   | j jS r-   )r/   network_configr8   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ifacer8   r)   r*   
<listcomp>   s
    z.NetHandler.device_detected.<locals>.<listcomp>zIfaces with ID=%s : %sr   )r
   r;   iter_interfacesLOGdebugr.   len)r3   netstatefoundr)   r8   r*   r=      s   

zNetHandler.device_detected)
rG   rH   rI   r4   r9   rL   r;   rM   r=   __classcell__r)   r)   rT   r*   rN      s    
rN   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?   r[   r   update_event_enabledr/   rm   r   rD   )hotplug_init	subsystemro   er)   r)   r*   
is_enabled   s$   rv   rs   rt   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)rf   rg   fetchget_supported_eventsr   rD   rv   )rs   rt   r/   r)   r)   r*   initialize_datasource   s   

r|   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/   r0   r1   r2   )rl         
      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|   rp   rf   rg   _write_to_cache	Exception	enumeraterh   rF   skip_hotplug_detectrA   r9   rB   timesleep)rs   r0   rt   
udevactionr/   handler_clsevent_handler
wait_timeslast_exceptionattemptwaitru   r)   r)   r*   handle_hotplug   sL   





r   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 )Nrw   rx   Frl   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_enabledrm   )rz   rp   r   rD   r{   ra   setprintsysstderrr   read_hotplug_enabled_filepathsvalueappend
write_file	get_cpathjsondumpsr   rm   )rs   rt   r/   ro   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   r0   r   z9Unable to determine hotplug state. No datasource detectedrl   enableddisabledr   )rs   r0   rt   r   r   z9Root is required. Try prepending your command with sudo.
)rs   rt   z)Enabled cloud-init hotplug for subsystem=z*Received fatal exception handling hotplug!zExiting hotplug handler)r   ReportEventStackr"   r   read_cfgr   setup_loggingrm   r   update_configurationra   rf   rg   r   rt   r   r0   r|   r   r   r   exitr   rP   getuidr   writer   r   	exceptionflush_events)nameargshotplug_reporterrs   r/   r)   r)   r*   handle_args  sx   







)r   __main__r-   )0r"   rJ   r   r   loggingrP   r   r   	cloudinitr   r   r   r   #cloudinit.config.cc_install_hotplugr   cloudinit.eventr   r   cloudinit.netr	   cloudinit.net.network_stater
   cloudinit.reportingr   cloudinit.sourcesr   r   cloudinit.stagesr   	getLoggerrG   rf   r!   r+   ABCr,   rN   NETWORKrp   rv   strr|   r   rM   r   r   
parse_argsr   r)   r)   r)   r*   <module>   s@   

62
((#E
