def test_migrate_live_unexpected_error(self): body = { 'os-migrateLive': { 'host': 'hostname', 'block_migration': 'auto' } } exc = exception.InvalidHypervisorType( reason="The supplied hypervisor type of is invalid.") instance = self._stub_instance_get() with mock.patch.object(self.compute_api, 'live_migrate', side_effect=exc) as mock_live_migrate: self.assertRaises(webob.exc.HTTPInternalServerError, self.controller._migrate_live, self.req, instance.uuid, body=body) mock_live_migrate.assert_called_once_with(self.context, instance, None, self.disk_over_commit, 'hostname', self.force, self. async) self.mock_get.assert_called_once_with(self.context, instance.uuid, expected_attrs=None)
def _live_migration_common_check(self, context, instance_ref, dest): """Live migration common check routine. The following checks are based on http://wiki.libvirt.org/page/TodoPreMigrationChecks :param context: security context :param instance_ref: nova.db.sqlalchemy.models.Instance object :param dest: destination host """ dservice_ref = self._get_compute_info(context, dest) src = instance_ref['host'] oservice_ref = self._get_compute_info(context, src) # Checking hypervisor is same. orig_hypervisor = oservice_ref['hypervisor_type'] dest_hypervisor = dservice_ref['hypervisor_type'] if orig_hypervisor != dest_hypervisor: raise exception.InvalidHypervisorType() # Checking hypervisor version. orig_hypervisor = oservice_ref['hypervisor_version'] dest_hypervisor = dservice_ref['hypervisor_version'] if orig_hypervisor > dest_hypervisor: raise exception.DestinationHypervisorTooOld()
def test_migrate_live_invalid_hypervisor_type(self): ctxt = context.get_admin_context() ctxt.user_id = 'fake' ctxt.project_id = 'fake' ctxt.is_admin = True app = fakes.wsgi_app(fake_auth_context=ctxt, init_only=('servers', )) req = webob.Request.blank('/v2/fake/servers/%s/action' % self.UUID) req.method = 'POST' req.body = jsonutils.dumps({ 'os-migrateLive': { 'host': 'hostname', 'block_migration': False, 'disk_over_commit': False, } }) req.content_type = 'application/json' def fake_update(inst, context, instance, task_state, expected_task_state): return None def fake_migrate_server(self, context, instance, scheduler_hint, live, rebuild, flavor, block_migration, disk_over_commit): raise exception.InvalidHypervisorType() self.stubs.Set(compute_api.API, 'update', fake_update) self.stubs.Set(conductor_api.ComputeTaskAPI, 'migrate_server', fake_migrate_server) res = req.get_response(app) self.assertEqual(res.status_int, 400) self.assertIn(unicode(exception.InvalidHypervisorType()), res.body)
def _live_migration_common_check(self, context, instance_ref, dest): """Live migration common check routine. Below checkings are followed by http://wiki.libvirt.org/page/TodoPreMigrationChecks :param context: security context :param instance_ref: nova.db.sqlalchemy.models.Instance object :param dest: destination host """ # Checking shared storage connectivity self.mounted_on_same_shared_storage(context, instance_ref, dest) # Checking dest exists. dservice_refs = db.service_get_all_compute_by_host(context, dest) dservice_ref = dservice_refs[0]['compute_node'][0] # Checking original host( where instance was launched at) exists. try: oservice_refs = db.service_get_all_compute_by_host( context, instance_ref['launched_on']) except exception.NotFound: raise exception.SourceHostUnavailable() oservice_ref = oservice_refs[0]['compute_node'][0] # Checking hypervisor is same. orig_hypervisor = oservice_ref['hypervisor_type'] dest_hypervisor = dservice_ref['hypervisor_type'] if orig_hypervisor != dest_hypervisor: raise exception.InvalidHypervisorType() # Checkng hypervisor version. orig_hypervisor = oservice_ref['hypervisor_version'] dest_hypervisor = dservice_ref['hypervisor_version'] if orig_hypervisor > dest_hypervisor: raise exception.DestinationHypervisorTooOld() # Checking cpuinfo. try: rpc.call( context, db.queue_get_for(context, FLAGS.compute_topic, dest), { "method": 'compare_cpu', "args": { 'cpu_info': oservice_ref['cpu_info'] } }) except rpc.RemoteError: src = instance_ref['host'] logging.exception( _("host %(dest)s is not compatible with " "original host %(src)s.") % locals()) raise
def _check_compatible_with_source_hypervisor(self, destination): source_info = self._get_compute_info(self.source) destination_info = self._get_compute_info(destination) source_type = source_info['hypervisor_type'] destination_type = destination_info['hypervisor_type'] if source_type != destination_type: raise exception.InvalidHypervisorType() source_version = source_info['hypervisor_version'] destination_version = destination_info['hypervisor_version'] if source_version > destination_version: raise exception.DestinationHypervisorTooOld()
def test_migrate_live_unexpected_error(self): exc = exception.InvalidHypervisorType( reason="The supplied hypervisor type of is invalid.") self.mox.StubOutWithMock(self.compute_api, 'live_migrate') instance = self._stub_instance_get() self.compute_api.live_migrate(self.context, instance, None, self.disk_over_commit, 'hostname', self.force, self. async).AndRaise(exc) self.mox.ReplayAll() body = { 'os-migrateLive': { 'host': 'hostname', 'block_migration': 'auto' } } self.assertRaises(webob.exc.HTTPInternalServerError, self.controller._migrate_live, self.req, instance.uuid, body=body)
def test_migrate_live_invalid_hypervisor_type(self): self._test_migrate_live_failed_with_exception( exception.InvalidHypervisorType())
def fake_migrate_server(self, context, instance, scheduler_hint, live, rebuild, flavor, block_migration, disk_over_commit): raise exception.InvalidHypervisorType()
def _live_migration_common_check(self, context, instance_ref, dest, block_migration): """Live migration common check routine. Below checkings are followed by http://wiki.libvirt.org/page/TodoPreMigrationChecks :param context: security context :param instance_ref: nova.db.sqlalchemy.models.Instance object :param dest: destination host :param block_migration if True, check for block_migration. """ # Checking shared storage connectivity # if block migration, instances_paths should not be on shared storage. try: self.mounted_on_same_shared_storage(context, instance_ref, dest) if block_migration: reason = _("Block migration can not be used " "with shared storage.") raise exception.InvalidSharedStorage(reason=reason, path=dest) except exception.FileNotFound: if not block_migration: src = instance_ref['host'] ipath = FLAGS.instances_path LOG.error( _("Cannot confirm tmpfile at %(ipath)s is on " "same shared storage between %(src)s " "and %(dest)s.") % locals()) raise # Checking dest exists. dservice_refs = db.service_get_all_compute_by_host(context, dest) dservice_ref = dservice_refs[0]['compute_node'][0] # Checking original host( where instance was launched at) exists. try: oservice_refs = db.service_get_all_compute_by_host( context, instance_ref['launched_on']) except exception.NotFound: raise exception.SourceHostUnavailable() oservice_ref = oservice_refs[0]['compute_node'][0] # Checking hypervisor is same. orig_hypervisor = oservice_ref['hypervisor_type'] dest_hypervisor = dservice_ref['hypervisor_type'] if orig_hypervisor != dest_hypervisor: raise exception.InvalidHypervisorType() # Checkng hypervisor version. orig_hypervisor = oservice_ref['hypervisor_version'] dest_hypervisor = dservice_ref['hypervisor_version'] if orig_hypervisor > dest_hypervisor: raise exception.DestinationHypervisorTooOld() # Checking cpuinfo. try: rpc.call( context, db.queue_get_for(context, FLAGS.compute_topic, dest), { "method": 'compare_cpu', "args": { 'cpu_info': oservice_ref['cpu_info'] } }) except rpc.RemoteError: src = instance_ref['host'] LOG.exception( _("host %(dest)s is not compatible with " "original host %(src)s.") % locals()) raise
def _live_migration_common_check(self, context, instance_ref, dest, block_migration, disk_over_commit): """Live migration common check routine. Below checkings are followed by http://wiki.libvirt.org/page/TodoPreMigrationChecks :param context: security context :param instance_ref: nova.db.sqlalchemy.models.Instance object :param dest: destination host :param block_migration: if true, block_migration. :param disk_over_commit: if True, consider real(not virtual) disk size. """ # Checking shared storage connectivity # if block migration, instances_paths should not be on shared storage. shared = self.mounted_on_same_shared_storage(context, instance_ref, dest) if block_migration: if shared: reason = _("Block migration can not be used " "with shared storage.") raise exception.InvalidSharedStorage(reason=reason, path=dest) elif not shared: reason = _("Live migration can not be used " "without shared storage.") raise exception.InvalidSharedStorage(reason=reason, path=dest) # Checking destination host exists. dservice_refs = db.service_get_all_compute_by_host(context, dest) dservice_ref = dservice_refs[0]['compute_node'][0] # Checking original host( where instance was launched at) exists. try: oservice_refs = db.service_get_all_compute_by_host(context, instance_ref['host']) except exception.NotFound: raise exception.SourceHostUnavailable() oservice_ref = oservice_refs[0]['compute_node'][0] # Checking hypervisor is same. orig_hypervisor = oservice_ref['hypervisor_type'] dest_hypervisor = dservice_ref['hypervisor_type'] if orig_hypervisor != dest_hypervisor: raise exception.InvalidHypervisorType() # Checkng hypervisor version. orig_hypervisor = oservice_ref['hypervisor_version'] dest_hypervisor = dservice_ref['hypervisor_version'] if orig_hypervisor > dest_hypervisor: raise exception.DestinationHypervisorTooOld() # Checking cpuinfo. try: self.compute_rpcapi.compare_cpu(context, oservice_ref['cpu_info'], dest) except exception.InvalidCPUInfo: src = instance_ref['host'] LOG.exception(_("host %(dest)s is not compatible with " "original host %(src)s.") % locals()) raise
def test_live_migration_auto_set_dest(self): instance = self._live_migration_instance() # Confirm scheduler picks target host if none given. self.mox.StubOutWithMock(db, 'instance_type_get') self.mox.StubOutWithMock(self.driver, '_live_migration_src_check') self.mox.StubOutWithMock(self.driver, 'select_hosts') self.mox.StubOutWithMock(self.driver, '_live_migration_common_check') self.mox.StubOutWithMock(rpc, 'call') self.mox.StubOutWithMock(self.driver.compute_rpcapi, 'live_migration') dest = None block_migration = False disk_over_commit = False instance_type = instance_types.extract_instance_type(instance) request_spec = {'instance_properties': instance, 'instance_type': instance_type, 'instance_uuids': [instance['uuid']], 'image': self.image_service.show(self.context, instance['image_ref']) } self.driver._live_migration_src_check(self.context, instance) db.instance_type_get(self.context, instance_type['id']).MultipleTimes().AndReturn( instance_type) # First selected host raises exception.InvalidHypervisorType self.driver.select_hosts(self.context, request_spec, {'ignore_hosts': [instance['host']]}).AndReturn(['fake_host2']) self.driver._live_migration_common_check(self.context, instance, 'fake_host2').AndRaise(exception.InvalidHypervisorType()) # Second selected host raises exception.InvalidCPUInfo self.driver.select_hosts(self.context, request_spec, {'ignore_hosts': [instance['host'], 'fake_host2']}).AndReturn(['fake_host3']) self.driver._live_migration_common_check(self.context, instance, 'fake_host3') rpc.call(self.context, "compute.fake_host3", {"method": 'check_can_live_migrate_destination', "args": {'instance': instance, 'block_migration': block_migration, 'disk_over_commit': disk_over_commit}, "version": compute_rpcapi.ComputeAPI.BASE_RPC_API_VERSION}, None).AndRaise(exception.InvalidCPUInfo(reason="")) # Third selected host pass all checks self.driver.select_hosts(self.context, request_spec, {'ignore_hosts': [instance['host'], 'fake_host2', 'fake_host3']}).AndReturn(['fake_host4']) self.driver._live_migration_common_check(self.context, instance, 'fake_host4') rpc.call(self.context, "compute.fake_host4", {"method": 'check_can_live_migrate_destination', "args": {'instance': instance, 'block_migration': block_migration, 'disk_over_commit': disk_over_commit}, "version": compute_rpcapi.ComputeAPI.BASE_RPC_API_VERSION}, None).AndReturn({}) self.driver.compute_rpcapi.live_migration(self.context, host=instance['host'], instance=instance, dest='fake_host4', block_migration=block_migration, migrate_data={}) self.mox.ReplayAll() result = self.driver.schedule_live_migration(self.context, instance=instance, dest=dest, block_migration=block_migration, disk_over_commit=disk_over_commit) self.assertEqual(result, None)
def fake_scheduler_api_live_migration(context, dest, block_migration=False, disk_over_commit=False, instance=None, instance_id=None, topic=None): raise exception.InvalidHypervisorType()