← Back to team overview

cloud-init-dev team mailing list archive

[Merge] ~smoser/cloud-init:bug/1635716-initrd-cfg-net6 into cloud-init:master

 

Scott Moser has proposed merging ~smoser/cloud-init:bug/1635716-initrd-cfg-net6 into cloud-init:master.

Commit message:
net/cmdline: add support for ipv6 config in net6-device.conf

The implementation of ipv6 support in initramfs changed from what
was previously implemented.  Now, instead of all values being
present in net-<device>.conf, there may also exist a net6-<device.conf>.

The change here is to allow the definition of a device's config
to be split across multiple files.  Subnet entries will be appended
to existing configuration.

One additional change here is the tightening up of what files that
are read.  Instead of /run/net*.conf, we now only read
net-*.conf and net6-*.conf.

LP: #1635716

Requested reviews:
  cloud init development team (cloud-init-dev)
Related bugs:
  Bug #1635716 in cloud-init (Ubuntu): "Can't bring up a machine on a dual network (ipv4 and ipv6)"
  https://bugs.launchpad.net/ubuntu/+source/cloud-init/+bug/1635716

For more details, see:
https://code.launchpad.net/~smoser/cloud-init/+git/cloud-init/+merge/309144
-- 
Your team cloud init development team is requested to review the proposed merge of ~smoser/cloud-init:bug/1635716-initrd-cfg-net6 into cloud-init:master.
diff --git a/cloudinit/net/cmdline.py b/cloudinit/net/cmdline.py
index 933317d..c4fdfcf 100644
--- a/cloudinit/net/cmdline.py
+++ b/cloudinit/net/cmdline.py
@@ -57,7 +57,7 @@ def _load_shell_content(content, add_empty=False, empty_val=None):
 
 
 def _klibc_to_config_entry(content, mac_addrs=None):
-    """Convert a klibc writtent shell content file to a 'config' entry
+    """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.
@@ -139,7 +139,7 @@ def _klibc_to_config_entry(content, mac_addrs=None):
 
 def config_from_klibc_net_cfg(files=None, mac_addrs=None):
     if files is None:
-        files = glob.glob('/run/net*.conf')
+        files = glob.glob('/run/net-*.conf') + glob.glob('/run/net6-*.conf')
 
     entries = []
     names = {}
@@ -147,12 +147,17 @@ def config_from_klibc_net_cfg(files=None, mac_addrs=None):
         name, entry = _klibc_to_config_entry(util.load_file(cfg_file),
                                              mac_addrs=mac_addrs)
         if name in names:
-            raise ValueError(
-                "device '%s' defined multiple times: %s and %s" % (
-                    name, names[name], cfg_file))
+            prev = names[name]['entry']
+            if prev.get('mac_address') != entry.get('mac_address'):
+                raise ValueError("device '%s' was defined multiple times (%s)"
+                    " but had differing mac addresses: %s -> %s.",
+                    (' '.join(names[name]['files']),
+                     prev.get('mac_address'), entry.get('mac_address')))
+            prev['subnets'].extend(entry['subnets'])
+        else:
+            names[name] = {'files': [cfg_file], 'entry': entry}
+            entries.append(entry)
 
-        names[name] = cfg_file
-        entries.append(entry)
     return {'config': entries, 'version': 1}
 
 
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index 78c080c..ef147c1 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -662,6 +662,38 @@ class TestCmdlineConfigParsing(TestCase):
                                                       mac_addrs=macs)
             self.assertEqual(found, expected)
 
+    def test_config_from_cmdline_net_cfg_4_and_6(self):
+        files = []
+        pairs = (('net6-eno1.cfg', DHCP_CONTENT_1.replace('eth0', 'eno1')),
+                 ('net-eno1.cfg', DHCP6_CONTENT_1))
+
+        macs = {'eno1': 'b8:ae:ed:75:ff:2a'}
+
+        expected = {
+            'config': [
+                {'type': 'physical', 'name': 'eno1',
+                 'mac_address': 'b8:ae:ed:75:ff:2a',
+                 'subnets': [
+                    {'netmask': '255.255.255.0',
+                     'broadcast': '192.168.122.255',
+                     'dns_nameservers': ['192.168.122.1'], 'type': 'dhcp',
+                     'control': 'manual', 'dns_search': ['foo.com'],
+                     'gateway': '192.168.122.1'},
+                    {'netmask': '64',
+                     'dns_nameservers': ['2001:67c:1562:8010::2:1'],
+                     'control': 'manual', 'type': 'dhcp6'}]}],
+            'version': 1}
+
+        with util.tempdir() as tmpd:
+            for fname, content in pairs:
+                fp = os.path.join(tmpd, fname)
+                files.append(fp)
+                util.write_file(fp, content)
+
+            found = cmdline.config_from_klibc_net_cfg(files=files,
+                                                      mac_addrs=macs)
+            self.assertEqual(found, expected)
+
     def test_cmdline_with_b64(self):
         data = base64.b64encode(json.dumps(self.simple_cfg).encode())
         encoded_text = data.decode()

References