
­­­­­­­­­­­­­­­­­­
<!DOCTYPE html>
<html>
3
\me-$                 @   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Zd dlm	Z	 d dl
mZmZ dZdZejeZG dd de jdZG d	d
 d
eZegZdddZdd Z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               @   s8   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   /usr/lib/python3.6/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               @   s6   e Zd ZdZ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   st   || _ || _|| _| j d kr$t | _ | jd kr8tj | _| jd krpi | _x&t D ]}t|d}|rP|| j|< qPW d 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   s>   | j r:x"tj| jD ]}|jdrdS qW tjjtr:dS d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
        ip=ip6=TF)r   r    )	r   shlexsplitr   
startswithospathexists_OPEN_ISCSI_INTERFACE_FILE)r	   itemr   r   r
   r   A   s    

z&KlibcNetworkConfigSource.is_applicablec             C   s   t | j| jdS )N)files	mac_addrs)config_from_klibc_net_cfgr   r   )r	   r   r   r
   r   T   s    z&KlibcNetworkConfigSource.render_config)NNN)	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 }W n, tk
r^ } ztd|W Y dd}~X nX |jd|jd}|s|jdrd}nd	}|d!krtd| d|g d}||kr|| |d< x,d"D ]"}|d |krq|j|d |}|d	k rd}|dd}	|dkr||d  |	d< x0d#D ](}
||
 |kr"|||
  |	|
j < q"W g }xDd$D ]<}|j|| }|rXt|jdrX|j|||   qXW |r||	d< |jd}|rd|kr|j	d|	d< n|j	 |	d< |d  j|	 qW ||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: %sZphysical)typenamesubnetsmac_addressIPV4IPV6ZADDRZstaticZmanual)r0   Zcontrolr   NETMASK	BROADCASTGATEWAYDNS0DNS1z:.0Zdns_nameserversZDOMAINSEARCH,Z
dns_searchr2   )r.   r-   r/   )r4   r5   )r6   r7   r8   )r9   r:   )
r   Zload_shell_contentKeyError
ValueErrorgetlowerlenstripappendr"   )Zcontentr*   datar1   eprotoZifaceZpreZ	cur_protoZsubnetkeyZdnsZnskeynssearchr   r   r
   _klibc_to_config_entry^   sZ    








rI   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rtdj|dj|| d |jd|jdd|d j|d  || d j	| q|g|d	||< |j	| qW |d
dS )N)r*   entryr3   zedevice '{name}' was defined multiple times ({files}) but had differing mac addresses: {old} -> {new}. r)   )r1   r)   oldnewr2   )r)   rK      )configversion)
r   rI   r   Z	load_filer>   r=   formatjoinextendrB   )r)   r*   ZentriesnamesZcfg_filer1   rK   prevr   r   r
   r+      s*    
r+   c              C   s(   x"t D ]} |  }|j sq|j S W d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    

rX   c             C   s^   t j| J}d }z0ytjd|d}|j S  tk
r<   | S X W d |rN|j  X W d Q R X d S )Nrb)modeZfileobj)ioBytesIOgzipZGzipFilereadIOErrorclose)blobZiobufZgzfpr   r   r
   _decomp_gzip   s    
rb   c             C   s<   yt j| }W n$ ttfk
r2   tjd|  dS X t|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	TypeErrorr=   LOGerrorrb   )rC   ra   r   r   r
   _b64dgz   s    rh   c             C   sn   | d krt j } d| krjd }x*| j D ]}|jdr&|jddd }q&W |rj|tkr\ddiS t jt|S d S )Nznetwork-config==rO   rP   r   )r   r   r"   r#   &KERNEL_CMDLINE_NETWORK_CONFIG_DISABLEDZ	load_yamlrh   )ZcmdlineZdata64tokr   r   r
   read_kernel_cmdline_config  s    
rl   )N)NN)N)r   rd   rJ   r]   r[   Zloggingr$   r!   Z	cloudinitr   Zcloudinit.netr   r   r'   rj   Z	getLoggerr   rf   ABCMetar   r   rW   rI   r   r+   rX   rb   rh   rl   r   r   r   r
   <module>   s,   
4
]
