summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nova/compute/api.py52
-rw-r--r--nova/compute/manager.py65
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()