diff options
Diffstat (limited to 'cloudinit/net')
-rw-r--r-- | cloudinit/net/__init__.py | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py index ae7b1c04..0560fa45 100644 --- a/cloudinit/net/__init__.py +++ b/cloudinit/net/__init__.py @@ -283,6 +283,96 @@ def parse_net_config(path): return ns +def load_klibc_net_cfg(data_mapping): + """Process key value pairs from files written because of the ip parameter + on the kernel cmdline, note that mode: manual is used because the + interface should already have been brought up by the kernel and + cloud-initramfs-tools""" + entry_ns = { + 'mtu': None, 'name': data_mapping['DEVICE'], 'type': 'physical', + 'mode': 'manual', 'inet': 'inet', 'gateway': None, 'address': None, + 'subnets': [] + } + + # ipconfig on precise does not write PROTO + # (lp:cloud-initramfs-tools/dyn-netconf/scripts/init-bottom/ + # cloud-initramfs-dyn-netconf) + if not data_mapping.get('PROTO'): + if data_mapping.get('filename'): + data_mapping['PROTO'] = 'dhcp' + else: + data_mapping['PROTO'] = 'static' + + if data_mapping.get('PROTO') == 'dhcp': + if data_mapping.get('IPV4ADDR'): + entry_ns['subnets'].append({'type': 'dhcp4'}) + if data_mapping.get('IPV6ADDR'): + entry_ns['subnets'].append({'type': 'dhcp6'}) + elif data_mapping.get('PROTO') in ['static', 'none']: + # It appears that specifying ipv6 static addrs does not work, so only + # check for ipv4 addr + entry_ns['subnets'].append( + {'type': 'static', 'address': data_mapping.get('IPV4ADDR')}) + + if data_mapping.get('IPV4ADDR'): + entry_ns['address'] = data_mapping['IPV4ADDR'] + if data_mapping.get('IPV6ADDR'): + entry_ns['address'] = data_mapping['IPV6ADDR'] + if data_mapping.get('IPV4BROADCAST'): + entry_ns['broadcast'] = data_mapping['IPV4BROADCAST'] + if data_mapping.get('IPV6BROADCAST'): + entry_ns['broadcast'] = data_mapping['IPV6BROADCAST'] + if data_mapping.get('IPV4NETMASK'): + entry_ns['netmask'] = data_mapping['IPV4NETMASK'] + if data_mapping.get('IPV6NETMASK'): + entry_ns['netmask'] = data_mapping['IPV6NETMASK'] + if data_mapping.get('IPV4GATEWAY'): + entry_ns['gateway'] = data_mapping['IPV4GATEWAY'] + if data_mapping.get('IPV6GATEWAY'): + entry_ns['gateway'] = data_mapping['IPV6GATEWAY'] + if data_mapping.get('HOSTNAME'): + entry_ns['hostname'] = data_mapping['HOSTNAME'] + + return entry_ns + + +def merge_from_cmdline_config(ns): + """If ip parameter passed on kernel cmdline then some initial network + configuration may have been done in initramfs. Files from the result of + this may have been written into /run. If any are present they should be + merged into network state""" + + if 'interfaces' not in ns: + ns['interfaces'] = {} + + for cfg_file in glob.glob('/run/net*.conf'): + with open(cfg_file, 'r') as fp: + data = [l.replace("'", "") for l in fp.readlines()] + try: + parsed = dict([l.strip().split('=') for l in data]) + except: + # if split did not work then this is likely not a netcfg file + continue + + dev_name = parsed.get('DEVICE') + if not dev_name: + # Not a net cfg file + continue + + loaded_ns = load_klibc_net_cfg(parsed) + + if dev_name in ns['interfaces']: + if 'subnets' not in ns['interfaces'][dev_name]: + ns['interfaces'][dev_name]['subnets'] = [] + for newsubnet in loaded_ns['subnets']: + if newsubnet not in ns['interfaces'][dev_name]['subnets']: + ns['interfaces'][dev_name]['subnets'].append(newsubnet) + else: + ns['interfaces'][dev_name] = loaded_ns + + return ns + + def render_persistent_net(network_state): ''' Given state, emit udev rules to map mac to ifname |