From 6edf269725f5539c57e134020baf59bc3722e810 Mon Sep 17 00:00:00 2001 From: Allard Hoeve Date: Fri, 16 Sep 2016 17:17:19 +0200 Subject: [PATCH] Create volume is more robust on newer OpenStacks --- CHANGES.rst | 12 ++++++++++++ libcloud/compute/drivers/openstack.py | 8 ++++++-- libcloud/test/compute/test_openstack.py | 24 ++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 671085ecee..b9a8212c85 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,18 @@ Changelog ========= +Changes in Apache Libcloud 1.2.2 + +Compute +~~~~~~~ + +- When creating volumes on OpenStack with defaults for `location` or `volume_type`, + newer OpenStack versions would throw errors. The OpenStack driver will now only + post those arguments if non-`NoneType`. + (GITHUB-857) + [Allard Hoeve] + + Changes in Apache Libcloud 1.2.1 -------------------------------- diff --git a/libcloud/compute/drivers/openstack.py b/libcloud/compute/drivers/openstack.py index 1fa34798b3..88622d29c4 100644 --- a/libcloud/compute/drivers/openstack.py +++ b/libcloud/compute/drivers/openstack.py @@ -206,13 +206,17 @@ def create_volume(self, size, name, location=None, snapshot=None, 'display_name': name, 'display_description': name, 'size': size, - 'volume_type': ex_volume_type, 'metadata': { 'contents': name, }, - 'availability_zone': location } + if ex_volume_type: + volume['volume_type'] = ex_volume_type + + if location: + volume['availability_zone'] = location + if snapshot: volume['snapshot_id'] = snapshot.id diff --git a/libcloud/test/compute/test_openstack.py b/libcloud/test/compute/test_openstack.py index 1d7049e1ff..1a0cdabc54 100644 --- a/libcloud/test/compute/test_openstack.py +++ b/libcloud/test/compute/test_openstack.py @@ -984,6 +984,30 @@ def test_create_volume(self): self.assertEqual(volume.name, 'test') self.assertEqual(volume.size, 1) + def test_create_volume_passes_location_to_request_only_if_not_none(self): + with patch.object(self.driver.connection, 'request') as mock_request: + self.driver.create_volume(1, 'test', location='mylocation') + name, args, kwargs = mock_request.mock_calls[0] + self.assertEqual(kwargs["data"]["volume"]["availability_zone"], "mylocation") + + def test_create_volume_does_not_pass_location_to_request_if_none(self): + with patch.object(self.driver.connection, 'request') as mock_request: + self.driver.create_volume(1, 'test') + name, args, kwargs = mock_request.mock_calls[0] + self.assertFalse("availability_zone" in kwargs["data"]["volume"]) + + def test_create_volume_passes_volume_type_to_request_only_if_not_none(self): + with patch.object(self.driver.connection, 'request') as mock_request: + self.driver.create_volume(1, 'test', ex_volume_type='myvolumetype') + name, args, kwargs = mock_request.mock_calls[0] + self.assertEqual(kwargs["data"]["volume"]["volume_type"], "myvolumetype") + + def test_create_volume_does_not_pass_volume_type_to_request_if_none(self): + with patch.object(self.driver.connection, 'request') as mock_request: + self.driver.create_volume(1, 'test') + name, args, kwargs = mock_request.mock_calls[0] + self.assertFalse("volume_type" in kwargs["data"]["volume"]) + def test_destroy_volume(self): volume = self.driver.ex_get_volume( 'cd76a3a1-c4ce-40f6-9b9f-07a61508938d')