adding mgmt action to reboot an instance

This commit is contained in:
Paul Marshall 2012-07-05 14:51:55 -05:00 committed by Tim Simpson
parent ab56688420
commit bb000df3bf
7 changed files with 102 additions and 7 deletions

View File

@ -71,6 +71,9 @@ agent_heartbeat_time = 10
agent_call_low_timeout = 5
agent_call_high_timeout = 100
# Reboot time out for instances
reboot_time_out = 60
# ============ notifer queue kombu connection options ========================
notifier_queue_hostname = localhost

View File

@ -73,12 +73,42 @@ class MgmtInstanceController(InstanceController):
@admin_context
def action(self, req, body, tenant_id, id):
LOG.info("Request made by tenant %s to stop instance %s."
% (tenant_id, id))
LOG.info("req : '%s'\n\n" % req)
LOG.info("Committing an ACTION against instance %s for tenant '%s'"
% (id, tenant_id))
if not body:
raise exception.BadRequest(_("Invalid request body."))
context = req.environ[wsgi.CONTEXT_KEY]
instance = models.MgmtInstance.load(context=context, id=id)
if 'stop' in body:
instance.stop_mysql()
_actions = {
'stop': self._action_stop,
'reboot': self._action_reboot
}
selected_action = None
for key in body:
if key in _actions:
if selected_action is not None:
msg = _("Only one action can be specified per request.")
raise exception.BadRequest(msg)
selected_action = _actions[key]
else:
msg = _("Invalid instance action: %s") % key
raise exception.BadRequest(msg)
if selected_action:
return selected_action(context, instance, body)
else:
raise exception.BadRequest(_("Invalid request body."))
def _action_stop(self, context, instance, body):
LOG.debug("Stopping MySQL on instance %s." % instance.id)
instance.stop_mysql()
return wsgi.Result(None, 202)
def _action_reboot(self, context, instance, body):
LOG.debug("Rebooting instance %s." % instance.id)
instance.reboot()
return wsgi.Result(None, 202)
@admin_context
def root(self, req, tenant_id, id):

View File

@ -461,9 +461,15 @@ class Instance(BuiltInstance):
self.update_db(task_status=InstanceTasks.RESIZING)
task_api.API(self.context).resize_volume(new_size, self.id)
def reboot(self):
self._validate_can_perform_action()
LOG.info("Rebooting instance %s..." % self.id)
self.update_db(task_status=InstanceTasks.REBOOTING)
task_api.API(self.context).reboot(self.id)
def restart(self):
self._validate_can_perform_action()
LOG.info("Restarting instance %s..." % self.id)
LOG.info("Restarting MySQL on instance %s..." % self.id)
# Set our local status since Nova might not change it quick enough.
#TODO(tim.simpson): Possible bad stuff can happen if this service
# shuts down before it can set status to NONE.

View File

@ -69,6 +69,10 @@ class API(ManagerAPI):
old_memory_size=old_memory_size,
new_memory_size=new_memory_size)
def reboot(self, instance_id):
LOG.debug("Making async call to reboot instance: %s" % instance_id)
self._cast("reboot", instance_id=instance_id)
def restart(self, instance_id):
LOG.debug("Making async call to restart instance: %s" % instance_id)
self._cast("restart", instance_id=instance_id)

View File

@ -49,6 +49,10 @@ class TaskManager(service.Manager):
instance_tasks.resize_flavor(new_flavor_id, old_memory_size,
new_memory_size)
def reboot(self, context, instance_id):
instance_tasks = models.BuiltInstanceTasks.load(context, instance_id)
instance_tasks.reboot()
def restart(self, context, instance_id):
instance_tasks = models.BuiltInstanceTasks.load(context, instance_id)
instance_tasks.restart()

View File

@ -400,11 +400,40 @@ class BuiltInstanceTasks(BuiltInstance):
finally:
self.update_db(task_status=inst_models.InstanceTasks.NONE)
def reboot(self):
try:
LOG.debug("Instance %s calling stop_mysql..." % self.id)
self.guest.stop_mysql()
LOG.debug("Rebooting instance %s" % self.id)
self.server.reboot()
# Poll nova until instance is active
reboot_time_out = int(config.Config.get("reboot_time_out", 60 * 2))
def update_server_info():
self._refresh_compute_server_info()
return self.server.status == 'ACTIVE'
utils.poll_until(
update_server_info,
sleep_time=2,
time_out=reboot_time_out)
# Set the status to PAUSED. The guest agent will reset the status
# when the reboot completes and MySQL is running.
status = InstanceServiceStatus.find_by(instance_id=self.id)
status.set_status(inst_models.ServiceStatuses.PAUSED)
status.save()
LOG.debug("Successfully rebooted instance %s" % self.id)
except Exception, e:
LOG.error("Failed to reboot instance %s: %s" % (self.id, str(e)))
finally:
LOG.debug("Rebooting FINALLY %s" % self.id)
self.update_db(task_status=inst_models.InstanceTasks.NONE)
def restart(self):
LOG.debug("Restarting instance %s " % self.id)
LOG.debug("Restarting MySQL on instance %s " % self.id)
try:
self.guest.restart()
LOG.debug("Restarting successful %s " % self.id)
LOG.debug("Restarting MySQL successful %s " % self.id)
except GuestError:
LOG.error("Failure to restart MySQL for instance %s." % self.id)
finally:

View File

@ -113,6 +113,13 @@ class FakeServer(object):
raise RuntimeError("Not in resize confirm mode.")
self._current_status = "ACTIVE"
def reboot(self):
LOG.debug("Rebooting server %s" % (self.id))
self._current_status = "REBOOT"
time.sleep(1)
self._current_status = "ACTIVE"
self.parent.schedule_simulate_running_server(self.id, 1.5)
def delete(self):
self.schedule_status = []
# TODO(pdmars): This is less than ideal, but a quick way to force it
@ -253,6 +260,18 @@ class FakeServers(object):
del self.db[id]
self.events.add_event(time_from_now, delete_server)
def schedule_simulate_running_server(self, id, time_from_now):
def set_server_running():
from reddwarf.instance.models import DBInstance
from reddwarf.instance.models import InstanceServiceStatus
from reddwarf.instance.models import ServiceStatuses
instance = DBInstance.find_by(compute_instance_id=id)
LOG.debug("Setting server %s to running" % instance.id)
status = InstanceServiceStatus.find_by(instance_id=instance.id)
status.status = ServiceStatuses.RUNNING
status.save()
self.events.add_event(time_from_now, set_server_running)
class FakeServerVolumes(object):