From 2c6f367035bd09978d0fbf8c959d03210e421a9b Mon Sep 17 00:00:00 2001 From: James Nzomo Date: Mon, 4 Jan 2016 16:09:29 +0300 Subject: [PATCH] Fix upload to pseudo-dir passed by arg This fix makes it possible to upload objects to pseudo-folders by passing the upload paths via arg regardless of whether the container or folder path exist or not. Change-Id: I575e58aa12adcf71cdaa70d025a0ea5c63f46903 Closes-Bug: #1478210 Partial-Bug: #1432734 Related-Bug: #1432734 --- swiftclient/service.py | 10 +++++++++- tests/unit/test_shell.py | 20 +++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/swiftclient/service.py b/swiftclient/service.py index 8df13897..3d32fe75 100644 --- a/swiftclient/service.py +++ b/swiftclient/service.py @@ -1338,6 +1338,12 @@ class SwiftService(object): except ValueError: raise SwiftError('Segment size should be an integer value') + # Incase we have a psudeo-folder path for arg, derive + # the container name from the top path to ensure new folder creation + # and prevent spawning zero-byte objects shadowing pseudo-folders + # by name. + container_name = container.split('/', 1)[0] + # Try to create the container, just in case it doesn't exist. If this # fails, it might just be because the user doesn't have container PUT # permissions, so we'll ignore any error. If there's really a problem, @@ -1349,7 +1355,9 @@ class SwiftService(object): _header[POLICY] create_containers = [ self.thread_manager.container_pool.submit( - self._create_container_job, container, headers=policy_header + self._create_container_job, + container_name, + headers=policy_header ) ] diff --git a/tests/unit/test_shell.py b/tests/unit/test_shell.py index f962c636..662fbcc7 100644 --- a/tests/unit/test_shell.py +++ b/tests/unit/test_shell.py @@ -463,7 +463,7 @@ class TestShell(testtools.TestCase): swiftclient.shell.main(argv) connection.return_value.put_container.assert_called_once_with( 'container', - {'X-Storage-Policy': mock.ANY}, + {'X-Storage-Policy': 'one'}, response_dict={}) connection.return_value.put_object.assert_called_with( @@ -475,6 +475,24 @@ class TestShell(testtools.TestCase): 'X-Storage-Policy': 'one'}, response_dict={}) + # upload to pseudo-folder (via param) + argv = ["", "upload", "container/pseudo-folder/nested", self.tmpfile, + "-H", "X-Storage-Policy:one"] + swiftclient.shell.main(argv) + connection.return_value.put_container.assert_called_with( + 'container', + {'X-Storage-Policy': 'one'}, + response_dict={}) + + connection.return_value.put_object.assert_called_with( + 'container/pseudo-folder/nested', + self.tmpfile.lstrip('/'), + mock.ANY, + content_length=0, + headers={'x-object-meta-mtime': mock.ANY, + 'X-Storage-Policy': 'one'}, + response_dict={}) + # Upload whole directory argv = ["", "upload", "container", "/tmp"] _tmpfile = self.tmpfile