From 2c16115e236760f3933eadd3a5d7d20dda39866d Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Tue, 6 Sep 2011 07:31:39 -0400 Subject: Update the v1.0 rescue admin action and the v1.1 rescue extension to generate 'adminPass'. Fixes an issue where rescue commands were broken on XenServer. lp#838518 --- nova/compute/api.py | 9 +++++++-- nova/compute/manager.py | 12 ++++++++---- 2 files changed, 15 insertions(+), 6 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index e045ef3de..ca59b5701 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -1271,13 +1271,18 @@ class API(base.Base): self._cast_compute_message('resume_instance', context, instance_id) @scheduler_api.reroute_compute("rescue") - def rescue(self, context, instance_id): + def rescue(self, context, instance_id, rescue_password=None): """Rescue the given instance.""" self.update(context, instance_id, vm_state=vm_states.ACTIVE, task_state=task_states.RESCUING) - self._cast_compute_message('rescue_instance', context, instance_id) + + rescue_params = { + "rescue_password": rescue_password + } + self._cast_compute_message('rescue_instance', context, instance_id, + params=rescue_params) @scheduler_api.reroute_compute("unrescue") def unrescue(self, context, instance_id): diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 0477db745..d5c2f9184 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -70,8 +70,6 @@ flags.DEFINE_string('compute_driver', 'nova.virt.connection.get_connection', 'Driver to use for controlling virtualization') flags.DEFINE_string('stub_network', False, 'Stub network related code') -flags.DEFINE_integer('password_length', 12, - 'Length of generated admin passwords') flags.DEFINE_string('console_host', socket.gethostname(), 'Console proxy host to use to connect to instances on' 'this host.') @@ -796,12 +794,18 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) @checks_instance_lock - def rescue_instance(self, context, instance_id): - """Rescue an instance on this host.""" + def rescue_instance(self, context, instance_id, **kwargs): + """ + Rescue an instance on this host. + :param rescue_password: password to set on rescue instance + """ + LOG.audit(_('instance %s: rescuing'), instance_id, context=context) context = context.elevated() instance_ref = self.db.instance_get(context, instance_id) + instance_ref.admin_pass = kwargs.get('rescue_password', + utils.generate_password(FLAGS.password_length)) network_info = self._get_instance_nw_info(context, instance_ref) # NOTE(blamar): None of the virt drivers use the 'callback' param -- cgit From 84b0492ccfd61a0e7f04db48abb83ec708ddb2d4 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Wed, 14 Sep 2011 10:15:20 -0500 Subject: run the instances filter through the network api first, then through the db --- nova/compute/api.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index d674224e5..acf7715ff 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -904,7 +904,7 @@ class API(base.Base): if 'reservation_id' in filters: recurse_zones = True - instances = self.db.instance_get_all_by_filters(context, filters) + instances = self._get_instances_by_filters(context, filters) if not recurse_zones: return instances @@ -929,6 +929,16 @@ class API(base.Base): return instances + def _get_instances_by_filters(self, context, filters): + ip_instances = None + if 'ip6' in filters or 'ip' in filters: + ids = self.network_api.get_instance_ids_by_ip_filter(context, + filters) + ip_instances = [self.db.instance_get(id) for id in ids] + + return self.db.instance_get_all_by_filters(context, filters, + ip_instances) + def _cast_compute_message(self, method, context, instance_id, host=None, params=None): """Generic handler for RPC casts to compute. -- cgit From aa4375c21a874fb619d38fb17c8026d083b73ffd Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Wed, 14 Sep 2011 13:46:09 -0500 Subject: make sure we are grabbing out just the ids --- nova/compute/api.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 8b73a8954..3b217a85e 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -932,9 +932,12 @@ class API(base.Base): def _get_instances_by_filters(self, context, filters): ip_instances = None if 'ip6' in filters or 'ip' in filters: - ids = self.network_api.get_instance_ids_by_ip_filter(context, - filters) - ip_instances = [self.db.instance_get(id) for id in ids] + res = self.network_api.get_instance_ids_by_ip_filter(context, + filters) + # NOTE(jkoelker) When this flips to using UUIDS the name + # needs to be updated accordingingly + ip_instances = [self.db.instance_get(r['instance_id']) \ + for r in res] return self.db.instance_get_all_by_filters(context, filters, ip_instances) -- cgit From 8f9453aeb8882509d825c9715fde4e6827b0bbf7 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Wed, 14 Sep 2011 14:02:54 -0500 Subject: move ip filtering over to the network side --- nova/compute/api.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 3b217a85e..f9f87fd28 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -934,10 +934,13 @@ class API(base.Base): if 'ip6' in filters or 'ip' in filters: res = self.network_api.get_instance_ids_by_ip_filter(context, filters) + # NOTE(jkoelker) It is possible that we will get the same + # instance id twice (one for ipv4 and ipv4) + ids = set([r['instance_id'] for r in res]) + # NOTE(jkoelker) When this flips to using UUIDS the name # needs to be updated accordingingly - ip_instances = [self.db.instance_get(r['instance_id']) \ - for r in res] + ip_instances = [self.db.instance_get(id) for id in ids] return self.db.instance_get_all_by_filters(context, filters, ip_instances) -- cgit From 7e379f6a77f53ad4d6ddc98fbb30cd853933bb08 Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Wed, 14 Sep 2011 14:38:40 -0500 Subject: Initial pass at automatically confirming resizes after a given window. --- nova/compute/manager.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 7915830ec..6ddbb20b0 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -81,6 +81,9 @@ flags.DEFINE_integer('live_migration_retry_count', 30, flags.DEFINE_integer("rescue_timeout", 0, "Automatically unrescue an instance after N seconds." " Set to 0 to disable.") +flags.DEFINE_integer("resize_confirm_window", 0, + "Automatically confirm resizes after N seconds." + " Set to 0 to disable.") flags.DEFINE_integer('host_state_interval', 120, 'Interval in seconds for querying the host status') @@ -1644,14 +1647,23 @@ class ComputeManager(manager.SchedulerDependentManager): self.driver.poll_rescued_instances(FLAGS.rescue_timeout) except Exception as ex: LOG.warning(_("Error during poll_rescued_instances: %s"), - unicode(ex)) + unicode(ex)) + error_list.append(ex) + + try: + if FLAGS.resize_confirm_window > 0: + self.driver.poll_unconfirmed_resizes( + FLAGS.resize_confirm_window) + except Exception as ex: + LOG.warning(_("Error during poll_unconfirmed_resizes: %s"), + unicode(ex)) error_list.append(ex) try: self._report_driver_status() except Exception as ex: LOG.warning(_("Error during report_driver_status(): %s"), - unicode(ex)) + unicode(ex)) error_list.append(ex) try: -- cgit From 9936e1e9457234f7285c794b7c2c286603c84e52 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Wed, 14 Sep 2011 16:13:59 -0500 Subject: make sure to pass in the context --- 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 f9f87fd28..22ae17e0a 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -940,7 +940,7 @@ class API(base.Base): # NOTE(jkoelker) When this flips to using UUIDS the name # needs to be updated accordingingly - ip_instances = [self.db.instance_get(id) for id in ids] + ip_instances = [self.db.instance_get(context, id) for id in ids] return self.db.instance_get_all_by_filters(context, filters, ip_instances) -- cgit From e8a2a540e574ca2d242b9c2749c1f285498809e7 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Wed, 14 Sep 2011 17:11:21 -0500 Subject: fix up the filtering so it does not return duplicates if both the network and the db filters match --- nova/compute/api.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 22ae17e0a..122e62208 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -930,7 +930,7 @@ class API(base.Base): return instances def _get_instances_by_filters(self, context, filters): - ip_instances = None + ids = None if 'ip6' in filters or 'ip' in filters: res = self.network_api.get_instance_ids_by_ip_filter(context, filters) @@ -938,12 +938,7 @@ class API(base.Base): # instance id twice (one for ipv4 and ipv4) ids = set([r['instance_id'] for r in res]) - # NOTE(jkoelker) When this flips to using UUIDS the name - # needs to be updated accordingingly - ip_instances = [self.db.instance_get(context, id) for id in ids] - - return self.db.instance_get_all_by_filters(context, filters, - ip_instances) + return self.db.instance_get_all_by_filters(context, filters, ids) def _cast_compute_message(self, method, context, instance_id, host=None, params=None): -- cgit From f0f13454a68cdf5e33bb9c667f2e57d84b70ae11 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Thu, 15 Sep 2011 13:30:38 -0500 Subject: make sure to use the uuid --- nova/compute/api.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 122e62208..45b7f3f21 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -932,11 +932,11 @@ class API(base.Base): def _get_instances_by_filters(self, context, filters): ids = None if 'ip6' in filters or 'ip' in filters: - res = self.network_api.get_instance_ids_by_ip_filter(context, - filters) + res = self.network_api.get_instance_uuids_by_ip_filter(context, + filters) # NOTE(jkoelker) It is possible that we will get the same # instance id twice (one for ipv4 and ipv4) - ids = set([r['instance_id'] for r in res]) + ids = set([r['instance_uuid'] for r in res]) return self.db.instance_get_all_by_filters(context, filters, ids) -- cgit From 0d674b525811583c4cc70accb8745be85199e76a Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Thu, 15 Sep 2011 15:07:49 -0500 Subject: update comment --- 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 45b7f3f21..c7fdf4126 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -935,7 +935,7 @@ class API(base.Base): res = self.network_api.get_instance_uuids_by_ip_filter(context, filters) # NOTE(jkoelker) It is possible that we will get the same - # instance id twice (one for ipv4 and ipv4) + # instance uuid twice (one for ipv4 and ipv4) ids = set([r['instance_uuid'] for r in res]) return self.db.instance_get_all_by_filters(context, filters, ids) -- cgit From 24db80baa4a5125ba32250b7aa495b58465cfdf5 Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Fri, 16 Sep 2011 17:04:27 +0900 Subject: compute/api: swap size issue When --block-device-mapping swap= is specified, its swap size is wrongly set to 0. Thus swap device will be missing. This is reported by https://bugs.launchpad.net/bugs/851218 This patch fixes it. --- nova/compute/api.py | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 4220f47ae..7ac504d32 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -287,18 +287,24 @@ class API(base.Base): return (num_instances, base_options, image) @staticmethod - def _ephemeral_size(instance_type, ephemeral_name): - num = block_device.ephemeral_num(ephemeral_name) + def _volume_size(instance_type, virtual_name): + size = 0 + if virtual_name == 'swap': + size = instance_type.get('swap', 0) + elif block_device.is_ephemeral(virtual_name): + num = block_device.ephemeral_num(virtual_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 + # 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') + size = instance_type.get('local_gb') + + return size def _update_image_block_device_mapping(self, elevated_context, instance_type, instance_id, @@ -319,12 +325,7 @@ class API(base.Base): 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) - + size = self._volume_size(instance_type, virtual_name) if size == 0: continue @@ -354,8 +355,8 @@ class API(base.Base): 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) + block_device.is_swap_or_ephemeral(virtual_name)): + size = self._volume_size(instance_type, virtual_name) if size == 0: continue values['volume_size'] = size -- cgit From fa359fa8024f247f119d97be46fb7886e999969b Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Fri, 16 Sep 2011 13:02:13 -0500 Subject: remove getting fixed_ips directly from the db --- nova/compute/manager.py | 5 ----- 1 file changed, 5 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 7915830ec..138e6c58d 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1388,11 +1388,6 @@ class ComputeManager(manager.SchedulerDependentManager): instance_ref = self.db.instance_get(context, instance_id) hostname = instance_ref['hostname'] - # Getting fixed ips - fixed_ips = self.db.instance_get_fixed_addresses(context, instance_id) - if not fixed_ips: - raise exception.FixedIpNotFoundForInstance(instance_id=instance_id) - # If any volume is mounted, prepare here. if not instance_ref['volumes']: LOG.info(_("%s has no volume."), hostname) -- cgit From d503671714645115eef0345e9ed1dbb6ff2fb883 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Fri, 16 Sep 2011 13:43:31 -0500 Subject: make sure to raise since the tests require it --- 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 138e6c58d..694792781 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1403,6 +1403,11 @@ class ComputeManager(manager.SchedulerDependentManager): # Retry operation is necessary because continuously request comes, # concorrent request occurs to iptables, then it complains. network_info = self._get_instance_nw_info(context, instance_ref) + + fixed_ips = [nw_info[1]['ips'] for nw_info in network_info] + if not fixed_ips: + raise exception.FixedIpNotFoundForInstance(instance_id=instance_id) + max_retry = FLAGS.live_migration_retry_count for cnt in range(max_retry): try: -- cgit From a51ea2b13dd865530fed1bb303ab2e259ddf7ec2 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Mon, 19 Sep 2011 09:33:47 -0500 Subject: Fix typo in comment --- 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 c7fdf4126..9c3cc934e 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -935,7 +935,7 @@ class API(base.Base): res = self.network_api.get_instance_uuids_by_ip_filter(context, filters) # NOTE(jkoelker) It is possible that we will get the same - # instance uuid twice (one for ipv4 and ipv4) + # instance uuid twice (one for ipv4 and ipv6) ids = set([r['instance_uuid'] for r in res]) return self.db.instance_get_all_by_filters(context, filters, ids) -- cgit From 83aca0e78727a870fb6aa788158920a1c8321541 Mon Sep 17 00:00:00 2001 From: Chris Behrens Date: Mon, 19 Sep 2011 14:53:17 -0700 Subject: Removed the extra code added to support filtering instances by instance uuids. Instead, added 'uuid' to the list of exact_filter_match names. Updated the caller to add 'uuid: uuid_list' to the filters dictionary, instead of passing it in as another argument. Updated the ID to UUID mapping code to return a dictionary, which allows the caller to be more efficient... It removes an extra loop there. A couple of typo fixes. --- nova/compute/api.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 853e6ef9e..76e1e7a60 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -937,9 +937,10 @@ class API(base.Base): filters) # NOTE(jkoelker) It is possible that we will get the same # instance uuid twice (one for ipv4 and ipv6) - ids = set([r['instance_uuid'] for r in res]) + uuids = set([r['instance_uuid'] for r in res]) + filters['uuid'] = uuids - return self.db.instance_get_all_by_filters(context, filters, ids) + return self.db.instance_get_all_by_filters(context, filters) def _cast_compute_message(self, method, context, instance_id, host=None, params=None): -- cgit