← Back to team overview

cloud-init-dev team mailing list archive

[Merge] ~chad.smith/cloud-init:fix/bug-1757176-get-host-name-metadata-only into cloud-init:master

 

Chad Smith has proposed merging ~chad.smith/cloud-init:fix/bug-1757176-get-host-name-metadata-only into cloud-init:master.

Commit message:
datasources: fix DataSource subclass get_hostname method signature

DataSource.get_hostname call signature changed to allow for metadata_only
parameter.  The metadata_only=True parameter is passed to get_hostname
during init-local stage in order to set the system hostname if present in
metadata prior to initial network bring up.

Fix subclasses of DataSource which have overridden get_hostname to allow
for metadata_only param.

LP: #1757176

Requested reviews:
  Server Team CI bot (server-team-bot): continuous-integration
  cloud-init commiters (cloud-init-dev)

For more details, see:
https://code.launchpad.net/~chad.smith/cloud-init/+git/cloud-init/+merge/341757

see commit message.
-- 
Your team cloud-init commiters is requested to review the proposed merge of ~chad.smith/cloud-init:fix/bug-1757176-get-host-name-metadata-only into cloud-init:master.
diff --git a/cloudinit/sources/DataSourceAliYun.py b/cloudinit/sources/DataSourceAliYun.py
index 7ac8288..22279d0 100644
--- a/cloudinit/sources/DataSourceAliYun.py
+++ b/cloudinit/sources/DataSourceAliYun.py
@@ -22,7 +22,7 @@ class DataSourceAliYun(EC2.DataSourceEc2):
         super(DataSourceAliYun, self).__init__(sys_cfg, distro, paths)
         self.seed_dir = os.path.join(paths.seed_dir, "AliYun")
 
-    def get_hostname(self, fqdn=False, _resolve_ip=False):
+    def get_hostname(self, fqdn=False, resolve_ip=False, metadata_only=False):
         return self.metadata.get('hostname', 'localhost.localdomain')
 
     def get_public_ssh_keys(self):
diff --git a/cloudinit/sources/DataSourceCloudSigma.py b/cloudinit/sources/DataSourceCloudSigma.py
index 4eaad47..c816f34 100644
--- a/cloudinit/sources/DataSourceCloudSigma.py
+++ b/cloudinit/sources/DataSourceCloudSigma.py
@@ -84,7 +84,7 @@ class DataSourceCloudSigma(sources.DataSource):
 
         return True
 
-    def get_hostname(self, fqdn=False, resolve_ip=False):
+    def get_hostname(self, fqdn=False, resolve_ip=False, metadata_only=False):
         """
         Cleans up and uses the server's name if the latter is set. Otherwise
         the first part from uuid is being used.
diff --git a/cloudinit/sources/DataSourceGCE.py b/cloudinit/sources/DataSourceGCE.py
index bebc991..d816262 100644
--- a/cloudinit/sources/DataSourceGCE.py
+++ b/cloudinit/sources/DataSourceGCE.py
@@ -90,7 +90,7 @@ class DataSourceGCE(sources.DataSource):
         public_keys_data = self.metadata['public-keys-data']
         return _parse_public_keys(public_keys_data, self.default_user)
 
-    def get_hostname(self, fqdn=False, resolve_ip=False):
+    def get_hostname(self, fqdn=False, resolve_ip=False, metadata_only=False):
         # GCE has long FDQN's and has asked for short hostnames.
         return self.metadata['local-hostname'].split('.')[0]
 
diff --git a/cloudinit/sources/DataSourceOpenNebula.py b/cloudinit/sources/DataSourceOpenNebula.py
index 02cb98f..d4a4111 100644
--- a/cloudinit/sources/DataSourceOpenNebula.py
+++ b/cloudinit/sources/DataSourceOpenNebula.py
@@ -102,7 +102,7 @@ class DataSourceOpenNebula(sources.DataSource):
         else:
             return None
 
-    def get_hostname(self, fqdn=False, resolve_ip=None):
+    def get_hostname(self, fqdn=False, resolve_ip=False, metadata_only=False):
         if resolve_ip is None:
             if self.dsmode == sources.DSMODE_NETWORK:
                 resolve_ip = True
diff --git a/cloudinit/sources/DataSourceScaleway.py b/cloudinit/sources/DataSourceScaleway.py
index b0b19c9..9005624 100644
--- a/cloudinit/sources/DataSourceScaleway.py
+++ b/cloudinit/sources/DataSourceScaleway.py
@@ -215,7 +215,7 @@ class DataSourceScaleway(sources.DataSource):
     def get_public_ssh_keys(self):
         return [key['key'] for key in self.metadata['ssh_public_keys']]
 
-    def get_hostname(self, fqdn=False, resolve_ip=False):
+    def get_hostname(self, fqdn=False, resolve_ip=False, metadata_only=False):
         return self.metadata['hostname']
 
     @property
diff --git a/cloudinit/sources/tests/test_init.py b/cloudinit/sources/tests/test_init.py
index 5065083..8e800e6 100644
--- a/cloudinit/sources/tests/test_init.py
+++ b/cloudinit/sources/tests/test_init.py
@@ -1,10 +1,12 @@
 # This file is part of cloud-init. See LICENSE file for license information.
 
+import inspect
 import os
 import six
 import stat
 
 from cloudinit.helpers import Paths
+from cloudinit import importer
 from cloudinit.sources import (
     INSTANCE_JSON_FILE, DataSource)
 from cloudinit.tests.helpers import CiTestCase, skipIf, mock
@@ -268,3 +270,27 @@ class TestDataSource(CiTestCase):
             "WARNING: Error persisting instance-data.json: 'utf8' codec can't"
             " decode byte 0xaa in position 2: invalid start byte",
             self.logs.getvalue())
+
+    def test_get_hostname_subclass_support(self):
+        """Validate get_hostname signature on all subclasses of DataSource."""
+        # Use inspect.getfullargspec when we drop py2.6 and py2.7
+        get_args_func = inspect.getargs  # pylint: disable=W1505
+        base_args = get_args_func(DataSource.get_hostname)
+        # Import all DataSource subclasses so we can inspect them.
+        modules = util.find_modules(os.path.dirname(os.path.dirname(__file__)))
+        for loc, name in modules.items():
+            mod_locs, _ = importer.find_module(name, ['cloudinit.sources'], [])
+            if mod_locs:
+                importer.import_module(mod_locs[0])
+        for child in DataSource.__subclasses__():
+            if 'Test' in child.dsname:
+                continue
+            self.assertEqual(
+                base_args, get_args_func(child.get_hostname),
+                '%s does not implement DataSource.get_hostname params'
+                % child)
+            for grandchild in child.__subclasses__():
+                self.assertEqual(
+                    base_args, get_args_func(grandchild.get_hostname),
+                    '%s does not implement DataSource.get_hostname params'
+                    % grandchild)