509318396
Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­
<!DOCTYPE html>
<html>
3
Šcjó¨  ã               @   sJ  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
mZmZ d dlmZ d dlmZmZ d dlmZmZ ejeƒZdZdZdd	d
dgZdddddddddddgZejdƒfdd„Zdd„ Zd¬dd„Zd­dd „Z d®d!d"„Z!d#d$„ Z"d%d&„ Z#d'd(„ Z$d)d*„ Z%d+d,„ Z&d-d.„ Z'd/d0„ Z(d1d2„ Z)ej*dd3�e+d4œd5d6„ƒZ,ej*dd3�e-d4œd7d8„ƒZ.e/e+d9œd:d;„Z0d¯d<d=„Z1d>d?„ Z2d@dA„ Z3d°e+d4œdBdC„Z4d±dDdE„Z5d²dFdG„Z6dHdI„ Z7dJdK„ Z8dLdM„ Z9dNdO„ Z:dPdQ„ Z;G dRdS„ dSe<ƒZ=dTdU„ Z>e
e/ d4œdVdW„Z?ee/ d4œdXdY„Z@e
e/ d4œdZd[„ZAee/ d4œd\d]„ZBe
e/ d4œd^d_„ZCee/ d4œd`da„ZDe
e/ d4œdbdc„ZEee/ d4œddde„ZFd³dfdg„ZGdhdi„ ZHd´dkdl„ZIdµdndo„ZJd¶dpdq„ZKdrds„ ZLdtdu„ ZMeNd4œdvdw„ZOe/ee/ dxœdydz„ZPeNd4œd{d|„ZQeNd4œd}d~„ZReNd4œdd€„ZSeNd4œd�d‚„ZTd·e+e+e+e+e+e+e+e-dƒœd„d…„ZUed¸ e
ee/e/e/e/f  dd‡œdˆd‰„ZVdŠd‹„ ZWe	e/ef e+dŒœd�dŽ„ZXee/d�œd�d‘„ZYe/e+d’œd“d”„ZZe/e+d’œd•d–„Z[e/e+d’œd—d˜„Z\e/e+d’œd™dš„Z]e/e+d’œd›dœ„Z^e/e+d’œd�dž„Z_e+d4œdŸd „Z`e/d4œd¡d¢„Zaebd4œd£d¤„Zcebd4œd¥d¦„Zde/e/e/d§œd¨d©„ZeG dªd«„ d«efƒZgdS )¹é    N)ÚAnyÚCallableÚDictÚListÚOptionalÚTuple)Úurlparse)ÚsubpÚutil)ÚUrlErrorÚreadurlz/sys/class/net/Zeth0Údhcp6Z
ipv6_slaaczipv6_dhcpv6-statelesszipv6_dhcpv6-statefulz	ovs-vsctlz--formatZcsvz--no-headingsz	--timeoutZ10z	--columnsÚnameÚfindÚ	interfaceztype=internalz([0-9]+)c             C   s   dd„ t j|| ƒD ƒS )aD  Sorting for Humans: natural sort order. Can be use as the key to sort
    functions.
    This will sort ['eth0', 'ens3', 'ens10', 'ens12', 'ens8', 'ens0'] as
    ['ens0', 'ens3', 'ens8', 'ens10', 'ens12', 'eth0'] instead of the simple
    python way which will produce ['ens0', 'ens10', 'ens12', 'ens3', 'ens8',
    'eth0'].c             S   s$   g | ]}|j ƒ rt|ƒn|jƒ ‘qS © )ÚisdigitÚintÚlower)Ú.0Útextr   r   ú/usr/lib/python3.6/__init__.pyú
<listcomp>4   s   z$natural_sort_key.<locals>.<listcomp>)ÚreÚsplit)ÚsZ_nsrer   r   r   Únatural_sort_key,   s    r   c               C   s   t S )z3Simple function to return the global SYS_CLASS_NET.)ÚSYS_CLASS_NETr   r   r   r   Úget_sys_class_path9   s    r   Ú c             C   s   t ƒ |  d | S )Nú/)r   )ÚdevnameÚpathr   r   r   Úsys_dev_path>   s    r#   c       
      C   sî   t | |ƒ}ytj|ƒ}W np ttfk
rˆ } zPt|dd ƒ}	|	tjtjfkrZ|d k	rZ||ƒS |	tj	fkrv|d k	rv||ƒS ‚ W Y d d }~X nX |j
ƒ }|d krž|S y|| S  tk
rè } z&|d k	rÈ||ƒS tjd||ƒ ‚ W Y d d }~X nX d S )NÚerrnoz5Found unexpected (not translatable) value '%s' in '%s)r#   r
   Z	load_fileÚOSErrorÚIOErrorÚgetattrr$   ÚENOENTÚENOTDIRZEINVALÚstripÚKeyErrorÚLOGÚdebug)
