From 39e8f5bd3bc976603c5a0a2dd4ada3dd6b79258d Mon Sep 17 00:00:00 2001 From: Chris Behrens Date: Mon, 3 Jun 2013 20:02:21 +0000 Subject: Cells: Add support for global cinder Implements cinder support for compute cells when cinder is a global installation. Adds syncing of the block device mapping table between child cells and API cells. Implements blueprint cells-cinder-support Change-Id: Ife5be9922db0742c8ee4f970517396be86597cce --- nova/tests/api/ec2/test_cloud.py | 1 + nova/tests/cells/test_cells_manager.py | 24 +++++ nova/tests/cells/test_cells_messaging.py | 170 +++++++++++++++++++++++++++++++ nova/tests/cells/test_cells_rpcapi.py | 26 +++++ nova/tests/conductor/test_conductor.py | 61 +++++++++-- nova/tests/db/test_db_api.py | 9 +- 6 files changed, 280 insertions(+), 11 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/api/ec2/test_cloud.py b/nova/tests/api/ec2/test_cloud.py index b4cb24404..95baec544 100644 --- a/nova/tests/api/ec2/test_cloud.py +++ b/nova/tests/api/ec2/test_cloud.py @@ -2121,6 +2121,7 @@ class CloudTestCase(test.TestCase): return [dict(id=1, source_type='snapshot', destination_type='volume', + instance_uuid=inst_id, snapshot_id=snapshots[0], volume_id=volumes[0], volume_size=1, diff --git a/nova/tests/cells/test_cells_manager.py b/nova/tests/cells/test_cells_manager.py index 4e35cd818..89a60cb35 100644 --- a/nova/tests/cells/test_cells_manager.py +++ b/nova/tests/cells/test_cells_manager.py @@ -548,3 +548,27 @@ class CellsManagerClassTestCase(test.TestCase): instance_uuid=instance_uuid, console_port=console_port, console_type=console_type) self.assertEqual('fake-response', response) + + def test_bdm_update_or_create_at_top(self): + self.mox.StubOutWithMock(self.msg_runner, + 'bdm_update_or_create_at_top') + self.msg_runner.bdm_update_or_create_at_top(self.ctxt, + 'fake-bdm', + create='foo') + self.mox.ReplayAll() + self.cells_manager.bdm_update_or_create_at_top(self.ctxt, + 'fake-bdm', + create='foo') + + def test_bdm_destroy_at_top(self): + self.mox.StubOutWithMock(self.msg_runner, 'bdm_destroy_at_top') + self.msg_runner.bdm_destroy_at_top(self.ctxt, + 'fake_instance_uuid', + device_name='fake_device_name', + volume_id='fake_volume_id') + + self.mox.ReplayAll() + self.cells_manager.bdm_destroy_at_top(self.ctxt, + 'fake_instance_uuid', + device_name='fake_device_name', + volume_id='fake_volume_id') diff --git a/nova/tests/cells/test_cells_messaging.py b/nova/tests/cells/test_cells_messaging.py index 9aae11201..54ec5ca15 100644 --- a/nova/tests/cells/test_cells_messaging.py +++ b/nova/tests/cells/test_cells_messaging.py @@ -1425,3 +1425,173 @@ class CellsBroadcastMethodsTestCase(test.TestCase): self.mox.ReplayAll() self.src_msg_runner.consoleauth_delete_tokens(self.ctxt, fake_uuid) + + def test_bdm_update_or_create_with_none_create(self): + fake_bdm = {'id': 'fake_id', + 'volume_id': 'fake_volume_id'} + expected_bdm = fake_bdm.copy() + expected_bdm.pop('id') + + # Shouldn't be called for these 2 cells + self.mox.StubOutWithMock(self.src_db_inst, + 'block_device_mapping_update_or_create') + self.mox.StubOutWithMock(self.mid_db_inst, + 'block_device_mapping_update_or_create') + + self.mox.StubOutWithMock(self.tgt_db_inst, + 'block_device_mapping_update_or_create') + self.tgt_db_inst.block_device_mapping_update_or_create( + self.ctxt, expected_bdm, legacy=False) + + self.mox.ReplayAll() + + self.src_msg_runner.bdm_update_or_create_at_top(self.ctxt, + fake_bdm, + create=None) + + def test_bdm_update_or_create_with_true_create(self): + fake_bdm = {'id': 'fake_id', + 'volume_id': 'fake_volume_id'} + expected_bdm = fake_bdm.copy() + expected_bdm.pop('id') + + # Shouldn't be called for these 2 cells + self.mox.StubOutWithMock(self.src_db_inst, + 'block_device_mapping_create') + self.mox.StubOutWithMock(self.mid_db_inst, + 'block_device_mapping_create') + + self.mox.StubOutWithMock(self.tgt_db_inst, + 'block_device_mapping_create') + self.tgt_db_inst.block_device_mapping_create( + self.ctxt, fake_bdm, legacy=False) + + self.mox.ReplayAll() + + self.src_msg_runner.bdm_update_or_create_at_top(self.ctxt, + fake_bdm, + create=True) + + def test_bdm_update_or_create_with_false_create_vol_id(self): + fake_bdm = {'id': 'fake_id', + 'instance_uuid': 'fake_instance_uuid', + 'device_name': 'fake_device_name', + 'volume_id': 'fake_volume_id'} + expected_bdm = fake_bdm.copy() + expected_bdm.pop('id') + + fake_inst_bdms = [{'id': 1, + 'volume_id': 'not-a-match', + 'device_name': 'not-a-match'}, + {'id': 2, + 'volume_id': 'fake_volume_id', + 'device_name': 'not-a-match'}, + {'id': 3, + 'volume_id': 'not-a-match', + 'device_name': 'not-a-match'}] + + # Shouldn't be called for these 2 cells + self.mox.StubOutWithMock(self.src_db_inst, + 'block_device_mapping_update') + self.mox.StubOutWithMock(self.mid_db_inst, + 'block_device_mapping_update') + + self.mox.StubOutWithMock(self.tgt_db_inst, + 'block_device_mapping_get_all_by_instance') + self.mox.StubOutWithMock(self.tgt_db_inst, + 'block_device_mapping_update') + + self.tgt_db_inst.block_device_mapping_get_all_by_instance( + self.ctxt, 'fake_instance_uuid').AndReturn( + fake_inst_bdms) + # Should try to update ID 2. + self.tgt_db_inst.block_device_mapping_update( + self.ctxt, 2, expected_bdm, legacy=False) + + self.mox.ReplayAll() + + self.src_msg_runner.bdm_update_or_create_at_top(self.ctxt, + fake_bdm, + create=False) + + def test_bdm_update_or_create_with_false_create_dev_name(self): + fake_bdm = {'id': 'fake_id', + 'instance_uuid': 'fake_instance_uuid', + 'device_name': 'fake_device_name', + 'volume_id': 'fake_volume_id'} + expected_bdm = fake_bdm.copy() + expected_bdm.pop('id') + + fake_inst_bdms = [{'id': 1, + 'volume_id': 'not-a-match', + 'device_name': 'not-a-match'}, + {'id': 2, + 'volume_id': 'not-a-match', + 'device_name': 'fake_device_name'}, + {'id': 3, + 'volume_id': 'not-a-match', + 'device_name': 'not-a-match'}] + + # Shouldn't be called for these 2 cells + self.mox.StubOutWithMock(self.src_db_inst, + 'block_device_mapping_update') + self.mox.StubOutWithMock(self.mid_db_inst, + 'block_device_mapping_update') + + self.mox.StubOutWithMock(self.tgt_db_inst, + 'block_device_mapping_get_all_by_instance') + self.mox.StubOutWithMock(self.tgt_db_inst, + 'block_device_mapping_update') + + self.tgt_db_inst.block_device_mapping_get_all_by_instance( + self.ctxt, 'fake_instance_uuid').AndReturn( + fake_inst_bdms) + # Should try to update ID 2. + self.tgt_db_inst.block_device_mapping_update( + self.ctxt, 2, expected_bdm, legacy=False) + + self.mox.ReplayAll() + + self.src_msg_runner.bdm_update_or_create_at_top(self.ctxt, + fake_bdm, + create=False) + + def test_bdm_destroy_by_volume(self): + fake_instance_uuid = 'fake-instance-uuid' + fake_volume_id = 'fake-volume-name' + + # Shouldn't be called for these 2 cells + self.mox.StubOutWithMock(self.src_db_inst, + 'block_device_mapping_destroy_by_instance_and_volume') + self.mox.StubOutWithMock(self.mid_db_inst, + 'block_device_mapping_destroy_by_instance_and_volume') + + self.mox.StubOutWithMock(self.tgt_db_inst, + 'block_device_mapping_destroy_by_instance_and_volume') + self.tgt_db_inst.block_device_mapping_destroy_by_instance_and_volume( + self.ctxt, fake_instance_uuid, fake_volume_id) + + self.mox.ReplayAll() + + self.src_msg_runner.bdm_destroy_at_top(self.ctxt, fake_instance_uuid, + volume_id=fake_volume_id) + + def test_bdm_destroy_by_device(self): + fake_instance_uuid = 'fake-instance-uuid' + fake_device_name = 'fake-device-name' + + # Shouldn't be called for these 2 cells + self.mox.StubOutWithMock(self.src_db_inst, + 'block_device_mapping_destroy_by_instance_and_device') + self.mox.StubOutWithMock(self.mid_db_inst, + 'block_device_mapping_destroy_by_instance_and_device') + + self.mox.StubOutWithMock(self.tgt_db_inst, + 'block_device_mapping_destroy_by_instance_and_device') + self.tgt_db_inst.block_device_mapping_destroy_by_instance_and_device( + self.ctxt, fake_instance_uuid, fake_device_name) + + self.mox.ReplayAll() + + self.src_msg_runner.bdm_destroy_at_top(self.ctxt, fake_instance_uuid, + device_name=fake_device_name) diff --git a/nova/tests/cells/test_cells_rpcapi.py b/nova/tests/cells/test_cells_rpcapi.py index e44c0be4a..5c3c0baa6 100644 --- a/nova/tests/cells/test_cells_rpcapi.py +++ b/nova/tests/cells/test_cells_rpcapi.py @@ -422,3 +422,29 @@ class CellsAPITestCase(test.TestCase): self._check_result(call_info, 'validate_console_port', expected_args, version='1.6') self.assertEqual(result, 'fake_response') + + def test_bdm_update_or_create_at_top(self): + fake_bdm = {'id': 2, 'other': 'meow'} + + call_info = self._stub_rpc_method('cast', None) + + self.cells_rpcapi.bdm_update_or_create_at_top( + self.fake_context, fake_bdm, create='fake-create') + + expected_args = {'bdm': fake_bdm, 'create': 'fake-create'} + self._check_result(call_info, 'bdm_update_or_create_at_top', + expected_args, version='1.10') + + def test_bdm_destroy_at_top(self): + call_info = self._stub_rpc_method('cast', None) + + self.cells_rpcapi.bdm_destroy_at_top(self.fake_context, + 'fake-uuid', + device_name='fake-device', + volume_id='fake-vol') + + expected_args = {'instance_uuid': 'fake-uuid', + 'device_name': 'fake-device', + 'volume_id': 'fake-vol'} + self._check_result(call_info, 'bdm_destroy_at_top', + expected_args, version='1.10') diff --git a/nova/tests/conductor/test_conductor.py b/nova/tests/conductor/test_conductor.py index 03896ee3a..253d99c76 100644 --- a/nova/tests/conductor/test_conductor.py +++ b/nova/tests/conductor/test_conductor.py @@ -632,13 +632,28 @@ class ConductorTestCase(_BaseTestCase, test.TestCase): self.conductor_manager = self.conductor def test_block_device_mapping_update_or_create(self): - fake_bdm = {'id': 'fake-id'} + fake_bdm = {'id': 'fake-id', 'device_name': 'foo'} + fake_bdm2 = {'id': 'fake-id', 'device_name': 'foo2'} + cells_rpcapi = self.conductor.cells_rpcapi self.mox.StubOutWithMock(db, 'block_device_mapping_create') self.mox.StubOutWithMock(db, 'block_device_mapping_update') self.mox.StubOutWithMock(db, 'block_device_mapping_update_or_create') - db.block_device_mapping_create(self.context, fake_bdm) - db.block_device_mapping_update(self.context, fake_bdm['id'], fake_bdm) - db.block_device_mapping_update_or_create(self.context, fake_bdm) + self.mox.StubOutWithMock(cells_rpcapi, + 'bdm_update_or_create_at_top') + db.block_device_mapping_create(self.context, + fake_bdm).AndReturn(fake_bdm2) + cells_rpcapi.bdm_update_or_create_at_top(self.context, fake_bdm2, + create=True) + db.block_device_mapping_update(self.context, fake_bdm['id'], + fake_bdm).AndReturn(fake_bdm2) + cells_rpcapi.bdm_update_or_create_at_top(self.context, + fake_bdm2, + create=False) + db.block_device_mapping_update_or_create( + self.context, fake_bdm).AndReturn(fake_bdm2) + cells_rpcapi.bdm_update_or_create_at_top(self.context, + fake_bdm2, + create=None) self.mox.ReplayAll() self.conductor.block_device_mapping_update_or_create(self.context, fake_bdm, @@ -650,22 +665,44 @@ class ConductorTestCase(_BaseTestCase, test.TestCase): fake_bdm) def test_block_device_mapping_destroy(self): - fake_bdm = {'id': 'fake-bdm'} - fake_bdm2 = {'id': 'fake-bdm-2'} + fake_bdm = {'id': 'fake-bdm', + 'instance_uuid': 'fake-uuid', + 'device_name': 'fake-device1', + 'volume_id': 'fake-vol-id1'} + fake_bdm2 = {'id': 'fake-bdm-2', + 'instance_uuid': 'fake-uuid2', + 'device_name': '', + 'volume_id': 'fake-vol-id2'} fake_inst = {'uuid': 'fake-uuid'} + + cells_rpcapi = self.conductor.cells_rpcapi + self.mox.StubOutWithMock(db, 'block_device_mapping_destroy') self.mox.StubOutWithMock( db, 'block_device_mapping_destroy_by_instance_and_device') self.mox.StubOutWithMock( db, 'block_device_mapping_destroy_by_instance_and_volume') + self.mox.StubOutWithMock(cells_rpcapi, 'bdm_destroy_at_top') + db.block_device_mapping_destroy(self.context, 'fake-bdm') + cells_rpcapi.bdm_destroy_at_top(self.context, + fake_bdm['instance_uuid'], + device_name=fake_bdm['device_name']) db.block_device_mapping_destroy(self.context, 'fake-bdm-2') + cells_rpcapi.bdm_destroy_at_top(self.context, + fake_bdm2['instance_uuid'], + volume_id=fake_bdm2['volume_id']) db.block_device_mapping_destroy_by_instance_and_device(self.context, 'fake-uuid', 'fake-device') + cells_rpcapi.bdm_destroy_at_top(self.context, fake_inst['uuid'], + device_name='fake-device') db.block_device_mapping_destroy_by_instance_and_volume(self.context, 'fake-uuid', 'fake-volume') + cells_rpcapi.bdm_destroy_at_top(self.context, fake_inst['uuid'], + volume_id='fake-volume') + self.mox.ReplayAll() self.conductor.block_device_mapping_destroy(self.context, [fake_bdm, @@ -810,8 +847,12 @@ class ConductorRPCAPITestCase(_BaseTestCase, test.TestCase): fake_bdm) def test_block_device_mapping_destroy(self): - fake_bdm = {'id': 'fake-bdm'} + fake_bdm = {'id': 'fake-bdm', + 'instance_uuid': 'fake-uuid', + 'device_name': 'fake-device1', + 'volume_id': 'fake-vol-id1'} fake_inst = {'uuid': 'fake-uuid'} + self.mox.StubOutWithMock(db, 'block_device_mapping_destroy') self.mox.StubOutWithMock( db, 'block_device_mapping_destroy_by_instance_and_device') @@ -961,8 +1002,12 @@ class ConductorAPITestCase(_BaseTestCase, test.TestCase): 'fake-bdm') def test_block_device_mapping_destroy(self): - fake_bdm = {'id': 'fake-bdm'} + fake_bdm = {'id': 'fake-bdm', + 'instance_uuid': 'fake-uuid', + 'device_name': 'fake-device1', + 'volume_id': 'fake-vol-id1'} fake_inst = {'uuid': 'fake-uuid'} + self.mox.StubOutWithMock(db, 'block_device_mapping_destroy') self.mox.StubOutWithMock( db, 'block_device_mapping_destroy_by_instance_and_device') diff --git a/nova/tests/db/test_db_api.py b/nova/tests/db/test_db_api.py index 711f81e52..dbcb67e9d 100644 --- a/nova/tests/db/test_db_api.py +++ b/nova/tests/db/test_db_api.py @@ -4039,12 +4039,15 @@ class BlockDeviceMappingTestCase(test.TestCase): def test_block_device_mapping_update(self): bdm = self._create_bdm({}) - db.block_device_mapping_update(self.ctxt, bdm['id'], - {'destination_type': 'moon'}, - legacy=False) + result = db.block_device_mapping_update( + self.ctxt, bdm['id'], {'destination_type': 'moon'}, + legacy=False) uuid = bdm['instance_uuid'] bdm_real = db.block_device_mapping_get_all_by_instance(self.ctxt, uuid) self.assertEqual(bdm_real[0]['destination_type'], 'moon') + # Also make sure the update call returned correct data + self.assertEqual(dict(bdm_real[0].iteritems()), + dict(result.iteritems())) def test_block_device_mapping_update_or_create(self): values = { -- cgit