Merge lp:~smoser/cloud-init/trunk.1532072 into lp:~cloud-init-dev/cloud-init/trunk

Proposed by Scott Moser
Status: Merged
Merged at revision: 1245
Proposed branch: lp:~smoser/cloud-init/trunk.1532072
Merge into: lp:~cloud-init-dev/cloud-init/trunk
Diff against target: 71 lines (+29/-12)
3 files modified
ChangeLog (+1/-0)
cloudinit/user_data.py (+16/-12)
tests/unittests/test_data.py (+12/-0)
To merge this branch: bzr merge lp:~smoser/cloud-init/trunk.1532072
Reviewer Review Type Date Requested Status
cloud-init Commiters Pending
Review via email: mp+298066@code.launchpad.net

Commit message

user_data: fix error when user-data is not utf-8 decodable

when user-data was not decodable, cloud-init would raise exception.
This also changes the signature of user_data.convert_string.
The 'headers' argument was never used, and woudl have been broken
if it was, as it was expected to be a dictionary but then was
passed in with *headers.

To post a comment you must log in.
Revision history for this message
Joshua Harlow (harlowja) wrote :

Seems ok to me!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ChangeLog'
2--- ChangeLog 2016-06-21 18:37:23 +0000
3+++ ChangeLog 2016-06-21 20:38:10 +0000
4@@ -125,6 +125,7 @@
5 - Remove trailing dot from GCE metadata URL (LP: #1581200) [Phil Roche]
6 - support network rendering to sysconfig (for centos and RHEL)
7 - write_files: if no permissions are given, just use default without warn.
8+ - user_data: fix error when user-data is not utf-8 decodable (LP: #1532072)
9
10 0.7.6:
11 - open 0.7.6
12
13=== modified file 'cloudinit/user_data.py'
14--- cloudinit/user_data.py 2016-05-12 17:56:26 +0000
15+++ cloudinit/user_data.py 2016-06-21 20:38:10 +0000
16@@ -334,19 +334,23 @@
17
18
19 # Coverts a raw string into a mime message
20-def convert_string(raw_data, headers=None):
21+def convert_string(raw_data, content_type=NOT_MULTIPART_TYPE):
22 if not raw_data:
23 raw_data = ''
24- if not headers:
25- headers = {}
26- data = util.decode_binary(util.decomp_gzip(raw_data))
27- if "mime-version:" in data[0:4096].lower():
28- msg = util.message_from_string(data)
29- for (key, val) in headers.items():
30- _replace_header(msg, key, val)
31- else:
32- mtype = headers.get(CONTENT_TYPE, NOT_MULTIPART_TYPE)
33- maintype, subtype = mtype.split("/", 1)
34- msg = MIMEBase(maintype, subtype, *headers)
35+
36+ def create_binmsg(data, content_type):
37+ maintype, subtype = content_type.split("/", 1)
38+ msg = MIMEBase(maintype, subtype)
39 msg.set_payload(data)
40+ return msg
41+
42+ try:
43+ data = util.decode_binary(util.decomp_gzip(raw_data))
44+ if "mime-version:" in data[0:4096].lower():
45+ msg = util.message_from_string(data)
46+ else:
47+ msg = create_binmsg(data, content_type)
48+ except UnicodeDecodeError:
49+ msg = create_binmsg(raw_data, content_type)
50+
51 return msg
52
53=== modified file 'tests/unittests/test_data.py'
54--- tests/unittests/test_data.py 2016-05-12 20:43:11 +0000
55+++ tests/unittests/test_data.py 2016-06-21 20:38:10 +0000
56@@ -557,3 +557,15 @@
57 ud_proc = ud.UserDataProcessor(self.getCloudPaths())
58 message = ud_proc.process(msg)
59 self.assertTrue(count_messages(message) == 1)
60+
61+
62+class TestConvert(helpers.TestCase):
63+ def test_handles_binary(self):
64+ blob = b'\x32\x99'
65+ msg = ud.convert_string(blob)
66+ self.assertEqual(blob, msg.get_payload(decode=True))
67+
68+ def test_handle_headers(self):
69+ text = "hi mom"
70+ msg = ud.convert_string(text)
71+ self.assertEqual(text, msg.get_payload(decode=False))