
"T`#                 @   s/  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 d d l	 m
 Z
 d d l	 m Z d Z d Z Gd d	   d	 d
 e  j Z Gd d   d e  Z e g Z d d d  Z d d   Z d d d d  Z d d   Z d d   Z d d   Z d d d  Z d S)    N)util   )get_devicelist)read_sys_net_safez#/run/initramfs/open-iscsi.interfacedisabledc               @   sR   e  Z d  Z d Z e j e d d d     Z e j e d d d     Z	 d S)InitramfsNetworkConfigSourcezBABC for net config sources that read config written by initramfses)returnc             C   s   d S)zAIs this initramfs config source applicable to the current system?N )selfr	   r	   7/usr/lib/python3/dist-packages/cloudinit/net/cmdline.pyis_applicable   s    z*InitramfsNetworkConfigSource.is_applicablec             C   s   d S)z;Render a v1 network config from the initramfs configurationNr	   )r
   r	   r	   r   render_config!   s    z*InitramfsNetworkConfigSource.render_configN)
__name__
__module____qualname____doc__abcabstractmethodboolr   dictr   r	   r	   r	   r   r      s
   r   	metaclassc               @   sU   e  Z d  Z d Z d d d d d  Z e d d d    Z e d d d	    Z d S)
KlibcNetworkConfigSourcezInitramfsNetworkConfigSource for klibc initramfs (i.e. Debian/Ubuntu)

    Has three parameters, but they are intended to make testing simpler, _not_
    for use in production code.  (This is indicated by the prepended
    underscores.)
    Nc             C   s   | |  _  | |  _ | |  _ |  j  d  k r6 t   |  _  |  j d  k rT t j   |  _ |  j d  k r i  |  _ x3 t   D]( } t | d  } | rv | |  j | <qv Wd  S)Naddress)_files
_mac_addrs_cmdline_get_klibc_net_cfg_filesr   get_cmdliner   r   )r
   r   r   r   kZmac_addrr	   r	   r   __init__.   s    				z!KlibcNetworkConfigSource.__init__)r   c             C   sE   |  j  rA d |  j k s' d |  j k r+ d St j j t  rA d Sd S)aD  
        Return whether this system has klibc initramfs network config or not

        Will return True if:
            (a) klibc files exist in /run, AND
            (b) either:
                (i) ip= or ip6= are on the kernel cmdline, OR
                (ii) an open-iscsi interface file is present in the system
        zip=zip6=TF)r   r   ospathexists_OPEN_ISCSI_INTERFACE_FILE)r
   r	   r	   r   r   @   s    
	z&KlibcNetworkConfigSource.is_applicablec             C   s   t  d |  j d |  j  S)Nfiles	mac_addrs)config_from_klibc_net_cfgr   r   )r
   r	   r	   r   r   R   s    z&KlibcNetworkConfigSource.render_config)	r   r   r   r   r   r   r   r   r   r	   r	   r	   r   r   &   s   r   c             C   s  | d k r i  } t  j |   } y$ d | k r: | d n | d } Wn4 t k
 r{ } z t d  |  WYd d } ~ Xn X| j d | j d   } | s | j d  r d } n d	 } | d" k r t d |   d d d | d g  i } | | k r	| | | d <xtd# D]l} | d | k r)q| j | d |  } | d	 k rQd } d | d d i }	 | d k r| | d |	 d <x6 d$ D]. }
 | |
 | k r| | |
 |	 |
 j   <qWg  } xQ d% D]I } | j | |  } | rt | j d   r| j | | |  qW| rk| |	 d <| j d  } | rkd  | k r[| j	 d   |	 d! <n | j	   |	 d! <| d j |	  qW| | f S)&a  Convert a klibc written shell content file to a 'config' entry
    When ip= is seen on the kernel command line in debian initramfs
    and networking is brought up, ipconfig will populate
    /run/net-<name>.cfg.

    The files are shell style syntax, and examples are in the tests
    provided here.  There is no good documentation on this unfortunately.

    DEVICE=<name> is expected/required and PROTO should indicate if
    this is 'none' (static) or 'dhcp' or 'dhcp6' (LP: #1621507).
    note that IPV6PROTO is also written by newer code to address the
    possibility of both ipv4 and ipv6 getting addresses.

    Full syntax is documented at:
    https://git.kernel.org/pub/scm/libs/klibc/klibc.git/plain/usr/kinit/ipconfig/README.ipconfig
    NZDEVICEZDEVICE6z&no 'DEVICE' or 'DEVICE6' entry in dataZPROTOZ	IPV6PROTOfilenamedhcpnonedhcp6zUnexpected value for PROTO: %stypeZphysicalnamesubnetsmac_addressIPV4IPV6ZADDRZstaticZcontrolZmanualr   NETMASK	BROADCASTGATEWAYDNS0DNS1z:.0Zdns_nameserversZDOMAINSEARCH,Z
dns_search)r)   r(   r*   )r/   r0   )r1   r2   r3   )r4   r5   )
r   Zload_shell_contentKeyError
ValueErrorgetlowerlenstripappendsplit)Zcontentr%   datar,   eprotoZifaceZpreZ	cur_protoZsubnetkeyZdnsZnskeynssearchr	   r	   r   _klibc_to_config_entry[   sZ    $"	
rE   c               C   s   t  j  d  t  j  d  S)Nz/run/net-*.confz/run/net6-*.conf)globr	   r	   r	   r   r      s    r   c             C   s;  |  d  k r t    }  g  } i  } x|  D] } t t j |  d | \ } } | | k r| | d } | j d  | j d  k r t d j d | d d j | | d  d | j d  d	 | j d     | d
 j | d
  | | d j	 |  q( d | g d | i | | <| j	 |  q( Wd | d d i S)Nr%   entryr.   zedevice '{name}' was defined multiple times ({files}) but had differing mac addresses: {old} -> {new}.r,   r$    oldnewr-   configversionr   )
