From b8a5fa9cb0e30518efbbf0ae4091ba843833f67b Mon Sep 17 00:00:00 2001 From: Boris Pavlovic Date: Tue, 23 Apr 2013 23:23:37 +0400 Subject: Move db.instance_type_extra_specs_* to db.instance_type_* methods All instance_type_* methods should be one after another blueprint db-cleanup Change-Id: Icc69c45dbcb3dcea5f81266a11f726b5b3215e27 --- nova/db/api.py | 39 ++++++------ nova/db/sqlalchemy/api.py | 157 +++++++++++++++++++++++----------------------- 2 files changed, 95 insertions(+), 101 deletions(-) (limited to 'nova') diff --git a/nova/db/api.py b/nova/db/api.py index 289dbf1d7..5073ad07e 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -1303,6 +1303,24 @@ def instance_type_access_remove(context, flavor_id, project_id): return IMPL.instance_type_access_remove(context, flavor_id, project_id) +def instance_type_extra_specs_get(context, flavor_id): + """Get all extra specs for an instance type.""" + return IMPL.instance_type_extra_specs_get(context, flavor_id) + + +def instance_type_extra_specs_delete(context, flavor_id, key): + """Delete the given extra specs item.""" + IMPL.instance_type_extra_specs_delete(context, flavor_id, key) + + +def instance_type_extra_specs_update_or_create(context, flavor_id, + extra_specs): + """Create or update instance type extra specs. This adds or modifies the + key/value pairs specified in the extra specs dict argument""" + IMPL.instance_type_extra_specs_update_or_create(context, flavor_id, + extra_specs) + + #################### @@ -1429,27 +1447,6 @@ def bw_usage_update(context, uuid, mac, start_period, bw_in, bw_out, return rv -#################### - - -def instance_type_extra_specs_get(context, flavor_id): - """Get all extra specs for an instance type.""" - return IMPL.instance_type_extra_specs_get(context, flavor_id) - - -def instance_type_extra_specs_delete(context, flavor_id, key): - """Delete the given extra specs item.""" - IMPL.instance_type_extra_specs_delete(context, flavor_id, key) - - -def instance_type_extra_specs_update_or_create(context, flavor_id, - extra_specs): - """Create or update instance type extra specs. This adds or modifies the - key/value pairs specified in the extra specs dict argument""" - IMPL.instance_type_extra_specs_update_or_create(context, flavor_id, - extra_specs) - - ################### diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index e9486ca22..f22a95066 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -3816,6 +3816,83 @@ def instance_type_access_remove(context, flavor_id, project_id): project_id=project_id) +def _instance_type_extra_specs_get_query(context, flavor_id, + session=None): + # Two queries necessary because join with update doesn't work. + t = model_query(context, models.InstanceTypes.id, + base_model=models.InstanceTypes, session=session, + read_deleted="no").\ + filter(models.InstanceTypes.flavorid == flavor_id).\ + subquery() + return model_query(context, models.InstanceTypeExtraSpecs, + session=session, read_deleted="no").\ + filter(models.InstanceTypeExtraSpecs. + instance_type_id.in_(t)) + + +@require_context +def instance_type_extra_specs_get(context, flavor_id): + rows = _instance_type_extra_specs_get_query( + context, flavor_id).\ + all() + + result = {} + for row in rows: + result[row['key']] = row['value'] + + return result + + +@require_context +def instance_type_extra_specs_delete(context, flavor_id, key): + # Don't need synchronize the session since we will not use the query result + _instance_type_extra_specs_get_query( + context, flavor_id).\ + filter(models.InstanceTypeExtraSpecs.key == key).\ + soft_delete(synchronize_session=False) + + +@require_context +def instance_type_extra_specs_update_or_create(context, flavor_id, specs): + # NOTE(boris-42): There is a race condition in this method. We should add + # UniqueConstraint on (instance_type_id, key, deleted) to + # avoid duplicated instance_type_extra_specs. This will be + # possible after bp/db-unique-keys implementation. + session = get_session() + with session.begin(): + instance_type_id = model_query(context, models.InstanceTypes.id, + base_model=models.InstanceTypes, + session=session, read_deleted="no").\ + filter(models.InstanceTypes.flavorid == flavor_id).\ + first() + if not instance_type_id: + raise exception.FlavorNotFound(flavor_id=flavor_id) + + instance_type_id = instance_type_id.id + + spec_refs = model_query(context, models.InstanceTypeExtraSpecs, + session=session, read_deleted="no").\ + filter_by(instance_type_id=instance_type_id).\ + filter(models.InstanceTypeExtraSpecs.key.in_(specs.keys())).\ + all() + + existing_keys = set() + for spec_ref in spec_refs: + key = spec_ref["key"] + existing_keys.add(key) + spec_ref.update({"value": specs[key]}) + + for key, value in specs.iteritems(): + if key in existing_keys: + continue + spec_ref = models.InstanceTypeExtraSpecs() + spec_ref.update({"key": key, "value": value, + "instance_type_id": instance_type_id}) + session.add(spec_ref) + + return specs + + #################### @@ -4176,86 +4253,6 @@ def bw_usage_update(context, uuid, mac, start_period, bw_in, bw_out, #################### -def _instance_type_extra_specs_get_query(context, flavor_id, - session=None): - # Two queries necessary because join with update doesn't work. - t = model_query(context, models.InstanceTypes.id, - base_model=models.InstanceTypes, session=session, - read_deleted="no").\ - filter(models.InstanceTypes.flavorid == flavor_id).\ - subquery() - return model_query(context, models.InstanceTypeExtraSpecs, - session=session, read_deleted="no").\ - filter(models.InstanceTypeExtraSpecs. - instance_type_id.in_(t)) - - -@require_context -def instance_type_extra_specs_get(context, flavor_id): - rows = _instance_type_extra_specs_get_query( - context, flavor_id).\ - all() - - result = {} - for row in rows: - result[row['key']] = row['value'] - - return result - - -@require_context -def instance_type_extra_specs_delete(context, flavor_id, key): - # Don't need synchronize the session since we will not use the query result - _instance_type_extra_specs_get_query( - context, flavor_id).\ - filter(models.InstanceTypeExtraSpecs.key == key).\ - soft_delete(synchronize_session=False) - - -@require_context -def instance_type_extra_specs_update_or_create(context, flavor_id, specs): - # NOTE(boris-42): There is a race condition in this method. We should add - # UniqueConstraint on (instance_type_id, key, deleted) to - # avoid duplicated instance_type_extra_specs. This will be - # possible after bp/db-unique-keys implementation. - session = get_session() - with session.begin(): - instance_type_id = model_query(context, models.InstanceTypes.id, - base_model=models.InstanceTypes, - session=session, read_deleted="no").\ - filter(models.InstanceTypes.flavorid == flavor_id).\ - first() - if not instance_type_id: - raise exception.FlavorNotFound(flavor_id=flavor_id) - - instance_type_id = instance_type_id.id - - spec_refs = model_query(context, models.InstanceTypeExtraSpecs, - session=session, read_deleted="no").\ - filter_by(instance_type_id=instance_type_id).\ - filter(models.InstanceTypeExtraSpecs.key.in_(specs.keys())).\ - all() - - existing_keys = set() - for spec_ref in spec_refs: - key = spec_ref["key"] - existing_keys.add(key) - spec_ref.update({"value": specs[key]}) - - for key, value in specs.iteritems(): - if key in existing_keys: - continue - spec_ref = models.InstanceTypeExtraSpecs() - spec_ref.update({"key": key, "value": value, - "instance_type_id": instance_type_id}) - session.add(spec_ref) - - return specs - - -#################### - - @require_context def vol_get_usage_by_time(context, begin): """Return volumes usage that have been updated after a specified time.""" -- cgit