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
_______________________________________________ Mailing list: https://launchpad.net/~cloud-init-dev Post to : cloud-init-dev@lists.launchpad.net Unsubscribe : https://launchpad.net/~cloud-init-dev More help : https://help.launchpad.net/ListHelp