U
    Ld,                     @   s   d dl Z d dlm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 eeZdZd	Zd
eiZdZdZdZedd eD ZG dd dejejZdd Zdd ZdddZ dd Z!d ddZ"eZ#eej$ffgZ%dd Z&dS )!    N)log)sourcessubputil)
EventScope	EventType)eni)get_ibm_platform)	openstackziid-dsconfigdrivepassinstance-id)ZvfatZiso9660)zconfig-2zCONFIG-2)srZcdc                 c   s*   | ]"}t d dD ]}d||f V  qqdS )r      z	/dev/%s%sN)range).0zi r   I/usr/lib/python3/dist-packages/cloudinit/sources/DataSourceConfigDrive.py	<genexpr>   s       r   c                       sr   e Zd ZdZejejejej	ej
hiZ fddZdd Zdd Zdd	 Zed
d Zedd Zdd Z  ZS )DataSourceConfigDriveZConfigDrivec                    s\   t t| ||| d | _tj|jd| _d | _d | _	d | _
tj| _d | _d | _i | _d S )NZconfig_drive)superr   __init__sourceospathjoinseed_dirversionec2_metadata_network_configr   UNSETnetwork_jsonnetwork_eni
known_macsfiles)selfsys_cfgdistropaths	__class__r   r   r   /   s    zDataSourceConfigDrive.__init__c                 C   s0   t j| }d|| j| jf }|d| j 7 }|S )Nz%s [%s,ver=%s]z[source=%s])r   
DataSource__str__dsmoder   r   )r&   rootZmstrr   r   r   r-   ;   s    zDataSourceConfigDrive.__str__c              
   C   s  d }i }i }| j dfD ]N}tj|s(qzt|}|}W  qfW q tjk
rb   tt	d| Y qX q|s| j
d}t|dD ]}d }t r|drd}ztj|t|d}|}W nN tjk
r   Y n: tjk
r   Y n& tjk
r   tt	d| Y nX |r qq|sd	S |d
i }t|tg}| |d| jd|d dkrbtjnd g| _| jtjkr~d	S t| j}|d }	||	krt|| j| jtjkd | jtjkrt	d| | j d	S || _|| _ |d| _!|d| _"|d | _#| j$%|di  |d}
|
| _&zt'|
| _(W n6 t)k
rl } zt	*d| d | _(W 5 d }~X Y nX |d}|| _+zt'|| _,W n6 t)k
r } zt	*d| d | _,W 5 d }~X Y nX |d| _-|d| _.dS )Nz/config-drivez#Failed reading config drive from %sZdatasource_list)dslistz/dev/cdZcd9660)mtypezBroken config drive: %sFmetadatar.   r      r   )r(   networkz&%s: not claiming datasource, dsmode=%szec2-metadataZuserdatar%   Z
vendordataz"Invalid content in vendor-data: %sZvendordata2z#Invalid content in vendor-data2: %snetwork_configZnetworkdataT)/r   r   r   isdirread_config_driver
   NonReadabler   logexcLOGr'   getfind_candidate_devsZis_BSD
startswithZmount_cbZMountFailedErrorZBrokenMetadataZmergemanydictDEFAULT_METADATAZ_determine_dsmodeZds_cfgr   ZDSMODE_PASSr.   ZDSMODE_DISABLEDget_previous_iidr)   on_first_bootr(   debugr   r2   r   Zuserdata_rawr   r%   updateZvendordata_pureZconvert_vendordataZvendordata_raw
ValueErrorwarningZvendordata2_pureZvendordata2_rawr#   r"   )r&   foundZmdZresultsZsdirr0   Zdevr1   Zprev_iidZcur_iidZvdeZvd2r   r   r   	_get_dataA   s    

  



  


zDataSourceConfigDrive._get_datac                 C   s   t |  S N)r   Zinstance_id_matches_system_uuidZget_instance_id)r&   r'   r   r   r   check_instance_id   s    z'DataSourceConfigDrive.check_instance_idc                 C   sn   | j d krh| jd tjfkr:td tj| j| jd| _ n.| j	d k	r^t
| j	| _ td n
td | j S )Nz(network config provided via network_json)r$   z.network config provided via converted eni dataz"no network configuration available)r    r"   r   r!   r:   rA   r
   Zconvert_net_jsonr$   r#   r   convert_eni_datar&   r   r   r   r5      s    

 