r!   r"   Ú	translateÚ	on_enoentÚon_keyerrorÚ	on_einvalZdev_pathÚcontentsÚeZe_errnor   r   r   Úread_sys_netB   s2    
r4   c             C   s   dd„ }t | |||||d�S )Nc             S   s   dS )NFr   )r3   r   r   r   Úon_excp_falseh   s    z(read_sys_net_safe.<locals>.on_excp_false)r0   r/   r1   r.   )r4   )ÚifaceÚfieldr.   r5   r   r   r   Úread_sys_net_safeg   s    r8   c             C   s8   t | |ƒ}|dkrd S yt|ƒS  tk
r2   d S X d S )NF)r8   r   Ú
ValueError)r6   r7   Úvalr   r   r   Úread_sys_net_intu   s    
r;   c             C   s   ddddœ}t | d|d�S )NTF)ÚupÚunknownÚdownÚ	operstate)r.   )r8   )r!   r.   r   r   r   Úis_up   s    r@   c             C   s   t jjt| dƒƒS )NÚbridge)Úosr"   Úexistsr#   )r!   r   r   r   Ú	is_bridge‡   s    rD   c             C   s   t jjt| dƒƒS )NÚbonding)rB   r"   rC   r#   )r!   r   r   r   Úis_bond‹   s    rF   c             C   s    t | dd�}tjj|ƒr|S dS )z8Return the master path for devname, or None if no masterÚmaster)r"   N)r#   rB   r"   rC   )r!   r"   r   r   r   Ú
get_master�   s    rH   c             C   sH   t | ƒ}|dkrdS tjj|dƒ}tjj|dƒ}tjj|ƒpFtjj|ƒS )z@Return a bool indicating if devname's master is a bridge or bondNFrE   rA   )rH   rB   r"   ÚjoinrC   )r!   Úmaster_pathZbonding_pathZbridge_pathr   r   r   Úmaster_is_bridge_or_bond—   s    rK   c             C   s,   t | ƒ}|dkrdS t| dd�}tjj|ƒS )z;Return a bool indicating if devname's master is openvswitchNFzupper_ovs-system)r"   )rH   r#   rB   r"   rC   )r!   rJ   Zovs_pathr   r   r   Úmaster_is_openvswitch¡   s
    rL   c             C   s   t | dƒdkS )NÚtypeÚ32)r8   )r!   r   r   r   Úis_ib_interfaceª   s    rO   )Úmaxsize)Úreturnc              C   s    t tjdƒƒ} | stjdƒ | S )zDReturn a bool indicating if Open vSwitch is installed in the system.z	ovs-vsctlz<ovs-vsctl not in PATH; not detecting Open vSwitch interfaces)Úboolr	   Zwhichr,   r-   )Úretr   r   r   Úopenvswitch_is_installed®   s
    rT   c              C   s^   yt j tƒ\} }W n> t jk
rP } z d|jkr>tjdƒ g S ‚ W Y dd}~X n
X | jƒ S dS )zÎReturn a list of the names of OVS internal interfaces on the system.

    These will all be strings, and are used to exclude OVS-specific interface
    from cloud-init's network configuration handling.
    zdatabase connection failedzJOpen vSwitch is not yet up; no interfaces will be detected as OVS-internalN)r	   Ú!OVS_INTERNAL_INTERFACE_LOOKUP_CMDZProcessExecutionErrorÚstderrr,   ÚinfoÚ
splitlines)ÚoutÚ_errÚexcr   r   r   Úget_ovs_internal_interfaces¹   s    
r\   )r!   rQ   c             C   s,   t ƒ s
dS tƒ }| |kr(tjd| ƒ dS dS )z€Returns True if this is an OVS internal interface.

    If OVS is not installed or not yet running, this will return False.
    FzDetected %s as an OVS interfaceT)rT   r\   r,   r-   )r!   Zovs_bridgesr   r   r   Ú!is_openvswitch_internal_interfaceÎ   s    r]   c             C   s,   |dkrt | ƒ}t| |ƒs$t| |ƒr(dS dS )z®netfailover driver uses 3 nics, master, primary and standby.
    this returns True if the device is either the primary or standby
    as these devices are to be ignored.
    NTF)Údevice_driverÚis_netfail_primaryÚis_netfail_standby)r!   Údriverr   r   r   Úis_netfailoverÜ   s    rb   c             C   s,   d}yt | dƒ}W n tk
r&   Y nX |S )zDReturns a str from reading /sys/class/net/<devname>/device/features.r   zdevice/features)r4   Ú	Exception)r!   Úfeaturesr   r   r   Úget_dev_featuresê   s    re   c             C   s*   t | ƒ}| st|ƒdk rdS |d dkS )zÅ Return True if VIRTIO_NET_F_STANDBY bit (62) is set.

    https://github.com/torvalds/linux/blob/         089cf7f6ecb266b6a4164919a2e69bd2f938374a/         include/uapi/linux/virtio_net.h#L60
    é@   Fé>   Ú1)re   Úlen)r!   rd   r   r   r   Úhas_netfail_standby_featureô   s    rj   c             C   s<   t | ƒdk	rdS |dkr t| ƒ}|dkr,dS t| ƒs8dS dS )zòA device is a "netfail master" device if:

    - The device does NOT have the 'master' sysfs attribute
    - The device driver is 'virtio_net'
    - The device has the standby feature bit set

    Return True if all of the above is True.
    NFÚ
