From 77c30189abe53326d99241a465b702ad7eed6b03 Mon Sep 17 00:00:00 2001 From: Ken'ichi Ohmichi Date: Thu, 31 Jan 2013 22:05:14 +0900 Subject: Fix inject_files for storing binary file. Now a nova-api server decodes injected_files by base64 after receiving encoded files from nova-client. And the server fails to publish run_instance because utf8 codec can't decode due to binary data. This patch fixes this problem, because the base64 decode is operated when a nova-compute server receives injected_files from a nova-api server. Fixes bug 1112134 Change-Id: I664134c74893a970de4464161071692a5b2b5ce7 --- nova/api/openstack/compute/servers.py | 3 +-- nova/compute/manager.py | 4 ++++ nova/tests/integrated/test_servers.py | 41 +++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/nova/api/openstack/compute/servers.py b/nova/api/openstack/compute/servers.py index bf3f4cacc..723997eba 100644 --- a/nova/api/openstack/compute/servers.py +++ b/nova/api/openstack/compute/servers.py @@ -605,8 +605,7 @@ class Controller(wsgi.Controller): except TypeError: expl = _('Bad personality format') raise exc.HTTPBadRequest(explanation=expl) - contents = self._decode_base64(contents) - if contents is None: + if self._decode_base64(contents) is None: expl = _('Personality content for %s cannot be decoded') % path raise exc.HTTPBadRequest(explanation=expl) injected_files.append((path, contents)) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 605ebab6c..60d72e565 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -27,6 +27,7 @@ terminating it. """ +import base64 import contextlib import functools import socket @@ -1069,6 +1070,9 @@ class ComputeManager(manager.SchedulerDependentManager): filter_properties = {} if injected_files is None: injected_files = [] + else: + injected_files = [(path, base64.b64decode(contents)) + for path, contents in injected_files] @lockutils.synchronized(instance['uuid'], 'nova-') def do_run_instance(): diff --git a/nova/tests/integrated/test_servers.py b/nova/tests/integrated/test_servers.py index 0756775dd..b70db93f2 100644 --- a/nova/tests/integrated/test_servers.py +++ b/nova/tests/integrated/test_servers.py @@ -16,6 +16,7 @@ # under the License. import time +import zlib from nova.openstack.common.log import logging from nova.tests import fake_network @@ -437,3 +438,43 @@ class ServersTest(integrated_helpers._IntegratedTestBase): self._delete_server(created_server_id) for server_id in server_map.iterkeys(): self._delete_server(server_id) + + def test_create_server_with_injected_files(self): + # Creates a server with injected_files. + fake_network.set_stub_network_methods(self.stubs) + personality = [] + + # Inject a text file + data = 'Hello, World!' + personality.append({ + 'path': '/helloworld.txt', + 'contents': data.encode('base64'), + }) + + # Inject a binary file + data = zlib.compress('Hello, World!') + personality.append({ + 'path': '/helloworld.zip', + 'contents': data.encode('base64'), + }) + + # Create server + server = self._build_minimal_create_server_request() + server['personality'] = personality + + post = {'server': server} + + created_server = self.api.post_server(post) + LOG.debug("created_server: %s" % created_server) + self.assertTrue(created_server['id']) + created_server_id = created_server['id'] + + # Check it's there + found_server = self.api.get_server(created_server_id) + self.assertEqual(created_server_id, found_server['id']) + + found_server = self._wait_for_state_change(found_server, 'BUILD') + self.assertEqual('ACTIVE', found_server['status']) + + # Cleanup + self._delete_server(created_server_id) -- cgit