Merge lp:~daniel-thewatkins/cloud-init/shim_fixes into lp:~cloud-init-dev/cloud-init/trunk

Proposed by Dan Watkins on 2015-08-26
Status: Superseded
Proposed branch: lp:~daniel-thewatkins/cloud-init/shim_fixes
Merge into: lp:~cloud-init-dev/cloud-init/trunk
Diff against target: 144 lines (+64/-42)
2 files modified
cloudinit/sources/helpers/azure.py (+16/-10)
tests/unittests/test_datasource/test_azure_helper.py (+48/-32)
To merge this branch: bzr merge lp:~daniel-thewatkins/cloud-init/shim_fixes
Reviewer Review Type Date Requested Status
cloud-init commiters 2015-08-26 Pending
Review via email: mp+269199@code.launchpad.net

This proposal has been superseded by a proposal from 2015-10-09.

To post a comment you must log in.
1139. By Scott Moser on 2015-09-01

Handle symlink mount points in mount_cb.

The Azure data source now uses a /dev/disk symlink to identify devices,
but the dereferenced version of this appears in the mount table.
mount_cb therefore doesn't identify when a disk is already mounted, and
attempts to mount it a second time (which fails with NTFS).

1140. By Scott Moser on 2015-09-02

sync curtin reporting changes back to cloud-init

this pulls in the reporting framework that we'd been working on
in curtin back to cloud-init.

1141. By Scott Moser on 2015-09-03

reporting/events: catch a final remaining incorrect use of 'reporting'

1142. By Scott Moser on 2015-09-08

NoCloud: fix consumption of vendor-data

the content of vendordata was was being assigned to vendordata,
rather than vendordata_raw. The result was that it is not processed
for includes or part handlers or other things as it is in other
datasources.

1143. By Scott Moser on 2015-09-08

  power_state: support 'condition' argument

  if 'condition' is provided to config in power_state, then
  consult it before powering off.

  This allows the user to shut down only if a condition is met, and
  leave the system in a debuggable state otherwise.

  An example is as simple as:
   power_state:
     mode: poweroff
     condition: ['sh', '-c', '[ -f /disable-poweroff ]']

1144. By Scott Moser on 2015-09-11

snappy: enable ssh on snappy if ssh keys are provided or password auth

If the user provides ssh keys or requests password auth in their
user-data then we will enable ssh by default.

1145. By Ben Howard on 2015-09-15

