From 94244b4b2375ae1aba1167dd2b03b1227bad89e3 Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Tue, 21 Jun 2016 14:37:23 -0400 Subject: write_files: if no permissions are given, just use default without warn. if no permissions were given in a write_files stanza, then a warning would be emitted. The fix here is just to special case handling of None. --- ChangeLog | 1 + cloudinit/config/cc_write_files.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/ChangeLog b/ChangeLog index 10bd58b8..8edf3249 100644 --- a/ChangeLog +++ b/ChangeLog @@ -124,6 +124,7 @@ - Change missing Cheetah log warning to debug [Andrew Jorgensen] - Remove trailing dot from GCE metadata URL (LP: #1581200) [Phil Roche] - support network rendering to sysconfig (for centos and RHEL) + - write_files: if no permissions are given, just use default without warn. 0.7.6: - open 0.7.6 diff --git a/cloudinit/config/cc_write_files.py b/cloudinit/config/cc_write_files.py index 351cfc8c..b1096b9b 100644 --- a/cloudinit/config/cc_write_files.py +++ b/cloudinit/config/cc_write_files.py @@ -79,6 +79,8 @@ def write_files(name, files, log): def decode_perms(perm, default, log): + if perm is None: + return default try: if isinstance(perm, six.integer_types + (float,)): # Just 'downcast' it (if a float) -- cgit v1.2.1 From 4e563faac0a466953cb83fb1252cf85d6ebc5212 Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Tue, 21 Jun 2016 16:27:02 -0400 Subject: user_data: fix error when user-data is not utf-8 decodable when user-data was not decodable, cloud-init would raise exception. --- ChangeLog | 1 + cloudinit/user_data.py | 28 ++++++++++++++++------------ tests/unittests/test_data.py | 12 ++++++++++++ 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8edf3249..fa5e7df4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -125,6 +125,7 @@ - Remove trailing dot from GCE metadata URL (LP: #1581200) [Phil Roche] - support network rendering to sysconfig (for centos and RHEL) - write_files: if no permissions are given, just use default without warn. + - user_data: fix error when user-data is not utf-8 decodable (LP: #1532072) 0.7.6: - open 0.7.6 diff --git a/cloudinit/user_data.py b/cloudinit/user_data.py index f0631906..393bf0bb 100644 --- a/cloudinit/user_data.py +++ b/cloudinit/user_data.py @@ -334,19 +334,23 @@ def is_skippable(part): # Coverts a raw string into a mime message -def convert_string(raw_data, headers=None): +def convert_string(raw_data, content_type=NOT_MULTIPART_TYPE): if not raw_data: raw_data = '' - if not headers: - headers = {} - data = util.decode_binary(util.decomp_gzip(raw_data)) - if "mime-version:" in data[0:4096].lower(): - msg = util.message_from_string(data) - for (key, val) in headers.items(): - _replace_header(msg, key, val) - else: - mtype = headers.get(CONTENT_TYPE, NOT_MULTIPART_TYPE) - maintype, subtype = mtype.split("/", 1) - msg = MIMEBase(maintype, subtype, *headers) + + def create_binmsg(data, content_type): + maintype, subtype = content_type.split("/", 1) + msg = MIMEBase(maintype, subtype) msg.set_payload(data) + return msg + + try: + data = util.decode_binary(util.decomp_gzip(raw_data)) + if "mime-version:" in data[0:4096].lower(): + msg = util.message_from_string(data) + else: + msg = create_binmsg(data, content_type) + except UnicodeDecodeError: + msg = create_binmsg(raw_data, content_type) + return msg diff --git a/tests/unittests/test_data.py b/tests/unittests/test_data.py index 1923e2af..17951117 100644 --- a/tests/unittests/test_data.py +++ b/tests/unittests/test_data.py @@ -557,3 +557,15 @@ class TestUDProcess(helpers.ResourceUsingTestCase): ud_proc = ud.UserDataProcessor(self.getCloudPaths()) message = ud_proc.process(msg) self.assertTrue(count_messages(message) == 1) + + +class TestConvert(helpers.TestCase): + def test_handles_binary(self): + blob = b'\x32\x99' + msg = ud.convert_string(blob) + self.assertEqual(blob, msg.get_payload(decode=True)) + + def test_handle_headers(self): + text = "hi mom" + msg = ud.convert_string(text) + self.assertEqual(text, msg.get_payload(decode=False)) -- cgit v1.2.1 From fe15c8d01619a62f50d19e84619d52cbba14cbea Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Wed, 22 Jun 2016 10:07:12 -0400 Subject: rename test class, add a test, improve test names --- tests/unittests/test_data.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/unittests/test_data.py b/tests/unittests/test_data.py index 17951117..13db8a4c 100644 --- a/tests/unittests/test_data.py +++ b/tests/unittests/test_data.py @@ -559,12 +559,17 @@ class TestUDProcess(helpers.ResourceUsingTestCase): self.assertTrue(count_messages(message) == 1) -class TestConvert(helpers.TestCase): - def test_handles_binary(self): +class TestConvertString(helpers.TestCase): + def test_handles_binary_non_utf8_decodable(self): blob = b'\x32\x99' msg = ud.convert_string(blob) self.assertEqual(blob, msg.get_payload(decode=True)) + def test_handles_binary_utf8_decodable(self): + blob = b'\x32\x32' + msg = ud.convert_string(blob) + self.assertEqual(blob, msg.get_payload(decode=True)) + def test_handle_headers(self): text = "hi mom" msg = ud.convert_string(text) -- cgit v1.2.1 From 65f611905dbf8690aeda355eafb4c431be96126e Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Mon, 27 Jun 2016 16:18:25 -0400 Subject: fix restoring from a datasource that did not have dsmode On upgrade and reboot, if datasource restored from obj.pkl did not have a dsmode attribute, then 'init --local' would fail due to stack trace. --- cloudinit/sources/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py index 2a6b8d90..87b8e524 100644 --- a/cloudinit/sources/__init__.py +++ b/cloudinit/sources/__init__.py @@ -55,6 +55,8 @@ class DataSourceNotFoundException(Exception): @six.add_metaclass(abc.ABCMeta) class DataSource(object): + dsmode = DSMODE_NETWORK + def __init__(self, sys_cfg, distro, paths, ud_proc=None): self.sys_cfg = sys_cfg self.distro = distro @@ -64,7 +66,6 @@ class DataSource(object): self.userdata_raw = None self.vendordata = None self.vendordata_raw = None - self.dsmode = DSMODE_NETWORK # find the datasource config name. # remove 'DataSource' from classname on front, and remove 'Net' on end. -- cgit v1.2.1 From d56b4668ec9d632089cb7c02f259f84b288e3adf Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Tue, 28 Jun 2016 11:52:09 -0400 Subject: distros/debian.py: fix calling of eni renderer to not render link files Under revno 1243 a failed attempt was made to not render systemd.link files into /etc/systemd/network/ . The 'config' that was passed in was incorrect though, and resulted in link files still getting rendered. (original bug was LP: #1594546). --- cloudinit/distros/debian.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cloudinit/distros/debian.py b/cloudinit/distros/debian.py index 5ae9a509..f9b3b92e 100644 --- a/cloudinit/distros/debian.py +++ b/cloudinit/distros/debian.py @@ -55,7 +55,6 @@ class Distro(distros.Distro): hostname_conf_fn = "/etc/hostname" locale_conf_fn = "/etc/default/locale" network_conf_fn = "/etc/network/interfaces.d/50-cloud-init.cfg" - links_prefix = "/etc/systemd/network/50-cloud-init-" def __init__(self, name, cfg, paths): distros.Distro.__init__(self, name, cfg, paths) @@ -67,7 +66,7 @@ class Distro(distros.Distro): self._net_renderer = eni.Renderer({ 'eni_path': self.network_conf_fn, 'eni_header': ENI_HEADER, - 'links_prefix_path': None, + 'links_path_prefix': None, 'netrules_path': None, }) -- cgit v1.2.1