summaryrefslogtreecommitdiff
path: root/cloudinit/sources
diff options
context:
space:
mode:
authorScott Moser <smoser@ubuntu.com>2016-03-21 22:30:56 -0400
committerScott Moser <smoser@ubuntu.com>2016-03-21 22:30:56 -0400
commit4f2065ad569355d5d0bc54176bde6b8e55047341 (patch)
tree0008ea8f19816c882f52dee82079776317982210 /cloudinit/sources
parent1b91b7cee6f2d4a2a7ddaf5f963225f0d36d1963 (diff)
parent8968f570787c0889f2c8b363e208e018903b63fa (diff)
downloadvyos-cloud-init-4f2065ad569355d5d0bc54176bde6b8e55047341.tar.gz
vyos-cloud-init-4f2065ad569355d5d0bc54176bde6b8e55047341.zip
quickly check to see if the previous instance id is still valid
This adds a check in cloud-init to see if the existing (cached) datasource is still valid. It relies on support from the Datasource to implement 'check_instance_id'. That method should quickly determine (if possible) if the instance id found in the datasource is still valid. This means that we can still notice new instance ids without depending on a network datasource on every boot. I've also implemented check_instance_id for the superclass and for sources: DataSourceAzure (check dmi data) DataSourceConfigDrive (check dmi data) DataSourceNocloud (check the seeded data or kernel command line) DataSourceOpenstack (check dmi data) LP: #1553815
Diffstat (limited to 'cloudinit/sources')
-rw-r--r--cloudinit/sources/DataSourceAzure.py4
-rw-r--r--cloudinit/sources/DataSourceConfigDrive.py4
-rw-r--r--cloudinit/sources/DataSourceNoCloud.py35
-rw-r--r--cloudinit/sources/DataSourceOpenStack.py4
-rw-r--r--cloudinit/sources/__init__.py16
5 files changed, 63 insertions, 0 deletions
diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py
index 2af0ad9b..832b3063 100644
--- a/cloudinit/sources/DataSourceAzure.py
+++ b/cloudinit/sources/DataSourceAzure.py
@@ -254,6 +254,10 @@ class DataSourceAzureNet(sources.DataSource):
def get_config_obj(self):
return self.cfg
+ def check_instance_id(self):
+ # quickly (local check only) if self.instance_id is still valid
+ return sources.instance_id_matches_system_uuid(self.get_instance_id())
+
def count_files(mp):
return len(fnmatch.filter(os.listdir(mp), '*[!cdrom]*'))
diff --git a/cloudinit/sources/DataSourceConfigDrive.py b/cloudinit/sources/DataSourceConfigDrive.py
index e3916208..6fc9e05b 100644
--- a/cloudinit/sources/DataSourceConfigDrive.py
+++ b/cloudinit/sources/DataSourceConfigDrive.py
@@ -146,6 +146,10 @@ class DataSourceConfigDrive(openstack.SourceMixin, sources.DataSource):
return True
+ def check_instance_id(self):
+ # quickly (local check only) if self.instance_id is still valid
+ return sources.instance_id_matches_system_uuid(self.get_instance_id())
+
class DataSourceConfigDriveNet(DataSourceConfigDrive):
def __init__(self, sys_cfg, distro, paths):
diff --git a/cloudinit/sources/DataSourceNoCloud.py b/cloudinit/sources/DataSourceNoCloud.py
index 4cad6877..d07e6f84 100644
--- a/cloudinit/sources/DataSourceNoCloud.py
+++ b/cloudinit/sources/DataSourceNoCloud.py
@@ -197,6 +197,41 @@ class DataSourceNoCloud(sources.DataSource):
mydata['meta-data']['dsmode'])
return False
+ def check_instance_id(self):
+ # quickly (local check only) if self.instance_id is still valid
+ # we check kernel command line or files.
+ current = self.get_instance_id()
+ if not current:
+ return None
+
+ quick_id = _quick_read_instance_id(cmdline_id=self.cmdline_id,
+ dirs=[self.seed_dir])
+ if not quick_id:
+ return None
+ return quick_id == current
+
+
+def _quick_read_instance_id(cmdline_id, dirs=None):
+ if dirs is None:
+ dirs = []
+
+ iid_key = 'instance-id'
+ if cmdline_id is None:
+ fill = {}
+ if parse_cmdline_data(cmdline_id, fill) and iid_key in fill:
+ return fill[iid_key]
+
+ for d in dirs:
+ try:
+ data = util.pathprefix2dict(d, required=['meta-data'])
+ md = util.load_yaml(data['meta-data'])
+ if iid_key in md:
+ return md[iid_key]
+ except ValueError:
+ pass
+
+ return None
+
# Returns true or false indicating if cmdline indicated
# that this module should be used
diff --git a/cloudinit/sources/DataSourceOpenStack.py b/cloudinit/sources/DataSourceOpenStack.py
index 469c2e2a..79bb9d63 100644
--- a/cloudinit/sources/DataSourceOpenStack.py
+++ b/cloudinit/sources/DataSourceOpenStack.py
@@ -150,6 +150,10 @@ class DataSourceOpenStack(openstack.SourceMixin, sources.DataSource):
return True
+ def check_instance_id(self):
+ # quickly (local check only) if self.instance_id is still valid
+ return sources.instance_id_matches_system_uuid(self.get_instance_id())
+
def read_metadata_service(base_url, ssl_details=None):
reader = openstack.MetadataReader(base_url, ssl_details=ssl_details)
diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py
index d3cfa560..28540a7b 100644
--- a/cloudinit/sources/__init__.py
+++ b/cloudinit/sources/__init__.py
@@ -217,6 +217,10 @@ class DataSource(object):
def get_package_mirror_info(self):
return self.distro.get_package_mirror_info(data_source=self)
+ def check_instance_id(self):
+ # quickly (local check only) if self.instance_id is still
+ return False
+
def normalize_pubkey_data(pubkey_data):
keys = []
@@ -299,6 +303,18 @@ def list_sources(cfg_list, depends, pkg_list):
return src_list
+def instance_id_matches_system_uuid(instance_id, field='system-uuid'):
+ # quickly (local check only) if self.instance_id is still valid
+ # we check kernel command line or files.
+ if not instance_id:
+ return False
+
+ dmi_value = util.read_dmi_data(field)
+ if not dmi_value:
+ return False
+ return instance_id.lower() == dmi_value.lower()
+
+
# 'depends' is a list of dependencies (DEP_FILESYSTEM)
# ds_list is a list of 2 item lists
# ds_list = [