From 16be8bae3574b4ab331da7d66a3b1bac6737c19c Mon Sep 17 00:00:00 2001 From: huangtianhua Date: Mon, 21 Nov 2016 16:09:50 +0800 Subject: [PATCH] Do not set the mime-type for userdata We set the mime-type to 'x-shellscript' for all single userdata when user_data_format='SOFTWARE_CONFIG', it's incorrect, for example, if user create a server with a cloud-config userdata, we will set the mime-type to 'x-shellscript', then cloud-init will consume the userdata as a shellscript and fail to execute. This change will improve this by not setting the mime-type and letting cloud-init figure it out from the first line in the file. Closes-Bug: #1643739 Change-Id: If026884a95c58bb81a0f04ab415909011b1a5414 --- heat/engine/clients/os/nova.py | 7 ++++--- .../scenario/templates/test_server_signal.yaml | 5 ++++- .../scenario/test_server_signal.py | 15 +++++++++++++-- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/heat/engine/clients/os/nova.py b/heat/engine/clients/os/nova.py index 3793d21035..065fd66073 100644 --- a/heat/engine/clients/os/nova.py +++ b/heat/engine/clients/os/nova.py @@ -325,7 +325,9 @@ class NovaClientPlugin(client_plugin.ClientPlugin): subtype = os.path.splitext(filename)[0] if content is None: content = '' - msg = text.MIMEText(content, _subtype=subtype) + msg = (text.MIMEText(content, _subtype=subtype) + if subtype else text.MIMEText(content)) + msg.add_header('Content-Disposition', 'attachment', filename=filename) return msg @@ -359,7 +361,6 @@ echo -e '%s\tALL=(ALL)\tNOPASSWD: ALL' >> /etc/sudoers (cloudinit_boothook, 'boothook.sh', 'cloud-boothook'), (read_cloudinit_file('part_handler.py'), 'part-handler.py')] - if is_cfntools: attachments.append((userdata, 'cfn-userdata', 'x-cfninitdata')) elif is_software_config: @@ -376,7 +377,7 @@ echo -e '%s\tALL=(ALL)\tNOPASSWD: ALL' >> /etc/sudoers part.get_filename(), part.get_content_subtype())) else: - attachments.append((userdata, 'userdata', 'x-shellscript')) + attachments.append((userdata, '')) if is_cfntools: attachments.append((read_cloudinit_file('loguserdata.py'), diff --git a/heat_integrationtests/scenario/templates/test_server_signal.yaml b/heat_integrationtests/scenario/templates/test_server_signal.yaml index dfb1155e99..4466a5ea1e 100644 --- a/heat_integrationtests/scenario/templates/test_server_signal.yaml +++ b/heat_integrationtests/scenario/templates/test_server_signal.yaml @@ -23,6 +23,9 @@ parameters: dns_servers: type: comma_delimited_list default: ["8.8.8.8", "8.8.4.4"] + user_data_format: + type: string + default: RAW resources: sg: type: OS::Neutron::SecurityGroup @@ -76,7 +79,7 @@ resources: - subnet: {get_resource: subnet} security_groups: - {get_resource: sg} - user_data_format: RAW + user_data_format: {get_param: user_data_format} user_data: str_replace: template: | diff --git a/heat_integrationtests/scenario/test_server_signal.py b/heat_integrationtests/scenario/test_server_signal.py index 4567e43df6..b2085e2deb 100644 --- a/heat_integrationtests/scenario/test_server_signal.py +++ b/heat_integrationtests/scenario/test_server_signal.py @@ -20,13 +20,15 @@ from heat_integrationtests.scenario import scenario_base class ServerSignalIntegrationTest(scenario_base.ScenarioTestsBase): """Test a server in a created network can signal to heat.""" - def test_server_signal(self): + def _test_server_signal(self, user_data_format='RAW', + image=None): """Check a server in a created network can signal to heat.""" parameters = { 'key_name': self.keypair_name, 'flavor': self.conf.minimal_instance_type, - 'image': self.conf.minimal_image_ref, + 'image': image, 'timeout': self.conf.build_timeout, + 'user_data_format': user_data_format } # Launch stack @@ -72,3 +74,12 @@ class ServerSignalIntegrationTest(scenario_base.ScenarioTestsBase): self._log_console_output(servers=[server]) self.fail( "Timed out waiting for %s to become reachable" % server_ip) + + def test_server_signal_userdata_format_raw(self): + self._test_server_signal(image=self.conf.minimal_image_ref) + + def test_server_signal_userdata_format_software_config(self): + if not self.conf.image_ref: + raise self.skipException("No image configured to test") + self._test_server_signal(user_data_format='SOFTWARE_CONFIG', + image=self.conf.image_ref)