diff options
| -rw-r--r-- | nova/compute/api.py | 52 | ||||
| -rw-r--r-- | nova/compute/manager.py | 65 |
2 files changed, 65 insertions, 52 deletions
diff --git a/nova/compute/api.py b/nova/compute/api.py index 0513ce95d..361ab9914 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -23,7 +23,6 @@ Handles all API requests relating to instances (guest vms). import datetime import logging import time -import functools from nova import db from nova import exception @@ -37,48 +36,6 @@ from nova.db import base FLAGS = flags.FLAGS -def checks_instance_lock(function): - """ - decorator used for preventing action against locked instances - unless, of course, you happen to be admin - - """ - - @functools.wraps(function) - def decorated_function(*args, **kwargs): - - logging.info(_("check_instance_locks decorating |%s|"), function) - logging.info(_("check_instance_locks: arguments: |%s| |%s|"), args, - kwargs) - # assume worst case (have to declare so they are in scope) - admin = False - locked = True - - # grab args to function - try: - if 'context' in kwargs: - context = kwargs['context'] - else: - context = args[1] - if 'instance_id' in kwargs: - instance_id = kwargs['instance_id'] - else: - instance_id = args[2] - locked = ComputeAPI().get_lock(context, instance_id) - admin = context.is_admin - except Exception as e: - logging.error(_("check_instance_lock: arguments: |%s| |%s|"), args, - kwargs) - raise e - - # if admin or unlocked call function, otherwise 405 - if admin or not locked: - return function(*args, **kwargs) - raise Exception(_("Instance is locked, cannot execute |%s|"), function) - - return decorated_function - - def generate_default_hostname(internal_id): """Default function to generate a hostname given an instance reference.""" return str(internal_id) @@ -241,7 +198,6 @@ class ComputeAPI(base.Base): 'project_id': context.project_id} db.security_group_create(context, values) - @checks_instance_lock def update_instance(self, context, instance_id, **kwargs): """Updates the instance in the datastore. @@ -256,7 +212,6 @@ class ComputeAPI(base.Base): """ return self.db.instance_update(context, instance_id, kwargs) - @checks_instance_lock def delete_instance(self, context, instance_id): logging.debug("Going to try and terminate %d" % instance_id) try: @@ -303,7 +258,6 @@ class ComputeAPI(base.Base): def get_instance(self, context, instance_id): return self.db.instance_get_by_internal_id(context, instance_id) - @checks_instance_lock def reboot(self, context, instance_id): """Reboot the given instance.""" instance = self.db.instance_get_by_internal_id(context, instance_id) @@ -313,7 +267,6 @@ class ComputeAPI(base.Base): {"method": "reboot_instance", "args": {"instance_id": instance['id']}}) - @checks_instance_lock def pause(self, context, instance_id): """Pause the given instance.""" instance = self.db.instance_get_by_internal_id(context, instance_id) @@ -323,7 +276,6 @@ class ComputeAPI(base.Base): {"method": "pause_instance", "args": {"instance_id": instance['id']}}) - @checks_instance_lock def unpause(self, context, instance_id): """Unpause the given instance.""" instance = self.db.instance_get_by_internal_id(context, instance_id) @@ -333,7 +285,6 @@ class ComputeAPI(base.Base): {"method": "unpause_instance", "args": {"instance_id": instance['id']}}) - @checks_instance_lock def suspend(self, context, instance_id): """suspend the instance with instance_id""" instance = self.db.instance_get_by_internal_id(context, instance_id) @@ -343,7 +294,6 @@ class ComputeAPI(base.Base): {"method": "suspend_instance", "args": {"instance_id": instance['id']}}) - @checks_instance_lock def resume(self, context, instance_id): """resume the instance with instance_id""" instance = self.db.instance_get_by_internal_id(context, instance_id) @@ -353,7 +303,6 @@ class ComputeAPI(base.Base): {"method": "resume_instance", "args": {"instance_id": instance['id']}}) - @checks_instance_lock def rescue(self, context, instance_id): """Rescue the given instance.""" instance = self.db.instance_get_by_internal_id(context, instance_id) @@ -363,7 +312,6 @@ class ComputeAPI(base.Base): {"method": "rescue_instance", "args": {"instance_id": instance['id']}}) - @checks_instance_lock def unrescue(self, context, instance_id): """Unrescue the given instance.""" instance = self.db.instance_get_by_internal_id(context, instance_id) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 9a33c7cac..224159596 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -36,6 +36,7 @@ terminating it. import datetime import logging +import functools from nova import exception from nova import flags @@ -53,6 +54,48 @@ flags.DEFINE_string('stub_network', False, 'Stub network related code') +def checks_instance_lock(function): + """ + decorator used for preventing action against locked instances + unless, of course, you happen to be admin + + """ + + @functools.wraps(function) + def decorated_function(*args, **kwargs): + + logging.info(_("check_instance_locks decorating |%s|"), function) + logging.info(_("check_instance_locks: arguments: |%s| |%s|"), args, + kwargs) + # assume worst case (have to declare so they are in scope) + admin = False + locked = True + + # grab args to function + try: + if 'context' in kwargs: + context = kwargs['context'] + else: + context = args[1] + if 'instance_id' in kwargs: + instance_id = kwargs['instance_id'] + else: + instance_id = args[2] + locked = args[0].get_locked(context, instance_id) + admin = context.is_admin + except Exception as e: + logging.error(_("check_instance_lock: arguments: |%s| |%s|"), args, + kwargs) + raise e + + # if admin or unlocked call function, otherwise 405 + if admin or not locked: + return function(*args, **kwargs) + raise Exception(_("Instance is locked, cannot execute |%s|"), function) + + return decorated_function + + class ComputeManager(manager.Manager): """Manages the running instances from creation to destruction.""" @@ -158,6 +201,7 @@ class ComputeManager(manager.Manager): self._update_state(context, instance_id) @exception.wrap_exception + @checks_instance_lock def terminate_instance(self, context, instance_id): """Terminate an instance on this machine.""" context = context.elevated() @@ -202,6 +246,7 @@ class ComputeManager(manager.Manager): self.db.instance_destroy(context, instance_id) @exception.wrap_exception + @checks_instance_lock def reboot_instance(self, context, instance_id): """Reboot an instance on this server.""" context = context.elevated() @@ -225,6 +270,7 @@ class ComputeManager(manager.Manager): self._update_state(context, instance_id) @exception.wrap_exception + @checks_instance_lock def rescue_instance(self, context, instance_id): """Rescue an instance on this server.""" context = context.elevated() @@ -241,6 +287,7 @@ class ComputeManager(manager.Manager): self._update_state(context, instance_id) @exception.wrap_exception + @checks_instance_lock def unrescue_instance(self, context, instance_id): """Rescue an instance on this server.""" context = context.elevated() @@ -261,6 +308,7 @@ class ComputeManager(manager.Manager): self._update_state(context, instance_id) @exception.wrap_exception + @checks_instance_lock def pause_instance(self, context, instance_id): """Pause an instance on this server.""" context = context.elevated() @@ -279,6 +327,7 @@ class ComputeManager(manager.Manager): result)) @exception.wrap_exception + @checks_instance_lock def unpause_instance(self, context, instance_id): """Unpause a paused instance on this server.""" context = context.elevated() @@ -297,6 +346,7 @@ class ComputeManager(manager.Manager): result)) @exception.wrap_exception + @checks_instance_lock def suspend_instance(self, context, instance_id): """suspend the instance with instance_id""" context = context.elevated() @@ -314,6 +364,7 @@ class ComputeManager(manager.Manager): result)) @exception.wrap_exception + @checks_instance_lock def resume_instance(self, context, instance_id): """resume the suspended instance with instance_id""" context = context.elevated() @@ -354,6 +405,18 @@ class ComputeManager(manager.Manager): self.db.instance_update(context, instance_id, {'locked': False}) @exception.wrap_exception + def get_locked(self, context, instance_id): + """ + return the boolean state of (instance with instance_id)'s lock + + """ + context = context.elevated() + logging.debug(_('instance %s: getting locked'), + instance_ref['internal_id']) + instance_ref = self.db.instance_get(context, instance_id) + return instance_ref['locked'] + + @exception.wrap_exception def get_console_output(self, context, instance_id): """Send the console output for an instance.""" context = context.elevated() @@ -363,6 +426,7 @@ class ComputeManager(manager.Manager): return self.driver.get_console_output(instance_ref) @exception.wrap_exception + @checks_instance_lock def attach_volume(self, context, instance_id, volume_id, mountpoint): """Attach a volume to an instance.""" context = context.elevated() @@ -392,6 +456,7 @@ class ComputeManager(manager.Manager): return True @exception.wrap_exception + @checks_instance_lock def detach_volume(self, context, instance_id, volume_id): """Detach a volume from an instance.""" context = context.elevated() |
