Merge "force_live_migration remove redundant check"
This commit is contained in:
@@ -13,7 +13,7 @@
|
|||||||
"disabled_reason": null,
|
"disabled_reason": null,
|
||||||
"report_count": 1,
|
"report_count": 1,
|
||||||
"forced_down": false,
|
"forced_down": false,
|
||||||
"version": 10
|
"version": 11
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"event_type": "service.update",
|
"event_type": "service.update",
|
||||||
|
|||||||
@@ -3439,7 +3439,7 @@ class API(base.Base):
|
|||||||
context, instance, instance_actions.LIVE_MIGRATION_FORCE_COMPLETE)
|
context, instance, instance_actions.LIVE_MIGRATION_FORCE_COMPLETE)
|
||||||
|
|
||||||
self.compute_rpcapi.live_migration_force_complete(
|
self.compute_rpcapi.live_migration_force_complete(
|
||||||
context, instance, migration.id)
|
context, instance, migration)
|
||||||
|
|
||||||
@check_instance_lock
|
@check_instance_lock
|
||||||
@check_instance_cell
|
@check_instance_cell
|
||||||
|
|||||||
@@ -499,7 +499,7 @@ class ComputeVirtAPI(virtapi.VirtAPI):
|
|||||||
class ComputeManager(manager.Manager):
|
class ComputeManager(manager.Manager):
|
||||||
"""Manages the running instances from creation to destruction."""
|
"""Manages the running instances from creation to destruction."""
|
||||||
|
|
||||||
target = messaging.Target(version='4.11')
|
target = messaging.Target(version='4.12')
|
||||||
|
|
||||||
# How long to wait in seconds before re-issuing a shutdown
|
# How long to wait in seconds before re-issuing a shutdown
|
||||||
# signal to an instance during power off. The overall
|
# signal to an instance during power off. The overall
|
||||||
@@ -5163,23 +5163,21 @@ class ComputeManager(manager.Manager):
|
|||||||
block_migration, migration,
|
block_migration, migration,
|
||||||
migrate_data)
|
migrate_data)
|
||||||
|
|
||||||
|
# TODO(tdurakov): migration_id is used since 4.12 rpc api version
|
||||||
|
# remove migration_id parameter when the compute RPC version
|
||||||
|
# is bumped to 5.x.
|
||||||
@wrap_exception()
|
@wrap_exception()
|
||||||
@wrap_instance_event
|
@wrap_instance_event
|
||||||
@wrap_instance_fault
|
@wrap_instance_fault
|
||||||
def live_migration_force_complete(self, context, instance, migration_id):
|
def live_migration_force_complete(self, context, instance,
|
||||||
|
migration_id=None):
|
||||||
"""Force live migration to complete.
|
"""Force live migration to complete.
|
||||||
|
|
||||||
:param context: Security context
|
:param context: Security context
|
||||||
:param instance: The instance that is being migrated
|
:param instance: The instance that is being migrated
|
||||||
:param migration_id: ID of ongoing migration
|
:param migration_id: ID of ongoing migration; is currently not used,
|
||||||
|
and isn't removed for backward compatibility
|
||||||
"""
|
"""
|
||||||
migration = objects.Migration.get_by_id(context, migration_id)
|
|
||||||
if migration.status != 'running':
|
|
||||||
raise exception.InvalidMigrationState(migration_id=migration_id,
|
|
||||||
instance_uuid=instance.uuid,
|
|
||||||
state=migration.status,
|
|
||||||
method='force complete')
|
|
||||||
|
|
||||||
self._notify_about_instance_usage(
|
self._notify_about_instance_usage(
|
||||||
context, instance, 'live.migration.force.complete.start')
|
context, instance, 'live.migration.force.complete.start')
|
||||||
|
|||||||
@@ -310,6 +310,8 @@ class ComputeAPI(object):
|
|||||||
... Mitaka supports messaging version 4.11. So, any changes to
|
... Mitaka supports messaging version 4.11. So, any changes to
|
||||||
existing methods in 4.x after that point should be done so that they
|
existing methods in 4.x after that point should be done so that they
|
||||||
can handle the version_cap being set to 4.11
|
can handle the version_cap being set to 4.11
|
||||||
|
|
||||||
|
* 4.12 - Remove migration_id from live_migration_force_complete
|
||||||
'''
|
'''
|
||||||
|
|
||||||
VERSION_ALIASES = {
|
VERSION_ALIASES = {
|
||||||
@@ -634,12 +636,16 @@ class ComputeAPI(object):
|
|||||||
dest=dest, block_migration=block_migration,
|
dest=dest, block_migration=block_migration,
|
||||||
migrate_data=migrate_data, **args)
|
migrate_data=migrate_data, **args)
|
||||||
|
|
||||||
def live_migration_force_complete(self, ctxt, instance, migration_id):
|
def live_migration_force_complete(self, ctxt, instance, migration):
|
||||||
version = '4.9'
|
version = '4.12'
|
||||||
cctxt = self.client.prepare(server=_compute_host(None, instance),
|
kwargs = {}
|
||||||
version=version)
|
if not self.client.can_send_version(version):
|
||||||
|
version = '4.9'
|
||||||
|
kwargs['migration_id'] = migration.id
|
||||||
|
cctxt = self.client.prepare(server=_compute_host(
|
||||||
|
migration.source_compute, instance), version=version)
|
||||||
cctxt.cast(ctxt, 'live_migration_force_complete', instance=instance,
|
cctxt.cast(ctxt, 'live_migration_force_complete', instance=instance,
|
||||||
migration_id=migration_id)
|
**kwargs)
|
||||||
|
|
||||||
def live_migration_abort(self, ctxt, instance, migration_id):
|
def live_migration_abort(self, ctxt, instance, migration_id):
|
||||||
version = '4.10'
|
version = '4.10'
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ LOG = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
# NOTE(danms): This is the global service version counter
|
# NOTE(danms): This is the global service version counter
|
||||||
SERVICE_VERSION = 10
|
SERVICE_VERSION = 11
|
||||||
|
|
||||||
|
|
||||||
# NOTE(danms): This is our SERVICE_VERSION history. The idea is that any
|
# NOTE(danms): This is our SERVICE_VERSION history. The idea is that any
|
||||||
@@ -73,6 +73,8 @@ SERVICE_VERSION_HISTORY = (
|
|||||||
{'compute_rpc': '4.11'},
|
{'compute_rpc': '4.11'},
|
||||||
# Version 10: Compute node conversion to Inventories
|
# Version 10: Compute node conversion to Inventories
|
||||||
{'compute_rpc': '4.11'},
|
{'compute_rpc': '4.11'},
|
||||||
|
# Version 11: Removed migration_id from live_migration_force_complete
|
||||||
|
{'compute_rpc': '4.12'},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ class ServerMigrationsSampleJsonTest(test_servers.ServersSampleBase):
|
|||||||
migration = objects.Migration()
|
migration = objects.Migration()
|
||||||
migration.id = 1
|
migration.id = 1
|
||||||
migration.status = 'running'
|
migration.status = 'running'
|
||||||
|
migration.source_compute = self.compute.host
|
||||||
get_by_id_and_instance.return_value = migration
|
get_by_id_and_instance.return_value = migration
|
||||||
self._do_post('servers/%s/action' % self.uuid, 'live-migrate-server',
|
self._do_post('servers/%s/action' % self.uuid, 'live-migrate-server',
|
||||||
{'hostname': self.compute.host})
|
{'hostname': self.compute.host})
|
||||||
|
|||||||
@@ -3673,11 +3673,11 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||||||
with mock.patch.object(
|
with mock.patch.object(
|
||||||
rpcapi, 'live_migration_force_complete') as lm_force_complete:
|
rpcapi, 'live_migration_force_complete') as lm_force_complete:
|
||||||
self.compute_api.live_migrate_force_complete(
|
self.compute_api.live_migrate_force_complete(
|
||||||
self.context, instance, migration.id)
|
self.context, instance, migration)
|
||||||
|
|
||||||
lm_force_complete.assert_called_once_with(self.context,
|
lm_force_complete.assert_called_once_with(self.context,
|
||||||
instance,
|
instance,
|
||||||
0)
|
migration)
|
||||||
action_start.assert_called_once_with(
|
action_start.assert_called_once_with(
|
||||||
self.context, instance.uuid, 'live_migration_force_complete',
|
self.context, instance.uuid, 'live_migration_force_complete',
|
||||||
want_result=False)
|
want_result=False)
|
||||||
|
|||||||
@@ -4663,23 +4663,6 @@ class ComputeManagerMigrationTestCase(test.NoDBTestCase):
|
|||||||
|
|
||||||
_do_test()
|
_do_test()
|
||||||
|
|
||||||
@mock.patch.object(compute_utils, 'add_instance_fault_from_exc')
|
|
||||||
def test_live_migration_pause_vm_invalid_migration_state(
|
|
||||||
self, add_instance_fault_from_exc):
|
|
||||||
|
|
||||||
instance = objects.Instance(id=1234, uuid=str(uuid.uuid4()))
|
|
||||||
migration = objects.Migration()
|
|
||||||
migration.status = 'aborted'
|
|
||||||
migration.id = 0
|
|
||||||
|
|
||||||
@mock.patch.object(objects.Migration, 'get_by_id',
|
|
||||||
return_value=migration)
|
|
||||||
def _do_test(get_by_id):
|
|
||||||
self.assertRaises(exception.InvalidMigrationState,
|
|
||||||
self.compute.live_migration_force_complete,
|
|
||||||
self.context, instance, migration.id)
|
|
||||||
_do_test()
|
|
||||||
|
|
||||||
def test_post_live_migration_at_destination_success(self):
|
def test_post_live_migration_at_destination_success(self):
|
||||||
|
|
||||||
@mock.patch.object(self.instance, 'save')
|
@mock.patch.object(self.instance, 'save')
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ from nova import context
|
|||||||
from nova import exception
|
from nova import exception
|
||||||
from nova.objects import block_device as objects_block_dev
|
from nova.objects import block_device as objects_block_dev
|
||||||
from nova.objects import migrate_data as migrate_data_obj
|
from nova.objects import migrate_data as migrate_data_obj
|
||||||
|
from nova.objects import migration as migration_obj
|
||||||
from nova import test
|
from nova import test
|
||||||
from nova.tests.unit import fake_block_device
|
from nova.tests.unit import fake_block_device
|
||||||
from nova.tests.unit import fake_flavor
|
from nova.tests.unit import fake_flavor
|
||||||
@@ -305,9 +306,45 @@ class ComputeRpcAPITestCase(test.NoDBTestCase):
|
|||||||
migrate_data={}, version='4.8')
|
migrate_data={}, version='4.8')
|
||||||
|
|
||||||
def test_live_migration_force_complete(self):
|
def test_live_migration_force_complete(self):
|
||||||
self._test_compute_api('live_migration_force_complete', 'cast',
|
migration = migration_obj.Migration()
|
||||||
instance=self.fake_instance_obj,
|
migration.id = 1
|
||||||
migration_id='1', version='4.9')
|
migration.source_compute = 'fake'
|
||||||
|
ctxt = context.RequestContext('fake_user', 'fake_project')
|
||||||
|
version = '4.12'
|
||||||
|
rpcapi = compute_rpcapi.ComputeAPI()
|
||||||
|
mock_client = mock.MagicMock()
|
||||||
|
rpcapi.client = mock_client
|
||||||
|
mock_client.can_send_version.return_value = True
|
||||||
|
mock_cctx = mock.MagicMock()
|
||||||
|
mock_client.prepare.return_value = mock_cctx
|
||||||
|
rpcapi.live_migration_force_complete(ctxt, self.fake_instance_obj,
|
||||||
|
migration)
|
||||||
|
mock_client.prepare.assert_called_with(server=migration.source_compute,
|
||||||
|
version=version)
|
||||||
|
mock_cctx.cast.assert_called_with(ctxt,
|
||||||
|
'live_migration_force_complete',
|
||||||
|
instance=self.fake_instance_obj)
|
||||||
|
|
||||||
|
def test_live_migration_force_complete_backward_compatibility(self):
|
||||||
|
migration = migration_obj.Migration()
|
||||||
|
migration.id = 1
|
||||||
|
migration.source_compute = 'fake'
|
||||||
|
version = '4.9'
|
||||||
|
ctxt = context.RequestContext('fake_user', 'fake_project')
|
||||||
|
rpcapi = compute_rpcapi.ComputeAPI()
|
||||||
|
mock_client = mock.MagicMock()
|
||||||
|
rpcapi.client = mock_client
|
||||||
|
mock_client.can_send_version.return_value = False
|
||||||
|
mock_cctx = mock.MagicMock()
|
||||||
|
mock_client.prepare.return_value = mock_cctx
|
||||||
|
rpcapi.live_migration_force_complete(ctxt, self.fake_instance_obj,
|
||||||
|
migration)
|
||||||
|
mock_client.prepare.assert_called_with(server=migration.source_compute,
|
||||||
|
version=version)
|
||||||
|
mock_cctx.cast.assert_called_with(ctxt,
|
||||||
|
'live_migration_force_complete',
|
||||||
|
instance=self.fake_instance_obj,
|
||||||
|
migration_id=migration.id)
|
||||||
|
|
||||||
def test_live_migration_abort(self):
|
def test_live_migration_abort(self):
|
||||||
self._test_compute_api('live_migration_abort', 'cast',
|
self._test_compute_api('live_migration_abort', 'cast',
|
||||||
|
|||||||
Reference in New Issue
Block a user