Permalink
Browse files

GCE: Search GCE in ds-identify, consider serial number in check.

While documentation indicates that the smbios product name should
contain 'Google Compute Engine', experimentation and bug reports
indicate that is not always the case.  The change here is to change
the check for GCE to also consider a serial number that starts with
'GoogleCompute-'.

Also, ds-identify was not currently searching for GCE if no config of
datasource_list was found.  Most images have a datasource_list defined.
So update the list to include GCE.

LP: #1674861
  • Loading branch information...
smoser committed Mar 27, 2017
1 parent 2163297 commit 328fe5ab399b1f5b48d1985f41fc2ef66e368922
Showing with 44 additions and 2 deletions.
  1. +18 −0 cloudinit/sources/DataSourceGCE.py
  2. +13 −1 tests/unittests/test_datasource/test_gce.py
  3. +13 −1 tools/ds-identify
@@ -62,6 +62,9 @@ def _trim_key(self, public_key):
return public_key
def get_data(self):
if not platform_reports_gce():
return False
# url_map: (our-key, path, required, is_text)
url_map = [
('instance-id', ('instance/id',), True, True),
@@ -144,6 +147,21 @@ def region(self):
return self.availability_zone.rsplit('-', 1)[0]
def platform_reports_gce():
pname = util.read_dmi_data('system-product-name') or "N/A"
if pname == "Google Compute Engine":
return True
# system-product-name is not always guaranteed (LP: #1674861)
serial = util.read_dmi_data('system-serial-number') or "N/A"
if serial.startswith("GoogleCloud-"):
return True
LOG.debug("Not running on google cloud. product-name=%s serial=%s",
pname, serial)
return False
# Used to match classes to dependencies
datasources = [
(DataSourceGCE, (sources.DEP_FILESYSTEM, sources.DEP_NETWORK)),
@@ -5,6 +5,7 @@
# This file is part of cloud-init. See LICENSE file for license information.
import httpretty
import mock
import re
from base64 import b64encode, b64decode
@@ -71,6 +72,11 @@ def setUp(self):
self.ds = DataSourceGCE.DataSourceGCE(
settings.CFG_BUILTIN, None,
helpers.Paths({}))
self.m_platform_reports_gce = mock.patch(
'cloudinit.sources.DataSourceGCE.platform_reports_gce',
return_value=True)
self.m_platform_reports_gce.start()
self.addCleanup(self.m_platform_reports_gce.stop)
super(TestDataSourceGCE, self).setUp()
def test_connection(self):
@@ -153,7 +159,13 @@ def test_instance_level_keys_replace_project_level_keys(self):
def test_only_last_part_of_zone_used_for_availability_zone(self):
_set_mock_metadata()
self.ds.get_data()
r = self.ds.get_data()
self.assertEqual(True, r)
self.assertEqual('bar', self.ds.availability_zone)
def test_get_data_returns_false_if_not_on_gce(self):
self.m_platform_reports_gce.return_value = False
self.assertEqual(False, self.ds.get_data())
# vi: ts=4 expandtab
@@ -108,7 +108,7 @@ DI_DSNAME=""
# this has to match the builtin list in cloud-init, it is what will
# be searched if there is no setting found in config.
DI_DSLIST_DEFAULT="MAAS ConfigDrive NoCloud AltCloud Azure Bigstep \
CloudSigma CloudStack DigitalOcean Ec2 OpenNebula OpenStack OVF SmartOS"
CloudSigma CloudStack DigitalOcean Ec2 GCE OpenNebula OpenStack OVF SmartOS"
DI_DSLIST=""
DI_MODE=""
DI_ON_FOUND=""
@@ -383,6 +383,14 @@ dmi_product_name_matches() {
return 1
}
dmi_product_serial_matches() {
is_container && return 1
case "${DI_DMI_PRODUCT_SERIAL}" in
$1) return 0;;
esac
return 1
}
dmi_product_name_is() {
is_container && return 1
[ "${DI_DMI_PRODUCT_NAME}" = "$1" ]
@@ -770,6 +778,10 @@ dscheck_GCE() {
if dmi_product_name_is "Google Compute Engine"; then
return ${DS_FOUND}
fi
# product name is not guaranteed (LP: #1674861)
if dmi_product_serial_matches "GoogleCloud-*"; then
return ${DS_FOUND}
fi
return ${DS_NOT_FOUND}
}

0 comments on commit 328fe5a

Please sign in to comment.