z$DataSourceConfigDrive.network_configc                 C   s   dS )Nr
   r   rK   r   r   r   platform   s    zDataSourceConfigDrive.platformc                 C   s$   | j drd}nd}d|| j f S )z/Return the subplatform metadata source details.z/devzconfig-diskzseed-dirz%s (%s))r   r=   )r&   Zsubplatform_typer   r   r   _get_subplatform   s    z&DataSourceConfigDrive._get_subplatform)__name__
__module____qualname__Zdsnamer   ZNETWORKr   ZBOOT_NEW_INSTANCEZBOOTZBOOT_LEGACYZHOTPLUGZsupported_update_eventsr   r-   rG   rI   propertyr5   rL   rM   __classcell__r   r   r*   r   r   "   s"   	f

r   c                 C   s   t | }|jg i f|jg i fg}g }|D ]J\}}}z|||W   S  t jk
rr } z|| W 5 d }~X Y q*X q*|d d S )N)r
   ZConfigDriveReaderZread_v2Zread_v1r8   append)Z
source_dirreaderZfindersZexcpsZfunctorargskwargsrF   r   r   r   r7      s    


r7   c                 C   sB   t j| dd}zt|dW S  tk
r<   Y d S X d S )Ndatar   
)r   r   r   Z	get_cpathr   Z	load_filerstripIOError)r)   fnamer   r   r   r?      s
    r?   Tc                 C   s^   t | tstdt|  |rL| dd}|rL|rLtd |t	| t
| d dS )zDPerforms any first-boot actions using data read from a config-drive.z/Config-drive data expected to be a dict; not %sr5    z-Updating network interfaces from config driver%   N)
isinstancedict	TypeErrortyper;   r:   rD   Zapply_network_configr   rJ   write_injected_files)rX   r(   r4   Znet_confr   r   r   r@      s    


r@   c              	   C   sx   | rtt dt|  |  D ]V\}}|tjs:tj| }ztj||dd W q t	k
rp   t
t d| Y qX qd S )NzWriting %s injected filesi  )modezFailed writing file: %s)r:   rA   lenitemsr=   r   sepr   Z
write_filer[   r9   )r%   filenameZcontentr   r   r   rb      s    
rb   c           
   	      s  |dkrg }| rBt D ],}ztj|d W q tjk
r>   Y qX qg }tD ]}|td|  qJg  tD ]} td|  ql|jdd  jdd   fdd|D  } fd	d|D }t	
d
|| |rd|krt \}}	|	|kr||	 t	
d|	| |S )a  Return a list of devices that may contain the config drive.

    The returned list is sorted by search order where the first item has
    should be searched first (highest priority)

    config drive v1:
       Per documentation, this is "associated as the last available disk on the
       instance", and should be VFAT.
       Currently, we do not restrict search list to "last available disk"

    config drive v2:
       Disk should be:
        * either vfat or iso9660 formatted
        * labeled with 'config-2' or 'CONFIG-2'
    N)r   zTYPE=%szLABEL=%sT)reversec                    s   g | ]}| kr|qS r   r   r   dZby_labelr   r   
<listcomp>%  s      z'find_candidate_devs.<locals>.<listcomp>c                    s"   g | ]}| kst |s|qS r   )r   Zis_partitionri   rk   r   r   rl   )  s     
 zdevices=%s dslist=%sZIBMCloudz5IBMCloud device '%s' (%s) removed from candidate list)OPTICAL_DEVICESr   Zfind_devs_withr   ZProcessExecutionErrorFS_TYPESextendLABEL_TYPESsortr:   rA   r	   remove)
Zprobe_opticalr0   ZdeviceZ	by_fstypeZfs_typeZlabelZ
candidatesZdevicesZibm_platformZibm_pathr   rk   r   r<      s>    



r<   c                 C   s   t | tS rH   )r   Zlist_from_dependsdatasources)Zdependsr   r   r   get_datasource_listF  s    rt   )NT)TN)'r   Z	cloudinitr   Zloggingr   r   r   Zcloudinit.eventr   r   Zcloudinit.netr   Z$cloudinit.sources.DataSourceIBMCloudr	   Zcloudinit.sources.helpersr
   Z	getLoggerrN   r:   ZDEFAULT_IIDZDEFAULT_MODEr>   rn   rp   ZPOSSIBLE_MOUNTStuplerm   ZSourceMixinr,   r   r7   r?   r@   rb   r<   ZDataSourceConfigDriveNetZDEP_FILESYSTEMrs   rt   r   r   r   r   <module>	   s:   
  &

B
