From 861efe3aa7ce6af7b5c548e5a555625fa53a3d86 Mon Sep 17 00:00:00 2001 From: Joe Gordon Date: Tue, 24 Jul 2012 17:03:56 -0700 Subject: General host aggregates part 2 Partially implements blueprint general-host-aggregates: Scheduler Filter * Add AggregateInstanceExtraSpecsFilter * change db.aggregate_get_by_host to return a list of aggregates instead of the first aggregate * Add optional key filter to db.aggregate_get_by_host along with test * Add db.aggregate_metadata_get_by_host to get host aggregate metadata * add optional key filter to db.aggregate_metadata_get_by_host * Add AggregateTypeAffinityFilter Change-Id: I4a3061276cc3b0c5c695eaf973b773183b3c4f4b --- nova/db/api.py | 15 ++++++++++++--- nova/db/sqlalchemy/api.py | 31 +++++++++++++++++++++++-------- 2 files changed, 35 insertions(+), 11 deletions(-) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index e6ebecbdf..83f4ca355 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -1828,9 +1828,18 @@ def aggregate_get(context, aggregate_id): return IMPL.aggregate_get(context, aggregate_id) -def aggregate_get_by_host(context, host): - """Get a specific aggregate by host""" - return IMPL.aggregate_get_by_host(context, host) +def aggregate_get_by_host(context, host, key=None): + """Get a list of aggregates that host belongs to""" + return IMPL.aggregate_get_by_host(context, host, key) + + +def aggregate_metadata_get_by_host(context, host, key=None): + """Get metadata for all aggregates that host belongs to. + + Returns a dictionary where each value is a set, this is to cover the case + where there two aggregates have different values for the same key. + Optional key filter""" + return IMPL.aggregate_metadata_get_by_host(context, host, key) def aggregate_update(context, aggregate_id, values): diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 2993aaaf3..325827089 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -19,6 +19,7 @@ """Implementation of SQLAlchemy backend.""" +from collections import defaultdict import copy import datetime import functools @@ -4926,16 +4927,30 @@ def aggregate_get(context, aggregate_id): @require_admin_context -def aggregate_get_by_host(context, host): - aggregate_host = _aggregate_get_query(context, - models.AggregateHost, - models.AggregateHost.host, - host).first() +def aggregate_get_by_host(context, host, key=None): + query = model_query(context, models.Aggregate).join( + "_hosts").filter(models.AggregateHost.host == host) + + if key: + query = query.join("_metadata").filter( + models.AggregateMetadata.key == key) + return query.all() - if not aggregate_host: - raise exception.AggregateHostNotFound(host=host) - return aggregate_get(context, aggregate_host.aggregate_id) +@require_admin_context +def aggregate_metadata_get_by_host(context, host, key=None): + query = model_query(context, models.Aggregate).join( + "_hosts").filter(models.AggregateHost.host == host).join( + "_metadata") + + if key: + query = query.filter(models.AggregateMetadata.key == key) + rows = query.all() + metadata = defaultdict(set) + for agg in rows: + for kv in agg._metadata: + metadata[kv['key']].add(kv['value']) + return metadata @require_admin_context -- cgit