virtio_netT)rH   r^   rj   )r!   ra   r   r   r   Úis_netfail_master  s    	rl   c             C   st   t | dd�}tjj|ƒsdS |dkr,t| ƒ}|dkr8dS tjjtjj|ƒƒ}t|ƒ}|dkr`dS t|ƒ}|spdS dS )a7  A device is a "netfail primary" device if:

    - the device has a 'master' sysfs file
    - the device driver is not 'virtio_net'
    - the 'master' sysfs file points to device with virtio_net driver
    - the 'master' device has the 'standby' feature bit set

    Return True if all of the above is True.
    rG   )r"   FNrk   T)r#   rB   r"   rC   r^   ÚbasenameÚrealpathrj   )r!   ra   Zmaster_sysfs_pathZmaster_devnameZmaster_driverZmaster_has_standbyr   r   r   r_     s    r_   c             C   s<   t | ƒdkrdS |dkr t| ƒ}|dkr,dS t| ƒs8dS dS )zçA device is a "netfail standby" device if:

    - The device has a 'master' sysfs attribute
    - The device driver is 'virtio_net'
    - The device has the standby feature bit set

    Return True if all of the above is True.
    NFrk   T)rH   r^   rj   )r!   ra   r   r   r   r`   :  s    	r`   c             C   s   t | dƒ}|r|dkrdS dS )a°  
    /* interface name assignment types (sysfs name_assign_type attribute) */
    #define NET_NAME_UNKNOWN      0  /* unknown origin (not exposed to user) */
    #define NET_NAME_ENUM         1  /* enumerated by kernel */
    #define NET_NAME_PREDICTABLE  2  /* predictably named by the kernel */
    #define NET_NAME_USER         3  /* provided by user-space */
    #define NET_NAME_RENAMED      4  /* renamed by user-space */
    Úname_assign_typeÚ3Ú4TF)rp   rq   )r8   )r!   ro   r   r   r   Ú
is_renamedR  s    	
rr   c             C   s   t t| dƒƒ}d|jƒ kS )NÚueventzDEVTYPE=vlan)Ústrr8   rX   )r!   rs   r   r   r   Úis_vlana  s    ru   c             C   s0   d}t | dƒ}tjj|ƒr,tjjtj|ƒƒ}|S )z8Return the device driver for net device named 'devname'.Nzdevice/driver)r#   rB   r"   Úislinkrm   Úreadlink)r!   ra   Zdriver_pathr   r   r   r^   f  s
    
r^   c             C   s   t | dƒ}|dkrdS |S )z;Return the device id string for net device named 'devname'.zdevice/deviceFN)r8   )r!   Zdev_idr   r   r   Údevice_devidq  s    
rx   c              C   sj   t jƒ st jƒ rttƒ jƒ ƒS ytjtƒ ƒ} W n6 t	k
rd } z|j
t
jkrRg } n‚ W Y d d }~X nX | S )N)r
   Ú
is_FreeBSDÚis_DragonFlyBSDÚlistÚget_interfaces_by_macÚvaluesrB   Úlistdirr   r%   r$   r(   )Údevsr3   r   r   r   Úget_devicelistz  s    r€   c               @   s   e Zd ZdZdS )ÚParserErrorz6Raised when a parser has issue parsing a file/content.N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r�   ˆ  s   r�   c             C   s$   |  st | tƒ rdS | jdƒdkS )NFÚconfigZdisabled)Ú
isinstanceÚdictÚget)Úcfgr   r   r   Úis_disabled_cfgŒ  s    r‹   c               C   s6   t jƒ st jƒ rtƒ S t jƒ s&t jƒ r,tƒ S tƒ S dS )zqGet the list of network interfaces viable for networking.

    @return List of interfaces, sorted naturally.
    N)r
   ry   rz   Úfind_candidate_nics_on_freebsdÚ	is_NetBSDÚ
is_OpenBSDÚ(find_candidate_nics_on_netbsd_or_openbsdÚfind_candidate_nics_on_linuxr   r   r   r   Úfind_candidate_nics’  s
    r‘   c               C   s6   t jƒ st jƒ rtƒ S t jƒ s&t jƒ r,tƒ S tƒ S dS )z.Get the name of the 'fallback' network device.N)r
   ry   rz   Úfind_fallback_nic_on_freebsdr�   rŽ   Ú&find_fallback_nic_on_netbsd_or_openbsdÚfind_fallback_nic_on_linuxr   r   r   r   Úfind_fallback_nicŸ  s
    r•   c               C   s   t tƒ jƒ td�S )zmGet the names of the candidate network devices on NetBSD/OpenBSD.

    @return list of sorted interfaces
    )Úkey)Úsortedr|   r}   r   r   r   r   r   r�   ©  s    r�   c              C   s   t ƒ } | r| d S dS )zfGet the 'fallback' network device name on NetBSD/OpenBSD.

    @return default interface, or None
    r   N)r�   )Únamesr   r   r   r“   ±  s    r“   c              C   s8   t j ddddgƒ\} }| jƒ }|r&|S ttƒ jƒ td�S )zgGet the names of the candidate network devices on FreeBSD.

    @return List of sorted interfaces.
    Úifconfigz-lz-uÚether)r–   )r	   r   r—   r|   r}   r   )ÚstdoutZ_stderrr}   r   r   r   rŒ   ½  s
    rŒ   c              C   s   t ƒ } | r| d S dS )z_Get the 'fallback' network device name on FreeBSD.

    @return List of sorted interfaces.
    r   N)rŒ   )r˜   r   r   r   r’   Ì  s    r’   c              C   s`  dt jƒ krtjdƒ n<dd„ tƒ D ƒ} t| ƒrTtjd| ƒ d}t jtj|t jd� g }g }x²tdddddd	d
