← Back to team overview

cloud-init-dev team mailing list archive

[Merge] ~mgerdts/cloud-init:lp1765801 into cloud-init:master

 

Mike Gerdts has proposed merging ~mgerdts/cloud-init:lp1765801 into cloud-init:master.

Commit message:
sources: apply_network_config should optionally happen on every boot

This change makes it possible to reconfigure networking on every boot,
as was the behavior prior to the fix for LP#1571004. Unlike the
original behavior, the default behavior is to reconfigure networking
PER_INSTANCE. If 'maintain_network' is set to True in the datasource's
metadata, networking is reconfigured PER_ALWAYS.

This change also updates DataSourceSmartOS to retrieve the value of
maintain_network from sdc:maintain_network.

LP: #1765801

Requested reviews:
  cloud-init commiters (cloud-init-dev)
Related bugs:
  Bug #1765801 in cloud-init: "network should be optionally reconfigured on every boot"
  https://bugs.launchpad.net/cloud-init/+bug/1765801

For more details, see:
https://code.launchpad.net/~mgerdts/cloud-init/+git/cloud-init/+merge/343712
-- 
Your team cloud-init commiters is requested to review the proposed merge of ~mgerdts/cloud-init:lp1765801 into cloud-init:master.
diff --git a/cloudinit/sources/DataSourceSmartOS.py b/cloudinit/sources/DataSourceSmartOS.py
index c8998b4..25a35da 100644
--- a/cloudinit/sources/DataSourceSmartOS.py
+++ b/cloudinit/sources/DataSourceSmartOS.py
@@ -51,6 +51,7 @@ SMARTOS_ATTRIB_MAP = {
     'operator-script': ('sdc:operator-script', False),
     'hostname': ('sdc:hostname', True),
     'dns_domain': ('sdc:dns_domain', True),
+    'maintain_network': ('sdc:maintain_network', True),
 }
 
 SMARTOS_ATTRIB_JSON = {
@@ -288,6 +289,9 @@ class DataSourceSmartOS(sources.DataSource):
                                            'per-boot'),
             }
 
+        md['maintain_network'] = md['maintain_network'] \
+            and md['maintain_network'] == 'true'
+
         self.metadata = util.mergemanydict([md, self.metadata])
         self.userdata_raw = ud
         self.vendordata_raw = md['vendor-data']
diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py
index df0b374..6cb6aab 100644
--- a/cloudinit/sources/__init__.py
+++ b/cloudinit/sources/__init__.py
@@ -1,6 +1,7 @@
 # Copyright (C) 2012 Canonical Ltd.
 # Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
 # Copyright (C) 2012 Yahoo! Inc.
+# Copyright (c) 2018, Joynet, Inc.
 #
 # Author: Scott Moser <scott.moser@xxxxxxxxxxxxx>
 # Author: Juerg Haefliger <juerg.haefliger@xxxxxx>
@@ -398,6 +399,15 @@ class DataSource(object):
         """
         return
 
+    def check_apply_network_config(self, is_new_instance):
+        """check_apply_network_config(is_new_instance)
+
+        By default, networking configuration is only applied when
+        is_new_instance is True.  A datasource may override this default by
+        setting manage_network to True.
+        """
+        return is_new_instance or self.metadata.get('maintain_network', False)
+
 
 def normalize_pubkey_data(pubkey_data):
     keys = []
diff --git a/cloudinit/stages.py b/cloudinit/stages.py
index bc4ebc8..bb00cdf 100644
--- a/cloudinit/stages.py
+++ b/cloudinit/stages.py
@@ -643,7 +643,8 @@ class Init(object):
             LOG.warning("Failed to rename devices: %s", e)
 
         if (self.datasource is not NULL_DATA_SOURCE and
-                not self.is_new_instance()):
+                not self.datasource.check_apply_network_config(
+                    self.is_new_instance())):
             LOG.debug("not a new instance. network config is not applied.")
             return
 
diff --git a/doc/rtd/topics/datasources/smartos.rst b/doc/rtd/topics/datasources/smartos.rst
index cb9a128..7161ce4 100644
--- a/doc/rtd/topics/datasources/smartos.rst
+++ b/doc/rtd/topics/datasources/smartos.rst
@@ -58,6 +58,7 @@ SmartOS tools. These are:
  * hostname
  * enable_motd_sys_info
  * iptables_disable
+ * manage_network
 
 Note: At this time iptables_disable and enable_motd_sys_info are read but
     are not actioned.
diff --git a/tests/unittests/test_datasource/test_smartos.py b/tests/unittests/test_datasource/test_smartos.py
index 2bea7a1..24bd918 100644
--- a/tests/unittests/test_datasource/test_smartos.py
+++ b/tests/unittests/test_datasource/test_smartos.py
@@ -601,6 +601,36 @@ class TestSmartOSDataSource(FilesystemMockingTestCase):
         self.assertEqual(dsrc.device_name_to_device('FOO'),
                          mydscfg['disk_aliases']['FOO'])
 
+    def test_sdc_maintain_network_unset(self):
+        dsrc = self._get_ds(mockdata=MOCK_RETURNS)
+        ret = dsrc.get_data()
+        self.assertTrue(ret)
+        self.assertFalse(dsrc.check_apply_network_config(False))
+
+    def test_sdc_maintain_network_true(self):
+        mockdata = MOCK_RETURNS.copy()
+        mockdata['sdc:maintain_network'] = 'true'
+        dsrc = self._get_ds(mockdata=mockdata)
+        ret = dsrc.get_data()
+        self.assertTrue(ret)
+        self.assertTrue(dsrc.check_apply_network_config(False))
+
+    def test_sdc_maintain_network_false(self):
+        mockdata = MOCK_RETURNS.copy()
+        mockdata['sdc:maintain_network'] = 'false'
+        dsrc = self._get_ds(mockdata=mockdata)
+        ret = dsrc.get_data()
+        self.assertTrue(ret)
+        self.assertFalse(dsrc.check_apply_network_config(False))
+
+    def test_sdc_maintain_network_invalid(self):
+        mockdata = MOCK_RETURNS.copy()
+        mockdata['sdc:maintain_network'] = 'junk'
+        dsrc = self._get_ds(mockdata=mockdata)
+        ret = dsrc.get_data()
+        self.assertTrue(ret)
+        self.assertFalse(dsrc.check_apply_network_config(False))
+
 
 class ShortReader(object):
     """Implements a 'read' interface for bytes provided.

Follow ups