Merge "Allow Pure drivers to handle detach with no host"
This commit is contained in:
commit
bbf2116abe
@ -206,7 +206,8 @@ class VolumeDriverCore(base.CinderInterface):
|
|||||||
|
|
||||||
:param volume: The volume to remove.
|
:param volume: The volume to remove.
|
||||||
:param connector: The Dictionary containing information about the
|
:param connector: The Dictionary containing information about the
|
||||||
connection.
|
connection. This is optional when doing a
|
||||||
|
force-detach and can be None.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def detach_volume(self, context, volume, attachment=None):
|
def detach_volume(self, context, volume, attachment=None):
|
||||||
|
@ -967,6 +967,27 @@ class PureBaseVolumeDriverTestCase(PureBaseSharedDriverTestCase):
|
|||||||
'Host cannot be deleted due to existing connections.'
|
'Host cannot be deleted due to existing connections.'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_terminate_connection_no_connector_with_host(self):
|
||||||
|
# Show the volume having a connection
|
||||||
|
self.array.list_volume_private_connections.return_value = \
|
||||||
|
[VOLUME_CONNECTIONS[0]]
|
||||||
|
|
||||||
|
self.driver.terminate_connection(VOLUME, None)
|
||||||
|
self.array.disconnect_host.assert_called_with(
|
||||||
|
VOLUME_CONNECTIONS[0]["host"],
|
||||||
|
VOLUME_CONNECTIONS[0]["name"]
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_terminate_connection_no_connector_no_host(self):
|
||||||
|
vol = fake_volume.fake_volume_obj(None, name=VOLUME["name"])
|
||||||
|
|
||||||
|
# Show the volume having a connection
|
||||||
|
self.array.list_volume_private_connections.return_value = []
|
||||||
|
|
||||||
|
# Make sure
|
||||||
|
self.driver.terminate_connection(vol, None)
|
||||||
|
self.array.disconnect_host.assert_not_called()
|
||||||
|
|
||||||
def test_extend_volume(self):
|
def test_extend_volume(self):
|
||||||
vol_name = VOLUME["name"] + "-cinder"
|
vol_name = VOLUME["name"] + "-cinder"
|
||||||
self.driver.extend_volume(VOLUME, 3)
|
self.driver.extend_volume(VOLUME, 3)
|
||||||
|
@ -1367,7 +1367,12 @@ class BaseVD(object):
|
|||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def terminate_connection(self, volume, connector, **kwargs):
|
def terminate_connection(self, volume, connector, **kwargs):
|
||||||
"""Disallow connection from connector."""
|
"""Disallow connection from connector.
|
||||||
|
|
||||||
|
:param volume: The volume to be disconnected.
|
||||||
|
:param connector: A dictionary describing the connection with details
|
||||||
|
about the initiator. Can be None.
|
||||||
|
"""
|
||||||
return
|
return
|
||||||
|
|
||||||
def terminate_connection_snapshot(self, snapshot, connector, **kwargs):
|
def terminate_connection_snapshot(self, snapshot, connector, **kwargs):
|
||||||
@ -2101,7 +2106,12 @@ class VolumeDriver(ManageableVD, CloneableImageVD, ManageableSnapshotsVD,
|
|||||||
"""Allow connection from connector for a snapshot."""
|
"""Allow connection from connector for a snapshot."""
|
||||||
|
|
||||||
def terminate_connection(self, volume, connector, **kwargs):
|
def terminate_connection(self, volume, connector, **kwargs):
|
||||||
"""Disallow connection from connector"""
|
"""Disallow connection from connector
|
||||||
|
|
||||||
|
:param volume: The volume to be disconnected.
|
||||||
|
:param connector: A dictionary describing the connection with details
|
||||||
|
about the initiator. Can be None.
|
||||||
|
"""
|
||||||
|
|
||||||
def terminate_connection_snapshot(self, snapshot, connector, **kwargs):
|
def terminate_connection_snapshot(self, snapshot, connector, **kwargs):
|
||||||
"""Disallow connection from connector for a snapshot."""
|
"""Disallow connection from connector for a snapshot."""
|
||||||
|
@ -428,17 +428,33 @@ class PureBaseVolumeDriver(san.SanDriver):
|
|||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def _disconnect(self, array, volume, connector, **kwargs):
|
def _disconnect(self, array, volume, connector, **kwargs):
|
||||||
vol_name = self._get_vol_name(volume)
|
"""Disconnect the volume from the host described by the connector.
|
||||||
host = self._get_host(array, connector)
|
|
||||||
if host:
|
|
||||||
host_name = host["name"]
|
|
||||||
result = self._disconnect_host(array, host_name, vol_name)
|
|
||||||
else:
|
|
||||||
LOG.error("Unable to disconnect host from volume, could not "
|
|
||||||
"determine Purity host")
|
|
||||||
result = False
|
|
||||||
|
|
||||||
return result
|
If no connector is specified it will remove *all* attachments for
|
||||||
|
the volume.
|
||||||
|
|
||||||
|
Returns True if it was the hosts last connection.
|
||||||
|
"""
|
||||||
|
vol_name = self._get_vol_name(volume)
|
||||||
|
if connector is None:
|
||||||
|
# If no connector was provided it is a force-detach, remove all
|
||||||
|
# host connections for the volume
|
||||||
|
LOG.warning("Removing ALL host connections for volume %s",
|
||||||
|
vol_name)
|
||||||
|
connections = array.list_volume_private_connections(vol_name)
|
||||||
|
for connection in connections:
|
||||||
|
self._disconnect_host(array, connection['host'], vol_name)
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
# Normal case with a specific initiator to detach it from
|
||||||
|
host = self._get_host(array, connector)
|
||||||
|
if host:
|
||||||
|
host_name = host["name"]
|
||||||
|
return self._disconnect_host(array, host_name, vol_name)
|
||||||
|
else:
|
||||||
|
LOG.error("Unable to disconnect host from volume, could not "
|
||||||
|
"determine Purity host")
|
||||||
|
return False
|
||||||
|
|
||||||
@pure_driver_debug_trace
|
@pure_driver_debug_trace
|
||||||
def terminate_connection(self, volume, connector, **kwargs):
|
def terminate_connection(self, volume, connector, **kwargs):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user