diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py
index 918c06c..9f0c3e8 100644
--- a/cloudinit/sources/DataSourceAzure.py
+++ b/cloudinit/sources/DataSourceAzure.py
@@ -256,11 +256,50 @@ def count_files(mp):
return len(fnmatch.filter(os.listdir(mp), '*[!cdrom]*'))
+def _batch_gen(data, batch_size):
+ # Generate batches of batch_size from data
+ for i in range(0, len(data), batch_size):
+ yield data[i:i+batch_size]
+
+
+def _get_reversed_endianness_uuid(uuid):
+ uuid_parts = uuid.split('-')
+ for part_number in [0, 1, 2]:
+ original_part = uuid_parts[part_number]
+ hex_bytes = _batch_gen(original_part, 2)
+ reversed_endianness_part = ''.join(reversed(list(hex_bytes)))
+ uuid_parts[part_number] = reversed_endianness_part
+ return '-'.join(uuid_parts)
+
+
+def _get_current_instance_uuid():
+ instance_directory = os.path.realpath('/var/lib/cloud/instance')
+ head, instance_uuid = os.path.split(instance_directory)
+ if not instance_uuid:
+ # The symlink target has a trailing slash
+ _, instance_uuid = os.path.split(head)
+ return instance_uuid
+
+
def get_instance_id():
"""
Read the instance ID from dmi data
+
+ If the reported UUID is the current instance ID with endianness changed (as
+ per LP #1551419), then the current instance ID will be used.
"""
- return util.read_dmi_data('system-uuid')
+ reported_instance_uuid = util.read_dmi_data('system-uuid')
+ if not os.path.exists('/var/lib/cloud/instance'):
+ # This is first boot of a fresh instance
+ return reported_instance_uuid
+ current_instance_uuid = _get_current_instance_uuid()
+ reversed_endianness_uuid = _get_reversed_endianness_uuid(
+ reported_instance_uuid)
+ if current_instance_uuid == reversed_endianness_uuid:
+ # The endianness of the instance UUID has changed, keep using the
+ # current UUID
+ return current_instance_uuid
+ return reported_instance_uuid
def find_fabric_formatted_ephemeral_part():