cloud-init-dev team mailing list archive
-
cloud-init-dev team
-
Mailing list archive
-
Message #06918
[Merge] ~ahosmanmsft/cloud-init:idchange into cloud-init:master
Ahmed has proposed merging ~ahosmanmsft/cloud-init:idchange into cloud-init:master.
Commit message:
Fixed instance id endioness on Azure
Requested reviews:
cloud-init Commiters (cloud-init-dev)
For more details, see:
https://code.launchpad.net/~ahosmanmsft/cloud-init/+git/cloud-init/+merge/376298
Corrected instance id comparison and implemented a change for id byte swap on gen2 VM's
--
Your team cloud-init Commiters is requested to review the proposed merge of ~ahosmanmsft/cloud-init:idchange into cloud-init:master.
diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py
index 87a848c..9afca1b 100755
--- a/cloudinit/sources/DataSourceAzure.py
+++ b/cloudinit/sources/DataSourceAzure.py
@@ -33,7 +33,8 @@ from cloudinit.sources.helpers.azure import (
get_boot_telemetry,
get_system_info,
report_diagnostic_event,
- EphemeralDHCPv4WithReporting)
+ EphemeralDHCPv4WithReporting,
+ byte_swapped)
LOG = logging.getLogger(__name__)
@@ -471,8 +472,7 @@ class DataSourceAzure(sources.DataSource):
seed = _get_random_seed()
if seed:
crawled_data['metadata']['random_seed'] = seed
- crawled_data['metadata']['instance-id'] = util.read_dmi_data(
- 'system-uuid')
+ crawled_data['metadata']['instance-id'] = self._iid()
if perform_reprovision:
LOG.info("Reporting ready to Azure after getting ReprovisionData")
@@ -558,6 +558,15 @@ class DataSourceAzure(sources.DataSource):
# quickly (local check only) if self.instance_id is still valid
return sources.instance_id_matches_system_uuid(self.get_instance_id())
+ def _iid(self):
+ previous = util.load_file(os.path.join(
+ self.paths.get_cpath('data'),
+ 'instance-id')).strip()
+ iid = util.read_dmi_data(
+ 'system-uuid')
+ swap = byte_swapped(previous, iid)
+ return swap if swap else iid
+
@azure_ds_telemetry_reporter
def setup(self, is_new_instance):
if self._negotiated is False:
diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py
index e6baf8f..ab268af 100644
--- a/cloudinit/sources/__init__.py
+++ b/cloudinit/sources/__init__.py
@@ -15,6 +15,7 @@ import json
import os
import six
+from cloudinit.sources.helpers.azure import byte_swapped
from cloudinit.atomic_helper import write_json
from cloudinit import importer
from cloudinit import log as logging
@@ -800,9 +801,11 @@ def instance_id_matches_system_uuid(instance_id, field='system-uuid'):
return False
dmi_value = util.read_dmi_data(field)
+ previous = dmi_value.lower()
+ current = instance_id.lower()
if not dmi_value:
return False
- return instance_id.lower() == dmi_value.lower()
+ return current == previous or current == byte_swapped(current, previous)
def canonical_cloud_id(cloud_name, region, platform):
diff --git a/cloudinit/sources/helpers/azure.py b/cloudinit/sources/helpers/azure.py
index f5cdb3f..88f3498 100755
--- a/cloudinit/sources/helpers/azure.py
+++ b/cloudinit/sources/helpers/azure.py
@@ -48,6 +48,37 @@ def azure_ds_telemetry_reporter(func):
return impl
+def byte_swapped(previous_id, current_id):
+ """
+ Azure stores the instance ID with an incorrect byte ordering for the
+ first parts. This corrects the byte order such that it is consistent with
+ that returned by the metadata service.
+ """
+ if previous_id == current_id:
+ return None
+
+ def swap_hexstring(s, width=2):
+ r = len(s) % width
+ if r != 0:
+ s = ('0' * (width - (len(s) % width))) + s
+
+ return ''.join(reversed(
+ re.findall(
+ r'[a-f0-9]{{{0}}}'.format(width),
+ s,
+ re.IGNORECASE)))
+
+ parts = current_id.split('-')
+ swapped_id = '-'.join([
+ swap_hexstring(parts[0], width=2),
+ swap_hexstring(parts[1], width=2),
+ swap_hexstring(parts[2], width=2),
+ parts[3],
+ parts[4]
+ ])
+
+ return swapped_id if previous_id == swapped_id else None
+
@azure_ds_telemetry_reporter
def get_boot_telemetry():
"""Report timestamps related to kernel initialization and systemd
Follow ups