summaryrefslogtreecommitdiffstats
path: root/nova/compute
diff options
context:
space:
mode:
authorTrey Morris <trey.morris@rackspace.com>2011-04-21 18:11:12 -0500
committerTrey Morris <trey.morris@rackspace.com>2011-04-21 18:11:12 -0500
commit35898af95004a79f75403d7a526cef65858da63a (patch)
tree89ed193ee4326ee3b2dd96647729d309497f6d4b /nova/compute
parent0842c63324f3daa04becb6114c9d6434743da53b (diff)
parent1b56402bff72e74d0c058e6aeb2a30de3fc492d2 (diff)
merge trunk
Diffstat (limited to 'nova/compute')
-rw-r--r--nova/compute/api.py167
-rw-r--r--nova/compute/instance_types.py39
-rw-r--r--nova/compute/manager.py245
-rw-r--r--nova/compute/monitor.py4
4 files changed, 217 insertions, 238 deletions
diff --git a/nova/compute/api.py b/nova/compute/api.py
index 082fb9935..c7ee0a119 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -16,9 +16,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-"""
-Handles all requests relating to instances (guest vms).
-"""
+"""Handles all requests relating to instances (guest vms)."""
import datetime
import re
@@ -69,10 +67,10 @@ class API(base.Base):
super(API, self).__init__(**kwargs)
def _check_injected_file_quota(self, context, injected_files):
- """
- Enforce quota limits on injected files
+ """Enforce quota limits on injected files.
+
+ Raises a QuotaError if any limit is exceeded.
- Raises a QuotaError if any limit is exceeded
"""
if injected_files is None:
return
@@ -87,16 +85,40 @@ class API(base.Base):
if len(content) > content_limit:
raise quota.QuotaError(code="OnsetFileContentLimitExceeded")
+ def _check_metadata_properties_quota(self, context, metadata={}):
+ """Enforce quota limits on metadata properties."""
+ num_metadata = len(metadata)
+ quota_metadata = quota.allowed_metadata_items(context, num_metadata)
+ if quota_metadata < num_metadata:
+ pid = context.project_id
+ msg = _("Quota exceeeded for %(pid)s, tried to set "
+ "%(num_metadata)s metadata properties") % locals()
+ LOG.warn(msg)
+ raise quota.QuotaError(msg, "MetadataLimitExceeded")
+
+ # Because metadata is stored in the DB, we hard-code the size limits
+ # In future, we may support more variable length strings, so we act
+ # as if this is quota-controlled for forwards compatibility
+ for k, v in metadata.iteritems():
+ if len(k) > 255 or len(v) > 255:
+ pid = context.project_id
+ msg = _("Quota exceeeded for %(pid)s, metadata property "
+ "key or value too long") % locals()
+ LOG.warn(msg)
+ raise quota.QuotaError(msg, "MetadataLimitExceeded")
+
def create(self, context, instance_type,
image_id, kernel_id=None, ramdisk_id=None,
min_count=1, max_count=1,
display_name='', display_description='',
key_name=None, key_data=None, security_group='default',
- availability_zone=None, user_data=None, metadata=[],
+ availability_zone=None, user_data=None, metadata={},
injected_files=None):
- """Create the number of instances requested if quota and
- other arguments check out ok."""
+ """Create the number and type of instances requested.
+ Verifies that quota and other arguments are valid.
+
+ """
if not instance_type:
instance_type = instance_types.get_default_instance_type()
@@ -110,30 +132,7 @@ class API(base.Base):
"run %s more instances of this type.") %
num_instances, "InstanceLimitExceeded")
- num_metadata = len(metadata)
- quota_metadata = quota.allowed_metadata_items(context, num_metadata)
- if quota_metadata < num_metadata:
- pid = context.project_id
- msg = (_("Quota exceeeded for %(pid)s,"
- " tried to set %(num_metadata)s metadata properties")
- % locals())
- LOG.warn(msg)
- raise quota.QuotaError(msg, "MetadataLimitExceeded")
-
- # Because metadata is stored in the DB, we hard-code the size limits
- # In future, we may support more variable length strings, so we act
- # as if this is quota-controlled for forwards compatibility
- for metadata_item in metadata:
- k = metadata_item['key']
- v = metadata_item['value']
- if len(k) > 255 or len(v) > 255:
- pid = context.project_id
- msg = (_("Quota exceeeded for %(pid)s,"
- " metadata property key or value too long")
- % locals())
- LOG.warn(msg)
- raise quota.QuotaError(msg, "MetadataLimitExceeded")
-
+ self._check_metadata_properties_quota(context, metadata)
self._check_injected_file_quota(context, injected_files)
image = self.image_service.show(context, image_id)
@@ -220,7 +219,7 @@ class API(base.Base):
# Set sane defaults if not specified
updates = dict(hostname=self.hostname_factory(instance_id))
if (not hasattr(instance, 'display_name') or
- instance.display_name == None):
+ instance.display_name is None):
updates['display_name'] = "Server %s" % instance_id
instance = self.update(context, instance_id, **updates)
@@ -244,8 +243,7 @@ class API(base.Base):
return [dict(x.iteritems()) for x in instances]
def has_finished_migration(self, context, instance_id):
- """Retrieves whether or not a finished migration exists for
- an instance"""
+ """Returns true if an instance has a finished migration."""
try:
db.migration_get_by_instance_and_status(context, instance_id,
'finished')
@@ -254,8 +252,10 @@ class API(base.Base):
return False
def ensure_default_security_group(self, context):
- """ Create security group for the security context if it
- does not already exist
+ """Ensure that a context has a security group.
+
+ Creates a security group for the security context if it does not
+ already exist.
:param context: the security context
@@ -271,7 +271,7 @@ class API(base.Base):
db.security_group_create(context, values)
def trigger_security_group_rules_refresh(self, context, security_group_id):
- """Called when a rule is added to or removed from a security_group"""
+ """Called when a rule is added to or removed from a security_group."""
security_group = self.db.security_group_get(context, security_group_id)
@@ -287,11 +287,12 @@ class API(base.Base):
"args": {"security_group_id": security_group.id}})
def trigger_security_group_members_refresh(self, context, group_id):
- """Called when a security group gains a new or loses a member
+ """Called when a security group gains a new or loses a member.
Sends an update request to each compute node for whom this is
- relevant."""
+ relevant.
+ """
# First, we get the security group rules that reference this group as
# the grantee..
security_group_rules = \
@@ -336,7 +337,7 @@ class API(base.Base):
as data fields of the instance to be
updated
- :retval None
+ :returns: None
"""
rv = self.db.instance_update(context, instance_id, kwargs)
@@ -344,6 +345,7 @@ class API(base.Base):
@scheduler_api.reroute_compute("delete")
def delete(self, context, instance_id):
+ """Terminate an instance."""
LOG.debug(_("Going to try to terminate %s"), instance_id)
try:
instance = self.get(context, instance_id)
@@ -375,22 +377,28 @@ class API(base.Base):
self.db.instance_destroy(context, instance_id)
def get(self, context, instance_id):
- """Get a single instance with the given ID."""
+ """Get a single instance with the given instance_id."""
rv = self.db.instance_get(context, instance_id)
return dict(rv.iteritems())
@scheduler_api.reroute_compute("get")
def routing_get(self, context, instance_id):
- """Use this method instead of get() if this is the only
- operation you intend to to. It will route to novaclient.get
- if the instance is not found."""
+ """A version of get with special routing characteristics.
+
+ Use this method instead of get() if this is the only operation you
+ intend to to. It will route to novaclient.get if the instance is not
+ found.
+
+ """
return self.get(context, instance_id)
def get_all(self, context, project_id=None, reservation_id=None,
fixed_ip=None):
- """Get all instances, possibly filtered by one of the
- given parameters. If there is no filter and the context is
- an admin, it will retreive all instances in the system.
+ """Get all instances filtered by one of the given parameters.
+
+ If there is no filter and the context is an admin, it will retreive
+ all instances in the system.
+
"""
if reservation_id is not None:
return self.db.instance_get_all_by_reservation(
@@ -419,7 +427,8 @@ class API(base.Base):
:param params: Optional dictionary of arguments to be passed to the
compute worker
- :retval None
+ :returns: None
+
"""
if not params:
params = {}
@@ -438,7 +447,7 @@ class API(base.Base):
:param params: Optional dictionary of arguments to be passed to the
compute worker
- :retval: Result returned by compute worker
+ :returns: Result returned by compute worker
"""
if not params:
params = {}
@@ -451,13 +460,14 @@ class API(base.Base):
return rpc.call(context, queue, kwargs)
def _cast_scheduler_message(self, context, args):
- """Generic handler for RPC calls to the scheduler"""
+ """Generic handler for RPC calls to the scheduler."""
rpc.cast(context, FLAGS.scheduler_topic, args)
def snapshot(self, context, instance_id, name):
"""Snapshot the given instance.
- :retval: A dict containing image metadata
+ :returns: A dict containing image metadata
+
"""
properties = {'instance_id': str(instance_id),
'user_id': str(context.user_id)}
@@ -474,7 +484,7 @@ class API(base.Base):
self._cast_compute_message('reboot_instance', context, instance_id)
def revert_resize(self, context, instance_id):
- """Reverts a resize, deleting the 'new' instance in the process"""
+ """Reverts a resize, deleting the 'new' instance in the process."""
context = context.elevated()
migration_ref = self.db.migration_get_by_instance_and_status(context,
instance_id, 'finished')
@@ -489,8 +499,7 @@ class API(base.Base):
{'status': 'reverted'})
def confirm_resize(self, context, instance_id):
- """Confirms a migration/resize, deleting the 'old' instance in the
- process."""
+ """Confirms a migration/resize and deletes the 'old' instance."""
context = context.elevated()
migration_ref = self.db.migration_get_by_instance_and_status(context,
instance_id, 'finished')
@@ -550,10 +559,9 @@ class API(base.Base):
@scheduler_api.reroute_compute("diagnostics")
def get_diagnostics(self, context, instance_id):
"""Retrieve diagnostics for the given instance."""
- return self._call_compute_message(
- "get_diagnostics",
- context,
- instance_id)
+ return self._call_compute_message("get_diagnostics",
+ context,
+ instance_id)
def get_actions(self, context, instance_id):
"""Retrieve actions for the given instance."""
@@ -561,12 +569,12 @@ class API(base.Base):
@scheduler_api.reroute_compute("suspend")
def suspend(self, context, instance_id):
- """suspend the instance with instance_id"""
+ """Suspend the given instance."""
self._cast_compute_message('suspend_instance', context, instance_id)
@scheduler_api.reroute_compute("resume")
def resume(self, context, instance_id):
- """resume the instance with instance_id"""
+ """Resume the given instance."""
self._cast_compute_message('resume_instance', context, instance_id)
@scheduler_api.reroute_compute("rescue")
@@ -581,15 +589,15 @@ class API(base.Base):
def set_admin_password(self, context, instance_id, password=None):
"""Set the root/admin password for the given instance."""
- self._cast_compute_message('set_admin_password', context, instance_id,
- password)
+ self._cast_compute_message(
+ 'set_admin_password', context, instance_id, password)
def inject_file(self, context, instance_id):
"""Write a file to the given instance."""
self._cast_compute_message('inject_file', context, instance_id)
def get_ajax_console(self, context, instance_id):
- """Get a url to an AJAX Console"""
+ """Get a url to an AJAX Console."""
output = self._call_compute_message('get_ajax_console',
context,
instance_id)
@@ -598,7 +606,7 @@ class API(base.Base):
'args': {'token': output['token'], 'host': output['host'],
'port': output['port']}})
return {'url': '%s/?token=%s' % (FLAGS.ajax_console_proxy_url,
- output['token'])}
+ output['token'])}
def get_vnc_console(self, context, instance_id):
"""Get a url to a VNC Console."""
@@ -620,39 +628,34 @@ class API(base.Base):
'portignore')}
def get_console_output(self, context, instance_id):
- """Get console output for an an instance"""
+ """Get console output for an an instance."""
return self._call_compute_message('get_console_output',
context,
instance_id)
def lock(self, context, instance_id):
- """lock the instance with instance_id"""
+ """Lock the given instance."""
self._cast_compute_message('lock_instance', context, instance_id)
def unlock(self, context, instance_id):
- """unlock the instance with instance_id"""
+ """Unlock the given instance."""
self._cast_compute_message('unlock_instance', context, instance_id)
def get_lock(self, context, instance_id):
- """return the boolean state of (instance with instance_id)'s lock"""
+ """Return the boolean state of given instance's lock."""
instance = self.get(context, instance_id)
return instance['locked']
def reset_network(self, context, instance_id):
- """
- Reset networking on the instance.
-
- """
+ """Reset networking on the instance."""
self._cast_compute_message('reset_network', context, instance_id)
def inject_network_info(self, context, instance_id):
- """
- Inject network info for the instance.
-
- """
+ """Inject network info for the instance."""
self._cast_compute_message('inject_network_info', context, instance_id)
def attach_volume(self, context, instance_id, volume_id, device):
+ """Attach an existing volume to an existing instance."""
if not re.match("^/dev/[a-z]d[a-z]+$", device):
raise exception.ApiError(_("Invalid device specified: %s. "
"Example device: /dev/vdb") % device)
@@ -667,6 +670,7 @@ class API(base.Base):
"mountpoint": device}})
def detach_volume(self, context, volume_id):
+ """Detach a volume from an instance."""
instance = self.db.volume_get_instance(context.elevated(), volume_id)
if not instance:
raise exception.ApiError(_("Volume isn't attached to anything!"))
@@ -713,11 +717,14 @@ class API(base.Base):
return dict(rv.iteritems())
def delete_instance_metadata(self, context, instance_id, key):
- """Delete the given metadata item"""
+ """Delete the given metadata item from an instance."""
self.db.instance_metadata_delete(context, instance_id, key)
def update_or_create_instance_metadata(self, context, instance_id,
metadata):
- """Updates or creates instance metadata"""
+ """Updates or creates instance metadata."""
+ combined_metadata = self.get_instance_metadata(context, instance_id)
+ combined_metadata.update(metadata)
+ self._check_metadata_properties_quota(context, combined_metadata)
self.db.instance_metadata_update_or_create(context, instance_id,
metadata)
diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py
index b3a5ab0ac..98b4425c8 100644
--- a/nova/compute/instance_types.py
+++ b/nova/compute/instance_types.py
@@ -18,9 +18,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-"""
-The built-in instance properties.
-"""
+"""Built-in instance properties."""
from nova import context
from nova import db
@@ -34,9 +32,7 @@ LOG = logging.getLogger('nova.instance_types')
def create(name, memory, vcpus, local_gb, flavorid, swap=0,
rxtx_quota=0, rxtx_cap=0):
- """Creates instance types / flavors
- arguments: name memory vcpus local_gb flavorid swap rxtx_quota rxtx_cap
- """
+ """Creates instance types."""
for option in [memory, vcpus, local_gb, flavorid]:
try:
int(option)
@@ -64,9 +60,8 @@ def create(name, memory, vcpus, local_gb, flavorid, swap=0,
def destroy(name):
- """Marks instance types / flavors as deleted
- arguments: name"""
- if name == None:
+ """Marks instance types as deleted."""
+ if name is None:
raise exception.InvalidInputException(_("No instance type specified"))
else:
try:
@@ -77,9 +72,8 @@ def destroy(name):
def purge(name):
- """Removes instance types / flavors from database
- arguments: name"""
- if name == None:
+ """Removes instance types from database."""
+ if name is None:
raise exception.InvalidInputException(_("No instance type specified"))
else:
try:
@@ -90,18 +84,19 @@ def purge(name):
def get_all_types(inactive=0):
- """Retrieves non-deleted instance_types.
- Pass true as argument if you want deleted instance types returned also."""
+ """Get all non-deleted instance_types.
+
+ Pass true as argument if you want deleted instance types returned also.
+
+ """
return db.instance_type_get_all(context.get_admin_context(), inactive)
-def get_all_flavors():
- """retrieves non-deleted flavors. alias for instance_types.get_all_types().
- Pass true as argument if you want deleted instance types returned also."""
- return get_all_types(context.get_admin_context())
+get_all_flavors = get_all_types
def get_default_instance_type():
+ """Get the default instance type."""
name = FLAGS.default_instance_type
try:
return get_instance_type_by_name(name)
@@ -110,7 +105,7 @@ def get_default_instance_type():
def get_instance_type(id):
- """Retrieves single instance type by id"""
+ """Retrieves single instance type by id."""
if id is None:
return get_default_instance_type()
try:
@@ -121,7 +116,7 @@ def get_instance_type(id):
def get_instance_type_by_name(name):
- """Retrieves single instance type by name"""
+ """Retrieves single instance type by name."""
if name is None:
return get_default_instance_type()
try:
@@ -131,8 +126,10 @@ def get_instance_type_by_name(name):
raise exception.ApiError(_("Unknown instance type: %s") % name)
+# TODO(termie): flavor-specific code should probably be in the API that uses
+# flavors.
def get_instance_type_by_flavor_id(flavor_id):
- """retrieve instance type by flavor_id"""
+ """Retrieve instance type by flavor_id."""
if flavor_id is None:
return get_default_instance_type()
try:
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index afa98a617..a92a160f8 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -17,8 +17,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-"""
-Handles all processes relating to instances (guest vms).
+"""Handles all processes relating to instances (guest vms).
The :py:class:`ComputeManager` class is a :py:class:`nova.manager.Manager` that
handles RPC calls relating to creating instances. It is responsible for
@@ -33,6 +32,7 @@ terminating it.
by :func:`nova.utils.import_object`
:volume_manager: Name of class that handles persistent storage, loaded by
:func:`nova.utils.import_object`
+
"""
import datetime
@@ -56,6 +56,7 @@ from nova import utils
from nova.compute import power_state
from nova.virt import driver
+
FLAGS = flags.FLAGS
flags.DEFINE_string('instances_path', '$state_path/instances',
'where instances are stored on disk')
@@ -75,19 +76,14 @@ flags.DEFINE_integer("rescue_timeout", 0,
"Automatically unrescue an instance after N seconds."
" Set to 0 to disable.")
+
LOG = logging.getLogger('nova.compute.manager')
def checks_instance_lock(function):
- """
- decorator used for preventing action against locked instances
- unless, of course, you happen to be admin
-
- """
-
+ """Decorator to prevent action against locked instances for non-admins."""
@functools.wraps(function)
def decorated_function(self, context, instance_id, *args, **kwargs):
-
LOG.info(_("check_instance_lock: decorating: |%s|"), function,
context=context)
LOG.info(_("check_instance_lock: arguments: |%(self)s| |%(context)s|"
@@ -113,7 +109,6 @@ def checks_instance_lock(function):
class ComputeManager(manager.SchedulerDependentManager):
-
"""Manages the running instances from creation to destruction."""
def __init__(self, compute_driver=None, *args, **kwargs):
@@ -138,9 +133,7 @@ class ComputeManager(manager.SchedulerDependentManager):
*args, **kwargs)
def init_host(self):
- """Do any initialization that needs to be run if this is a
- standalone service.
- """
+ """Initialization for a standalone compute service."""
self.driver.init_host(host=self.host)
def _update_state(self, context, instance_id):
@@ -155,9 +148,11 @@ class ComputeManager(manager.SchedulerDependentManager):
self.db.instance_set_state(context, instance_id, state)
def get_console_topic(self, context, **kwargs):
- """Retrieves the console host for a project on this host
- Currently this is just set in the flags for each compute
- host."""
+ """Retrieves the console host for a project on this host.
+
+ Currently this is just set in the flags for each compute host.
+
+ """
#TODO(mdragon): perhaps make this variable by console_type?
return self.db.queue_get_for(context,
FLAGS.console_topic,
@@ -167,15 +162,23 @@ class ComputeManager(manager.SchedulerDependentManager):
return self.driver.get_console_pool_info(console_type)
@exception.wrap_exception
- def refresh_security_group_rules(self, context,
- security_group_id, **kwargs):
- """This call passes straight through to the virtualization driver."""
+ def refresh_security_group_rules(self, context, security_group_id,
+ **kwargs):
+ """Tell the virtualization driver to refresh security group rules.
+
+ Passes straight through to the virtualization driver.
+
+ """
return self.driver.refresh_security_group_rules(security_group_id)
@exception.wrap_exception
def refresh_security_group_members(self, context,
security_group_id, **kwargs):
- """This call passes straight through to the virtualization driver."""
+ """Tell the virtualization driver to refresh security group members.
+
+ Passes straight through to the virtualization driver.
+
+ """
return self.driver.refresh_security_group_members(security_group_id)
@exception.wrap_exception
@@ -235,7 +238,7 @@ class ComputeManager(manager.SchedulerDependentManager):
@exception.wrap_exception
@checks_instance_lock
def terminate_instance(self, context, instance_id):
- """Terminate an instance on this machine."""
+ """Terminate an instance on this host."""
context = context.elevated()
instance = self.db.instance_get(context, instance_id)
LOG.audit(_("Terminating instance %s"), instance_id, context=context)
@@ -258,7 +261,7 @@ class ComputeManager(manager.SchedulerDependentManager):
@exception.wrap_exception
@checks_instance_lock
def reboot_instance(self, context, instance_id):
- """Reboot an instance on this server."""
+ """Reboot an instance on this host."""
context = context.elevated()
self._update_state(context, instance_id)
instance_ref = self.db.instance_get(context, instance_id)
@@ -282,7 +285,7 @@ class ComputeManager(manager.SchedulerDependentManager):
@exception.wrap_exception
def snapshot_instance(self, context, instance_id, image_id):
- """Snapshot an instance on this server."""
+ """Snapshot an instance on this host."""
context = context.elevated()
instance_ref = self.db.instance_get(context, instance_id)
@@ -305,7 +308,7 @@ class ComputeManager(manager.SchedulerDependentManager):
@exception.wrap_exception
@checks_instance_lock
def set_admin_password(self, context, instance_id, new_pass=None):
- """Set the root/admin password for an instance on this server."""
+ """Set the root/admin password for an instance on this host."""
context = context.elevated()
instance_ref = self.db.instance_get(context, instance_id)
instance_id = instance_ref['id']
@@ -326,7 +329,7 @@ class ComputeManager(manager.SchedulerDependentManager):
@exception.wrap_exception
@checks_instance_lock
def inject_file(self, context, instance_id, path, file_contents):
- """Write a file to the specified path on an instance on this server"""
+ """Write a file to the specified path in an instance on this host."""
context = context.elevated()
instance_ref = self.db.instance_get(context, instance_id)
instance_id = instance_ref['id']
@@ -344,44 +347,34 @@ class ComputeManager(manager.SchedulerDependentManager):
@exception.wrap_exception
@checks_instance_lock
def rescue_instance(self, context, instance_id):
- """Rescue an instance on this server."""
+ """Rescue an instance on this host."""
context = context.elevated()
instance_ref = self.db.instance_get(context, instance_id)
LOG.audit(_('instance %s: rescuing'), instance_id, context=context)
- self.db.instance_set_state(
- context,
- instance_id,
- power_state.NOSTATE,
- 'rescuing')
+ self.db.instance_set_state(context,
+ instance_id,
+ power_state.NOSTATE,
+ 'rescuing')
self.network_manager.setup_compute_network(context, instance_id)
- self.driver.rescue(
- instance_ref,
- lambda result: self._update_state_callback(
- self,
- context,
- instance_id,
- result))
+ _update_state = lambda result: self._update_state_callback(
+ self, context, instance_id, result)
+ self.driver.rescue(instance_ref, _update_state)
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."""
+ """Rescue an instance on this host."""
context = context.elevated()
instance_ref = self.db.instance_get(context, instance_id)
LOG.audit(_('instance %s: unrescuing'), instance_id, context=context)
- self.db.instance_set_state(
- context,
- instance_id,
- power_state.NOSTATE,
- 'unrescuing')
- self.driver.unrescue(
- instance_ref,
- lambda result: self._update_state_callback(
- self,
- context,
- instance_id,
- result))
+ self.db.instance_set_state(context,
+ instance_id,
+ power_state.NOSTATE,
+ 'unrescuing')
+ _update_state = lambda result: self._update_state_callback(
+ self, context, instance_id, result)
+ self.driver.unrescue(instance_ref, _update_state)
self._update_state(context, instance_id)
@staticmethod
@@ -392,18 +385,20 @@ class ComputeManager(manager.SchedulerDependentManager):
@exception.wrap_exception
@checks_instance_lock
def confirm_resize(self, context, instance_id, migration_id):
- """Destroys the source instance"""
+ """Destroys the source instance."""
context = context.elevated()
instance_ref = self.db.instance_get(context, instance_id)
- migration_ref = self.db.migration_get(context, migration_id)
self.driver.destroy(instance_ref)
@exception.wrap_exception
@checks_instance_lock
def revert_resize(self, context, instance_id, migration_id):
- """Destroys the new instance on the destination machine,
- reverts the model changes, and powers on the old
- instance on the source machine"""
+ """Destroys the new instance on the destination machine.
+
+ Reverts the model changes, and powers on the old instance on the
+ source machine.
+
+ """
instance_ref = self.db.instance_get(context, instance_id)
migration_ref = self.db.migration_get(context, migration_id)
@@ -420,9 +415,12 @@ class ComputeManager(manager.SchedulerDependentManager):
@exception.wrap_exception
@checks_instance_lock
def finish_revert_resize(self, context, instance_id, migration_id):
- """Finishes the second half of reverting a resize, powering back on
- the source instance and reverting the resized attributes in the
- database"""
+ """Finishes the second half of reverting a resize.
+
+ Power back on the source instance and revert the resized attributes
+ in the database.
+
+ """
instance_ref = self.db.instance_get(context, instance_id)
migration_ref = self.db.migration_get(context, migration_id)
instance_type = self.db.instance_type_get_by_flavor_id(context,
@@ -442,8 +440,11 @@ class ComputeManager(manager.SchedulerDependentManager):
@exception.wrap_exception
@checks_instance_lock
def prep_resize(self, context, instance_id, flavor_id):
- """Initiates the process of moving a running instance to another
- host, possibly changing the RAM and disk size in the process"""
+ """Initiates the process of moving a running instance to another host.
+
+ Possibly changes the RAM and disk size in the process.
+
+ """
context = context.elevated()
instance_ref = self.db.instance_get(context, instance_id)
if instance_ref['host'] == FLAGS.host:
@@ -475,34 +476,38 @@ class ComputeManager(manager.SchedulerDependentManager):
@exception.wrap_exception
@checks_instance_lock
def resize_instance(self, context, instance_id, migration_id):
- """Starts the migration of a running instance to another host"""
+ """Starts the migration of a running instance to another host."""
migration_ref = self.db.migration_get(context, migration_id)
instance_ref = self.db.instance_get(context, instance_id)
- self.db.migration_update(context, migration_id,
- {'status': 'migrating', })
-
- disk_info = self.driver.migrate_disk_and_power_off(instance_ref,
- migration_ref['dest_host'])
- self.db.migration_update(context, migration_id,
- {'status': 'post-migrating', })
-
- service = self.db.service_get_by_host_and_topic(context,
- migration_ref['dest_compute'], FLAGS.compute_topic)
- topic = self.db.queue_get_for(context, FLAGS.compute_topic,
- migration_ref['dest_compute'])
- rpc.cast(context, topic,
- {'method': 'finish_resize',
- 'args': {
- 'migration_id': migration_id,
- 'instance_id': instance_id,
- 'disk_info': disk_info, },
- })
+ self.db.migration_update(context,
+ migration_id,
+ {'status': 'migrating'})
+
+ disk_info = self.driver.migrate_disk_and_power_off(
+ instance_ref, migration_ref['dest_host'])
+ self.db.migration_update(context,
+ migration_id,
+ {'status': 'post-migrating'})
+
+ service = self.db.service_get_by_host_and_topic(
+ context, migration_ref['dest_compute'], FLAGS.compute_topic)
+ topic = self.db.queue_get_for(context,
+ FLAGS.compute_topic,
+ migration_ref['dest_compute'])
+ rpc.cast(context, topic, {'method': 'finish_resize',
+ 'args': {'migration_id': migration_id,
+ 'instance_id': instance_id,
+ 'disk_info': disk_info}})
@exception.wrap_exception
@checks_instance_lock
def finish_resize(self, context, instance_id, migration_id, disk_info):
- """Completes the migration process by setting up the newly transferred
- disk and turning on the instance on its new host machine"""
+ """Completes the migration process.
+
+ Sets up the newly transferred disk and turns on the instance at its
+ new host machine.
+
+ """
migration_ref = self.db.migration_get(context, migration_id)
instance_ref = self.db.instance_get(context,
migration_ref['instance_id'])
@@ -527,7 +532,7 @@ class ComputeManager(manager.SchedulerDependentManager):
@exception.wrap_exception
@checks_instance_lock
def pause_instance(self, context, instance_id):
- """Pause an instance on this server."""
+ """Pause an instance on this host."""
context = context.elevated()
instance_ref = self.db.instance_get(context, instance_id)
LOG.audit(_('instance %s: pausing'), instance_id, context=context)
@@ -544,7 +549,7 @@ class ComputeManager(manager.SchedulerDependentManager):
@exception.wrap_exception
@checks_instance_lock
def unpause_instance(self, context, instance_id):
- """Unpause a paused instance on this server."""
+ """Unpause a paused instance on this host."""
context = context.elevated()
instance_ref = self.db.instance_get(context, instance_id)
LOG.audit(_('instance %s: unpausing'), instance_id, context=context)
@@ -560,7 +565,7 @@ class ComputeManager(manager.SchedulerDependentManager):
@exception.wrap_exception
def get_diagnostics(self, context, instance_id):
- """Retrieve diagnostics for an instance on this server."""
+ """Retrieve diagnostics for an instance on this host."""
instance_ref = self.db.instance_get(context, instance_id)
if instance_ref["state"] == power_state.RUNNING:
@@ -571,10 +576,7 @@ class ComputeManager(manager.SchedulerDependentManager):
@exception.wrap_exception
@checks_instance_lock
def suspend_instance(self, context, instance_id):
- """
- suspend the instance with instance_id
-
- """
+ """Suspend the given instance."""
context = context.elevated()
instance_ref = self.db.instance_get(context, instance_id)
LOG.audit(_('instance %s: suspending'), instance_id, context=context)
@@ -590,10 +592,7 @@ class ComputeManager(manager.SchedulerDependentManager):
@exception.wrap_exception
@checks_instance_lock
def resume_instance(self, context, instance_id):
- """
- resume the suspended instance with instance_id
-
- """
+ """Resume the given suspended instance."""
context = context.elevated()
instance_ref = self.db.instance_get(context, instance_id)
LOG.audit(_('instance %s: resuming'), instance_id, context=context)
@@ -608,34 +607,23 @@ class ComputeManager(manager.SchedulerDependentManager):
@exception.wrap_exception
def lock_instance(self, context, instance_id):
- """
- lock the instance with instance_id
-
- """
+ """Lock the given instance."""
context = context.elevated()
- instance_ref = self.db.instance_get(context, instance_id)
LOG.debug(_('instance %s: locking'), instance_id, context=context)
self.db.instance_update(context, instance_id, {'locked': True})
@exception.wrap_exception
def unlock_instance(self, context, instance_id):
- """
- unlock the instance with instance_id
-
- """
+ """Unlock the given instance."""
context = context.elevated()
- instance_ref = self.db.instance_get(context, instance_id)
LOG.debug(_('instance %s: unlocking'), instance_id, context=context)
self.db.instance_update(context, instance_id, {'locked': False})
@exception.wrap_exception
def get_lock(self, context, instance_id):
- """
- return the boolean state of (instance with instance_id)'s lock
-
- """
+ """Return the boolean state of the given instance's lock."""
context = context.elevated()
LOG.debug(_('instance %s: getting locked state'), instance_id,
context=context)
@@ -644,10 +632,7 @@ class ComputeManager(manager.SchedulerDependentManager):
@checks_instance_lock
def reset_network(self, context, instance_id):
- """
- Reset networking on the instance.
-
- """
+ """Reset networking on the given instance."""
context = context.elevated()
instance_ref = self.db.instance_get(context, instance_id)
LOG.debug(_('instance %s: reset network'), instance_id,
@@ -656,10 +641,7 @@ class ComputeManager(manager.SchedulerDependentManager):
@checks_instance_lock
def inject_network_info(self, context, instance_id):
- """
- Inject network info for the instance.
-
- """
+ """Inject network info for the given instance."""
context = context.elevated()
LOG.debug(_('instance %s: inject network info'), instance_id,
context=context)
@@ -672,7 +654,7 @@ class ComputeManager(manager.SchedulerDependentManager):
@exception.wrap_exception
def get_console_output(self, context, instance_id):
- """Send the console output for an instance."""
+ """Send the console output for the given instance."""
context = context.elevated()
instance_ref = self.db.instance_get(context, instance_id)
LOG.audit(_("Get console output for instance %s"), instance_id,
@@ -681,20 +663,18 @@ class ComputeManager(manager.SchedulerDependentManager):
@exception.wrap_exception
def get_ajax_console(self, context, instance_id):
- """Return connection information for an ajax console"""
+ """Return connection information for an ajax console."""
context = context.elevated()
LOG.debug(_("instance %s: getting ajax console"), instance_id)
instance_ref = self.db.instance_get(context, instance_id)
-
return self.driver.get_ajax_console(instance_ref)
@exception.wrap_exception
def get_vnc_console(self, context, instance_id):
- """Return connection information for an vnc console."""
+ """Return connection information for a vnc console."""
context = context.elevated()
LOG.debug(_("instance %s: getting vnc console"), instance_id)
instance_ref = self.db.instance_get(context, instance_id)
-
return self.driver.get_vnc_console(instance_ref)
@checks_instance_lock
@@ -748,7 +728,7 @@ class ComputeManager(manager.SchedulerDependentManager):
@exception.wrap_exception
def compare_cpu(self, context, cpu_info):
- """Checks the host cpu is compatible to a cpu given by xml.
+ """Checks that the host cpu is compatible with a cpu given by xml.
:param context: security context
:param cpu_info: json string obtained from virConnect.getCapabilities
@@ -769,7 +749,6 @@ class ComputeManager(manager.SchedulerDependentManager):
:returns: tmpfile name(basename)
"""
-
dirpath = FLAGS.instances_path
fd, tmp_file = tempfile.mkstemp(dir=dirpath)
LOG.debug(_("Creating tmpfile %s to notify to other "
@@ -786,7 +765,6 @@ class ComputeManager(manager.SchedulerDependentManager):
:param filename: confirm existence of FLAGS.instances_path/thisfile
"""
-
tmp_file = os.path.join(FLAGS.instances_path, filename)
if not os.path.exists(tmp_file):
raise exception.NotFound(_('%s not found') % tmp_file)
@@ -799,7 +777,6 @@ class ComputeManager(manager.SchedulerDependentManager):
:param filename: remove existence of FLAGS.instances_path/thisfile
"""
-
tmp_file = os.path.join(FLAGS.instances_path, filename)
os.remove(tmp_file)
@@ -811,7 +788,6 @@ class ComputeManager(manager.SchedulerDependentManager):
:returns: See driver.update_available_resource()
"""
-
return self.driver.update_available_resource(context, self.host)
def pre_live_migration(self, context, instance_id, time=None):
@@ -821,7 +797,6 @@ class ComputeManager(manager.SchedulerDependentManager):
:param instance_id: nova.db.sqlalchemy.models.Instance.Id
"""
-
if not time:
time = greenthread
@@ -880,7 +855,6 @@ class ComputeManager(manager.SchedulerDependentManager):
:param dest: destination host
"""
-
# Get instance for error handling.
instance_ref = self.db.instance_get(context, instance_id)
i_name = instance_ref.name
@@ -976,12 +950,10 @@ class ComputeManager(manager.SchedulerDependentManager):
:param ctxt: security context
:param instance_id: nova.db.sqlalchemy.models.Instance.Id
- :param host:
- DB column value is updated by this hostname.
- if none, the host instance currently running is selected.
+ :param host: DB column value is updated by this hostname.
+ If none, the host instance currently running is selected.
"""
-
if not host:
host = instance_ref['host']
@@ -1076,6 +1048,9 @@ class ComputeManager(manager.SchedulerDependentManager):
# Are there VMs not in the DB?
for vm_not_found_in_db in vms_not_found_in_db:
name = vm_not_found_in_db
- # TODO(justinsb): What to do here? Adopt it? Shut it down?
- LOG.warning(_("Found VM not in DB: '%(name)s'. Ignoring")
- % locals())
+
+ # We only care about instances that compute *should* know about
+ if name.startswith("instance-"):
+ # TODO(justinsb): What to do here? Adopt it? Shut it down?
+ LOG.warning(_("Found VM not in DB: '%(name)s'. Ignoring")
+ % locals())
diff --git a/nova/compute/monitor.py b/nova/compute/monitor.py
index 04e08a235..3bb54a382 100644
--- a/nova/compute/monitor.py
+++ b/nova/compute/monitor.py
@@ -260,7 +260,7 @@ class Instance(object):
try:
data = self.fetch_cpu_stats()
- if data != None:
+ if data is not None:
LOG.debug('CPU: %s', data)
update_rrd(self, 'cpu', data)
@@ -313,7 +313,7 @@ class Instance(object):
LOG.debug('CPU: %d', self.cputime)
# Skip calculation on first pass. Need delta to get a meaningful value.
- if cputime_last_updated == None:
+ if cputime_last_updated is None:
return None
# Calculate the number of seconds between samples.