From 6b83e1cd31f5e138af20fbd5c118d55da092eb35 Mon Sep 17 00:00:00 2001 From: Ed Leafe Date: Thu, 7 Jul 2011 15:24:12 +0000 Subject: Added API and supporting code for rebooting or shutting down XenServer hosts. --- nova/compute/api.py | 6 ++++++ nova/compute/manager.py | 6 ++++++ 2 files changed, 12 insertions(+) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index b0eedcd64..71e11c5ea 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -917,6 +917,12 @@ class API(base.Base): return self._call_compute_message("set_host_enabled", context, instance_id=None, host=host, params={"enabled": enabled}) + def set_power_state(self, context, host, power_state): + """Turns the specified host on/off, or reboots the host.""" + return self._call_compute_message("set_power_state", context, + instance_id=None, host=host, + params={"power_state": power_state}) + @scheduler_api.reroute_compute("diagnostics") def get_diagnostics(self, context, instance_id): """Retrieve diagnostics for the given instance.""" diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 91a604934..eb8e4df3c 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -880,6 +880,12 @@ class ComputeManager(manager.SchedulerDependentManager): """Sets the specified host's ability to accept new instances.""" return self.driver.set_host_enabled(host, enabled) + @exception.wrap_exception + def set_power_state(self, context, instance_id=None, host=None, + power_state=None): + """Turns the specified host on/off, or reboots the host.""" + return self.driver.set_power_state(host, power_state) + @exception.wrap_exception def get_diagnostics(self, context, instance_id): """Retrieve diagnostics for an instance on this host.""" -- cgit From 76aab6d65fa35ae88f9b16acd4ee2968dfe049ce Mon Sep 17 00:00:00 2001 From: "matt.dietz@rackspace.com" <> Date: Wed, 20 Jul 2011 16:56:45 -0500 Subject: CHanges based on feedback --- nova/compute/manager.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index eb3996d29..01a7d195f 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -820,20 +820,24 @@ class ComputeManager(manager.SchedulerDependentManager): migration_ref['instance_id']) # TODO(mdietz): apply the rest of the instance_type attributes going # after they're supported - instance_type = self.db.instance_type_get_by_flavor_id(context, - migration_ref['new_flavor_id']) - self.db.instance_update(context, instance_id, - dict(instance_type_id=instance_type['id'], - memory_mb=instance_type['memory_mb'], - vcpus=instance_type['vcpus'], - local_gb=instance_type['local_gb'])) + resize_instance = False + if migration_ref['old_flavor_id'] != migration_ref['new_flavor_id']: + instance_type = self.db.instance_type_get_by_flavor_id(context, + migration_ref['new_flavor_id']) + self.db.instance_update(context, instance_id, + dict(instance_type_id=instance_type['id'], + memory_mb=instance_type['memory_mb'], + vcpus=instance_type['vcpus'], + local_gb=instance_type['local_gb'])) + resize_instance = True # reload the updated instance ref # FIXME(mdietz): is there reload functionality? instance = self.db.instance_get(context, instance_id) network_info = self.network_api.get_instance_nw_info(context, instance) - self.driver.finish_resize(instance, disk_info, network_info) + self.driver.finish_resize(instance, disk_info, network_info, + resize_instance) self.db.migration_update(context, migration_id, {'status': 'finished', }) -- cgit From 806be42000cf54e5b2ff9fb03446e8e6924bd38b Mon Sep 17 00:00:00 2001 From: "matt.dietz@rackspace.com" <> Date: Thu, 21 Jul 2011 12:46:58 -0500 Subject: Renamed the virt driver resize methods to migration for marginally more understandable code --- nova/compute/manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 01a7d195f..78d7f6479 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -723,7 +723,7 @@ class ComputeManager(manager.SchedulerDependentManager): local_gb=instance_type['local_gb'], instance_type_id=instance_type['id'])) - self.driver.revert_resize(instance_ref) + self.driver.revert_migration(instance_ref) self.db.migration_update(context, migration_id, {'status': 'reverted'}) usage_info = utils.usage_from_instance(instance_ref) @@ -836,7 +836,7 @@ class ComputeManager(manager.SchedulerDependentManager): instance = self.db.instance_get(context, instance_id) network_info = self.network_api.get_instance_nw_info(context, instance) - self.driver.finish_resize(instance, disk_info, network_info, + self.driver.finish_migration(instance, disk_info, network_info, resize_instance) self.db.migration_update(context, migration_id, -- cgit From 5f75097eb46fa03814fe53c5d9fda84f0000fdd4 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Thu, 21 Jul 2011 22:46:57 +0000 Subject: start removing references to AuthManager --- nova/compute/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 67aa3c20f..51a903d40 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -688,7 +688,7 @@ class API(base.Base): raise instances = None elif project_id or not context.is_admin: - if not context.project: + if not context.project_id: instances = self.db.instance_get_all_by_user( context, context.user_id) else: -- cgit From 8d97118be776fcaad3053d1f93f61d339685a4ae Mon Sep 17 00:00:00 2001 From: Nikolay Sokolov Date: Fri, 22 Jul 2011 17:26:11 +0400 Subject: Moved restaring instances from livbirt driver to ComputeManager. --- nova/compute/manager.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 5819a520a..c7d3004a5 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -146,7 +146,26 @@ class ComputeManager(manager.SchedulerDependentManager): def init_host(self): """Initialization for a standalone compute service.""" + # NOTE(nsokolov): based on itoumsn's implementation from libvirt driver + from nova import context self.driver.init_host(host=self.host) + admin_context = context.get_admin_context() + for instance in self.db.instance_get_all_by_host(admin_context, self.host): + try: + LOG.debug(_('Checking state of %s'), instance['name']) + state = self.driver.get_info(instance['name'])['state'] + except exception.NotFound: + state = power_state.SHUTOFF + + LOG.debug(_('Current state of %(name)s is %(state)s, state in DB is %(db_state)s.'), + {'name': instance['name'], 'state': state, 'db_state': instance['state']}) + + if instance['state'] == power_state.RUNNING and state != power_state.RUNNING \ + and FLAGS.start_guests_on_host_boot: + LOG.debug(_('Rebooting instance %(name)s after nova-compute restart.')) + self.reboot_instance(admin_context, instance[id]) + else: + self.db.instance_set_state(ctxt, instance['id'], state) def _update_state(self, context, instance_id, state=None): """Update the state of an instance from the driver info.""" -- cgit From 44d1024a53b8150cf9542d08d5886f430365f161 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Fri, 22 Jul 2011 19:47:41 +0000 Subject: fix all tests --- nova/compute/api.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 51a903d40..9a1ce7452 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -676,6 +676,7 @@ class API(base.Base): all instances in the system. """ + LOG.info(locals()) if reservation_id is not None: recurse_zones = True instances = self.db.instance_get_all_by_reservation( @@ -688,6 +689,7 @@ class API(base.Base): raise instances = None elif project_id or not context.is_admin: + LOG.info(context.project_id) if not context.project_id: instances = self.db.instance_get_all_by_user( context, context.user_id) -- cgit From 1f55e116adbf00a0a5bd990f99a680e9d6b1618e Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Sat, 23 Jul 2011 16:55:25 +0900 Subject: ec2utils: factor generic helper function into generic place This patch moves out a helper function, properties_root_device_name(), into generic file nova/block_device.py. --- nova/compute/api.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 9994e5724..43a95aa17 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -22,6 +22,7 @@ import eventlet import re import time +from nova import block_device from nova import db from nova import exception from nova import flags @@ -218,7 +219,7 @@ class API(base.Base): if reservation_id is None: reservation_id = utils.generate_uid('r') - root_device_name = ec2utils.properties_root_device_name( + root_device_name = block_device.properties_root_device_name( image['properties']) base_options = { -- cgit From e0517aef19bb00aa88809cb3c7d650ea38a08be2 Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Sat, 23 Jul 2011 16:55:25 +0900 Subject: compute/manager, virt: pass down root device name/swap/ephemeral to virt driver This patch makes compute/manager pass down infos about root device name, swap and ephemerals to virt driver. --- nova/compute/manager.py | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 5819a520a..a4d2797d6 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -44,6 +44,7 @@ import functools from eventlet import greenthread +from nova import block_device from nova import exception from nova import flags import nova.image @@ -223,6 +224,8 @@ class ComputeManager(manager.SchedulerDependentManager): volume_api = volume.API() block_device_mapping = [] + swap = None + ephemerals = [] for bdm in self.db.block_device_mapping_get_all_by_instance( context, instance_id): LOG.debug(_("setting up bdm %s"), bdm) @@ -230,11 +233,18 @@ class ComputeManager(manager.SchedulerDependentManager): if bdm['no_device']: continue if bdm['virtual_name']: - # TODO(yamahata): - # block devices for swap and ephemeralN will be - # created by virt driver locally in compute node. - assert (bdm['virtual_name'] == 'swap' or - bdm['virtual_name'].startswith('ephemeral')) + virtual_name = bdm['virtual_name'] + device_name = bdm['device_name'] + assert block_device.is_swap_or_ephemeral(virtual_name) + if virtual_name == 'swap': + swap = {'device_name': device_name, + 'swap_size': bdm['volume_size']} + elif block_device.is_ephemeral(virtual_name): + eph = {'num': block_device.ephemeral_num(virtual_name), + 'virtual_name': virtual_name, + 'device_name': device_name, + 'size': bdm['volume_size']} + ephemerals.append(eph) continue if ((bdm['snapshot_id'] is not None) and @@ -270,7 +280,7 @@ class ComputeManager(manager.SchedulerDependentManager): 'mount_device': bdm['device_name']}) - return block_device_mapping + return (swap, ephemerals, block_device_mapping) def _run_instance(self, context, instance_id, **kwargs): """Launch a new instance with specified options.""" @@ -313,13 +323,20 @@ class ComputeManager(manager.SchedulerDependentManager): # all vif creation and network injection, maybe this is correct network_info = [] - bd_mapping = self._setup_block_device_mapping(context, instance_id) + (swap, ephemerals, + block_device_mapping) = self._setup_block_device_mapping( + context, instance_id) + block_device_info = { + 'root_device_name': instance['root_device_name'], + 'swap': swap, + 'ephemerals': ephemerals, + 'block_device_mapping': block_device_mapping} # TODO(vish) check to make sure the availability zone matches self._update_state(context, instance_id, power_state.BUILDING) try: - self.driver.spawn(instance, network_info, bd_mapping) + self.driver.spawn(instance, network_info, block_device_info) except Exception as ex: # pylint: disable=W0702 msg = _("Instance '%(instance_id)s' failed to spawn. Is " "virtualization enabled in the BIOS? Details: " -- cgit From e05b3b11e67f18a6ff4867dfbc75554fd78cad1b Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Sat, 23 Jul 2011 16:55:25 +0900 Subject: compute/api: pass down ephemeral device info --- nova/compute/api.py | 70 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 16 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 43a95aa17..942114161 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -33,7 +33,6 @@ from nova import quota from nova import rpc from nova import utils from nova import volume -from nova.api.ec2 import ec2utils from nova.compute import instance_types from nova.compute import power_state from nova.compute.utils import terminate_volumes @@ -251,34 +250,64 @@ class API(base.Base): return (num_instances, base_options, image) - def _update_image_block_device_mapping(self, elevated_context, instance_id, + @staticmethod + def _ephemeral_size(instance_type, ephemeral_name): + num = block_device.ephemeral_num(ephemeral_name) + + # TODO(yamahata): ephemeralN where N > 0 + # Only ephemeral0 is allowed for now because InstanceTypes + # table only allows single local disk, local_gb. + # In order to enhance it, we need to add a new columns to + # instance_types table. + if num > 0: + return 0 + + return instance_type.get('local_gb') + + def _update_image_block_device_mapping(self, elevated_context, + instance_type, instance_id, mappings): """tell vm driver to create ephemeral/swap device at boot time by updating BlockDeviceMapping """ - for bdm in ec2utils.mappings_prepend_dev(mappings): + instance_type = (instance_type or + instance_types.get_default_instance_type()) + + for bdm in block_device.mappings_prepend_dev(mappings): LOG.debug(_("bdm %s"), bdm) virtual_name = bdm['virtual'] if virtual_name == 'ami' or virtual_name == 'root': continue - assert (virtual_name == 'swap' or - virtual_name.startswith('ephemeral')) + if not block_device.is_swap_or_ephemeral(virtual_name): + continue + + size = 0 + if virtual_name == 'swap': + size = instance_type.get('swap', 0) + elif block_device.is_ephemeral(virtual_name): + size = self._ephemeral_size(instance_type, virtual_name) + + if size == 0: + continue + values = { 'instance_id': instance_id, 'device_name': bdm['device'], - 'virtual_name': virtual_name, } + 'virtual_name': virtual_name, + 'volume_size': size} self.db.block_device_mapping_update_or_create(elevated_context, values) - def _update_block_device_mapping(self, elevated_context, instance_id, + def _update_block_device_mapping(self, elevated_context, + instance_type, instance_id, block_device_mapping): """tell vm driver to attach volume at boot time by updating BlockDeviceMapping """ + LOG.debug(_("block_device_mapping %s"), block_device_mapping) for bdm in block_device_mapping: - LOG.debug(_('bdm %s'), bdm) assert 'device_name' in bdm values = {'instance_id': instance_id} @@ -287,10 +316,18 @@ class API(base.Base): 'no_device'): values[key] = bdm.get(key) + virtual_name = bdm.get('virtual_name') + if (virtual_name is not None and + block_device.is_ephemeral(virtual_name)): + size = self._ephemeral_size(instance_type, virtual_name) + if size == 0: + continue + values['volume_size'] = size + # NOTE(yamahata): NoDevice eliminates devices defined in image # files by command line option. # (--block-device-mapping) - if bdm.get('virtual_name') == 'NoDevice': + if virtual_name == 'NoDevice': values['no_device'] = True for k in ('delete_on_termination', 'volume_id', 'snapshot_id', 'volume_id', 'volume_size', @@ -300,8 +337,8 @@ class API(base.Base): self.db.block_device_mapping_update_or_create(elevated_context, values) - def create_db_entry_for_new_instance(self, context, image, base_options, - security_group, block_device_mapping, num=1): + def create_db_entry_for_new_instance(self, context, instance_type, image, + base_options, security_group, block_device_mapping, num=1): """Create an entry in the DB for this new instance, including any related table updates (such as security group, etc). @@ -334,12 +371,12 @@ class API(base.Base): security_group_id) # BlockDeviceMapping table - self._update_image_block_device_mapping(elevated, instance_id, - image['properties'].get('mappings', [])) - self._update_block_device_mapping(elevated, instance_id, + self._update_image_block_device_mapping(elevated, instance_type, + instance_id, image['properties'].get('mappings', [])) + self._update_block_device_mapping(elevated, instance_type, instance_id, image['properties'].get('block_device_mapping', [])) # override via command line option - self._update_block_device_mapping(elevated, instance_id, + self._update_block_device_mapping(elevated, instance_type, instance_id, block_device_mapping) # Set sane defaults if not specified @@ -454,7 +491,8 @@ class API(base.Base): instances = [] LOG.debug(_("Going to run %s instances..."), num_instances) for num in range(num_instances): - instance = self.create_db_entry_for_new_instance(context, image, + instance = self.create_db_entry_for_new_instance(context, + instance_type, image, base_options, security_group, block_device_mapping, num=num) instances.append(instance) -- cgit From 708b0cb65a672e9f6b8bab4817061be4fa2a8928 Mon Sep 17 00:00:00 2001 From: Nikolay Sokolov Date: Mon, 25 Jul 2011 14:22:38 +0400 Subject: Fixed init_host context name. --- nova/compute/manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index c7d3004a5..b876e87d0 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -165,7 +165,7 @@ class ComputeManager(manager.SchedulerDependentManager): LOG.debug(_('Rebooting instance %(name)s after nova-compute restart.')) self.reboot_instance(admin_context, instance[id]) else: - self.db.instance_set_state(ctxt, instance['id'], state) + self.db.instance_set_state(admin_context, instance['id'], state) def _update_state(self, context, instance_id, state=None): """Update the state of an instance from the driver info.""" -- cgit From d8f4d773b08a94b171ff2643d48daa5b2709118a Mon Sep 17 00:00:00 2001 From: Nikolay Sokolov Date: Mon, 25 Jul 2011 14:33:45 +0400 Subject: Fixed id. --- nova/compute/manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index b876e87d0..b7e54d903 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -163,7 +163,7 @@ class ComputeManager(manager.SchedulerDependentManager): if instance['state'] == power_state.RUNNING and state != power_state.RUNNING \ and FLAGS.start_guests_on_host_boot: LOG.debug(_('Rebooting instance %(name)s after nova-compute restart.')) - self.reboot_instance(admin_context, instance[id]) + self.reboot_instance(admin_context, instance['id']) else: self.db.instance_set_state(admin_context, instance['id'], state) -- cgit From 19379c78e6efd4637d876c91b022e6e7dbd38836 Mon Sep 17 00:00:00 2001 From: Nikolay Sokolov Date: Mon, 25 Jul 2011 14:37:21 +0400 Subject: Fixed logging. --- nova/compute/manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index b7e54d903..071eabcfe 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -162,7 +162,7 @@ class ComputeManager(manager.SchedulerDependentManager): if instance['state'] == power_state.RUNNING and state != power_state.RUNNING \ and FLAGS.start_guests_on_host_boot: - LOG.debug(_('Rebooting instance %(name)s after nova-compute restart.')) + LOG.debug(_('Rebooting instance %(name)s after nova-compute restart.'), {'name': instance['name']}) self.reboot_instance(admin_context, instance['id']) else: self.db.instance_set_state(admin_context, instance['id'], state) -- cgit From cf4aea379eb337b16a9816d45c50c0553c500d0d Mon Sep 17 00:00:00 2001 From: Nikolay Sokolov Date: Mon, 25 Jul 2011 15:03:02 +0400 Subject: pep8 --- nova/compute/manager.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 071eabcfe..ebd91177f 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -150,22 +150,29 @@ class ComputeManager(manager.SchedulerDependentManager): from nova import context self.driver.init_host(host=self.host) admin_context = context.get_admin_context() - for instance in self.db.instance_get_all_by_host(admin_context, self.host): + for instance in self.db.instance_get_all_by_host(admin_context, + self.host): try: LOG.debug(_('Checking state of %s'), instance['name']) state = self.driver.get_info(instance['name'])['state'] except exception.NotFound: state = power_state.SHUTOFF - LOG.debug(_('Current state of %(name)s is %(state)s, state in DB is %(db_state)s.'), - {'name': instance['name'], 'state': state, 'db_state': instance['state']}) - - if instance['state'] == power_state.RUNNING and state != power_state.RUNNING \ - and FLAGS.start_guests_on_host_boot: - LOG.debug(_('Rebooting instance %(name)s after nova-compute restart.'), {'name': instance['name']}) + LOG.debug(_('Current state of %(name)s is %(state)s, state in ' + 'DB is %(db_state)s.'), {'name': instance['name'], + 'state': state, + 'db_state': + instance['state']}) + + if instance['state'] == power_state.RUNNING \ + and state != power_state.RUNNING \ + and FLAGS.start_guests_on_host_boot: + LOG.debug(_('Rebooting instance %(name)s after nova-compute ' + ' restart.'), {'name': instance['name']}) self.reboot_instance(admin_context, instance['id']) else: - self.db.instance_set_state(admin_context, instance['id'], state) + self.db.instance_set_state(admin_context, instance['id'], + state) def _update_state(self, context, instance_id, state=None): """Update the state of an instance from the driver info.""" -- cgit From d85a43c4cdb1bfd28355ded486af2ded8f43d6b0 Mon Sep 17 00:00:00 2001 From: Nikolay Sokolov Date: Mon, 25 Jul 2011 19:54:23 +0400 Subject: Some estetic refactoring. --- nova/compute/manager.py | 48 +++++++++++++++++++++--------------------------- 1 file changed, 21 insertions(+), 27 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index ebd91177f..950fe0d53 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -44,6 +44,7 @@ import functools from eventlet import greenthread +import nova.context from nova import exception from nova import flags import nova.image @@ -145,34 +146,26 @@ class ComputeManager(manager.SchedulerDependentManager): *args, **kwargs) def init_host(self): - """Initialization for a standalone compute service.""" - # NOTE(nsokolov): based on itoumsn's implementation from libvirt driver - from nova import context + """Initialization for a standalone compute service. + + Reboots instances marked as running in DB if they is not running.""" self.driver.init_host(host=self.host) - admin_context = context.get_admin_context() - for instance in self.db.instance_get_all_by_host(admin_context, - self.host): - try: - LOG.debug(_('Checking state of %s'), instance['name']) - state = self.driver.get_info(instance['name'])['state'] - except exception.NotFound: - state = power_state.SHUTOFF - - LOG.debug(_('Current state of %(name)s is %(state)s, state in ' - 'DB is %(db_state)s.'), {'name': instance['name'], - 'state': state, - 'db_state': - instance['state']}) - - if instance['state'] == power_state.RUNNING \ - and state != power_state.RUNNING \ - and FLAGS.start_guests_on_host_boot: - LOG.debug(_('Rebooting instance %(name)s after nova-compute ' - ' restart.'), {'name': instance['name']}) - self.reboot_instance(admin_context, instance['id']) - else: - self.db.instance_set_state(admin_context, instance['id'], - state) + context = nova.context.get_admin_context() + instances = self.db.instance_get_all_by_host(context, self.host) + for instance in instances: + inst_name = instance['name'] + db_state = instance['state'] + drv_state = self._update_state(context, instance['id']) + + expect_running = db_state == power_state.RUNNING != drv_state + + LOG.debug(_('Current state of %(inst_name)s is %(drv_state)s, ' + 'state in DB is %(db_state)s.'), locals()) + + if expect_running and FLAGS.start_guests_on_host_boot: + LOG.info(_('Rebooting instance %(inst_name)s after ' + 'nova-compute restart.'), locals()) + self.reboot_instance(context, instance['id']) def _update_state(self, context, instance_id, state=None): """Update the state of an instance from the driver info.""" @@ -180,6 +173,7 @@ class ComputeManager(manager.SchedulerDependentManager): if state is None: try: + LOG.debug(_('Checking state of %s'), instance_ref['name']) info = self.driver.get_info(instance_ref['name']) except exception.NotFound: info = None -- cgit From 9c88bbee56dd05703af8f7c0df839a4da73f491a Mon Sep 17 00:00:00 2001 From: Nikolay Sokolov Date: Mon, 25 Jul 2011 19:59:00 +0400 Subject: Hotfix. --- nova/compute/manager.py | 1 + 1 file changed, 1 insertion(+) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 950fe0d53..79e9b16d3 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -184,6 +184,7 @@ class ComputeManager(manager.SchedulerDependentManager): state = power_state.FAILED self.db.instance_set_state(context, instance_id, state) + return state def _update_launched_at(self, context, instance_id, launched_at=None): """Update the launched_at parameter of the given instance.""" -- cgit From 8de3c0fcaee546fae3d415ef5ddcbb51fb1db6d7 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Mon, 25 Jul 2011 17:49:09 +0000 Subject: fix for reviews --- nova/compute/api.py | 1 - 1 file changed, 1 deletion(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index d1c3fd6fd..487d23b0d 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -676,7 +676,6 @@ class API(base.Base): all instances in the system. """ - LOG.info(locals()) if reservation_id is not None: recurse_zones = True instances = self.db.instance_get_all_by_reservation( -- cgit From ba4946d0d3c73e5d9f67f42203d103bf98563458 Mon Sep 17 00:00:00 2001 From: Nikolay Sokolov Date: Tue, 26 Jul 2011 00:31:42 +0400 Subject: Fixed old libvirt semantics, added resume_guests_state_on_host_boot flag. --- nova/compute/manager.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 79e9b16d3..bfac3df28 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -146,9 +146,7 @@ class ComputeManager(manager.SchedulerDependentManager): *args, **kwargs) def init_host(self): - """Initialization for a standalone compute service. - - Reboots instances marked as running in DB if they is not running.""" + """Initialization for a standalone compute service.""" self.driver.init_host(host=self.host) context = nova.context.get_admin_context() instances = self.db.instance_get_all_by_host(context, self.host) @@ -157,12 +155,13 @@ class ComputeManager(manager.SchedulerDependentManager): db_state = instance['state'] drv_state = self._update_state(context, instance['id']) - expect_running = db_state == power_state.RUNNING != drv_state + expect_running = (db_state == power_state.RUNNING != drv_state) LOG.debug(_('Current state of %(inst_name)s is %(drv_state)s, ' 'state in DB is %(db_state)s.'), locals()) - if expect_running and FLAGS.start_guests_on_host_boot: + if (expect_running and FLAGS.resume_guests_state_on_host_boot)\ + or FLAGS.start_guests_on_host_boot: LOG.info(_('Rebooting instance %(inst_name)s after ' 'nova-compute restart.'), locals()) self.reboot_instance(context, instance['id']) -- cgit From 879e49c67b78d3336a24cf1af12f21258c2225fa Mon Sep 17 00:00:00 2001 From: Nikolay Sokolov Date: Tue, 26 Jul 2011 01:46:40 +0400 Subject: Estetic fix. --- nova/compute/manager.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index bfac3df28..a6eb1efb2 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -155,7 +155,8 @@ class ComputeManager(manager.SchedulerDependentManager): db_state = instance['state'] drv_state = self._update_state(context, instance['id']) - expect_running = (db_state == power_state.RUNNING != drv_state) + expect_running = db_state == power_state.RUNNING \ + and drv_state != db_state LOG.debug(_('Current state of %(inst_name)s is %(drv_state)s, ' 'state in DB is %(db_state)s.'), locals()) -- cgit From d4842ac958bda3b446d14c7348692acc231e0041 Mon Sep 17 00:00:00 2001 From: Nikolay Sokolov Date: Tue, 26 Jul 2011 02:30:20 +0400 Subject: Added ensuring filter rules for all VMs. --- nova/compute/manager.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index a6eb1efb2..53390098a 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -166,6 +166,11 @@ class ComputeManager(manager.SchedulerDependentManager): LOG.info(_('Rebooting instance %(inst_name)s after ' 'nova-compute restart.'), locals()) self.reboot_instance(context, instance['id']) + elif drv_state == power_state.RUNNING: + try: # Hyper-V and VMWareAPI drivers will raise and exception + self.driver.ensure_filtering_rules_for_instance(instance) + except NotImplementedError: + pass def _update_state(self, context, instance_id, state=None): """Update the state of an instance from the driver info.""" -- cgit From 8f5a6d15e671c95c6e38147ca15fb49fd672e788 Mon Sep 17 00:00:00 2001 From: Nikolay Sokolov Date: Tue, 26 Jul 2011 02:33:39 +0400 Subject: Warn user instead of ignoring --- nova/compute/manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 53390098a..1f207e6f0 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -170,7 +170,7 @@ class ComputeManager(manager.SchedulerDependentManager): try: # Hyper-V and VMWareAPI drivers will raise and exception self.driver.ensure_filtering_rules_for_instance(instance) except NotImplementedError: - pass + LOG.warning(_('Hypervisor driver does not support firewall rules')) def _update_state(self, context, instance_id, state=None): """Update the state of an instance from the driver info.""" -- cgit From b18754473785611112ae54523677da83dff24075 Mon Sep 17 00:00:00 2001 From: "Kevin L. Mitchell" Date: Tue, 26 Jul 2011 20:58:33 +0000 Subject: First pass at converting this stuff--pass context down into vmops. Still need to fix unit tests and actually use auth_token from the context... --- nova/compute/manager.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 31627fe3b..667d231ae 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -326,7 +326,7 @@ class ComputeManager(manager.SchedulerDependentManager): self._update_state(context, instance_id, power_state.BUILDING) try: - self.driver.spawn(instance, network_info, bd_mapping) + self.driver.spawn(context, instance, network_info, bd_mapping) except Exception as ex: # pylint: disable=W0702 msg = _("Instance '%(instance_id)s' failed to spawn. Is " "virtualization enabled in the BIOS? Details: " @@ -430,7 +430,7 @@ class ComputeManager(manager.SchedulerDependentManager): image_ref = kwargs.get('image_ref') instance_ref.image_ref = image_ref instance_ref.injected_files = kwargs.get('injected_files', []) - self.driver.spawn(instance_ref, network_info) + self.driver.spawn(context, instance_ref, network_info) self._update_image_ref(context, instance_id, image_ref) self._update_launched_at(context, instance_id) @@ -498,7 +498,7 @@ class ComputeManager(manager.SchedulerDependentManager): 'instance: %(instance_id)s (state: %(state)s ' 'expected: %(running)s)') % locals()) - self.driver.snapshot(instance_ref, image_id) + self.driver.snapshot(context, instance_ref, image_id) if image_type == 'snapshot': if rotation: @@ -855,7 +855,8 @@ class ComputeManager(manager.SchedulerDependentManager): instance_ref = self.db.instance_get_by_uuid(context, instance_ref.uuid) network_info = self._get_instance_nw_info(context, instance_ref) - self.driver.finish_resize(instance_ref, disk_info, network_info) + self.driver.finish_resize(context, instance_ref, disk_info, + network_info) self.db.migration_update(context, migration_id, {'status': 'finished', }) -- cgit From 1e8a7f2846ce0a3fb3d9e31fc7d4dbf27d54fac2 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Thu, 28 Jul 2011 19:06:48 -0700 Subject: remove extra log statement --- nova/compute/api.py | 1 - 1 file changed, 1 deletion(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 51c5ae155..8f7b3c3ef 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -689,7 +689,6 @@ class API(base.Base): raise instances = None elif project_id or not context.is_admin: - LOG.info(context.project_id) if not context.project_id: instances = self.db.instance_get_all_by_user( context, context.user_id) -- cgit From 7a165843aa5c1a98b1dbf13dedf556878a3d0435 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Fri, 29 Jul 2011 11:06:02 -0400 Subject: Updated resize to call compute API with instance_type identifiers instead of flavor identifiers. Updated tests. --- nova/compute/instance_types.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index c13a629a9..824416514 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -132,11 +132,8 @@ def get_instance_type_by_name(name): # flavors. def get_instance_type_by_flavor_id(flavor_id): """Retrieve instance type by flavor_id.""" - if flavor_id is None: - return get_default_instance_type() + ctxt = context.get_admin_context() try: - ctxt = context.get_admin_context() return db.instance_type_get_by_flavor_id(ctxt, flavor_id) - except exception.DBError, e: - LOG.exception(_('DB error: %s') % e) - raise exception.ApiError(_("Unknown flavor: %s") % flavor_id) + except ValueError: + raise exception.FlavorNotFound(flavor_id=flavor_id) -- cgit From fc2682bc9c01c445b9ee7003c5cb561c452757e5 Mon Sep 17 00:00:00 2001 From: "Kevin L. Mitchell" Date: Fri, 29 Jul 2011 21:58:27 +0000 Subject: Revert to using context; to avoid conflict, we import context module as nova_context; add context to rescue --- nova/compute/manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 56331f86b..cf4ee229d 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -660,7 +660,7 @@ class ComputeManager(manager.SchedulerDependentManager): _update_state = lambda result: self._update_state_callback( self, context, instance_id, result) network_info = self._get_instance_nw_info(context, instance_ref) - self.driver.rescue(instance_ref, _update_state, network_info) + self.driver.rescue(context, instance_ref, _update_state, network_info) self._update_state(context, instance_id) @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) -- cgit From 055a422643fc229ec0e7db3f6dcba9904c5a4f5d Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Fri, 29 Jul 2011 18:05:31 -0400 Subject: Created exceptions for accepting in OSAPI, and handled them appropriately. --- nova/compute/api.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 8f7b3c3ef..9e4841e64 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -940,18 +940,15 @@ class API(base.Base): LOG.debug(_("Old instance type %(current_instance_type_name)s, " " new instance type %(new_instance_type_name)s") % locals()) if not new_instance_type: - raise exception.ApiError(_("Requested flavor %(flavor_id)d " - "does not exist") % locals()) + raise exception.FlavorDoesNotExist(flavor_id=flavor_id) current_memory_mb = current_instance_type['memory_mb'] new_memory_mb = new_instance_type['memory_mb'] if current_memory_mb > new_memory_mb: - raise exception.ApiError(_("Invalid flavor: cannot downsize" - "instances")) + raise exception.CannotResizeToSmallerSize() if (current_memory_mb == new_memory_mb) and flavor_id: - raise exception.ApiError(_("Invalid flavor: cannot use" - "the same flavor. ")) + raise exception.CannotResizeToSameSize() instance_ref = self._get_instance(context, instance_id, 'resize') self._cast_scheduler_message(context, -- cgit From a7f0eb04236b15a026654346b47bc434886b9d97 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Fri, 29 Jul 2011 18:13:28 -0400 Subject: FlavorNotFound already existed, no need to create another exception. --- nova/compute/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 9e4841e64..aae16d1da 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -940,7 +940,7 @@ class API(base.Base): LOG.debug(_("Old instance type %(current_instance_type_name)s, " " new instance type %(new_instance_type_name)s") % locals()) if not new_instance_type: - raise exception.FlavorDoesNotExist(flavor_id=flavor_id) + raise exception.FlavorNotFound(flavor_id=flavor_id) current_memory_mb = current_instance_type['memory_mb'] new_memory_mb = new_instance_type['memory_mb'] -- cgit From 85795ff1f8b6a0ff3de634828208d6debd91692f Mon Sep 17 00:00:00 2001 From: Ed Leafe Date: Mon, 1 Aug 2011 21:06:47 +0000 Subject: Added option for rebooting or shutting down a host. --- nova/compute/api.py | 5 +++++ nova/compute/manager.py | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 8f7b3c3ef..bd17fdf31 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -998,6 +998,11 @@ class API(base.Base): return self._call_compute_message("set_host_enabled", context, instance_id=None, host=host, params={"enabled": enabled}) + def set_host_powerstate(self, context, host, state): + """Reboots or shuts down the host.""" + return self._call_compute_message("set_host_powerstate", context, + instance_id=None, host=host, params={"state": state}) + @scheduler_api.reroute_compute("diagnostics") def get_diagnostics(self, context, instance_id): """Retrieve diagnostics for the given instance.""" diff --git a/nova/compute/manager.py b/nova/compute/manager.py index a2d84cd76..d0f9a81f4 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1,4 +1,4 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 +: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. @@ -927,6 +927,12 @@ class ComputeManager(manager.SchedulerDependentManager): instance_id, result)) + @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) + def set_host_powerstate(self, context, instance_id=None, host=None, + state=None): + """Reboots or shuts down the host.""" + return self.driver.set_host_powerstate(host, state) + @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) def set_host_enabled(self, context, instance_id=None, host=None, enabled=None): -- cgit From 07646e85841a4f7c81e80254ac63715bece2aadd Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Tue, 2 Aug 2011 10:09:58 -0400 Subject: removing compute monitor --- nova/compute/monitor.py | 435 ------------------------------------------------ 1 file changed, 435 deletions(-) delete mode 100644 nova/compute/monitor.py (limited to 'nova/compute') diff --git a/nova/compute/monitor.py b/nova/compute/monitor.py deleted file mode 100644 index 9d8e2a25d..000000000 --- a/nova/compute/monitor.py +++ /dev/null @@ -1,435 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -Instance Monitoring: - - Optionally may be run on each compute node. Provides RRD - based statistics and graphs and makes them internally available - in the object store. -""" - -import datetime -import os -import time - -import boto -import boto.s3 -import rrdtool -from twisted.internet import task -from twisted.application import service - -from nova import flags -from nova import log as logging -from nova import utils -from nova.virt import connection as virt_connection - - -FLAGS = flags.FLAGS -flags.DEFINE_integer('monitoring_instances_delay', 5, - 'Sleep time between updates') -flags.DEFINE_integer('monitoring_instances_step', 300, - 'Interval of RRD updates') -flags.DEFINE_string('monitoring_rrd_path', '$state_path/monitor/instances', - 'Location of RRD files') - - -RRD_VALUES = { - 'cpu': [ - 'DS:cpu:GAUGE:600:0:100', - 'RRA:AVERAGE:0.5:1:800', - 'RRA:AVERAGE:0.5:6:800', - 'RRA:AVERAGE:0.5:24:800', - 'RRA:AVERAGE:0.5:288:800', - 'RRA:MAX:0.5:1:800', - 'RRA:MAX:0.5:6:800', - 'RRA:MAX:0.5:24:800', - 'RRA:MAX:0.5:288:800', - ], - 'net': [ - 'DS:rx:COUNTER:600:0:1250000', - 'DS:tx:COUNTER:600:0:1250000', - 'RRA:AVERAGE:0.5:1:800', - 'RRA:AVERAGE:0.5:6:800', - 'RRA:AVERAGE:0.5:24:800', - 'RRA:AVERAGE:0.5:288:800', - 'RRA:MAX:0.5:1:800', - 'RRA:MAX:0.5:6:800', - 'RRA:MAX:0.5:24:800', - 'RRA:MAX:0.5:288:800', - ], - 'disk': [ - 'DS:rd:COUNTER:600:U:U', - 'DS:wr:COUNTER:600:U:U', - 'RRA:AVERAGE:0.5:1:800', - 'RRA:AVERAGE:0.5:6:800', - 'RRA:AVERAGE:0.5:24:800', - 'RRA:AVERAGE:0.5:288:800', - 'RRA:MAX:0.5:1:800', - 'RRA:MAX:0.5:6:800', - 'RRA:MAX:0.5:24:800', - 'RRA:MAX:0.5:444:800', - ]} - - -utcnow = utils.utcnow - - -LOG = logging.getLogger('nova.compute.monitor') - - -def update_rrd(instance, name, data): - """ - Updates the specified RRD file. - """ - filename = os.path.join(instance.get_rrd_path(), '%s.rrd' % name) - - if not os.path.exists(filename): - init_rrd(instance, name) - - timestamp = int(time.mktime(utcnow().timetuple())) - rrdtool.update(filename, '%d:%s' % (timestamp, data)) - - -def init_rrd(instance, name): - """ - Initializes the specified RRD file. - """ - path = os.path.join(FLAGS.monitoring_rrd_path, instance.instance_id) - - if not os.path.exists(path): - os.makedirs(path) - - filename = os.path.join(path, '%s.rrd' % name) - - if not os.path.exists(filename): - rrdtool.create( - filename, - '--step', '%d' % FLAGS.monitoring_instances_step, - '--start', '0', - *RRD_VALUES[name]) - - -def graph_cpu(instance, duration): - """ - Creates a graph of cpu usage for the specified instance and duration. - """ - path = instance.get_rrd_path() - filename = os.path.join(path, 'cpu-%s.png' % duration) - - rrdtool.graph( - filename, - '--disable-rrdtool-tag', - '--imgformat', 'PNG', - '--width', '400', - '--height', '120', - '--start', 'now-%s' % duration, - '--vertical-label', '% cpu used', - '-l', '0', - '-u', '100', - 'DEF:cpu=%s:cpu:AVERAGE' % os.path.join(path, 'cpu.rrd'), - 'AREA:cpu#eacc00:% CPU',) - - store_graph(instance.instance_id, filename) - - -def graph_net(instance, duration): - """ - Creates a graph of network usage for the specified instance and duration. - """ - path = instance.get_rrd_path() - filename = os.path.join(path, 'net-%s.png' % duration) - - rrdtool.graph( - filename, - '--disable-rrdtool-tag', - '--imgformat', 'PNG', - '--width', '400', - '--height', '120', - '--start', 'now-%s' % duration, - '--vertical-label', 'bytes/s', - '--logarithmic', - '--units', 'si', - '--lower-limit', '1000', - '--rigid', - 'DEF:rx=%s:rx:AVERAGE' % os.path.join(path, 'net.rrd'), - 'DEF:tx=%s:tx:AVERAGE' % os.path.join(path, 'net.rrd'), - 'AREA:rx#00FF00:In traffic', - 'LINE1:tx#0000FF:Out traffic',) - - store_graph(instance.instance_id, filename) - - -def graph_disk(instance, duration): - """ - Creates a graph of disk usage for the specified duration. - """ - path = instance.get_rrd_path() - filename = os.path.join(path, 'disk-%s.png' % duration) - - rrdtool.graph( - filename, - '--disable-rrdtool-tag', - '--imgformat', 'PNG', - '--width', '400', - '--height', '120', - '--start', 'now-%s' % duration, - '--vertical-label', 'bytes/s', - '--logarithmic', - '--units', 'si', - '--lower-limit', '1000', - '--rigid', - 'DEF:rd=%s:rd:AVERAGE' % os.path.join(path, 'disk.rrd'), - 'DEF:wr=%s:wr:AVERAGE' % os.path.join(path, 'disk.rrd'), - 'AREA:rd#00FF00:Read', - 'LINE1:wr#0000FF:Write',) - - store_graph(instance.instance_id, filename) - - -def store_graph(instance_id, filename): - """ - Transmits the specified graph file to internal object store on cloud - controller. - """ - # TODO(devcamcar): Need to use an asynchronous method to make this - # connection. If boto has some separate method that generates - # the request it would like to make and another method to parse - # the response we can make our own client that does the actual - # request and hands it off to the response parser. - s3 = boto.s3.connection.S3Connection( - aws_access_key_id=FLAGS.aws_access_key_id, - aws_secret_access_key=FLAGS.aws_secret_access_key, - is_secure=False, - calling_format=boto.s3.connection.OrdinaryCallingFormat(), - port=FLAGS.s3_port, - host=FLAGS.s3_host) - bucket_name = '_%s.monitor' % instance_id - - # Object store isn't creating the bucket like it should currently - # when it is first requested, so have to catch and create manually. - try: - bucket = s3.get_bucket(bucket_name) - except Exception: - bucket = s3.create_bucket(bucket_name) - - key = boto.s3.Key(bucket) - key.key = os.path.basename(filename) - key.set_contents_from_filename(filename) - - -class Instance(object): - def __init__(self, conn, instance_id): - self.conn = conn - self.instance_id = instance_id - self.last_updated = datetime.datetime.min - self.cputime = 0 - self.cputime_last_updated = None - - init_rrd(self, 'cpu') - init_rrd(self, 'net') - init_rrd(self, 'disk') - - def needs_update(self): - """ - Indicates whether this instance is due to have its statistics updated. - """ - delta = utcnow() - self.last_updated - return delta.seconds >= FLAGS.monitoring_instances_step - - def update(self): - """ - Updates the instances statistics and stores the resulting graphs - in the internal object store on the cloud controller. - """ - LOG.debug(_('updating %s...'), self.instance_id) - - try: - data = self.fetch_cpu_stats() - if data is not None: - LOG.debug('CPU: %s', data) - update_rrd(self, 'cpu', data) - - data = self.fetch_net_stats() - LOG.debug('NET: %s', data) - update_rrd(self, 'net', data) - - data = self.fetch_disk_stats() - LOG.debug('DISK: %s', data) - update_rrd(self, 'disk', data) - - # TODO(devcamcar): Turn these into pool.ProcessPool.execute() calls - # and make the methods @defer.inlineCallbacks. - graph_cpu(self, '1d') - graph_cpu(self, '1w') - graph_cpu(self, '1m') - - graph_net(self, '1d') - graph_net(self, '1w') - graph_net(self, '1m') - - graph_disk(self, '1d') - graph_disk(self, '1w') - graph_disk(self, '1m') - except Exception: - LOG.exception(_('unexpected error during update')) - - self.last_updated = utcnow() - - def get_rrd_path(self): - """ - Returns the path to where RRD files are stored. - """ - return os.path.join(FLAGS.monitoring_rrd_path, self.instance_id) - - def fetch_cpu_stats(self): - """ - Returns cpu usage statistics for this instance. - """ - info = self.conn.get_info(self.instance_id) - - # Get the previous values. - cputime_last = self.cputime - cputime_last_updated = self.cputime_last_updated - - # Get the raw CPU time used in nanoseconds. - self.cputime = float(info['cpu_time']) - self.cputime_last_updated = utcnow() - - LOG.debug('CPU: %d', self.cputime) - - # Skip calculation on first pass. Need delta to get a meaningful value. - if cputime_last_updated is None: - return None - - # Calculate the number of seconds between samples. - d = self.cputime_last_updated - cputime_last_updated - t = d.days * 86400 + d.seconds - - LOG.debug('t = %d', t) - - # Calculate change over time in number of nanoseconds of CPU time used. - cputime_delta = self.cputime - cputime_last - - LOG.debug('cputime_delta = %s', cputime_delta) - - # Get the number of virtual cpus in this domain. - vcpus = int(info['num_cpu']) - - LOG.debug('vcpus = %d', vcpus) - - # Calculate CPU % used and cap at 100. - return min(cputime_delta / (t * vcpus * 1.0e9) * 100, 100) - - def fetch_disk_stats(self): - """ - Returns disk usage statistics for this instance. - """ - rd = 0 - wr = 0 - - disks = self.conn.get_disks(self.instance_id) - - # Aggregate the read and write totals. - for disk in disks: - try: - rd_req, rd_bytes, wr_req, wr_bytes, errs = \ - self.conn.block_stats(self.instance_id, disk) - rd += rd_bytes - wr += wr_bytes - except TypeError: - iid = self.instance_id - LOG.error(_('Cannot get blockstats for "%(disk)s"' - ' on "%(iid)s"') % locals()) - raise - - return '%d:%d' % (rd, wr) - - def fetch_net_stats(self): - """ - Returns network usage statistics for this instance. - """ - rx = 0 - tx = 0 - - interfaces = self.conn.get_interfaces(self.instance_id) - - # Aggregate the in and out totals. - for interface in interfaces: - try: - stats = self.conn.interface_stats(self.instance_id, interface) - rx += stats[0] - tx += stats[4] - except TypeError: - iid = self.instance_id - LOG.error(_('Cannot get ifstats for "%(interface)s"' - ' on "%(iid)s"') % locals()) - raise - - return '%d:%d' % (rx, tx) - - -class InstanceMonitor(object, service.Service): - """ - Monitors the running instances of the current machine. - """ - - def __init__(self): - """ - Initialize the monitoring loop. - """ - self._instances = {} - self._loop = task.LoopingCall(self.updateInstances) - - def startService(self): - self._instances = {} - self._loop.start(interval=FLAGS.monitoring_instances_delay) - service.Service.startService(self) - - def stopService(self): - self._loop.stop() - service.Service.stopService(self) - - def updateInstances(self): - """ - Update resource usage for all running instances. - """ - try: - conn = virt_connection.get_connection(read_only=True) - except Exception, exn: - LOG.exception(_('unexpected exception getting connection')) - time.sleep(FLAGS.monitoring_instances_delay) - return - - domain_ids = conn.list_instances() - try: - self.updateInstances_(conn, domain_ids) - except Exception, exn: - LOG.exception('updateInstances_') - - def updateInstances_(self, conn, domain_ids): - for domain_id in domain_ids: - if not domain_id in self._instances: - instance = Instance(conn, domain_id) - self._instances[domain_id] = instance - LOG.debug(_('Found instance: %s'), domain_id) - - for key in self._instances.keys(): - instance = self._instances[key] - if instance.needs_update(): - instance.update() -- cgit From f06dee2b82bd658a57736d94974f431976085400 Mon Sep 17 00:00:00 2001 From: Ed Leafe Date: Tue, 2 Aug 2011 19:02:40 +0000 Subject: Fixed several typos --- nova/compute/manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index d0f9a81f4..cd05f3f24 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1,4 +1,4 @@ -: tabstop=4 shiftwidth=4 softtabstop=4 +#: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. -- cgit From 4c07cac5b0e79f3911fbcc392c3f9e7f07333968 Mon Sep 17 00:00:00 2001 From: Ed Leafe Date: Tue, 2 Aug 2011 20:39:14 +0000 Subject: Fixed a missing space. --- nova/compute/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index b83c4831c..5ea7a1c01 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -995,7 +995,7 @@ class API(base.Base): return self._call_compute_message("set_host_enabled", context, instance_id=None, host=host, params={"enabled": enabled}) - def set_host_powerstate(self, context, host, state): + def set_host_powerstate(self, context, host, state): """Reboots or shuts down the host.""" return self._call_compute_message("set_host_powerstate", context, instance_id=None, host=host, params={"state": state}) -- cgit From a0ec6a6aa5ebdde1d099c5f6c03cf1dbd28441fa Mon Sep 17 00:00:00 2001 From: Ed Leafe Date: Wed, 3 Aug 2011 00:52:15 +0000 Subject: Removed duplicate methods created by previous merge. --- nova/compute/manager.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 37b920074..3c89042c8 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1,4 +1,4 @@ -#: tabstop=4 shiftwidth=4 softtabstop=4 +# vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. @@ -939,12 +939,6 @@ class ComputeManager(manager.SchedulerDependentManager): """Sets the specified host's ability to accept new instances.""" return self.driver.set_host_enabled(host, enabled) - @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) - def set_power_state(self, context, instance_id=None, host=None, - power_state=None): - """Turns the specified host on/off, or reboots the host.""" - return self.driver.set_power_state(host, power_state) - @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) def get_diagnostics(self, context, instance_id): """Retrieve diagnostics for an instance on this host.""" -- cgit From 2d2405e35d34c928c87d575bcfc7c74db9de6b1d Mon Sep 17 00:00:00 2001 From: Johannes Erdfelt Date: Wed, 3 Aug 2011 11:31:10 +0000 Subject: Use flavorid only at the API level and use instance_type_id internally --- nova/compute/api.py | 2 +- nova/compute/manager.py | 21 +++++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index aae16d1da..f42df015a 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -955,7 +955,7 @@ class API(base.Base): {"method": "prep_resize", "args": {"topic": FLAGS.compute_topic, "instance_id": instance_ref['uuid'], - "flavor_id": new_instance_type['id']}}) + "instance_type_id": new_instance_type['id']}}) @scheduler_api.reroute_compute("add_fixed_ip") def add_fixed_ip(self, context, instance_id, network_id): diff --git a/nova/compute/manager.py b/nova/compute/manager.py index a2d84cd76..9b5fac58b 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -736,8 +736,8 @@ class ComputeManager(manager.SchedulerDependentManager): instance_ref = self.db.instance_get_by_uuid(context, migration_ref.instance_uuid) - instance_type = self.db.instance_type_get_by_flavor_id(context, - migration_ref['old_flavor_id']) + instance_type = self.db.instance_type_get(context, + migration_ref['old_instance_type_id']) # Just roll back the record. There's no need to resize down since # the 'old' VM already has the preferred attributes @@ -758,7 +758,7 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) @checks_instance_lock - def prep_resize(self, context, instance_id, flavor_id): + def prep_resize(self, context, instance_id, instance_type_id): """Initiates the process of moving a running instance to another host. Possibly changes the RAM and disk size in the process. @@ -777,16 +777,16 @@ class ComputeManager(manager.SchedulerDependentManager): old_instance_type = self.db.instance_type_get(context, instance_ref['instance_type_id']) - new_instance_type = self.db.instance_type_get_by_flavor_id(context, - flavor_id) + new_instance_type = self.db.instance_type_get(context, + instance_type_id) migration_ref = self.db.migration_create(context, {'instance_uuid': instance_ref['uuid'], 'source_compute': instance_ref['host'], 'dest_compute': FLAGS.host, 'dest_host': self.driver.get_host_ip_addr(), - 'old_flavor_id': old_instance_type['flavorid'], - 'new_flavor_id': flavor_id, + 'old_instance_type_id': old_instance_type['id'], + 'new_instance_type_id': instance_type_id, 'status': 'pre-migrating'}) LOG.audit(_('instance %s: migrating'), instance_ref['uuid'], @@ -849,9 +849,10 @@ class ComputeManager(manager.SchedulerDependentManager): resize_instance = False instance_ref = self.db.instance_get_by_uuid(context, migration_ref.instance_uuid) - if migration_ref['old_flavor_id'] != migration_ref['new_flavor_id']: - instance_type = self.db.instance_type_get_by_flavor_id(context, - migration_ref['new_flavor_id']) + if migration_ref['old_instance_type_id'] != \ + migration_ref['new_instance_type_id']: + instance_type = self.db.instance_type_get(context, + migration_ref['new_instance_type_id']) self.db.instance_update(context, instance_ref.uuid, dict(instance_type_id=instance_type['id'], memory_mb=instance_type['memory_mb'], -- cgit From 6f3b63cd51549843b269cc6c138575a5af2337b2 Mon Sep 17 00:00:00 2001 From: Johannes Erdfelt Date: Thu, 4 Aug 2011 08:43:13 +0000 Subject: Revert should be sent to destination node and confirm should be sent to source node --- nova/compute/api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index aae16d1da..1d09c69f6 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -888,7 +888,7 @@ class API(base.Base): params = {'migration_id': migration_ref['id']} self._cast_compute_message('revert_resize', context, instance_ref['uuid'], - migration_ref['source_compute'], + migration_ref['dest_compute'], params=params) self.db.migration_update(context, migration_ref['id'], @@ -908,7 +908,7 @@ class API(base.Base): params = {'migration_id': migration_ref['id']} self._cast_compute_message('confirm_resize', context, instance_ref['uuid'], - migration_ref['dest_compute'], + migration_ref['source_compute'], params=params) self.db.migration_update(context, migration_ref['id'], -- cgit From 7f35619377593b5bb30425984999e8bb9ed2bdb2 Mon Sep 17 00:00:00 2001 From: Chris Behrens Date: Thu, 4 Aug 2011 10:34:36 -0700 Subject: fix pep8 issues that are in trunk --- nova/compute/manager.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 94bac9be4..9f566dea7 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -167,10 +167,12 @@ class ComputeManager(manager.SchedulerDependentManager): 'nova-compute restart.'), locals()) self.reboot_instance(context, instance['id']) elif drv_state == power_state.RUNNING: - try: # Hyper-V and VMWareAPI drivers will raise and exception + # Hyper-V and VMWareAPI drivers will raise and exception + try: self.driver.ensure_filtering_rules_for_instance(instance) except NotImplementedError: - LOG.warning(_('Hypervisor driver does not support firewall rules')) + LOG.warning(_('Hypervisor driver does not ' + 'support firewall rules')) def _update_state(self, context, instance_id, state=None): """Update the state of an instance from the driver info.""" -- cgit From 75b110aa451382cce94f10a392597b40df97839c Mon Sep 17 00:00:00 2001 From: Ed Leafe Date: Thu, 4 Aug 2011 20:49:21 +0000 Subject: Changed all references to 'power state' to 'power action' as requested by review. --- nova/compute/api.py | 6 +++--- nova/compute/manager.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 3e0cd7cfa..5f85ca908 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -995,10 +995,10 @@ class API(base.Base): return self._call_compute_message("set_host_enabled", context, instance_id=None, host=host, params={"enabled": enabled}) - def set_host_powerstate(self, context, host, state): + def host_power_action(self, context, host, action): """Reboots or shuts down the host.""" - return self._call_compute_message("set_host_powerstate", context, - instance_id=None, host=host, params={"state": state}) + return self._call_compute_message("host_power_action", context, + instance_id=None, host=host, params={"action": action}) @scheduler_api.reroute_compute("diagnostics") def get_diagnostics(self, context, instance_id): diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 220b09554..c2c12a9a2 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -955,10 +955,10 @@ class ComputeManager(manager.SchedulerDependentManager): result)) @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) - def set_host_powerstate(self, context, instance_id=None, host=None, - state=None): + def host_power_action(self, context, instance_id=None, host=None, + action=None): """Reboots or shuts down the host.""" - return self.driver.set_host_powerstate(host, state) + return self.driver.host_power_action(host, action) @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) def set_host_enabled(self, context, instance_id=None, host=None, -- cgit From dae356ad06bb4926ca91fd9a5182271d93c4b7be Mon Sep 17 00:00:00 2001 From: Matt Dietz Date: Thu, 4 Aug 2011 21:18:55 +0000 Subject: Forgot the instance_id parameter in the finish call --- nova/compute/manager.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 94bac9be4..a062cbe91 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -746,7 +746,8 @@ class ComputeManager(manager.SchedulerDependentManager): instance_ref['host']) rpc.cast(context, topic, {'method': 'finish_revert_resize', - 'args': {'migration_id': migration_ref['id']}, + 'args': { 'instance_id': instance_ref['uuid'], + 'migration_id': migration_ref['id']}, }) @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) -- cgit From 5fe92058d0ee11a7e9ea1c8f56b7e9350cf703e4 Mon Sep 17 00:00:00 2001 From: Matt Dietz Date: Thu, 4 Aug 2011 22:18:52 +0000 Subject: Revert migration now finishes --- nova/compute/manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index a062cbe91..0fd9c3c13 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -746,8 +746,8 @@ class ComputeManager(manager.SchedulerDependentManager): instance_ref['host']) rpc.cast(context, topic, {'method': 'finish_revert_resize', - 'args': { 'instance_id': instance_ref['uuid'], - 'migration_id': migration_ref['id']}, + 'args': {'instance_id': instance_ref['uuid'], + 'migration_id': migration_ref['id']}, }) @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) -- cgit From 8c6ccfd51698bffe0d56193bc4137ad80708e6d3 Mon Sep 17 00:00:00 2001 From: Chris Behrens Date: Fri, 5 Aug 2011 16:41:03 -0700 Subject: zone_aware_scheduler classes couldn't build instances due to a change to compute api's create_db_entry_for_new_instance call. now passing image argument down to the scheduler and through to the call. updated a existing test to cover this --- nova/compute/api.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 80d54d029..752f29384 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -360,6 +360,7 @@ class API(base.Base): instance_type, zone_blob, availability_zone, injected_files, admin_password, + image, instance_id=None, num_instances=1): """Send the run_instance request to the schedulers for processing.""" pid = context.project_id @@ -373,6 +374,7 @@ class API(base.Base): filter_class = 'nova.scheduler.host_filter.InstanceTypeFilter' request_spec = { + 'image': image, 'instance_properties': base_options, 'instance_type': instance_type, 'filter': filter_class, @@ -415,6 +417,7 @@ class API(base.Base): instance_type, zone_blob, availability_zone, injected_files, admin_password, + image, num_instances=num_instances) return base_options['reservation_id'] @@ -463,6 +466,7 @@ class API(base.Base): instance_type, zone_blob, availability_zone, injected_files, admin_password, + image, instance_id=instance_id) return [dict(x.iteritems()) for x in instances] -- cgit From 586359f792cb32210f83046e46a0cdb85b319fcd Mon Sep 17 00:00:00 2001 From: Ed Leafe Date: Mon, 8 Aug 2011 14:51:42 +0000 Subject: Cleaned up some old code added by the last merge --- nova/compute/manager.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 4908cba97..ecfbd3908 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1,4 +1,4 @@ -#: tabstop=4 shiftwidth=4 softtabstop=4 +# vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. @@ -969,12 +969,6 @@ class ComputeManager(manager.SchedulerDependentManager): """Sets the specified host's ability to accept new instances.""" return self.driver.set_host_enabled(host, enabled) - @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) - def set_power_state(self, context, instance_id=None, host=None, - power_state=None): - """Turns the specified host on/off, or reboots the host.""" - return self.driver.set_power_state(host, power_state) - @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) def get_diagnostics(self, context, instance_id): """Retrieve diagnostics for an instance on this host.""" -- cgit From b23387ef7a0024ac11e0970e3b76fa3441e30a9c Mon Sep 17 00:00:00 2001 From: Ed Leafe Date: Mon, 8 Aug 2011 17:34:42 +0000 Subject: Review fixes --- nova/compute/api.py | 4 ++-- nova/compute/manager.py | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index d5d66fa57..d2c08678b 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -997,12 +997,12 @@ class API(base.Base): def set_host_enabled(self, context, host, enabled): """Sets the specified host's ability to accept new instances.""" return self._call_compute_message("set_host_enabled", context, - instance_id=None, host=host, params={"enabled": enabled}) + host=host, params={"enabled": enabled}) def host_power_action(self, context, host, action): """Reboots, shuts down or powers up the host.""" return self._call_compute_message("host_power_action", context, - instance_id=None, host=host, params={"action": action}) + host=host, params={"action": action}) @scheduler_api.reroute_compute("diagnostics") def get_diagnostics(self, context, instance_id): diff --git a/nova/compute/manager.py b/nova/compute/manager.py index ecfbd3908..cb6617c33 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -958,14 +958,12 @@ class ComputeManager(manager.SchedulerDependentManager): result)) @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) - def host_power_action(self, context, instance_id=None, host=None, - action=None): + def host_power_action(self, context, host=None, action=None): """Reboots, shuts down or powers up the host.""" return self.driver.host_power_action(host, action) @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) - def set_host_enabled(self, context, instance_id=None, host=None, - enabled=None): + def set_host_enabled(self, context, host=None, enabled=None): """Sets the specified host's ability to accept new instances.""" return self.driver.set_host_enabled(host, enabled) -- cgit