Revert "Relocate volume to compliant datastore"
Commit4be8913520
introduced a regression which causes failures during cinder volume re-attach. This patch reverts commit4be8913520
as an immediate fix. Closes-Bug: #1379830 Change-Id: I5dfbd45533489c3c81db8d256bbfd2f85614a357 (cherry picked from commit48cb82971e
)
This commit is contained in:
parent
07531e75b1
commit
01e7c51685
@ -375,97 +375,30 @@ class VMwareEsxVmdkDriverTestCase(test.TestCase):
|
||||
m.UnsetStubs()
|
||||
m.VerifyAll()
|
||||
|
||||
@mock.patch.object(VMDK_DRIVER, 'volumeops')
|
||||
@mock.patch.object(VMDK_DRIVER, '_relocate_backing')
|
||||
@mock.patch.object(VMDK_DRIVER, '_create_backing')
|
||||
def test_initialize_connection_with_instance_and_backing(
|
||||
self, create_backing, relocate_backing, vops):
|
||||
self._test_initialize_connection_with_instance_and_backing(
|
||||
create_backing, relocate_backing, vops)
|
||||
def test_init_conn_with_instance_and_backing(self):
|
||||
"""Test initialize_connection with instance and backing."""
|
||||
m = self.mox
|
||||
m.StubOutWithMock(self._driver.__class__, 'volumeops')
|
||||
self._driver.volumeops = self._volumeops
|
||||
m.StubOutWithMock(self._volumeops, 'get_backing')
|
||||
volume = FakeObject()
|
||||
volume['name'] = 'volume_name'
|
||||
volume['id'] = 'volume_id'
|
||||
volume['size'] = 1
|
||||
connector = {'instance': 'my_instance'}
|
||||
backing = FakeMor('VirtualMachine', 'my_back')
|
||||
self._volumeops.get_backing(volume['name']).AndReturn(backing)
|
||||
m.StubOutWithMock(self._volumeops, 'get_host')
|
||||
host = FakeMor('HostSystem', 'my_host')
|
||||
self._volumeops.get_host(mox.IgnoreArg()).AndReturn(host)
|
||||
|
||||
def _test_initialize_connection_with_instance_and_backing(
|
||||
self, create_backing, relocate_backing, vops):
|
||||
instance = mock.sentinel.instance
|
||||
connector = {'instance': instance}
|
||||
|
||||
backing = mock.Mock(value=mock.sentinel.backing_value)
|
||||
vops.get_backing.return_value = backing
|
||||
|
||||
host = mock.sentinel.host
|
||||
vops.get_host.return_value = host
|
||||
|
||||
volume = {'name': 'vol-1', 'id': 1}
|
||||
m.ReplayAll()
|
||||
conn_info = self._driver.initialize_connection(volume, connector)
|
||||
|
||||
relocate_backing.assert_called_once_with(volume, backing, host)
|
||||
self.assertFalse(create_backing.called)
|
||||
|
||||
self.assertEqual('vmdk', conn_info['driver_volume_type'])
|
||||
self.assertEqual(backing.value, conn_info['data']['volume'])
|
||||
self.assertEqual(volume['id'],
|
||||
conn_info['data']['volume_id'])
|
||||
|
||||
@mock.patch.object(VMDK_DRIVER, 'volumeops')
|
||||
@mock.patch.object(VMDK_DRIVER, '_relocate_backing')
|
||||
@mock.patch.object(VMDK_DRIVER, '_create_backing')
|
||||
def test_initialize_connection_with_instance_and_no_backing(
|
||||
self, create_backing, relocate_backing, vops):
|
||||
self._test_initialize_connection_with_instance_and_no_backing(
|
||||
create_backing, relocate_backing, vops)
|
||||
|
||||
def _test_initialize_connection_with_instance_and_no_backing(
|
||||
self, create_backing, relocate_backing, vops):
|
||||
instance = mock.sentinel.instance
|
||||
connector = {'instance': instance}
|
||||
|
||||
vops.get_backing.return_value = None
|
||||
|
||||
host = mock.sentinel.host
|
||||
vops.get_host.return_value = host
|
||||
|
||||
backing = mock.Mock(value=mock.sentinel.backing_value)
|
||||
create_backing.return_value = backing
|
||||
|
||||
volume = {'name': 'vol-1', 'id': 1}
|
||||
conn_info = self._driver.initialize_connection(volume, connector)
|
||||
|
||||
create_backing.assert_called_once_with(volume, host)
|
||||
self.assertFalse(relocate_backing.called)
|
||||
|
||||
self.assertEqual('vmdk', conn_info['driver_volume_type'])
|
||||
self.assertEqual(backing.value, conn_info['data']['volume'])
|
||||
self.assertEqual(volume['id'],
|
||||
conn_info['data']['volume_id'])
|
||||
|
||||
@mock.patch.object(VMDK_DRIVER, 'volumeops')
|
||||
@mock.patch.object(VMDK_DRIVER, '_relocate_backing')
|
||||
@mock.patch.object(VMDK_DRIVER, '_create_backing_in_inventory')
|
||||
def test_initialize_connection_with_no_instance_and_no_backing(
|
||||
self, create_backing_in_inventory, relocate_backing, vops):
|
||||
self._test_initialize_connection_with_no_instance_and_no_backing(
|
||||
create_backing_in_inventory, relocate_backing, vops)
|
||||
|
||||
def _test_initialize_connection_with_no_instance_and_no_backing(
|
||||
self, create_backing_in_inventory, relocate_backing, vops):
|
||||
vops.get_backing.return_value = None
|
||||
|
||||
host = mock.sentinel.host
|
||||
vops.get_host.return_value = host
|
||||
|
||||
backing = mock.Mock(value=mock.sentinel.backing_value)
|
||||
create_backing_in_inventory.return_value = backing
|
||||
|
||||
connector = {}
|
||||
volume = {'name': 'vol-1', 'id': 1}
|
||||
conn_info = self._driver.initialize_connection(volume, connector)
|
||||
|
||||
create_backing_in_inventory.assert_called_once_with(volume)
|
||||
self.assertFalse(relocate_backing.called)
|
||||
|
||||
self.assertEqual('vmdk', conn_info['driver_volume_type'])
|
||||
self.assertEqual(backing.value, conn_info['data']['volume'])
|
||||
self.assertEqual(volume['id'],
|
||||
conn_info['data']['volume_id'])
|
||||
self.assertEqual(conn_info['driver_volume_type'], 'vmdk')
|
||||
self.assertEqual(conn_info['data']['volume'], 'my_back')
|
||||
self.assertEqual(conn_info['data']['volume_id'], 'volume_id')
|
||||
m.UnsetStubs()
|
||||
m.VerifyAll()
|
||||
|
||||
def test_get_volume_group_folder(self):
|
||||
"""Test _get_volume_group_folder."""
|
||||
@ -596,6 +529,71 @@ class VMwareEsxVmdkDriverTestCase(test.TestCase):
|
||||
vmdk.VMwareEsxVmdkDriver._get_disk_type,
|
||||
volume)
|
||||
|
||||
def test_init_conn_with_instance_no_backing(self):
|
||||
"""Test initialize_connection with instance and without backing."""
|
||||
m = self.mox
|
||||
m.StubOutWithMock(self._driver.__class__, 'volumeops')
|
||||
self._driver.volumeops = self._volumeops
|
||||
m.StubOutWithMock(self._volumeops, 'get_backing')
|
||||
volume = FakeObject()
|
||||
volume['name'] = 'volume_name'
|
||||
volume['id'] = 'volume_id'
|
||||
volume['size'] = 1
|
||||
volume['volume_type_id'] = None
|
||||
connector = {'instance': 'my_instance'}
|
||||
self._volumeops.get_backing(volume['name'])
|
||||
m.StubOutWithMock(self._volumeops, 'get_host')
|
||||
host = FakeMor('HostSystem', 'my_host')
|
||||
self._volumeops.get_host(mox.IgnoreArg()).AndReturn(host)
|
||||
m.StubOutWithMock(self._volumeops, 'get_dss_rp')
|
||||
resource_pool = FakeMor('ResourcePool', 'my_rp')
|
||||
datastores = [FakeMor('Datastore', 'my_ds')]
|
||||
self._volumeops.get_dss_rp(host).AndReturn((datastores, resource_pool))
|
||||
m.StubOutWithMock(self._driver, '_get_folder_ds_summary')
|
||||
folder = FakeMor('Folder', 'my_fol')
|
||||
summary = FakeDatastoreSummary(1, 1)
|
||||
self._driver._get_folder_ds_summary(volume, resource_pool,
|
||||
datastores).AndReturn((folder,
|
||||
summary))
|
||||
backing = FakeMor('VirtualMachine', 'my_back')
|
||||
m.StubOutWithMock(self._volumeops, 'create_backing')
|
||||
self._volumeops.create_backing(volume['name'],
|
||||
volume['size'] * units.Mi,
|
||||
mox.IgnoreArg(), folder,
|
||||
resource_pool, host,
|
||||
mox.IgnoreArg(),
|
||||
mox.IgnoreArg(),
|
||||
mox.IgnoreArg()).AndReturn(backing)
|
||||
|
||||
m.ReplayAll()
|
||||
conn_info = self._driver.initialize_connection(volume, connector)
|
||||
self.assertEqual(conn_info['driver_volume_type'], 'vmdk')
|
||||
self.assertEqual(conn_info['data']['volume'], 'my_back')
|
||||
self.assertEqual(conn_info['data']['volume_id'], 'volume_id')
|
||||
m.UnsetStubs()
|
||||
m.VerifyAll()
|
||||
|
||||
def test_init_conn_without_instance(self):
|
||||
"""Test initialize_connection without instance and a backing."""
|
||||
m = self.mox
|
||||
m.StubOutWithMock(self._driver.__class__, 'volumeops')
|
||||
self._driver.volumeops = self._volumeops
|
||||
m.StubOutWithMock(self._volumeops, 'get_backing')
|
||||
backing = FakeMor('VirtualMachine', 'my_back')
|
||||
volume = FakeObject()
|
||||
volume['name'] = 'volume_name'
|
||||
volume['id'] = 'volume_id'
|
||||
connector = {}
|
||||
self._volumeops.get_backing(volume['name']).AndReturn(backing)
|
||||
|
||||
m.ReplayAll()
|
||||
conn_info = self._driver.initialize_connection(volume, connector)
|
||||
self.assertEqual(conn_info['driver_volume_type'], 'vmdk')
|
||||
self.assertEqual(conn_info['data']['volume'], 'my_back')
|
||||
self.assertEqual(conn_info['data']['volume_id'], 'volume_id')
|
||||
m.UnsetStubs()
|
||||
m.VerifyAll()
|
||||
|
||||
def test_create_snapshot_without_backing(self):
|
||||
"""Test vmdk.create_snapshot without backing."""
|
||||
m = self.mox
|
||||
@ -2005,29 +2003,37 @@ class VMwareVcVmdkDriverTestCase(VMwareEsxVmdkDriverTestCase):
|
||||
self._test_create_backing_by_copying(volumeops, create_backing,
|
||||
extend_virtual_disk)
|
||||
|
||||
@mock.patch.object(VMDK_DRIVER, 'volumeops')
|
||||
@mock.patch.object(VMDK_DRIVER, '_relocate_backing')
|
||||
@mock.patch.object(VMDK_DRIVER, '_create_backing')
|
||||
def test_initialize_connection_with_instance_and_backing(
|
||||
self, create_backing, relocate_backing, vops):
|
||||
self._test_initialize_connection_with_instance_and_backing(
|
||||
create_backing, relocate_backing, vops)
|
||||
def test_init_conn_with_instance_and_backing(self):
|
||||
"""Test initialize_connection with instance and backing."""
|
||||
m = self.mox
|
||||
m.StubOutWithMock(self._driver.__class__, 'volumeops')
|
||||
self._driver.volumeops = self._volumeops
|
||||
m.StubOutWithMock(self._volumeops, 'get_backing')
|
||||
volume = FakeObject()
|
||||
volume['name'] = 'volume_name'
|
||||
volume['id'] = 'volume_id'
|
||||
volume['size'] = 1
|
||||
connector = {'instance': 'my_instance'}
|
||||
backing = FakeMor('VirtualMachine', 'my_back')
|
||||
self._volumeops.get_backing(volume['name']).AndReturn(backing)
|
||||
m.StubOutWithMock(self._volumeops, 'get_host')
|
||||
host = FakeMor('HostSystem', 'my_host')
|
||||
self._volumeops.get_host(mox.IgnoreArg()).AndReturn(host)
|
||||
datastore = FakeMor('Datastore', 'my_ds')
|
||||
resource_pool = FakeMor('ResourcePool', 'my_rp')
|
||||
m.StubOutWithMock(self._volumeops, 'get_dss_rp')
|
||||
self._volumeops.get_dss_rp(host).AndReturn(([datastore],
|
||||
resource_pool))
|
||||
m.StubOutWithMock(self._volumeops, 'get_datastore')
|
||||
self._volumeops.get_datastore(backing).AndReturn(datastore)
|
||||
|
||||
@mock.patch.object(VMDK_DRIVER, 'volumeops')
|
||||
@mock.patch.object(VMDK_DRIVER, '_relocate_backing')
|
||||
@mock.patch.object(VMDK_DRIVER, '_create_backing')
|
||||
def test_initialize_connection_with_instance_and_no_backing(
|
||||
self, create_backing, relocate_backing, vops):
|
||||
self._test_initialize_connection_with_instance_and_no_backing(
|
||||
create_backing, relocate_backing, vops)
|
||||
|
||||
@mock.patch.object(VMDK_DRIVER, 'volumeops')
|
||||
@mock.patch.object(VMDK_DRIVER, '_relocate_backing')
|
||||
@mock.patch.object(VMDK_DRIVER, '_create_backing_in_inventory')
|
||||
def test_initialize_connection_with_no_instance_and_no_backing(
|
||||
self, create_backing_in_inventory, relocate_backing, vops):
|
||||
self._test_initialize_connection_with_no_instance_and_no_backing(
|
||||
create_backing_in_inventory, relocate_backing, vops)
|
||||
m.ReplayAll()
|
||||
conn_info = self._driver.initialize_connection(volume, connector)
|
||||
self.assertEqual(conn_info['driver_volume_type'], 'vmdk')
|
||||
self.assertEqual(conn_info['data']['volume'], 'my_back')
|
||||
self.assertEqual(conn_info['data']['volume_id'], 'volume_id')
|
||||
m.UnsetStubs()
|
||||
m.VerifyAll()
|
||||
|
||||
def test_get_volume_group_folder(self):
|
||||
"""Test _get_volume_group_folder."""
|
||||
@ -2046,6 +2052,50 @@ class VMwareVcVmdkDriverTestCase(VMwareEsxVmdkDriverTestCase):
|
||||
m.UnsetStubs()
|
||||
m.VerifyAll()
|
||||
|
||||
def test_init_conn_with_instance_and_backing_and_relocation(self):
|
||||
"""Test initialize_connection with backing being relocated."""
|
||||
m = self.mox
|
||||
m.StubOutWithMock(self._driver.__class__, 'volumeops')
|
||||
self._driver.volumeops = self._volumeops
|
||||
m.StubOutWithMock(self._volumeops, 'get_backing')
|
||||
volume = FakeObject()
|
||||
volume['name'] = 'volume_name'
|
||||
volume['id'] = 'volume_id'
|
||||
volume['size'] = 1
|
||||
connector = {'instance': 'my_instance'}
|
||||
backing = FakeMor('VirtualMachine', 'my_back')
|
||||
self._volumeops.get_backing(volume['name']).AndReturn(backing)
|
||||
m.StubOutWithMock(self._volumeops, 'get_host')
|
||||
host = FakeMor('HostSystem', 'my_host')
|
||||
self._volumeops.get_host(mox.IgnoreArg()).AndReturn(host)
|
||||
datastore1 = FakeMor('Datastore', 'my_ds_1')
|
||||
datastore2 = FakeMor('Datastore', 'my_ds_2')
|
||||
resource_pool = FakeMor('ResourcePool', 'my_rp')
|
||||
m.StubOutWithMock(self._volumeops, 'get_dss_rp')
|
||||
self._volumeops.get_dss_rp(host).AndReturn(([datastore1],
|
||||
resource_pool))
|
||||
m.StubOutWithMock(self._volumeops, 'get_datastore')
|
||||
self._volumeops.get_datastore(backing).AndReturn(datastore2)
|
||||
m.StubOutWithMock(self._driver, '_get_folder_ds_summary')
|
||||
folder = FakeMor('Folder', 'my_fol')
|
||||
summary = FakeDatastoreSummary(1, 1, datastore1)
|
||||
self._driver._get_folder_ds_summary(volume, resource_pool,
|
||||
[datastore1]).AndReturn((folder,
|
||||
summary))
|
||||
m.StubOutWithMock(self._volumeops, 'relocate_backing')
|
||||
self._volumeops.relocate_backing(backing, datastore1,
|
||||
resource_pool, host)
|
||||
m.StubOutWithMock(self._volumeops, 'move_backing_to_folder')
|
||||
self._volumeops.move_backing_to_folder(backing, folder)
|
||||
|
||||
m.ReplayAll()
|
||||
conn_info = self._driver.initialize_connection(volume, connector)
|
||||
self.assertEqual(conn_info['driver_volume_type'], 'vmdk')
|
||||
self.assertEqual(conn_info['data']['volume'], 'my_back')
|
||||
self.assertEqual(conn_info['data']['volume_id'], 'volume_id')
|
||||
m.UnsetStubs()
|
||||
m.VerifyAll()
|
||||
|
||||
@mock.patch.object(VMDK_DRIVER, '_extend_vmdk_virtual_disk')
|
||||
@mock.patch.object(VMDK_DRIVER, 'volumeops')
|
||||
def test_clone_backing_linked(self, volume_ops, _extend_vmdk_virtual_disk):
|
||||
@ -2641,86 +2691,6 @@ class VMwareVcVmdkDriverTestCase(VMwareEsxVmdkDriverTestCase):
|
||||
close.assert_called_once_with(fd)
|
||||
delete_if_exists.assert_called_once_with(tmp)
|
||||
|
||||
@mock.patch.object(VMDK_DRIVER, 'volumeops')
|
||||
@mock.patch.object(VMDK_DRIVER, 'ds_sel')
|
||||
def test_relocate_backing_nop(self, ds_sel, vops):
|
||||
volume = {'name': 'vol-1', 'size': 1}
|
||||
|
||||
datastore = mock.sentinel.datastore
|
||||
vops.get_datastore.return_value = datastore
|
||||
|
||||
profile = mock.sentinel.profile
|
||||
vops.get_profile.return_value = profile
|
||||
|
||||
vops.is_datastore_accessible.return_value = True
|
||||
ds_sel.is_datastore_compliant.return_value = True
|
||||
|
||||
backing = mock.sentinel.backing
|
||||
host = mock.sentinel.host
|
||||
self._driver._relocate_backing(volume, backing, host)
|
||||
|
||||
vops.is_datastore_accessible.assert_called_once_with(datastore, host)
|
||||
ds_sel.is_datastore_compliant.assert_called_once_with(datastore,
|
||||
profile)
|
||||
self.assertFalse(vops.relocate_backing.called)
|
||||
|
||||
@mock.patch.object(VMDK_DRIVER, 'volumeops')
|
||||
@mock.patch.object(VMDK_DRIVER, 'ds_sel')
|
||||
def test_relocate_backing_with_no_datastore(
|
||||
self, ds_sel, vops):
|
||||
volume = {'name': 'vol-1', 'size': 1}
|
||||
|
||||
profile = mock.sentinel.profile
|
||||
vops.get_profile.return_value = profile
|
||||
|
||||
vops.is_datastore_accessible.return_value = True
|
||||
ds_sel.is_datastore_compliant.return_value = False
|
||||
|
||||
ds_sel.select_datastore.return_value = []
|
||||
|
||||
backing = mock.sentinel.backing
|
||||
host = mock.sentinel.host
|
||||
|
||||
self.assertRaises(error_util.NoValidDatastoreException,
|
||||
self._driver._relocate_backing,
|
||||
volume,
|
||||
backing,
|
||||
host)
|
||||
ds_sel.select_datastore.assert_called_once_with(
|
||||
{hub.DatastoreSelector.SIZE_BYTES: volume['size'] * units.Gi,
|
||||
hub.DatastoreSelector.PROFILE_NAME: profile}, hosts=[host])
|
||||
self.assertFalse(vops.relocate_backing.called)
|
||||
|
||||
@mock.patch.object(VMDK_DRIVER, 'volumeops')
|
||||
@mock.patch.object(VMDK_DRIVER, '_get_volume_group_folder')
|
||||
@mock.patch.object(VMDK_DRIVER, 'ds_sel')
|
||||
def test_relocate_backing(
|
||||
self, ds_sel, get_volume_group_folder, vops):
|
||||
volume = {'name': 'vol-1', 'size': 1}
|
||||
|
||||
vops.is_datastore_accessible.return_value = False
|
||||
ds_sel.is_datastore_compliant.return_value = True
|
||||
|
||||
backing = mock.sentinel.backing
|
||||
host = mock.sentinel.host
|
||||
|
||||
rp = mock.sentinel.rp
|
||||
datastore = mock.sentinel.datastore
|
||||
summary = mock.Mock(datastore=datastore)
|
||||
ds_sel.select_datastore.return_value = (host, rp, summary)
|
||||
|
||||
folder = mock.sentinel.folder
|
||||
get_volume_group_folder.return_value = folder
|
||||
|
||||
self._driver._relocate_backing(volume, backing, host)
|
||||
|
||||
vops.relocate_backing.assert_called_once_with(backing,
|
||||
datastore,
|
||||
rp,
|
||||
host)
|
||||
vops.move_backing_to_folder.assert_called_once_with(backing,
|
||||
folder)
|
||||
|
||||
|
||||
class ImageDiskTypeTest(test.TestCase):
|
||||
"""Unit tests for ImageDiskType."""
|
||||
|
@ -237,30 +237,6 @@ class VolumeOpsTestCase(test.TestCase):
|
||||
hosts = self.vops.get_connected_hosts(datastore)
|
||||
self.assertEqual([], hosts)
|
||||
|
||||
@mock.patch('cinder.volume.drivers.vmware.volumeops.VMwareVolumeOps.'
|
||||
'get_connected_hosts')
|
||||
def test_is_datastore_accessible(self, get_connected_hosts):
|
||||
host_1 = mock.Mock(value=mock.sentinel.host_1)
|
||||
host_2 = mock.Mock(value=mock.sentinel.host_2)
|
||||
get_connected_hosts.return_value = [host_1, host_2]
|
||||
|
||||
ds = mock.sentinel.datastore
|
||||
host = mock.Mock(value=mock.sentinel.host_1)
|
||||
self.assertTrue(self.vops.is_datastore_accessible(ds, host))
|
||||
get_connected_hosts.assert_called_once_with(ds)
|
||||
|
||||
@mock.patch('cinder.volume.drivers.vmware.volumeops.VMwareVolumeOps.'
|
||||
'get_connected_hosts')
|
||||
def test_is_datastore_accessible_with_inaccessible(self,
|
||||
get_connected_hosts):
|
||||
host_1 = mock.Mock(value=mock.sentinel.host_1)
|
||||
get_connected_hosts.return_value = [host_1]
|
||||
|
||||
ds = mock.sentinel.datastore
|
||||
host = mock.Mock(value=mock.sentinel.host_2)
|
||||
self.assertFalse(self.vops.is_datastore_accessible(ds, host))
|
||||
get_connected_hosts.assert_called_once_with(ds)
|
||||
|
||||
def test_is_valid(self):
|
||||
with mock.patch.object(self.vops, 'get_summary') as get_summary:
|
||||
summary = mock.Mock(spec=object)
|
||||
@ -1309,52 +1285,6 @@ class VolumeOpsTestCase(test.TestCase):
|
||||
datacenter=dc_ref)
|
||||
self.session.wait_for_task.assert_called_once_with(task)
|
||||
|
||||
def test_get_profile(self):
|
||||
server_obj = mock.Mock()
|
||||
self.session.pbm.client.factory.create.return_value = server_obj
|
||||
|
||||
profile_ids = [mock.sentinel.profile_id]
|
||||
profile_name = mock.sentinel.profile_name
|
||||
profile = mock.Mock()
|
||||
profile.name = profile_name
|
||||
self.session.invoke_api.side_effect = [profile_ids, [profile]]
|
||||
|
||||
value = mock.sentinel.value
|
||||
backing = mock.Mock(value=value)
|
||||
self.assertEqual(profile_name, self.vops.get_profile(backing))
|
||||
|
||||
pbm = self.session.pbm
|
||||
profile_manager = pbm.service_content.profileManager
|
||||
exp_calls = [mock.call(pbm, 'PbmQueryAssociatedProfile',
|
||||
profile_manager, entity=server_obj),
|
||||
mock.call(pbm, 'PbmRetrieveContent', profile_manager,
|
||||
profileIds=profile_ids)]
|
||||
self.assertEqual(exp_calls, self.session.invoke_api.call_args_list)
|
||||
|
||||
self.assertEqual(value, server_obj.key)
|
||||
self.assertEqual('virtualMachine', server_obj.objectType)
|
||||
self.session.invoke_api.side_effect = None
|
||||
|
||||
def test_get_profile_with_no_profile(self):
|
||||
server_obj = mock.Mock()
|
||||
self.session.pbm.client.factory.create.return_value = server_obj
|
||||
|
||||
self.session.invoke_api.side_effect = [[]]
|
||||
|
||||
value = mock.sentinel.value
|
||||
backing = mock.Mock(value=value)
|
||||
self.assertIsNone(self.vops.get_profile(backing))
|
||||
|
||||
pbm = self.session.pbm
|
||||
profile_manager = pbm.service_content.profileManager
|
||||
exp_calls = [mock.call(pbm, 'PbmQueryAssociatedProfile',
|
||||
profile_manager, entity=server_obj)]
|
||||
self.assertEqual(exp_calls, self.session.invoke_api.call_args_list)
|
||||
|
||||
self.assertEqual(value, server_obj.key)
|
||||
self.assertEqual('virtualMachine', server_obj.objectType)
|
||||
self.session.invoke_api.side_effect = None
|
||||
|
||||
def test_extend_virtual_disk(self):
|
||||
"""Test volumeops.extend_virtual_disk."""
|
||||
task = mock.sentinel.task
|
||||
|
@ -93,8 +93,3 @@ class VirtualDiskNotFoundException(VMwareDriverException):
|
||||
class ProfileNotFoundException(VMwareDriverException):
|
||||
"""Thrown when the given storage profile cannot be found."""
|
||||
message = _("Storage profile: %(storage_profile)s not found.")
|
||||
|
||||
|
||||
class NoValidDatastoreException(VMwareDriverException):
|
||||
"""Thrown when there are no valid datastores."""
|
||||
message = _("There are no valid datastores.")
|
||||
|
@ -1916,52 +1916,38 @@ class VMwareVcVmdkDriver(VMwareEsxVmdkDriver):
|
||||
return self.volumeops.create_folder(vm_folder, volume_folder)
|
||||
|
||||
def _relocate_backing(self, volume, backing, host):
|
||||
"""Relocate volume backing to a datastore accessible to the given host.
|
||||
"""Relocate volume backing under host and move to volume_group folder.
|
||||
|
||||
The backing is not relocated if the current datastore is already
|
||||
accessible to the host and compliant with the backing's storage
|
||||
profile.
|
||||
If the volume backing is on a datastore that is visible to the host,
|
||||
then need not do any operation.
|
||||
|
||||
:param volume: Volume to be relocated
|
||||
:param volume: volume to be relocated
|
||||
:param backing: Reference to the backing
|
||||
:param host: Reference to the host
|
||||
"""
|
||||
# Check if current datastore is visible to host managing
|
||||
# the instance and compliant with the storage profile.
|
||||
# Check if volume's datastore is visible to host managing
|
||||
# the instance
|
||||
(datastores, resource_pool) = self.volumeops.get_dss_rp(host)
|
||||
datastore = self.volumeops.get_datastore(backing)
|
||||
backing_profile = self.volumeops.get_profile(backing)
|
||||
if (self.volumeops.is_datastore_accessible(datastore, host) and
|
||||
self.ds_sel.is_datastore_compliant(datastore,
|
||||
backing_profile)):
|
||||
LOG.debug("Datastore: %(datastore)s of backing: %(backing)s is "
|
||||
"already accessible to instance's host: %(host)s and "
|
||||
"compliant with storage profile: %(profile)s.",
|
||||
{'backing': backing,
|
||||
'datastore': datastore,
|
||||
'host': host,
|
||||
'profile': backing_profile})
|
||||
|
||||
visible_to_host = False
|
||||
for _datastore in datastores:
|
||||
if _datastore.value == datastore.value:
|
||||
visible_to_host = True
|
||||
break
|
||||
if visible_to_host:
|
||||
return
|
||||
|
||||
# We need to relocate the backing to an accessible and profile
|
||||
# compliant datastore.
|
||||
req = {}
|
||||
req[hub.DatastoreSelector.SIZE_BYTES] = (volume['size'] *
|
||||
units.Gi)
|
||||
req[hub.DatastoreSelector.PROFILE_NAME] = backing_profile
|
||||
|
||||
# Select datastore satisfying the requirements.
|
||||
best_candidate = self.ds_sel.select_datastore(req, hosts=[host])
|
||||
if not best_candidate:
|
||||
# No candidate datastore to relocate.
|
||||
msg = _("There are no datastores matching volume requirements;"
|
||||
" can't relocate volume: %s.") % volume['name']
|
||||
LOG.error(msg)
|
||||
raise error_util.NoValidDatastoreException(msg)
|
||||
|
||||
(host, resource_pool, summary) = best_candidate
|
||||
dc = self.volumeops.get_dc(resource_pool)
|
||||
folder = self._get_volume_group_folder(dc)
|
||||
# The volume's backing is on a datastore that is not visible to the
|
||||
# host managing the instance. We relocate the volume's backing.
|
||||
|
||||
# Pick a folder and datastore to relocate volume backing to
|
||||
(folder, summary) = self._get_folder_ds_summary(volume,
|
||||
resource_pool,
|
||||
datastores)
|
||||
LOG.info(_("Relocating volume: %(backing)s to %(ds)s and %(rp)s.") %
|
||||
{'backing': backing, 'ds': summary, 'rp': resource_pool})
|
||||
# Relocate the backing to the datastore and folder
|
||||
self.volumeops.relocate_backing(backing, summary.datastore,
|
||||
resource_pool, host)
|
||||
self.volumeops.move_backing_to_folder(backing, folder)
|
||||
|
@ -388,15 +388,6 @@ class VMwareVolumeOps(object):
|
||||
|
||||
return connected_hosts
|
||||
|
||||
def is_datastore_accessible(self, datastore, host):
|
||||
"""Check if the datastore is accessible to the given host.
|
||||
|
||||
:param datastore: datastore reference
|
||||
:return: True if the datastore is accessible
|
||||
"""
|
||||
hosts = self.get_connected_hosts(datastore)
|
||||
return host.value in [host_ref.value for host_ref in hosts]
|
||||
|
||||
def _in_maintenance(self, summary):
|
||||
"""Check if a datastore is entering maintenance or in maintenance.
|
||||
|
||||
@ -1391,27 +1382,3 @@ class VMwareVolumeOps(object):
|
||||
profile=profile_id)
|
||||
LOG.debug("Filtered hubs: %s", filtered_hubs)
|
||||
return filtered_hubs
|
||||
|
||||
def get_profile(self, backing):
|
||||
"""Query storage profile associated with the given backing.
|
||||
|
||||
:param backing: backing reference
|
||||
:return: profile name
|
||||
"""
|
||||
pbm = self._session.pbm
|
||||
profile_manager = pbm.service_content.profileManager
|
||||
|
||||
object_ref = pbm.client.factory.create('ns0:PbmServerObjectRef')
|
||||
object_ref.key = backing.value
|
||||
object_ref.objectType = 'virtualMachine'
|
||||
|
||||
profile_ids = self._session.invoke_api(pbm,
|
||||
'PbmQueryAssociatedProfile',
|
||||
profile_manager,
|
||||
entity=object_ref)
|
||||
if profile_ids:
|
||||
profiles = self._session.invoke_api(pbm,
|
||||
'PbmRetrieveContent',
|
||||
profile_manager,
|
||||
profileIds=profile_ids)
|
||||
return profiles[0].name
|
||||
|
Loading…
Reference in New Issue
Block a user