Change Snappy SSH enabled default from false to 'auto' (LP: #1494816)

1146. By Scott Moser on 2015-09-17

webhook: report with json data

the handler was passing a dictionary to readurl
which was then passing that on to requests.request as 'data'.
the requests library would urlencode that, but we want the
json data posted instead.

Scott Moser (smoser) wrote :

Odd_Bloke, it seems maybe the part find_endpoint after 'No endpoint found in DHCP config.' could/should be its own method . and then some tests on it. maybe 'extract_value_from_leases_key' or something like that.

other thing, is if you're just reading your two test cases that you added, its very difficult to see how they're any different . since the only difference is in fact the ip address. at very lease a comment would be good there.

1147. By Scott Moser on 2015-09-29

MAAS: fix issues with url_helper and oauth module

This would cause problems in the event that we actually had a bad
clock. We add a retry in the main (for test) also, to ensure that
the oauth timestamp fix gets in place.

1148. By Dan Watkins on 2015-10-09

Handle escaped quotes in WALinuxAgentShim.find_endpoint.

This fixes bug 1488891.

1149. By Dan Watkins on 2015-10-09

Handle colons in packed strings in WALinuxAgentShim.find_endpoint.

This fixes bug 1488896.

1150. By Dan Watkins on 2015-10-09

Convert test helper to staticmethod.

1151. By Dan Watkins on 2015-10-09

Refactor WALinuxAgentShim.find_endpoint to use a helper method for IP address unpacking.

1152. By Dan Watkins on 2015-10-09

Refactor tests to test helper method directly, and remove need for test helper.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'cloudinit/sources/helpers/azure.py'
2--- cloudinit/sources/helpers/azure.py 2015-05-08 15:52:58 +0000
3+++ cloudinit/sources/helpers/azure.py 2015-10-09 13:01:25 +0000
4@@ -216,6 +216,21 @@
5 self.openssl_manager.clean_up()
6
7 @staticmethod
8+ def get_ip_from_lease_value(lease_value):
9+ unescaped_value = lease_value.replace('\\', '')
10+ if len(unescaped_value) > 4:
11+ hex_string = ''
12+ for hex_pair in unescaped_value.split(':'):
13+ if len(hex_pair) == 1:
14+ hex_pair = '0' + hex_pair
15+ hex_string += hex_pair
16+ packed_bytes = struct.pack(
17+ '>L', int(hex_string.replace(':', ''), 16))
18+ else:
19+ packed_bytes = unescaped_value.encode('utf-8')
20+ return socket.inet_ntoa(packed_bytes)
21+
22+ @staticmethod
23 def find_endpoint():
24 LOG.debug('Finding Azure endpoint...')
25 content = util.load_file('/var/lib/dhcp/dhclient.eth0.leases')
26@@ -225,16 +240,7 @@
27 value = line.strip(' ').split(' ', 2)[-1].strip(';\n"')
28 if value is None:
29 raise Exception('No endpoint found in DHCP config.')
30- if ':' in value:
31- hex_string = ''
32- for hex_pair in value.split(':'):
33- if len(hex_pair) == 1:
34- hex_pair = '0' + hex_pair
35- hex_string += hex_pair
36- value = struct.pack('>L', int(hex_string.replace(':', ''), 16))
37- else:
38- value = value.encode('utf-8')
39- endpoint_ip_address = socket.inet_ntoa(value)
40+ endpoint_ip_address = WALinuxAgentShim.get_ip_from_lease_value(value)
41 LOG.debug('Azure endpoint found at %s', endpoint_ip_address)
42 return endpoint_ip_address
43
44
45=== modified file 'tests/unittests/test_datasource/test_azure_helper.py'
46--- tests/unittests/test_datasource/test_azure_helper.py 2015-05-15 20:28:24 +0000
47+++ tests/unittests/test_datasource/test_azure_helper.py 2015-10-09 13:01:25 +0000
48@@ -90,48 +90,64 @@
49 self.assertRaises(Exception,
50 azure_helper.WALinuxAgentShim.find_endpoint)
51
52- def _build_lease_content(self, ip_address, use_hex=True):
53- ip_address_repr = ':'.join(
54- [hex(int(part)).replace('0x', '')
55- for part in ip_address.split('.')])
56- if not use_hex:
57- ip_address_repr = struct.pack(
58- '>L', int(ip_address_repr.replace(':', ''), 16))
59- ip_address_repr = '"{0}"'.format(ip_address_repr.decode('utf-8'))
60+ @staticmethod
61+ def _build_lease_content(encoded_address):
62 return '\n'.join([
63 'lease {',
64 ' interface "eth0";',
65- ' option unknown-245 {0};'.format(ip_address_repr),
66+ ' option unknown-245 {0};'.format(encoded_address),
67 '}'])
68
69+ def test_latest_lease_used(self):
70+ encoded_addresses = ['5:4:3:2', '4:3:2:1']
71+ file_content = '\n'.join([self._build_lease_content(encoded_address)
72+ for encoded_address in encoded_addresses])
73+ self.load_file.return_value = file_content
74+ self.assertEqual(encoded_addresses[-1].replace(':', '.'),
75+ azure_helper.WALinuxAgentShim.find_endpoint())
76+
77+
78+class TestExtractIpAddressFromLeaseValue(TestCase):
79+
80 def test_hex_string(self):
81- ip_address = '98.76.54.32'
82- file_content = self._build_lease_content(ip_address)
83- self.load_file.return_value = file_content
84- self.assertEqual(ip_address,
85- azure_helper.WALinuxAgentShim.find_endpoint())
86+ ip_address, encoded_address = '98.76.54.32', '62:4c:36:20'
87+ self.assertEqual(
88+ ip_address,
89+ azure_helper.WALinuxAgentShim.get_ip_from_lease_value(
90+ encoded_address
91+ ))
92
93 def test_hex_string_with_single_character_part(self):
94- ip_address = '4.3.2.1'
95- file_content = self._build_lease_content(ip_address)
96- self.load_file.return_value = file_content
97- self.assertEqual(ip_address,
98- azure_helper.WALinuxAgentShim.find_endpoint())
99+ ip_address, encoded_address = '4.3.2.1', '4:3:2:1'
100+ self.assertEqual(
101+ ip_address,
102+ azure_helper.WALinuxAgentShim.get_ip_from_lease_value(
103+ encoded_address
104+ ))
105
106 def test_packed_string(self):
107- ip_address = '98.76.54.32'
108- file_content = self._build_lease_content(ip_address, use_hex=False)
109- self.load_file.return_value = file_content
110- self.assertEqual(ip_address,
111- azure_helper.WALinuxAgentShim.find_endpoint())
112-
113- def test_latest_lease_used(self):
114- ip_addresses = ['4.3.2.1', '98.76.54.32']
115- file_content = '\n'.join([self._build_lease_content(ip_address)
116- for ip_address in ip_addresses])
117- self.load_file.return_value = file_content
118- self.assertEqual(ip_addresses[-1],
119- azure_helper.WALinuxAgentShim.find_endpoint())
120+ ip_address, encoded_address = '98.76.54.32', 'bL6 '
121+ self.assertEqual(
122+ ip_address,
123+ azure_helper.WALinuxAgentShim.get_ip_from_lease_value(
124+ encoded_address
125+ ))
126+
127+ def test_packed_string_with_escaped_quote(self):
128+ ip_address, encoded_address = '100.72.34.108', 'dH\\"l'
129+ self.assertEqual(
130+ ip_address,
131+ azure_helper.WALinuxAgentShim.get_ip_from_lease_value(
132+ encoded_address
133+ ))
134+
135+ def test_packed_string_containing_a_colon(self):
136+ ip_address, encoded_address = '100.72.58.108', 'dH:l'
137+ self.assertEqual(
138+ ip_address,
139+ azure_helper.WALinuxAgentShim.get_ip_from_lease_value(
140+ encoded_address
141+ ))
142
143
144 class TestGoalStateParsing(TestCase):