From 16a44056eaa5cc36fd9f6b08fe3a6bb4700fe1e7 Mon Sep 17 00:00:00 2001 From: Wesley Wiedenmeier Date: Thu, 17 Mar 2016 21:54:57 -0500 Subject: Check for and merge in configuration caused by the 'ip' parameter on the kernel's cmdline during network configuration parsing. - Search for .conf files in /run with names starting with 'net', as these are created during early boot if the ip parameter is present - If any are present and valid they are merged with network configuration from the current data source - If the devices affected by the 'ip' parameter are already present in network configuration, then a subnet entry will be added to the device's configuration unless an identical entry is already present - If any of the devices affected are not present then a mostly blank configuration will be generated for the device and the appropriate subnet specified --- cloudinit/net/__init__.py | 56 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'cloudinit') diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py index 3cf99604..e455040d 100644 --- a/cloudinit/net/__init__.py +++ b/cloudinit/net/__init__.py @@ -280,6 +280,62 @@ def parse_net_config(path): return ns +def load_key_value_pair_net_cfg(data_mapping): + """Process key value pairs from files written because of the ip parameter + on the kernel cmdline""" + subnets = [] + entry_ns = { + 'mtu': None, 'name': data_mapping['DEVICE'], 'type': 'physical', + 'mode': 'manual', 'inet': 'inet', 'gateway': None, 'address': None + } + + if data_mapping.get('PROTO') == 'dhcp': + if 'IPV4ADDR' in data_mapping: + subnets.append({'type': 'dhcp4'}) + if 'IPV6ADDR' in data_mapping: + subnets.append({'type': 'dhcp6'}) + entry_ns['subnets'] = subnets + + 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_key_value_pair_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 -- cgit v1.2.3