r   rE   r   Z	load_filer9   r8   formatjoinextendr=   )r$   r%   entriesnamesZcfg_filer,   rG   prevr	   r	   r   r&      s(    		r&   c              C   s4   x- t  D]% }  |    } | j   s% q | j   SWd S)a  
    Return v1 network config for initramfs-configured networking (or None)

    This will consider each _INITRAMFS_CONFIG_SOURCES entry in turn, and return
    v1 network configuration for the first one that is applicable.  If none are
    applicable, return None.
    N)_INITRAMFS_CONFIG_SOURCESr   r   )Zsrc_clsZ
cfg_sourcer	   r	   r   read_initramfs_config   s    	rT   c             C   sz   t  j |   d } d  } zC y& t j d d d |  } | j   SWn t k
 rY |  SYn XWd  | rn | j   XWd  QRXd  S)NmoderbZfileobj)ioBytesIOgzipZGzipFilereadIOErrorclose)blobZiobufZgzfpr	   r	   r   _decomp_gzip   s    r^   c             C   sL   y t  j |   } Wn, t t f k
 rA t j d |   d SYn Xt |  S)zDecode a string base64 encoding, if gzipped, uncompress as well

    :return: decompressed unencoded string of the data or empty string on
       unencoded data.
    z`Expected base64 encoded kernel commandline parameter network-config. Ignoring network-config=%s. )base64Z	b64decode	TypeErrorr8   loggingerrorr^   )r?   r]   r	   r	   r   _b64dgz   s    	rd   c             C   s   |  d  k r t  j   }  d |  k r d  } x9 |  j   D]+ } | j d  r7 | j d d  d } q7 W| r | t k r d d i St  j t |   Sd  S)Nznetwork-config==r   rK   r   )r   r   r>   
startswith&KERNEL_CMDLINE_NETWORK_CONFIG_DISABLEDZ	load_yamlrd   )ZcmdlineZdata64tokr	   r	   r   read_kernel_cmdline_config  s    
ri   )r   r`   rF   rY   rW   rb   r    Z	cloudinitr   r_   r   r   r#   rg   ABCMetar   r   rS   rE   r   r&   rT   r^   rd   ri   r	   r	   r	   r   <module>   s*   2	]