�D ]š\}}}}|dkrˆqr|j	dƒr tjd|ƒ qrt
|dƒ}|rº|j|ƒ qrtjd|ƒ t
|dƒ}|rà|j|ƒ qrt|dƒ}|dk�r |j|ƒ qrtjd|ƒ qrW g }	xF||gD ]:}
t|
td�}
t|
k�rN|
jtƒ |
jdtƒ |	|
7 }	�qW |	S )zeGet the names of the candidate network devices on Linux.

    @return List of sorted interfaces.
    znet.ifnames=0z9Stable ifnames disabled by net.ifnames=0 in /proc/cmdlinec             S   s"   g | ]}|d krt |ƒ r|‘qS )Úlo)rr   )r   Zdevicer   r   r   r   á  s   z0find_candidate_nics_on_linux.<locals>.<listcomp>z4Found unstable nic names: %s; calling udevadm settlez!Waiting for udev events to settle)ÚfuncFT)Úfilter_openvswitch_internalÚ2filter_slave_if_master_not_bridge_bond_openvswitchÚfilter_vlanÚfilter_without_own_macÚfilter_zero_macÚlog_filtered_reasonsrœ   ZvethzIgnoring veth interface: %sÚcarrierzInterface has no carrier: %sÚdormantr?   r>   Úlowerlayerdownr=   zInterface ignored: %s)r–   r   )r¥   r>   r¦   r=   )r
   Zget_cmdliner,   r-   r€   ri   Zlog_timeZudevadm_settleÚget_interfacesÚ
startswithr;   Úappendr8   r—   r   ÚDEFAULT_PRIMARY_INTERFACEÚremoveÚinsert)ZunstableÚmsgZ	connectedZpossibly_connectedr   Ú_r¤   r¥   r?   Zsorted_interfacesÚ
interfacesr   r   r   r�   Ø  s\    










r�   c              C   s   t ƒ } | r| d S dS )z]Get the 'fallback' network device name on Linux.

    @return List of sorted interfaces.
    r   N)r�   )r˜   r   r   r   r”   !  s    r”   c             C   sv   | sd} t ƒ }|sdS t|ƒr(d|i}ndt|dƒjƒ i}dd||dœ}| rdt|ƒ}|rd||d d	< ||id
dœ}|S )zBGenerate network cfg v2 for dhcp on the NIC most likely connected.FNr   Ú
macaddressÚaddressT)Zdhcp4r   zset-nameÚmatchr²   ra   é   )Ú	ethernetsÚversion)r•   rl   r8   r   r^   )Zconfig_driverZtarget_namer²   rŠ   ra   Znconfr   r   r   Úgenerate_fallback_config-  s$    
r¶   c             C   sJ   dd„ }dd„ }| j dƒ}|dkr*|| ƒS |dkr:|| ƒS td| ƒ‚d S )	Nc             S   s–   g }xŒ| j di ƒD ]|}|j dƒdkr&q|j dƒ}|s6q|j dƒ}|j di ƒj dƒ}|j di ƒj dƒ}|spt|ƒ}|s|t|ƒ}|j||||gƒ qW |S )	Nr†   rM   ZphysicalZmac_addressr   Úparamsra   Ú	device_id)r‰   r^   rx   r©   )ÚnetcfgÚphysdevsÚentÚmacr   ra   r¸   r   r   r   Ú
_version_1M  s     

z$extract_physdevs.<locals>._version_1c             S   s˜   g }xŽ| j di ƒjƒ D ]z}|j dƒ}|s*q|j di ƒj dƒ}|sBq|j di ƒj dƒ}|j di ƒj dƒ}|srt|ƒ}|s~t|ƒ}|j||||gƒ qW |S )Nr´   zset-namer²   r°   ra   r¸   )r‰   r}   r^   rx   r©   )r¹   rº   r»   r   r¼   ra   r¸   r   r   r   Ú
_version_2_  s     
z$extract_physdevs.<locals>._version_2rµ   é   r³   z"Unknown network config version: %s)r‰   ÚRuntimeError)r¹   r½   r¾   rµ   r   r   r   Úextract_physdevsL  s    
rÁ   Fc             C   s*   t | dƒ}|dkr"|rtdƒ‚dS |dkS )	aœ  return True if the provided interface has its own address.

    Based on addr_assign_type in /sys.  Return true for any interface
    that does not have a 'stolen' address. Examples of such devices
    are bonds or vlans that inherit their mac from another device.
    Possible values are:
      0: permanent address    2: stolen from another device
      1: randomly generated   3: set using dev_set_mac_addressZaddr_assign_typeNz%s had no addr_assign_type.Tr   r¿   é   )r   r¿   rÂ   )r;   r9   )ÚifnameÚstrictZassign_typer   r   r   Úinterface_has_own_mac|  s    

rÅ   Tc             C   sÜ   i }x4t ƒ D ]*\}}}}d|||jƒ |t|ƒdœ||< qW | rØtjdƒ}tjdddddd	d
gdd�\}}tjddddgdd�\}	}tƒ }
x ||	fD ]}|
j|j|ƒƒ q’W x,|j	ƒ D ] }|d dkpÎ|d |
k|d< q´W |S )aà  Collect information necessary for rename_interfaces.

    returns a dictionary by mac address like:
       {name:
         {
          'downable': None or boolean indicating that the
                      device has only automatically assigned ip addrs.
          'device_id': Device id value (if it has one)
          'driver': Device driver (if it has one)
          'mac': mac address (in lower case)
          'name': name
          'up': boolean: is_up(name)
         }}
    N)Údownabler¸   ra   r¼   r   r<   z[0-9]+:\s+(\w+)[@:]Úipz-6ZaddrZshowZ	permanentZscopeÚglobalT)Úcapturez-4r<   Fr   rÆ   )
