← Back to team overview

cloud-init-dev team mailing list archive

[Merge] ~smoser/cloud-init:feature/curtin-centos6 into cloud-init:master

 

Scott Moser has proposed merging ~smoser/cloud-init:feature/curtin-centos6 into cloud-init:master.

Requested reviews:
  cloud-init commiters (cloud-init-dev)
Related bugs:
  Bug #1687725 in cloud-init: "sysconfig render does not support type manual subnets"
  https://bugs.launchpad.net/cloud-init/+bug/1687725
  Bug #1694801 in cloud-init: "sysconfig needs fix for ipv6 gateway routes"
  https://bugs.launchpad.net/cloud-init/+bug/1694801

For more details, see:
https://code.launchpad.net/~smoser/cloud-init/+git/cloud-init/+merge/327832
-- 
Your team cloud-init commiters is requested to review the proposed merge of ~smoser/cloud-init:feature/curtin-centos6 into cloud-init:master.
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index eb3c91d..b0f2ccf 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -152,9 +152,10 @@ class Route(ConfigMap):
                 elif proto == "ipv6" and self.is_ipv6_route(address_value):
                     netmask_value = str(self._conf['NETMASK' + index])
                     gateway_value = str(self._conf['GATEWAY' + index])
-                    buf.write("%s/%s via %s\n" % (address_value,
-                                                  netmask_value,
-                                                  gateway_value))
+                    buf.write("%s/%s via %s dev %s\n" % (address_value,
+                                                         netmask_value,
+                                                         gateway_value,
+                                                         self._route_name))
 
         return buf.getvalue()
 
@@ -297,6 +298,9 @@ class Renderer(renderer.Renderer):
                                  " for interface '%s'" % (subnet_type,
                                                           iface_cfg.name))
 
+            if subnet.get('control') == 'manual':
+                iface_cfg['ONBOOT'] = False
+
         # set IPv4 and IPv6 static addresses
         ipv4_index = -1
         ipv6_index = -1
@@ -334,7 +338,7 @@ class Renderer(renderer.Renderer):
     def _render_subnet_routes(cls, iface_cfg, route_cfg, subnets):
         for i, subnet in enumerate(subnets, start=len(iface_cfg.children)):
             for route in subnet.get('routes', []):
-                is_ipv6 = subnet.get('ipv6')
+                is_ipv6 = subnet.get('ipv6') or is_ipv6_addr(route['gateway'])
 
                 if _is_default_route(route):
                     if (
@@ -356,7 +360,7 @@ class Renderer(renderer.Renderer):
                     # also provided the default route?
                     iface_cfg['DEFROUTE'] = True
                     if 'gateway' in route:
-                        if is_ipv6:
+                        if is_ipv6 or is_ipv6_addr(route['gateway']):
                             iface_cfg['IPV6_DEFAULTGW'] = route['gateway']
                             route_cfg.has_set_default_ipv6 = True
                         else:
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index f786eea..e625934 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -949,11 +949,12 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
                 BOOTPROTO=none
                 DEFROUTE=yes
                 DEVICE=en0.99
-                GATEWAY=2001:1::1
+                GATEWAY=192.168.1.1
                 IPADDR=192.168.2.2
                 IPADDR1=192.168.1.2
                 IPV6ADDR=2001:1::bbbb/96
                 IPV6INIT=yes
+                IPV6_DEFAULTGW=2001:1::1
                 NETMASK=255.255.255.0
                 NETMASK1=255.255.255.0
                 NM_CONTROLLED=no
@@ -1030,6 +1031,39 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
                 """),
         },
     },
+    'manual': {
+        'yaml': textwrap.dedent("""
+            version: 1
+            config:
+              - type: physical
+                name: eth0
+                mac_address: "52:54:00:12:34:00"
+                subnets:
+                  - type: static
+                    address: 192.168.1.2/24
+                    control: manual"""),
+        'expected_eni': textwrap.dedent("""\
+            auto lo
+            iface lo inet loopback
+
+            # control-manual eth0
+            iface eth0 inet static
+                address 192.168.1.2/24
+            """),
+        'expected_sysconfig': {
+            'ifcfg-eth0': textwrap.dedent("""\
+                BOOTPROTO=none
+                DEVICE=eth0
+                HWADDR=52:54:00:12:34:00
+                IPADDR=192.168.1.2
+                NETMASK=255.255.255.0
+                NM_CONTROLLED=no
+                ONBOOT=no
+                TYPE=Ethernet
+                USERCTL=no
+                """),
+        },
+    },
 }
 
 
@@ -1459,6 +1493,12 @@ USERCTL=no
         self._compare_files_to_expected(entry['expected_sysconfig'], found)
         self._assert_headers(found)
 
+    def test_manual_config(self):
+        entry = NETWORK_CONFIGS['manual']
+        found = self._render_and_read(network_config=yaml.load(entry['yaml']))
+        self._compare_files_to_expected(entry['expected_sysconfig'], found)
+        self._assert_headers(found)
+
 
 class TestEniNetRendering(CiTestCase):
 
@@ -1910,6 +1950,13 @@ class TestEniRoundTrip(CiTestCase):
             entry['expected_eni'].splitlines(),
             files['/etc/network/interfaces'].splitlines())
 
+    def testsimple_render_manual(self):
+        entry = NETWORK_CONFIGS['manual']
+        files = self._render_and_read(network_config=yaml.load(entry['yaml']))
+        self.assertEqual(
+            entry['expected_eni'].splitlines(),
+            files['/etc/network/interfaces'].splitlines())
+
     def test_routes_rendered(self):
         # as reported in bug 1649652
         conf = [

Follow ups