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 +++-- nova/db/api.py | 13 ++++++------- nova/db/sqlalchemy/api.py | 40 ++++++++++++---------------------------- nova/network/manager.py | 9 +++------ nova/tests/fake_network.py | 8 +++++--- nova/tests/test_compute.py | 4 ++-- 6 files changed, 31 insertions(+), 48 deletions(-) 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): diff --git a/nova/db/api.py b/nova/db/api.py index f68e1c48e..0f959a606 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -463,7 +463,7 @@ def virtual_interface_delete_by_instance(context, instance_id): def virtual_interface_get_all(context): - """Gets all virtual interfaces from the table,""" + """Gets all virtual interfaces from the table""" return IMPL.virtual_interface_get_all(context) @@ -505,10 +505,9 @@ def instance_get_all(context): return IMPL.instance_get_all(context) -def instance_get_all_by_filters(context, filters, instance_uuids=None): +def instance_get_all_by_filters(context, filters): """Get all instances that match all filters.""" - return IMPL.instance_get_all_by_filters(context, filters, - instance_uuids=instance_uuids) + return IMPL.instance_get_all_by_filters(context, filters) def instance_get_active_by_window(context, begin, end=None, project_id=None): @@ -612,9 +611,9 @@ def instance_get_actions(context, instance_id): return IMPL.instance_get_actions(context, instance_id) -def instance_get_uuids_by_ids(context, ids): - """Return the UUIDs of the instances given the ids""" - return IMPL.instance_get_uuids_by_ids(context, ids) +def instance_get_id_to_uuid_mapping(context, ids): + """Return a dictionary containing 'ID: UUID' given the ids""" + return IMPL.instance_get_id_to_uuid_mapping(context, ids) ################### diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index c4bff8308..6a2c0f743 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1203,7 +1203,7 @@ def instance_get_all(context): @require_context -def instance_get_all_by_filters(context, filters, instance_uuids=None): +def instance_get_all_by_filters(context, filters): """Return instances that match all filters. Deleted instances will be returned by default, unless there's a filter that says otherwise""" @@ -1234,7 +1234,7 @@ def instance_get_all_by_filters(context, filters, instance_uuids=None): """Do exact match against a column. value to match can be a list so you can match any value in the list. """ - if isinstance(value, list): + if isinstance(value, list) or isinstance(value, set): column_attr = getattr(models.Instance, column) return query.filter(column_attr.in_(value)) else: @@ -1268,7 +1268,7 @@ def instance_get_all_by_filters(context, filters, instance_uuids=None): # Filters for exact matches that we can do along with the SQL query... # For other filters that don't match this, we will do regexp matching exact_match_filter_names = ['project_id', 'user_id', 'image_ref', - 'vm_state', 'instance_type_id', 'deleted'] + 'vm_state', 'instance_type_id', 'deleted', 'uuid'] query_filters = [key for key in filters.iterkeys() if key in exact_match_filter_names] @@ -1279,30 +1279,10 @@ def instance_get_all_by_filters(context, filters, instance_uuids=None): query_prefix = _exact_match_filter(query_prefix, filter_name, filters.pop(filter_name)) - db_instances = query_prefix.all() - db_uuids = [instance['uuid'] for instance in db_instances \ - if instance['uuid']] - - if instance_uuids is None: - instance_uuids = [] - - uuids = [] - - # NOTE(jkoelker): String UUIDs only! - if not instance_uuids: - uuids = db_uuids - elif not db_instances: - uuids = instance_uuids - else: - uuids = list(set(instance_uuids) & set(db_uuids)) - - if not uuids: + instances = query_prefix.all() + if not instances: return [] - instances = session.query(models.Instance).\ - filter(models.Instance.uuid.in_(uuids)).\ - all() - # Now filter on everything else for regexp matching.. # For filters not in the list, we'll attempt to use the filter_name # as a column name in Instance.. @@ -1320,6 +1300,8 @@ def instance_get_all_by_filters(context, filters, instance_uuids=None): filter_l = lambda instance: _regexp_filter_by_column(instance, filter_name, filter_re) instances = filter(filter_l, instances) + if not instances: + break return instances @@ -1564,13 +1546,15 @@ def instance_get_actions(context, instance_id): @require_context -def instance_get_uuids_by_ids(context, ids): +def instance_get_id_to_uuid_mapping(context, ids): session = get_session() instances = session.query(models.Instance).\ filter(models.Instance.id.in_(ids)).\ all() - return [{'uuid': instance['uuid'], - 'id': instance['id']} for instance in instances] + mapping = {} + for instance in instances: + mapping[instance['id']] = instance['uuid'] + return mapping ################### diff --git a/nova/network/manager.py b/nova/network/manager.py index 2687d8faf..ffb9f976c 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -410,7 +410,7 @@ class NetworkManager(manager.SchedulerDependentManager): ip_filter = re.compile(str(filters.get('ip'))) ipv6_filter = re.compile(str(filters.get('ip6'))) - # NOTE(jkoelker) Should probably figur out a better way to do + # NOTE(jkoelker) Should probably figure out a better way to do # this. But for now it "works", this could suck on # large installs. @@ -448,12 +448,9 @@ class NetworkManager(manager.SchedulerDependentManager): # NOTE(jkoelker) Until we switch over to instance_uuid ;) ids = [res['instance_id'] for res in results] - uuids = self.db.instance_get_uuids_by_ids(context, ids) + uuid_map = self.db.instance_get_id_to_uuid_mapping(context, ids) for res in results: - uuid = [u['uuid'] for u in uuids if u['id'] == res['instance_id']] - # NOTE(jkoelker) UUID must exist, so no test here - res['instance_uuid'] = uuid[0] - + res['instance_uuid'] = uuid_map.get(res['instance_id']) return results def _get_networks_for_instance(self, context, instance_id, project_id, diff --git a/nova/tests/fake_network.py b/nova/tests/fake_network.py index d839f20b0..febac5e09 100644 --- a/nova/tests/fake_network.py +++ b/nova/tests/fake_network.py @@ -105,10 +105,12 @@ class FakeNetworkManager(network_manager.NetworkManager): 'floating_ips': [floats[2]]}]}] return vifs - def instance_get_uuids_by_ids(self, context, ids): + def instance_get_id_to_uuid_mapping(self, context, ids): # NOTE(jkoelker): This is just here until we can rely on UUIDs - return [{'uuid': str(utils.gen_uuid()), - 'id': id} for id in ids] + mapping = {} + for id in ids: + mapping[id] = str(utils.gen_uuid()) + return mapping def __init__(self): self.db = self.FakeDB() diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py index 4ef57b760..948c7ad40 100644 --- a/nova/tests/test_compute.py +++ b/nova/tests/test_compute.py @@ -1033,8 +1033,8 @@ class ComputeTestCase(test.TestCase): 'get_instance_uuids_by_ip_filter', network_manager.get_instance_uuids_by_ip_filter) self.stubs.Set(network_manager.db, - 'instance_get_uuids_by_ids', - db.instance_get_uuids_by_ids) + 'instance_get_id_to_uuid_mapping', + db.instance_get_id_to_uuid_mapping) instance_id1 = self._create_instance({'display_name': 'woot', 'id': 0}) -- cgit From b0ca3a42995cc25852420083e431c3be5071d221 Mon Sep 17 00:00:00 2001 From: Chris Behrens Date: Mon, 19 Sep 2011 15:08:25 -0700 Subject: fix a test where list order was assumed --- nova/tests/test_db_api.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/nova/tests/test_db_api.py b/nova/tests/test_db_api.py index 5ebab9cc8..aaf5212d0 100644 --- a/nova/tests/test_db_api.py +++ b/nova/tests/test_db_api.py @@ -92,6 +92,9 @@ class DbApiTestCase(test.TestCase): db.instance_destroy(self.context, inst1.id) result = db.instance_get_all_by_filters(self.context.elevated(), {}) self.assertEqual(2, len(result)) - self.assertEqual(result[0].id, inst1.id) - self.assertEqual(result[1].id, inst2.id) - self.assertTrue(result[0].deleted) + self.assertIn(inst1.id, [result[0].id, result[1].id]) + self.assertIn(inst2.id, [result[0].id, result[1].id]) + if inst1.id == result[0].id: + self.assertTrue(result[0].deleted) + else: + self.assertTrue(result[1].deleted) -- cgit From 83023c3035746f296fd024b282c355e8499770f1 Mon Sep 17 00:00:00 2001 From: Chris Behrens Date: Mon, 19 Sep 2011 15:23:52 -0700 Subject: fix unrelated pep8 issue in trunk --- nova/network/linux_net.py | 1 - 1 file changed, 1 deletion(-) diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py index 2f9805fa3..9bf98fc27 100755 --- a/nova/network/linux_net.py +++ b/nova/network/linux_net.py @@ -824,7 +824,6 @@ class LinuxNetInterfaceDriver(object): raise NotImplementedError() - # plugs interfaces using Linux Bridge class LinuxBridgeInterfaceDriver(LinuxNetInterfaceDriver): -- cgit