r§   r   r@   r   Úcompiler	   ÚsetÚupdateÚfindallr}   )Zcheck_downableÚcur_infor   r¼   ra   r¸   ZnmatchZipv6rZ   Zipv4Znics_with_addressesZ	bytes_outÚdr   r   r   Ú_get_current_rename_info�  s(    
 rÐ   c                sž  t | ƒstjdƒ d S |d kr$tƒ }i ‰ xF|jƒ D ]:\}}|jƒ }|jdƒr\|d jƒ |d< ||d< |ˆ |< q2W tjdˆ ƒ ‡ fdd„}dd„ }d	d
„ }	dd„ }
g }g }g }|ˆ ƒ}d}d"}dd„ ‰‡ ‡fdd„}�xæ| D �]Ü\}}}}|rô|jƒ }g }||||ƒ}|�s"|rÚ|jd||f ƒ qÚ|jdƒ}||k�r8qÚ|�sV|rÚ|jd||f ƒ qÚ|d �r¸d}|d �sˆ|rÚ|j||||f ƒ qÚd|d< |jd|||ffƒ |jd|||ffƒ ||k�r†|| }|d �rd}|d �sþ|rÚ|j||||f ƒ qÚn|jd|||ffƒ d }x*|d k�s,||k�r@|d7 }|| }�qW |jd||||ffƒ ||d< |ˆ ƒ}|d �r†|jd|||ffƒ |jd|||d |ffƒ ||d< |ˆ ƒ}||7 }qÚW ||	|
dœ}t |ƒt |ƒ dk�rt |ƒ�rötjd| ƒ ntjd| ƒ n~tjd| || ƒ xj|| D ]^\}}}}y|j|ƒ|Ž  W n< t	k
�rz } z|jd |||||f ƒ W Y d d }~X nX �q W t |ƒ�ršt
d!j|ƒƒ‚d S )#Nzno interfaces to renamer¼   r   zDetected interfaces %sc                s   t dd„ ˆ jƒ D ƒƒS )Nc             s   s   | ]}|d  |fV  qdS )r   Nr   )r   Údatar   r   r   ú	<genexpr>Ô  s    z<_rename_interfaces.<locals>.update_byname.<locals>.<genexpr>)rˆ   r}   )Zbymac)rÎ   r   r   Úupdate_bynameÓ  s    z)_rename_interfaces.<locals>.update_bynamec             S   s   t j ddd| d|gdd� d S )NrÇ   ÚlinkrË   r   T)rÉ   )r	   )ÚcurÚnewr   r   r   ÚrenameÖ  s    z"_rename_interfaces.<locals>.renamec             S   s   t j ddd| dgdd� d S )NrÇ   rÔ   rË   r>   T)rÉ   )r	   )r   r   r   r   r>   Ù  s    z _rename_interfaces.<locals>.downc             S   s   t j ddd| dgdd� d S )NrÇ   rÔ   rË   r<   T)rÉ   )r	   )r   r   r   r   r<   Ü  s    z_rename_interfaces.<locals>.upz
cirename%dr¿   c             S   sd   |r0|r0|r0| d |ko.| d |ko.| d |kS |rP|rP| d |koN| d |kS |r`| d |kS dS )zmatch if set and in datar¼   ra   r¸   Fr   )rÑ   r¼   ra   r¸   r   r   r   Úentry_matchæ  s    z'_rename_interfaces.<locals>.entry_matchc                sT   ‡ ‡‡‡fdd„ˆj ƒ D ƒ}t|ƒrPt|ƒdkrHd|ˆˆˆ f }t|ƒ‚|d S d S )Nc                s   g | ]}ˆ|ˆˆˆ ƒr|‘qS r   r   )r   rÑ   )r¸   ra   rØ   r¼   r   r   r   ÷  s   z:_rename_interfaces.<locals>.find_entry.<locals>.<listcomp>r¿   zjFailed to match a single device. Matched devices "%s" with search values "(mac:%s driver:%s device_id:%s)"r   )r}   ri   r9   )r¼   ra   r¸   r²   r­   )rÎ   rØ   )r¸   ra   r¼   r   Ú
find_entryõ  s    z&_rename_interfaces.<locals>.find_entryz<[nic not present] Cannot rename mac=%s to %s, not available.r<   z*[busy] Error renaming mac=%s from %s to %srÆ   Fr>   z2[busy-target] Error renaming mac=%s from %s to %s.r×   )r×   r>   r<   r   z(unable to do any work for renaming of %sz$no work necessary for renaming of %sz$achieving renaming of %s with ops %sz.[unknown] Error performing %s%s for %s, %s: %sÚ
éÿÿÿÿ)ri   r,   r-   rÐ   ÚitemsÚcopyr‰   r   r©   rc   rÀ   rI   )ÚrenamesZstrict_presentZstrict_busyZcurrent_infor   rÑ   rÕ   rÓ   r×   r>   r<   ZopsÚerrorsZupsZ
cur_bynameZtmpname_fmtZtmpirÙ   r¼   Únew_namera   r¸   Zcur_opsZcur_namer­   ÚtargetZtmp_nameZopmapÚopr·   r3   r   )rÎ   rØ   r   Ú_rename_interfaces¾  s¶    










*
rã   c             C   s$   d}t jjt| dƒƒrd}t| |ƒS )z6Returns the string value of an interface's MAC Addressr±   Zbonding_slavezbonding_slave/perm_hwaddr)rB   r"   Úisdirr#   r8   )rÃ   r"   r   r   r   Úget_interface_mac]  s    rå   c             C   s>   t | dƒdkr:t| ƒ}|r6|r6|dd… |dd…  }|S dS )z½Returns the string value of an Infiniband interface's hardware
    address. If ethernet_format is True, an Ethernet MAC-style 6 byte
    representation of the address will be returned.
    rM   rN   é$   é   é3   Niòÿÿÿ)r8   rå   )rÃ   Zethernet_formatr¼   r   r   r   Úget_ib_interface_hwaddrg  s
    ré   c               C   s<   t jƒ st jƒ rtƒ S t jƒ r$tƒ S t jƒ r2tƒ S tƒ S d S )N)	r
   ry   rz   Ú get_interfaces_by_mac_on_freebsdr�   Úget_interfaces_by_mac_on_netbsdrŽ   Ú get_interfaces_by_mac_on_openbsdÚget_interfaces_by_mac_on_linuxr   r   r   r   r|   u  s    r|   )r¼   rQ   c             C   s0   x*t ƒ jƒ D ]\}}| jƒ |jƒ kr|S qW d S )N)r|   rÜ   r   )r¼   Zinterface_macZinterface_namer   r   r   Úfind_interface_name_from_mac€  s    rî   c              C   s>   t j dddgƒ\} }dd„ }dd„ }dd	„ ||| ƒƒD ƒ}|S )
Nr™   z-arš   c             s   sD   d}x4| j dƒD ]&}|jdƒr(||7 }q|r2|V  |}qW |V  d S )Nr   rÚ   ú	)r   r¨   )rY   Z
curr_blockÚliner   r   r   Úflatten‹  s    

z1get_interfaces_by_mac_on_freebsd.<locals>.flattenc             s   s8   x2| D ]*}t jd|ƒ}|r|jdƒ|jdƒfV  qW d S )Nz2^(?P<ifname>\S*): .*ether\s(?P<mac>[\da-f:]{17}).*r¼   rÃ   )r   ÚsearchÚgroup)Z	flat_listÚblockÚmr   r   r   Úfind_mac—  s
    
z2get_interfaces_by_mac_on_freebsd.<locals>.find_macc             S   s   i | ]\}}||“qS r   r   )r   r¼   rÃ   r   r   r   ú
<dictcomp>Ÿ  s    z4get_interfaces_by_mac_on_freebsd.<locals>.<dictcomp>)r	   )rY   r®   rñ   rö   Úresultsr   r   r   rê   ‡  s
    rê   c              C   sf   i } d}t j ddgƒ\}}tjdd|ƒjƒ }x4|D ],}tj||ƒ}|r2|jƒ }|d | |d < q2W | S )NzE(?P<ifname>\w+).*address:\s(?P<mac>([\da-f]{2}[:-]){5}([\da-f]{2})).*r™   z-az\n\s+ú rÃ   r¼   )r	   r   ÚsubrX   r²   Ú	groupdict)rS   Úre_field_matchrY   r®   Úif_linesrð   rõ   Úfieldsr   r   r   rë   £  s    
rë   c              C   sf   i } d}t j ddgƒ\}}tjdd|ƒjƒ }x4|D ],}tj||ƒ}|r2|jƒ }|d | |d < q2W | S )NzC(?P<ifname>\w+).*lladdr\s(?P<mac>([\da-f]{2}[:-]){5}([\da-f]{2})).*r™   z-az\n\s+rù   rÃ   r¼   )r	   r   rú   rX   r²   rû   )rS   rü   rY   r®   rý   rð   rõ   rþ   r   r   r   rì   ³  s    
rì   c              C   sœ   i } x’t ƒ D ]ˆ\}}}}|| krX|dkr>tjd|| | |ƒ qd|| | |f }t|ƒ‚|| |< t|dƒ}|r|| kr€|| |< qtjd|| | |ƒ qW | S )	zmBuild a dictionary of tuples {mac: name}.

    Bridges and any devices that have a 'stolen' mac are excluded.Ú	fsl_enetcÚ
mscc_felixÚqmi_wwanz>Ignoring duplicate macs from '%s' and '%s' due to driver '%s'.z6duplicate mac found! both '%s' and '%s' have mac '%s'.Tz^Ethernet and InfiniBand interfaces have the same address both '%s' and '%s' have address '%s'.)rÿ   r   r  )r§   r,   r-   rÀ   ré   Úwarning)rS   r   r¼   ra   Z_devidr­   Úib_macr   r   r   rí   Ã  s4    


rí   )Úfilter_hyperv_vf_with_syntheticrž   rŸ   r    r¡   r¢   r£   rQ   c             C   s0  |r
t jndd„ }g }tƒ }	djdƒ}
xô|	D ]ì}|r@t|ƒ r@q,t|ƒrT|d|ƒ q,|rbt|ƒrbq,t|ƒrv|d|ƒ q,|rœt|ƒdk	rœt	|ƒ rœt
|ƒ rœq,t|ƒr°|d	|ƒ q,t|ƒ}|sÈ|d
|ƒ q,|rê|dkrê||
dt|ƒ… krêq,|oôt|ƒ� rúq,t|ƒ}|j|||t|ƒfƒ q,W | �r,t||ƒ |S )z‚Return list of interface tuples (name, mac, driver, device_id)

    Bridges and any devices that have a 'stolen' mac are excluded.c              W   s   d S )Nr   )Úargsr   r   r   Ú<lambda>  s    z get_interfaces.<locals>.<lambda>ú:Ú00é   zIgnoring bridge interface: %szIgnoring bond interface: %sNzIgnoring failover interface: %sz"Ignoring interface without mac: %srœ   )r  )r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  )r,   r-   r€   rI   rÅ   rD   ru   rF   rH   rK   rL   rb   rå   ri   r]   r^   r©   rx   Ú)filter_hyperv_vf_with_synthetic_interface)r  rž   rŸ   r    r¡   r¢   r£   Úfiltered_loggerrS   r   Zzero_macr   r¼   ra   r   r   r   r§   
  sJ    







 
r§   .)r  r¯   rQ   c                s\   dd„ |D ƒ‰ ‡ fdd„|D ƒ}x6|D ].}|\}}}}| d||ˆ | |ƒ |j |ƒ q&W dS )a�  Filter Hyper-V SR-IOV/VFs when used with synthetic hv_netvsc.

    Hyper-V's netvsc driver may register an SR-IOV/VF interface with a mac
    that matches the synthetic (hv_netvsc) interface.  This VF will be
    enslaved to the synthetic interface, but cloud-init may be racing this
    process.  The [perhaps-yet-to-be-enslaved] VF should never be directly
    configured, so we filter interfaces that duplicate any hv_netvsc mac
    address, as this the most reliable indicator that it is meant to be
    subordinate to the synthetic interface.

    VF drivers will be mlx4_core, mlx5_core, or mana.  However, given that
    this list of drivers has changed over time and mana's dependency on
    hv_netvsc is expected to be removed in the future, we no longer rely
    on these names. Note that this will not affect mlx4/5 instances outside
    of Hyper-V, as it only affects environments where hv_netvsc is present.
    c             S   s&   i | ]}|d  dkr|d |d “qS )r³   Ú	hv_netvscr   r¿   r   )r   Úir   r   r   r÷   Z  s   z=filter_hyperv_vf_with_synthetic_interface.<locals>.<dictcomp>c                s(   g | ] }|d  ˆ kr|d dkr|‘qS )r¿   r³   r  r   )r   r  )Úhv_netvsc_mac_to_namer   r   r   ^  s   z=filter_hyperv_vf_with_synthetic_interface.<locals>.<listcomp>zdIgnoring %r VF interface with driver %r due to synthetic hv_netvsc interface %r with mac address %r.N)r«   )r  r¯   Zinterfaces_to_remover   r   r¼   ra   r®   r   )r  r   r
  F  s    

r
  c              C   sT   i } xJt ƒ D ]@\}}}}t|dƒ}|r|| krDtd|| | |f ƒ‚|| |< qW | S )zTBuild a dictionary mapping Infiniband interface names to their hardware
    address.Fz5duplicate mac found! both '%s' and '%s' have mac '%s')r§   ré   rÀ   )rS   r   r®   r  r   r   r   Úget_ib_hwaddrs_by_interfacep  s    
r  )Úurl_datarQ   c             C   s¼   d| krt jd| ƒ dS | d }y6t|ƒ}t|jdk|jdkgƒsTt jd|jƒ dS W n, tk
r‚ } zt jd|ƒ dS d}~X nX d	| kr”d
| d	< ytf | Ž W n tk
r¶   dS X dS )aD  Return true when the instance has access to the provided URL.

    Logs a warning if url is not the expected format.

    url_data is a dictionary of kwargs to send to readurl. E.g.:

    has_url_connectivity({
        "url": "http://example.invalid",
        "headers": {"some": "header"},
        "timeout": 10
    })
    Úurlz4Ignoring connectivity check. No 'url' to check in %sFZhttpZhttpsz2Ignoring connectivity check. Invalid URL scheme %sz+Ignoring connectivity check. Invalid URL %sNZtimeouté   T)r,   r  r   ÚanyÚschemer9   r   r   )r  r  ÚresultÚerrr   r   r   Úhas_url_connectivity€  s,    r  )Úconvert_to_addressr±   c             K   s&   y| |f|ŽS  t k
r    dS X dS )a  Use a function to return an address. If conversion throws a ValueError
    exception return False.

    :param check_cb:
        Test function, must return a truthy value
    :param address:
        The string to test.

    :return:
        Address or False

    FN)r9   )r  r±   Úkwargsr   r   r   Úmaybe_get_address§  s    r  )r±   rQ   c             C   s   t ttj| ƒƒS )z¹Returns a bool indicating if ``s`` is an IP address.

    :param address:
        The string to test.

    :return:
        A bool indicating if the string is an IP address or not.
    )rR   r  Ú	ipaddressÚ
ip_address)r±   r   r   r   Úis_ip_addressº  s    	r  c             C   s   t ttj| ƒƒS )z½Returns a bool indicating if ``s`` is an IPv4 address.

    :param address:
        The string to test.

    :return:
        A bool indicating if the string is an IPv4 address or not.
    )rR   r  r  ZIPv4Address)r±   r   r   r   Úis_ipv4_addressÆ  s    	r  c             C   s   t ttj| ƒƒS )z½Returns a bool indicating if ``s`` is an IPv6 address.

    :param address:
        The string to test.

    :return:
        A bool indicating if the string is an IPv4 address or not.
    )rR   r  r  ZIPv6Address)r±   r   r   r   Úis_ipv6_addressÒ  s    	r  c             C   s   t ttj| dd�ƒS )zÅReturns a bool indicating if ``s`` is an IPv4 or IPv6 network.

    :param address:
        The string to test.

    :return:
        A bool indicating if the string is an IPv4 address or not.
    F)rÄ   )rR   r  r  Ú
ip_network)r±   r   r   r   Úis_ip_networkÞ  s    	r!  c             C   s   t ttj| dd�ƒS )z½Returns a bool indicating if ``s`` is an IPv4 network.

    :param address:
        The string to test.

    :return:
        A bool indicating if the string is an IPv4 address or not.
    F)rÄ   )rR   r  r  ÚIPv4Network)r±   r   r   r   Úis_ipv4_networkê  s    	r#  c             C   s   t ttj| dd�ƒS )z½Returns a bool indicating if ``s`` is an IPv6 network.

    :param address:
        The string to test.

    :return:
        A bool indicating if the string is an IPv4 address or not.
    F)rÄ   )rR   r  r  ZIPv6Network)r±   r   r   r   Úis_ipv6_networkø  s    	r$  c             C   s@   | d j dƒs| d tkrdS | d dkr<t| jdƒƒr<dS dS )z:Common helper for checking network_state subnets for ipv6.rM   Ú6TZstaticr±   F)ÚendswithÚIPV6_DYNAMIC_TYPESr  r‰   )Zsubnetr   r   r   Úsubnet_is_ipv6  s
    r(  c             C   s   t tjd| › �ƒjƒS )z¤Convert a network prefix to an ipv4 netmask.

    This is the inverse of ipv4_mask_to_net_prefix.
        24 -> "255.255.255.0"
    Also supports input as a string.z0.0.0.0/)rt   r  r"  Únetmask)Úprefixr   r   r   Únet_prefix_to_ipv4_mask  s    r+  c             C   s   t jd| › �ƒjS )a  Convert an ipv4 netmask into a network prefix length.

    If the input is already an integer or a string representation of
    an integer, then int(mask) will be returned.
       "255.255.255.0" => 24
       str(24)         => 24
       "24"            => 24
    z0.0.0.0/)r  r   Ú	prefixlen)Úmaskr   r   r   Úipv4_mask_to_net_prefix  s    	r.  c             C   sš   yt jd| › �ƒj}|S  tk
r*   Y nX t j| ƒ}t|ƒ}|dkrJ|S tt j| |d @ jƒ ƒ}||? }t j| }d|> d }||kr–td|  ƒ‚|S )zÿConvert an ipv6 netmask (very uncommon) or prefix (64) to prefix.

    If the input is already an integer or a string representation of
    an integer, then int(mask) will be returned.
       "ffff:ffff:ffff::"  => 48
       "48"                => 48
    z::/r   r¿   zInvalid network mask '%s')	r  r   r,  r9   r  r   ÚminZ
IPV6LENGTHÚ
bit_length)r-  r,  r)  Zmask_intZtrailing_zeroesZleading_onesZall_onesr   r   r   Úipv6_mask_to_net_prefix)  s"    

r1  )r-  rÇ   rQ   c             C   s   t tj|› d| › �dd�jƒS )zCGet string representation of broadcast address from an ip/mask pairr    F)rÄ   )rt   r  r"  Zbroadcast_address)r-  rÇ   r   r   r   Úmask_and_ipv4_to_bcast_addrL  s    r2  c               @   s   e Zd ZdS )ÚRendererNotFoundErrorN)r‚   rƒ   r„   r   r   r   r   r3  S  s   r3  )r   )NNNN)N)N)N)N)N)N)F)T)TTN)TTTTTTF).N)hr$   Ú	functoolsr  ZloggingrB   r   Ztypingr   r   r   r   r   r   Zurllib.parser   Z	cloudinitr	   r
   Zcloudinit.url_helperr   r   Z	getLoggerr‚   r,   r   rª   r'  rU   rÊ   r   r   r#   r4   r8   r;   r@   rD   rF   rH   rK   rL   rO   Ú	lru_cacherR   rT   r{   r\   rt   r]   rb   re   rj   rl   r_   r`   rr   ru   r^   rx   r€   rc   r�   r‹   r‘   r•   r�   r“   rŒ   r’   r�   r”   r¶   rÁ   rÅ   rÐ   rã   rå   ré   rˆ   r|   rî   rê   rë   rì   rí   r§   r
  r  r  r  r  r  r  r!  r#  r$  r(  r+  r   r.  r1  r2  rÀ   r3  r   r   r   r   Ú<module>   sÚ    

   



	





!
	
I
0

/
 
H      5''	#