From: Anthony Lee Date: Thu, 25 Sep 2014 12:10:05 +0000 (-0700) Subject: Fixed server name being retained after detach in LeftHand X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=891aa3c6024bc68a2434a24244b66b3dc9942bb3;p=openstack-build%2Fcinder-build.git Fixed server name being retained after detach in LeftHand There was an issue with the LeftHand driver where the initiator names of servers were not being removed when the last volume attached to that server was detached. This fix will now remove the server from the LeftHand backend when no more volumes are attached to it. Closes-Bug: #1353137 Change-Id: I58be39d14979e1d3966232095cb49693c1424f8a --- diff --git a/cinder/tests/test_hplefthand.py b/cinder/tests/test_hplefthand.py index 029436fd2..564dbdeb4 100644 --- a/cinder/tests/test_hplefthand.py +++ b/cinder/tests/test_hplefthand.py @@ -981,7 +981,10 @@ class TestHPLeftHandRESTISCSIDriver(HPLeftHandBaseDriver, test.TestCase): mock_client = self.setup_driver() mock_client.getVolumeByName.return_value = {'id': self.volume_id} - mock_client.getServerByName.return_value = {'id': self.server_id} + mock_client.getServerByName.return_value = { + 'id': self.server_id, + 'name': self.serverName} + mock_client.findServerVolumes.return_value = [{'id': self.volume_id}] with mock.patch.object(hp_lefthand_rest_proxy.HPLeftHandRESTProxy, '_create_client') as mock_do_setup: @@ -993,14 +996,55 @@ class TestHPLeftHandRESTISCSIDriver(HPLeftHandBaseDriver, test.TestCase): expected = self.driver_startup_call_stack + [ mock.call.getVolumeByName('fakevolume'), mock.call.getServerByName('fakehost'), + mock.call.findServerVolumes('fakehost'), mock.call.removeServerAccess(1, 0), - mock.call.logout()] + mock.call.deleteServer(0)] # validate call chain mock_client.assert_has_calls(expected) - mock_client.getVolumeByName.side_effect =\ - hpexceptions.HTTPNotFound() + mock_client.getVolumeByName.side_effect = ( + hpexceptions.HTTPNotFound()) + # ensure the raised exception is a cinder exception + self.assertRaises( + exception.VolumeBackendAPIException, + self.driver.terminate_connection, + self.volume, + self.connector) + + def test_terminate_connection_multiple_volumes_on_server(self): + + # setup drive with default configuration + # and return the mock HTTP LeftHand client + mock_client = self.setup_driver() + + mock_client.getVolumeByName.return_value = {'id': self.volume_id} + mock_client.getServerByName.return_value = { + 'id': self.server_id, + 'name': self.serverName} + mock_client.findServerVolumes.return_value = [ + {'id': self.volume_id}, + {'id': 99999}] + + with mock.patch.object(hp_lefthand_rest_proxy.HPLeftHandRESTProxy, + '_create_client') as mock_do_setup: + mock_do_setup.return_value = mock_client + + # execute terminate_connection + self.driver.terminate_connection(self.volume, self.connector) + + expected = self.driver_startup_call_stack + [ + mock.call.getVolumeByName('fakevolume'), + mock.call.getServerByName('fakehost'), + mock.call.findServerVolumes('fakehost'), + mock.call.removeServerAccess(1, 0)] + + # validate call chain + mock_client.assert_has_calls(expected) + self.assertFalse(mock_client.deleteServer.called) + + mock_client.getVolumeByName.side_effect = ( + hpexceptions.HTTPNotFound()) # ensure the raised exception is a cinder exception self.assertRaises( exception.VolumeBackendAPIException, diff --git a/cinder/volume/drivers/san/hp/hp_lefthand_rest_proxy.py b/cinder/volume/drivers/san/hp/hp_lefthand_rest_proxy.py index f295d8255..6387bfa7f 100644 --- a/cinder/volume/drivers/san/hp/hp_lefthand_rest_proxy.py +++ b/cinder/volume/drivers/san/hp/hp_lefthand_rest_proxy.py @@ -94,9 +94,11 @@ class HPLeftHandRESTProxy(ISCSIDriver): 1.0.5 - Fixed bug #1311350, Live-migration of an instance when attached to a volume was causing an error. 1.0.6 - Removing locks bug #1395953 + 1.0.7 - Fixed bug #1353137, Server was not removed from the HP + Lefthand backend after the last volume was detached. """ - VERSION = "1.0.6" + VERSION = "1.0.7" device_stats = {} @@ -338,9 +340,20 @@ class HPLeftHandRESTProxy(ISCSIDriver): try: volume_info = client.getVolumeByName(volume['name']) server_info = client.getServerByName(connector['host']) + volume_list = client.findServerVolumes(server_info['name']) + + removeServer = True + for entry in volume_list: + if entry['id'] != volume_info['id']: + removeServer = False + break + client.removeServerAccess( volume_info['id'], server_info['id']) + + if removeServer: + client.deleteServer(server_info['id']) except Exception as ex: raise exception.VolumeBackendAPIException(ex) finally: