Merge ~ahosmanmsft/cloud-init:idchange into cloud-init:master

Proposed by Ahmed
Status: Needs review
Proposed branch: ~ahosmanmsft/cloud-init:idchange
Merge into: cloud-init:master
Diff against target: 107 lines (+47/-4)
3 files modified
cloudinit/sources/DataSourceAzure.py (+12/-3)
cloudinit/sources/__init__.py (+4/-1)
cloudinit/sources/helpers/azure.py (+31/-0)
Reviewer Review Type Date Requested Status
Chad Smith Needs Resubmitting
Review via email: mp+376298@code.launchpad.net

Commit message

Fixed instance id endianness on Azure

Description of the change

Corrected instance id comparison and implemented a change for id byte swap on gen2 VM's

To post a comment you must log in.
Revision history for this message
Chad Smith (chad.smith) wrote :

Thanks for the branch suggestion. I think we'd like to see this over in github as a pull request.

Please run the tools/migrate-lp-user-to-github so we can link your Launchpad account to your github account. Then you can push this PR over to <email address hidden>:<YOUR_GITHUB_USER>/cloud-init.git

That was you'll have public travis CI runs against your branches so we don't have to manually trigger jenkins jobs.

The basic instructions on cloning instructions in https://cloudinit.readthedocs.io/en/latest/topics/hacking.html

review: Needs Resubmitting
Revision history for this message
Chad Smith (chad.smith) wrote :

Also can we get a unit test that covers this logic in tests/unittests/test_datasource/test_azure_helper.py OR tests/unittests/test_datasource/test_azure.py?

Revision history for this message
Chad Smith (chad.smith) :

Unmerged commits

dc04345... by Ahmed

moved to Azure

adf4f43... by Ahmed

corrected instance_id in Azure

12d1bb5... by Ahmed

Merge branch 'master' of https://git.launchpad.net/cloud-init into idchange

2718008... by Ahmed

implemented byte swap method

70d4099... by Ahmed

implemented byte swap correction

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py
2index 87a848c..9afca1b 100755
3--- a/cloudinit/sources/DataSourceAzure.py
4+++ b/cloudinit/sources/DataSourceAzure.py
5@@ -33,7 +33,8 @@ from cloudinit.sources.helpers.azure import (
6 get_boot_telemetry,
7 get_system_info,
8 report_diagnostic_event,
9- EphemeralDHCPv4WithReporting)
10+ EphemeralDHCPv4WithReporting,
11+ byte_swapped)
12
13 LOG = logging.getLogger(__name__)
14
15@@ -471,8 +472,7 @@ class DataSourceAzure(sources.DataSource):
16 seed = _get_random_seed()
17 if seed:
18 crawled_data['metadata']['random_seed'] = seed
19- crawled_data['metadata']['instance-id'] = util.read_dmi_data(
20- 'system-uuid')
21+ crawled_data['metadata']['instance-id'] = self._iid()
22
23 if perform_reprovision:
24 LOG.info("Reporting ready to Azure after getting ReprovisionData")
25@@ -558,6 +558,15 @@ class DataSourceAzure(sources.DataSource):
26 # quickly (local check only) if self.instance_id is still valid
27 return sources.instance_id_matches_system_uuid(self.get_instance_id())
28
29+ def _iid(self):
30+ previous = util.load_file(os.path.join(
31+ self.paths.get_cpath('data'),
32+ 'instance-id')).strip()
33+ iid = util.read_dmi_data(
34+ 'system-uuid')
35+ swap = byte_swapped(previous, iid)
36+ return swap if swap else iid
37+
38 @azure_ds_telemetry_reporter
39 def setup(self, is_new_instance):
40 if self._negotiated is False:
41diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py
42index e6baf8f..ab268af 100644
43--- a/cloudinit/sources/__init__.py
44+++ b/cloudinit/sources/__init__.py
45@@ -15,6 +15,7 @@ import json
46 import os
47 import six
48
49+from cloudinit.sources.helpers.azure import byte_swapped
50 from cloudinit.atomic_helper import write_json
51 from cloudinit import importer
52 from cloudinit import log as logging
53@@ -800,9 +801,11 @@ def instance_id_matches_system_uuid(instance_id, field='system-uuid'):
54 return False
55
56 dmi_value = util.read_dmi_data(field)
57+ previous = dmi_value.lower()
58+ current = instance_id.lower()
59 if not dmi_value:
60 return False
61- return instance_id.lower() == dmi_value.lower()
62+ return current == previous or current == byte_swapped(current, previous)
63
64
65 def canonical_cloud_id(cloud_name, region, platform):
66diff --git a/cloudinit/sources/helpers/azure.py b/cloudinit/sources/helpers/azure.py
67index f5cdb3f..88f3498 100755
68--- a/cloudinit/sources/helpers/azure.py
69+++ b/cloudinit/sources/helpers/azure.py
70@@ -48,6 +48,37 @@ def azure_ds_telemetry_reporter(func):
71 return impl
72
73
74+def byte_swapped(previous_id, current_id):
75+ """
76+ Azure stores the instance ID with an incorrect byte ordering for the
77+ first parts. This corrects the byte order such that it is consistent with
78+ that returned by the metadata service.
79+ """
80+ if previous_id == current_id:
81+ return None
82+
83+ def swap_hexstring(s, width=2):
84+ r = len(s) % width
85+ if r != 0:
86+ s = ('0' * (width - (len(s) % width))) + s
87+
88+ return ''.join(reversed(
89+ re.findall(
90+ r'[a-f0-9]{{{0}}}'.format(width),
91+ s,
92+ re.IGNORECASE)))
93+
94+ parts = current_id.split('-')
95+ swapped_id = '-'.join([
96+ swap_hexstring(parts[0], width=2),
97+ swap_hexstring(parts[1], width=2),
98+ swap_hexstring(parts[2], width=2),
99+ parts[3],
100+ parts[4]
101+ ])
102+
103+ return swapped_id if previous_id == swapped_id else None
104+
105 @azure_ds_telemetry_reporter
106 def get_boot_telemetry():
107 """Report timestamps related to kernel initialization and systemd

Subscribers

People subscribed via source and target branches