summaryrefslogtreecommitdiff
path: root/cloudinit/net
diff options
context:
space:
mode:
Diffstat (limited to 'cloudinit/net')
-rw-r--r--cloudinit/net/__init__.py90
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