diff --git a/nova/compute/api.py b/nova/compute/api.py index c3bf0c1ea5ac..145e675b5824 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -3283,10 +3283,17 @@ class API(base.Base): self._record_action_start(context, instance, instance_actions.LIVE_MIGRATION) - + try: + request_spec = objects.RequestSpec.get_by_instance_uuid( + context, instance.uuid) + except exception.RequestSpecNotFound: + # Some old instances can still have no RequestSpec object attached + # to them, we need to support the old way + request_spec = None self.compute_task_api.live_migrate_instance(context, instance, host_name, block_migration=block_migration, - disk_over_commit=disk_over_commit) + disk_over_commit=disk_over_commit, + request_spec=request_spec) @check_instance_lock @check_instance_cell diff --git a/nova/conductor/api.py b/nova/conductor/api.py index ceca53459fcf..b9be88204a3f 100644 --- a/nova/conductor/api.py +++ b/nova/conductor/api.py @@ -75,11 +75,12 @@ class LocalComputeTaskAPI(object): reservations=reservations, clean_shutdown=clean_shutdown) def live_migrate_instance(self, context, instance, host_name, - block_migration, disk_over_commit): + block_migration, disk_over_commit, + request_spec=None): scheduler_hint = {'host': host_name} self._manager.migrate_server( context, instance, scheduler_hint, True, False, None, - block_migration, disk_over_commit, None) + block_migration, disk_over_commit, None, request_spec=request_spec) def build_instances(self, context, instances, image, filter_properties, admin_password, injected_files, @@ -185,11 +186,12 @@ class ComputeTaskAPI(object): reservations=reservations, clean_shutdown=clean_shutdown) def live_migrate_instance(self, context, instance, host_name, - block_migration, disk_over_commit): + block_migration, disk_over_commit, + request_spec=None): scheduler_hint = {'host': host_name} self.conductor_compute_rpcapi.migrate_server( context, instance, scheduler_hint, True, False, None, - block_migration, disk_over_commit, None) + block_migration, disk_over_commit, None, request_spec=request_spec) def build_instances(self, context, instances, image, filter_properties, admin_password, injected_files, requested_networks, diff --git a/nova/conductor/manager.py b/nova/conductor/manager.py index 1bdb97e4c8dc..7eb2aad0d079 100644 --- a/nova/conductor/manager.py +++ b/nova/conductor/manager.py @@ -144,7 +144,7 @@ class ComputeTaskManager(base.Base): may involve coordinating activities on multiple compute nodes. """ - target = messaging.Target(namespace='compute_task', version='1.12') + target = messaging.Target(namespace='compute_task', version='1.13') def __init__(self): super(ComputeTaskManager, self).__init__() @@ -175,7 +175,7 @@ class ComputeTaskManager(base.Base): exception.UnsupportedPolicyException) def migrate_server(self, context, instance, scheduler_hint, live, rebuild, flavor, block_migration, disk_over_commit, reservations=None, - clean_shutdown=True): + clean_shutdown=True, request_spec=None): if instance and not isinstance(instance, nova_object.NovaObject): # NOTE(danms): Until v2 of the RPC API, we need to tolerate # old-world instance objects here @@ -191,7 +191,7 @@ class ComputeTaskManager(base.Base): flavor = objects.Flavor.get_by_id(context, flavor['id']) if live and not rebuild and not flavor: self._live_migrate(context, instance, scheduler_hint, - block_migration, disk_over_commit) + block_migration, disk_over_commit, request_spec) elif not live and not rebuild and flavor: instance_uuid = instance.uuid with compute_utils.EventReporter(context, 'cold_migrate', @@ -272,7 +272,7 @@ class ComputeTaskManager(base.Base): pass def _live_migrate(self, context, instance, scheduler_hint, - block_migration, disk_over_commit): + block_migration, disk_over_commit, request_spec): destination = scheduler_hint.get("host") def _set_vm_state(context, instance, ex, vm_state=None, @@ -304,7 +304,7 @@ class ComputeTaskManager(base.Base): task = self._build_live_migrate_task(context, instance, destination, block_migration, disk_over_commit, - migration) + migration, request_spec) try: task.execute() except (exception.NoValidHost, @@ -337,13 +337,15 @@ class ComputeTaskManager(base.Base): raise exception.MigrationError(reason=six.text_type(ex)) def _build_live_migrate_task(self, context, instance, destination, - block_migration, disk_over_commit, migration): + block_migration, disk_over_commit, migration, + request_spec=None): return live_migrate.LiveMigrationTask(context, instance, destination, block_migration, disk_over_commit, migration, self.compute_rpcapi, self.servicegroup_api, - self.scheduler_client) + self.scheduler_client, + request_spec) def _build_cold_migrate_task(self, context, instance, flavor, filter_properties, request_spec, reservations, diff --git a/nova/conductor/rpcapi.py b/nova/conductor/rpcapi.py index dd502001a72a..5e818a66735b 100644 --- a/nova/conductor/rpcapi.py +++ b/nova/conductor/rpcapi.py @@ -268,6 +268,7 @@ class ComputeTaskAPI(object): 1.10 - Made migrate_server() and build_instances() send flavor objects 1.11 - Added clean_shutdown to migrate_server() 1.12 - Added request_spec to rebuild_instance() + 1.13 - Added request_spec to migrate_server() """ def __init__(self): @@ -280,14 +281,19 @@ class ComputeTaskAPI(object): def migrate_server(self, context, instance, scheduler_hint, live, rebuild, flavor, block_migration, disk_over_commit, - reservations=None, clean_shutdown=True): + reservations=None, clean_shutdown=True, request_spec=None): kw = {'instance': instance, 'scheduler_hint': scheduler_hint, 'live': live, 'rebuild': rebuild, 'flavor': flavor, 'block_migration': block_migration, 'disk_over_commit': disk_over_commit, 'reservations': reservations, - 'clean_shutdown': clean_shutdown} - version = '1.11' + 'clean_shutdown': clean_shutdown, + 'request_spec': request_spec, + } + version = '1.13' + if not self.client.can_send_version(version): + del kw['request_spec'] + version = '1.11' if not self.client.can_send_version(version): del kw['clean_shutdown'] version = '1.10' diff --git a/nova/conductor/tasks/live_migrate.py b/nova/conductor/tasks/live_migrate.py index 9065de278314..93560c2347c2 100644 --- a/nova/conductor/tasks/live_migrate.py +++ b/nova/conductor/tasks/live_migrate.py @@ -38,7 +38,7 @@ CONF.register_opt(migrate_opt) class LiveMigrationTask(base.TaskBase): def __init__(self, context, instance, destination, block_migration, disk_over_commit, migration, compute_rpcapi, - servicegroup_api, scheduler_client): + servicegroup_api, scheduler_client, request_spec=None): super(LiveMigrationTask, self).__init__(context, instance) self.destination = destination self.block_migration = block_migration @@ -50,6 +50,7 @@ class LiveMigrationTask(base.TaskBase): self.compute_rpcapi = compute_rpcapi self.servicegroup_api = servicegroup_api self.scheduler_client = scheduler_client + self.request_spec = request_spec def _execute(self): self._check_instance_is_active() @@ -165,22 +166,32 @@ class LiveMigrationTask(base.TaskBase): attempted_hosts = [self.source] image = utils.get_image_from_system_metadata( self.instance.system_metadata) - request_spec = scheduler_utils.build_request_spec(self.context, image, - [self.instance]) + filter_properties = {'ignore_hosts': attempted_hosts} + # TODO(sbauza): Remove that once setup_instance_group() accepts a + # RequestSpec object + request_spec = {'instance_properties': {'uuid': self.instance.uuid}} + scheduler_utils.setup_instance_group(self.context, request_spec, + filter_properties) + if not self.request_spec: + # NOTE(sbauza): We were unable to find an original RequestSpec + # object - probably because the instance is old. + # We need to mock that the old way + request_spec = objects.RequestSpec.from_components( + self.context, self.instance.uuid, image, + self.instance.flavor, self.instance.numa_topology, + self.instance.pci_requests, + filter_properties, None, self.instance.availability_zone + ) + else: + request_spec = self.request_spec host = None while host is None: self._check_not_over_max_retries(attempted_hosts) - filter_properties = {'ignore_hosts': attempted_hosts} - scheduler_utils.setup_instance_group(self.context, request_spec, - filter_properties) - # TODO(sbauza): Hydrate here the object until we modify the - # scheduler.utils methods to directly use the RequestSpec object - spec_obj = objects.RequestSpec.from_primitives( - self.context, request_spec, filter_properties) + request_spec.ignore_hosts = attempted_hosts try: host = self.scheduler_client.select_destinations(self.context, - spec_obj)[0]['host'] + request_spec)[0]['host'] except messaging.RemoteError as ex: # TODO(ShaoHe Feng) There maybe multi-scheduler, and the # scheduling algorithm is R-R, we can let other scheduler try. diff --git a/nova/tests/functional/api_sample_tests/test_migrate_server.py b/nova/tests/functional/api_sample_tests/test_migrate_server.py index 5a2c6854a0e5..3cb32894d8e9 100644 --- a/nova/tests/functional/api_sample_tests/test_migrate_server.py +++ b/nova/tests/functional/api_sample_tests/test_migrate_server.py @@ -53,7 +53,7 @@ class MigrateServerSamplesJsonTest(test_servers.ServersSampleBase): def test_post_live_migrate_server(self): # Get api samples to server live migrate request. def fake_live_migrate(_self, context, instance, scheduler_hint, - block_migration, disk_over_commit): + block_migration, disk_over_commit, request_spec): self.assertEqual(self.uuid, instance["uuid"]) host = scheduler_hint["host"] self.assertEqual(self.compute.host, host) diff --git a/nova/tests/unit/compute/test_compute.py b/nova/tests/unit/compute/test_compute.py index cc8515cf3183..db7e37ef93da 100644 --- a/nova/tests/unit/compute/test_compute.py +++ b/nova/tests/unit/compute/test_compute.py @@ -10052,21 +10052,29 @@ class ComputeAPITestCase(BaseTestCase): instance, instance_uuid = self._run_instance() rpcapi = self.compute_api.compute_task_api - self.mox.StubOutWithMock(self.compute_api, '_record_action_start') - self.mox.StubOutWithMock(rpcapi, 'live_migrate_instance') - self.compute_api._record_action_start(self.context, instance, - 'live-migration') - rpcapi.live_migrate_instance(self.context, instance, 'fake_dest_host', - block_migration=True, - disk_over_commit=True) + fake_spec = objects.RequestSpec() - self.mox.ReplayAll() + @mock.patch.object(rpcapi, 'live_migrate_instance') + @mock.patch.object(objects.RequestSpec, 'get_by_instance_uuid') + @mock.patch.object(self.compute_api, '_record_action_start') + def do_test(record_action_start, get_by_instance_uuid, + live_migrate_instance): + get_by_instance_uuid.return_value = fake_spec - self.compute_api.live_migrate(self.context, instance, - block_migration=True, - disk_over_commit=True, - host_name='fake_dest_host') + self.compute_api.live_migrate(self.context, instance, + block_migration=True, + disk_over_commit=True, + host_name='fake_dest_host') + record_action_start.assert_called_once_with(self.context, instance, + 'live-migration') + live_migrate_instance.assert_called_once_with( + self.context, instance, 'fake_dest_host', + block_migration=True, + disk_over_commit=True, + request_spec=fake_spec) + + do_test() instance.refresh() self.assertEqual(instance['task_state'], task_states.MIGRATING) diff --git a/nova/tests/unit/compute/test_compute_api.py b/nova/tests/unit/compute/test_compute_api.py index d5d95bec6def..701dcca359d3 100644 --- a/nova/tests/unit/compute/test_compute_api.py +++ b/nova/tests/unit/compute/test_compute_api.py @@ -1788,9 +1788,10 @@ class _ComputeAPIUnitTestMixIn(object): instance = self._create_instance_obj(params=paused_state) self._live_migrate_instance(instance) + @mock.patch.object(objects.RequestSpec, 'get_by_instance_uuid') @mock.patch.object(objects.Instance, 'save') @mock.patch.object(objects.InstanceAction, 'action_start') - def _live_migrate_instance(self, instance, _save, _action): + def _live_migrate_instance(self, instance, _save, _action, get_spec): # TODO(gilliard): This logic is upside-down (different # behaviour depending on which class this method is mixed-into. Once # we have cellsv2 we can remove this kind of logic from this test @@ -1798,6 +1799,8 @@ class _ComputeAPIUnitTestMixIn(object): api = self.compute_api.cells_rpcapi else: api = conductor.api.ComputeTaskAPI + fake_spec = objects.RequestSpec() + get_spec.return_value = fake_spec with mock.patch.object(api, 'live_migrate_instance') as task: self.compute_api.live_migrate(self.context, instance, block_migration=True, @@ -1807,7 +1810,8 @@ class _ComputeAPIUnitTestMixIn(object): task.assert_called_once_with(self.context, instance, 'fake_dest_host', block_migration=True, - disk_over_commit=True) + disk_over_commit=True, + request_spec=fake_spec) def test_swap_volume_volume_api_usage(self): # This test ensures that volume_id arguments are passed to volume_api diff --git a/nova/tests/unit/compute/test_compute_cells.py b/nova/tests/unit/compute/test_compute_cells.py index e4376cce7a22..7d98576af499 100644 --- a/nova/tests/unit/compute/test_compute_cells.py +++ b/nova/tests/unit/compute/test_compute_cells.py @@ -370,9 +370,10 @@ class CellsConductorAPIRPCRedirect(test.NoDBTestCase): self.compute_api.resize(self.context, instance) self.assertTrue(self.cells_rpcapi.resize_instance.called) + @mock.patch.object(objects.RequestSpec, 'get_by_instance_uuid') @mock.patch.object(compute_api.API, '_record_action_start') @mock.patch.object(objects.Instance, 'save') - def test_live_migrate_instance(self, instance_save, _record): + def test_live_migrate_instance(self, instance_save, _record, _get_spec): orig_system_metadata = {} instance = fake_instance.fake_instance_obj(self.context, vm_state=vm_states.ACTIVE, cell_name='fake-cell', diff --git a/nova/tests/unit/conductor/tasks/test_live_migrate.py b/nova/tests/unit/conductor/tasks/test_live_migrate.py index a6c399d37024..ff48f98c4279 100644 --- a/nova/tests/unit/conductor/tasks/test_live_migrate.py +++ b/nova/tests/unit/conductor/tasks/test_live_migrate.py @@ -11,7 +11,6 @@ # under the License. import mock -from mox3 import mox import oslo_messaging as messaging from nova.compute import power_state @@ -49,13 +48,15 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase): self.block_migration = "bm" self.disk_over_commit = "doc" self.migration = objects.Migration() + self.fake_spec = objects.RequestSpec() self._generate_task() def _generate_task(self): self.task = live_migrate.LiveMigrationTask(self.context, self.instance, self.destination, self.block_migration, self.disk_over_commit, self.migration, compute_rpcapi.ComputeAPI(), - servicegroup.API(), scheduler_client.SchedulerClient()) + servicegroup.API(), scheduler_client.SchedulerClient(), + self.fake_spec) def test_execute_with_destination(self): self.mox.StubOutWithMock(self.task, '_check_host_is_up') @@ -252,9 +253,7 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase): def test_find_destination_works(self): self.mox.StubOutWithMock(utils, 'get_image_from_system_metadata') - self.mox.StubOutWithMock(scheduler_utils, 'build_request_spec') self.mox.StubOutWithMock(scheduler_utils, 'setup_instance_group') - self.mox.StubOutWithMock(objects.RequestSpec, 'from_primitives') self.mox.StubOutWithMock(self.task.scheduler_client, 'select_destinations') self.mox.StubOutWithMock(self.task, @@ -263,16 +262,11 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase): utils.get_image_from_system_metadata( self.instance.system_metadata).AndReturn("image") - scheduler_utils.build_request_spec(self.context, mox.IgnoreArg(), - mox.IgnoreArg()).AndReturn({}) + fake_props = {'instance_properties': {'uuid': self.instance_uuid}} scheduler_utils.setup_instance_group( - self.context, {}, {'ignore_hosts': [self.instance_host]}) - fake_spec = objects.RequestSpec() - objects.RequestSpec.from_primitives( - self.context, mox.IgnoreArg(), - mox.IgnoreArg()).AndReturn(fake_spec) + self.context, fake_props, {'ignore_hosts': [self.instance_host]}) self.task.scheduler_client.select_destinations( - self.context, fake_spec).AndReturn( + self.context, self.fake_spec).AndReturn( [{'host': 'host1'}]) self.task._check_compatible_with_source_hypervisor("host1") self.task._call_livem_checks_on_host("host1") @@ -280,30 +274,57 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase): self.mox.ReplayAll() self.assertEqual("host1", self.task._find_destination()) + def test_find_destination_works_with_no_request_spec(self): + task = live_migrate.LiveMigrationTask( + self.context, self.instance, self.destination, + self.block_migration, self.disk_over_commit, self.migration, + compute_rpcapi.ComputeAPI(), servicegroup.API(), + scheduler_client.SchedulerClient(), request_spec=None) + another_spec = objects.RequestSpec() + self.instance.flavor = objects.Flavor() + self.instance.numa_topology = None + self.instance.pci_requests = None + + @mock.patch.object(task, '_call_livem_checks_on_host') + @mock.patch.object(task, '_check_compatible_with_source_hypervisor') + @mock.patch.object(task.scheduler_client, 'select_destinations') + @mock.patch.object(objects.RequestSpec, 'from_components') + @mock.patch.object(scheduler_utils, 'setup_instance_group') + @mock.patch.object(utils, 'get_image_from_system_metadata') + def do_test(get_image, setup_ig, from_components, select_dest, + check_compat, call_livem_checks): + get_image.return_value = "image" + from_components.return_value = another_spec + select_dest.return_value = [{'host': 'host1'}] + + self.assertEqual("host1", task._find_destination()) + + get_image.assert_called_once_with(self.instance.system_metadata) + fake_props = {'instance_properties': {'uuid': self.instance_uuid}} + setup_ig.assert_called_once_with( + self.context, fake_props, + {'ignore_hosts': [self.instance_host]} + ) + select_dest.assert_called_once_with(self.context, another_spec) + check_compat.assert_called_once_with("host1") + call_livem_checks.assert_called_once_with("host1") + do_test() + def test_find_destination_no_image_works(self): self.instance['image_ref'] = '' - self.mox.StubOutWithMock(scheduler_utils, 'build_request_spec') self.mox.StubOutWithMock(scheduler_utils, 'setup_instance_group') - self.mox.StubOutWithMock(objects.RequestSpec, 'from_primitives') self.mox.StubOutWithMock(self.task.scheduler_client, 'select_destinations') self.mox.StubOutWithMock(self.task, '_check_compatible_with_source_hypervisor') self.mox.StubOutWithMock(self.task, '_call_livem_checks_on_host') - scheduler_utils.build_request_spec( - self.context, - {'properties': {'hw_disk_bus': 'scsi'}}, - mox.IgnoreArg()).AndReturn({}) + fake_props = {'instance_properties': {'uuid': self.instance_uuid}} scheduler_utils.setup_instance_group( - self.context, {}, {'ignore_hosts': [self.instance_host]}) - fake_spec = objects.RequestSpec() - objects.RequestSpec.from_primitives( - self.context, mox.IgnoreArg(), - mox.IgnoreArg()).AndReturn(fake_spec) + self.context, fake_props, {'ignore_hosts': [self.instance_host]}) self.task.scheduler_client.select_destinations(self.context, - fake_spec).AndReturn( + self.fake_spec).AndReturn( [{'host': 'host1'}]) self.task._check_compatible_with_source_hypervisor("host1") self.task._call_livem_checks_on_host("host1") @@ -313,9 +334,7 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase): def _test_find_destination_retry_hypervisor_raises(self, error): self.mox.StubOutWithMock(utils, 'get_image_from_system_metadata') - self.mox.StubOutWithMock(scheduler_utils, 'build_request_spec') self.mox.StubOutWithMock(scheduler_utils, 'setup_instance_group') - self.mox.StubOutWithMock(objects.RequestSpec, 'from_primitives') self.mox.StubOutWithMock(self.task.scheduler_client, 'select_destinations') self.mox.StubOutWithMock(self.task, @@ -324,25 +343,17 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase): utils.get_image_from_system_metadata( self.instance.system_metadata).AndReturn("image") - scheduler_utils.build_request_spec(self.context, mox.IgnoreArg(), - mox.IgnoreArg()).AndReturn({}) + fake_props = {'instance_properties': {'uuid': self.instance_uuid}} scheduler_utils.setup_instance_group( - self.context, {}, {'ignore_hosts': [self.instance_host]}) - fake_spec = objects.RequestSpec() - objects.RequestSpec.from_primitives( - self.context, {}, mox.IgnoreArg()).AndReturn(fake_spec) + self.context, fake_props, {'ignore_hosts': [self.instance_host]}) self.task.scheduler_client.select_destinations(self.context, - fake_spec).AndReturn( + self.fake_spec).AndReturn( [{'host': 'host1'}]) self.task._check_compatible_with_source_hypervisor("host1")\ .AndRaise(error) - scheduler_utils.setup_instance_group( - self.context, {}, {'ignore_hosts': [self.instance_host, "host1"]}) - objects.RequestSpec.from_primitives( - self.context, {}, mox.IgnoreArg()).AndReturn(fake_spec) self.task.scheduler_client.select_destinations(self.context, - fake_spec).AndReturn( + self.fake_spec).AndReturn( [{'host': 'host2'}]) self.task._check_compatible_with_source_hypervisor("host2") self.task._call_livem_checks_on_host("host2") @@ -361,9 +372,7 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase): def test_find_destination_retry_with_invalid_livem_checks(self): self.flags(migrate_max_retries=1) self.mox.StubOutWithMock(utils, 'get_image_from_system_metadata') - self.mox.StubOutWithMock(scheduler_utils, 'build_request_spec') self.mox.StubOutWithMock(scheduler_utils, 'setup_instance_group') - self.mox.StubOutWithMock(objects.RequestSpec, 'from_primitives') self.mox.StubOutWithMock(self.task.scheduler_client, 'select_destinations') self.mox.StubOutWithMock(self.task, @@ -372,28 +381,18 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase): utils.get_image_from_system_metadata( self.instance.system_metadata).AndReturn("image") - scheduler_utils.build_request_spec(self.context, mox.IgnoreArg(), - mox.IgnoreArg()).AndReturn({}) + fake_props = {'instance_properties': {'uuid': self.instance_uuid}} scheduler_utils.setup_instance_group( - self.context, {}, {'ignore_hosts': [self.instance_host]}) - fake_spec = objects.RequestSpec() - objects.RequestSpec.from_primitives( - self.context, mox.IgnoreArg(), - mox.IgnoreArg()).AndReturn(fake_spec) + self.context, fake_props, {'ignore_hosts': [self.instance_host]}) self.task.scheduler_client.select_destinations(self.context, - fake_spec).AndReturn( + self.fake_spec).AndReturn( [{'host': 'host1'}]) self.task._check_compatible_with_source_hypervisor("host1") self.task._call_livem_checks_on_host("host1")\ .AndRaise(exception.Invalid) - scheduler_utils.setup_instance_group( - self.context, {}, {'ignore_hosts': [self.instance_host, "host1"]}) - objects.RequestSpec.from_primitives( - self.context, mox.IgnoreArg(), - mox.IgnoreArg()).AndReturn(fake_spec) self.task.scheduler_client.select_destinations(self.context, - fake_spec).AndReturn( + self.fake_spec).AndReturn( [{'host': 'host2'}]) self.task._check_compatible_with_source_hypervisor("host2") self.task._call_livem_checks_on_host("host2") @@ -404,9 +403,7 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase): def test_find_destination_retry_with_failed_migration_pre_checks(self): self.flags(migrate_max_retries=1) self.mox.StubOutWithMock(utils, 'get_image_from_system_metadata') - self.mox.StubOutWithMock(scheduler_utils, 'build_request_spec') self.mox.StubOutWithMock(scheduler_utils, 'setup_instance_group') - self.mox.StubOutWithMock(objects.RequestSpec, 'from_primitives') self.mox.StubOutWithMock(self.task.scheduler_client, 'select_destinations') self.mox.StubOutWithMock(self.task, @@ -415,29 +412,18 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase): utils.get_image_from_system_metadata( self.instance.system_metadata).AndReturn("image") - scheduler_utils.build_request_spec(self.context, mox.IgnoreArg(), - mox.IgnoreArg()).AndReturn({}) + fake_props = {'instance_properties': {'uuid': self.instance_uuid}} scheduler_utils.setup_instance_group( - self.context, {}, {'ignore_hosts': [self.instance_host]}) - fake_spec = objects.RequestSpec() - objects.RequestSpec.from_primitives( - self.context, mox.IgnoreArg(), - mox.IgnoreArg()).AndReturn(fake_spec) + self.context, fake_props, {'ignore_hosts': [self.instance_host]}) self.task.scheduler_client.select_destinations(self.context, - fake_spec).AndReturn( + self.fake_spec).AndReturn( [{'host': 'host1'}]) self.task._check_compatible_with_source_hypervisor("host1") self.task._call_livem_checks_on_host("host1")\ .AndRaise(exception.MigrationPreCheckError("reason")) - scheduler_utils.setup_instance_group( - self.context, {}, {'ignore_hosts': [self.instance_host, "host1"]}) - fake_spec = objects.RequestSpec() - objects.RequestSpec.from_primitives( - self.context, mox.IgnoreArg(), - mox.IgnoreArg()).AndReturn(fake_spec) self.task.scheduler_client.select_destinations(self.context, - fake_spec).AndReturn( + self.fake_spec).AndReturn( [{'host': 'host2'}]) self.task._check_compatible_with_source_hypervisor("host2") self.task._call_livem_checks_on_host("host2") @@ -448,9 +434,7 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase): def test_find_destination_retry_exceeds_max(self): self.flags(migrate_max_retries=0) self.mox.StubOutWithMock(utils, 'get_image_from_system_metadata') - self.mox.StubOutWithMock(scheduler_utils, 'build_request_spec') self.mox.StubOutWithMock(scheduler_utils, 'setup_instance_group') - self.mox.StubOutWithMock(objects.RequestSpec, 'from_primitives') self.mox.StubOutWithMock(self.task.scheduler_client, 'select_destinations') self.mox.StubOutWithMock(self.task, @@ -458,16 +442,11 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase): utils.get_image_from_system_metadata( self.instance.system_metadata).AndReturn("image") - scheduler_utils.build_request_spec(self.context, mox.IgnoreArg(), - mox.IgnoreArg()).AndReturn({}) + fake_props = {'instance_properties': {'uuid': self.instance_uuid}} scheduler_utils.setup_instance_group( - self.context, {}, {'ignore_hosts': [self.instance_host]}) - fake_spec = objects.RequestSpec() - objects.RequestSpec.from_primitives( - self.context, mox.IgnoreArg(), - mox.IgnoreArg()).AndReturn(fake_spec) + self.context, fake_props, {'ignore_hosts': [self.instance_host]}) self.task.scheduler_client.select_destinations(self.context, - fake_spec).AndReturn( + self.fake_spec).AndReturn( [{'host': 'host1'}]) self.task._check_compatible_with_source_hypervisor("host1")\ .AndRaise(exception.DestinationHypervisorTooOld) @@ -481,23 +460,16 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase): def test_find_destination_when_runs_out_of_hosts(self): self.mox.StubOutWithMock(utils, 'get_image_from_system_metadata') - self.mox.StubOutWithMock(scheduler_utils, 'build_request_spec') self.mox.StubOutWithMock(scheduler_utils, 'setup_instance_group') - self.mox.StubOutWithMock(objects.RequestSpec, 'from_primitives') self.mox.StubOutWithMock(self.task.scheduler_client, 'select_destinations') utils.get_image_from_system_metadata( self.instance.system_metadata).AndReturn("image") - scheduler_utils.build_request_spec(self.context, mox.IgnoreArg(), - mox.IgnoreArg()).AndReturn({}) + fake_props = {'instance_properties': {'uuid': self.instance_uuid}} scheduler_utils.setup_instance_group( - self.context, {}, {'ignore_hosts': [self.instance_host]}) - fake_spec = objects.RequestSpec() - objects.RequestSpec.from_primitives( - self.context, - mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(fake_spec) + self.context, fake_props, {'ignore_hosts': [self.instance_host]}) self.task.scheduler_client.select_destinations(self.context, - fake_spec).AndRaise( + self.fake_spec).AndRaise( exception.NoValidHost(reason="")) self.mox.ReplayAll()