allows a mgmt user to migrate an instance to a specific host

a mgmt user and use the instance migrate api and specify a host that
they would like the instance to move to.
Fixing migration fake mode.

implements blueprint migration-force-to-host
https://blueprints.launchpad.net/reddwarf/+spec/migration-force-to-host

Change-Id: I1fd7b2f5ae5328de642ec1ad6ee4d62c5a29168f
This commit is contained in:
Craig Vyvial 2013-03-13 11:49:04 -05:00
parent 58917ea6e2
commit 166fd33ee0
7 changed files with 29 additions and 16 deletions

View File

@ -128,7 +128,9 @@ class MgmtInstanceController(InstanceController):
def _action_migrate(self, context, instance, body):
LOG.debug("Migrating instance %s." % instance.id)
instance.migrate()
LOG.debug("body['migrate']= %s" % body['migrate'])
host = body['migrate'].get('host', None)
instance.migrate(host)
return wsgi.Result(None, 202)
def _action_reset_task_status(self, context, instance, body):

View File

@ -554,11 +554,11 @@ class Instance(BuiltInstance):
self.update_db(task_status=InstanceTasks.REBOOTING)
task_api.API(self.context).restart(self.id)
def migrate(self):
def migrate(self, host=None):
self.validate_can_perform_action()
LOG.info("Migrating instance %s..." % self.id)
LOG.info("Migrating instance id = %s, to host = %s" % (self.id, host))
self.update_db(task_status=InstanceTasks.MIGRATING)
task_api.API(self.context).migrate(self.id)
task_api.API(self.context).migrate(self.id, host)
def reset_task_status(self):
LOG.info("Settting task status to NONE on instance %s..." % self.id)

View File

@ -88,9 +88,9 @@ class API(ManagerAPI):
LOG.debug("Making async call to restart instance: %s" % instance_id)
self._cast("restart", instance_id=instance_id)
def migrate(self, instance_id):
def migrate(self, instance_id, host):
LOG.debug("Making async call to migrate instance: %s" % instance_id)
self._cast("migrate", instance_id=instance_id)
self._cast("migrate", instance_id=instance_id, host=host)
def delete_instance(self, instance_id):
LOG.debug("Making async call to delete instance: %s" % instance_id)

View File

@ -59,9 +59,9 @@ class Manager(periodic_task.PeriodicTasks):
instance_tasks = models.BuiltInstanceTasks.load(context, instance_id)
instance_tasks.restart()
def migrate(self, context, instance_id):
def migrate(self, context, instance_id, host):
instance_tasks = models.BuiltInstanceTasks.load(context, instance_id)
instance_tasks.migrate()
instance_tasks.migrate(host)
def delete_instance(self, context, instance_id):
try:

View File

@ -487,8 +487,9 @@ class BuiltInstanceTasks(BuiltInstance, NotifyMixin, ConfigurationMixin):
action = ResizeAction(self, old_flavor, new_flavor)
action.execute()
def migrate(self):
action = MigrateAction(self)
def migrate(self, host):
LOG.debug("Calling migrate with host(%s)..." % host)
action = MigrateAction(self, host)
action.execute()
def create_backup(self, backup_id):
@ -788,13 +789,18 @@ class ResizeAction(ResizeActionBase):
class MigrateAction(ResizeActionBase):
def __init__(self, instance, host=None):
self.instance = instance
self.host = host
def _assert_nova_action_was_successful(self):
LOG.debug("Currently no assertions for a Migrate Action")
def _initiate_nova_action(self):
LOG.debug("Migrating instance %s without flavor change ..."
% self.instance.id)
self.instance.server.migrate()
LOG.debug("Forcing migration to host(%s)" % self.host)
self.instance.server.migrate(force_host=self.host)
def _record_action_success(self):
LOG.debug("Successfully finished Migration to %s: %s" %

View File

@ -227,8 +227,9 @@ class MigrateTests(ResizeTestBase):
self.guest.restart()
def test_successful_migrate(self):
self.mock.StubOutWithMock(self.instance.server, 'migrate')
self._stop_db()
self.server.migrate()
self.server.migrate(force_host=None)
self._server_changes_to("VERIFY_RESIZE", NEW_FLAVOR_ID)
self.instance._set_service_status_to_paused()
self.instance.service_status = ServiceStatuses.RUNNING

View File

@ -174,10 +174,10 @@ class FakeServer(object):
return [{"href": url, "rel": link_type}
for link_type in ['self', 'bookmark']]
def migrate(self):
self.resize(None)
def migrate(self, force_host=None):
self.resize(None, force_host)
def resize(self, new_flavor_id=None):
def resize(self, new_flavor_id=None, force_host=None):
self._current_status = "RESIZE"
if self.name.endswith("_RESIZE_TIMEOUT"):
raise PollTimeOut()
@ -191,7 +191,11 @@ class FakeServer(object):
def change_host():
self.old_host = self.host
self.host = [host for host in FAKE_HOSTS if host != self.host][0]
if not force_host:
self.host = [host for host in FAKE_HOSTS
if host != self.host][0]
else:
self.host = force_host
def set_flavor():
if self.name.endswith("_RESIZE_ERROR"):