From 33ec0904362bc0011abab4e02944d504ff47b4f1 Mon Sep 17 00:00:00 2001 From: Dan Prince <dan.prince@rackspace.com> Date: Wed, 17 Aug 2011 11:46:28 -0400 Subject: [PATCH 01/25] Split set state into vm, task, and power state functions. --- nova/db/sqlalchemy/api.py | 46 +++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 57a4370d8..07207b8ee 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1439,15 +1439,43 @@ def instance_get_floating_address(context, instance_id): @require_admin_context -def instance_set_state(context, instance_id, state, description=None): - # TODO(devcamcar): Move this out of models and into driver - from nova.compute import power_state - if not description: - description = power_state.name(state) - db.instance_update(context, - instance_id, - {'state': state, - 'state_description': description}) +def instance_set_power_state(context, instance_id, power_state): + session = get_session() + partial = session.query(models.Instance) + + if utils.is_uuid_like(instance_id): + result = partial.filter_by(uuid=instance_id) + else: + result = partial.filter_by(id=instance_id) + + result.update({'power_state': power_state}) + + +@require_admin_context +def instance_set_vm_state(context, instance_id, vm_state): + # vm_state = running, halted, suspended, paused + session = get_session() + partial = session.query(models.Instance) + + if utils.is_uuid_like(instance_id): + result = partial.filter_by(uuid=instance_id) + else: + result = partial.filter_by(id=instance_id) + + result.update({'vm_state': vm_state}) + + +def instance_set_task_state(context, instance_id, task_state): + # task_state = running, halted, suspended, paused + session = get_session() + partial = session.query(models.Instance) + + if utils.is_uuid_like(instance_id): + result = partial.filter_by(uuid=instance_id) + else: + result = partial.filter_by(id=instance_id) + + result.update({'task_state': task_state}) @require_context From 18b5c50a0c666f87c39d6e8badce7a60232fd293 Mon Sep 17 00:00:00 2001 From: Dan Prince <dan.prince@rackspace.com> Date: Wed, 17 Aug 2011 11:51:39 -0400 Subject: [PATCH 02/25] Pep8 fixes. --- nova/db/sqlalchemy/api.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 07207b8ee..e7d02cb5d 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1442,7 +1442,7 @@ def instance_get_floating_address(context, instance_id): def instance_set_power_state(context, instance_id, power_state): session = get_session() partial = session.query(models.Instance) - + if utils.is_uuid_like(instance_id): result = partial.filter_by(uuid=instance_id) else: @@ -1456,7 +1456,7 @@ def instance_set_vm_state(context, instance_id, vm_state): # vm_state = running, halted, suspended, paused session = get_session() partial = session.query(models.Instance) - + if utils.is_uuid_like(instance_id): result = partial.filter_by(uuid=instance_id) else: @@ -1469,7 +1469,7 @@ def instance_set_task_state(context, instance_id, task_state): # task_state = running, halted, suspended, paused session = get_session() partial = session.query(models.Instance) - + if utils.is_uuid_like(instance_id): result = partial.filter_by(uuid=instance_id) else: From 20a4630b69d9ea47a3e44317d279881db4e7db24 Mon Sep 17 00:00:00 2001 From: Brian Lamar <brian.lamar@rackspace.com> Date: Thu, 18 Aug 2011 12:34:01 -0400 Subject: [PATCH 03/25] Updated a number of items to pave the way for new states. --- nova/db/sqlalchemy/api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index e7d02cb5d..67736dea2 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1079,8 +1079,8 @@ def instance_stop(context, instance_id): session.query(models.Instance).\ filter_by(id=instance_id).\ update({'host': None, - 'state': power_state.SHUTOFF, - 'state_description': 'stopped', + 'vm_state': vm_state.STOP, + 'task_state': None, 'updated_at': literal_column('updated_at')}) session.query(models.SecurityGroupInstanceAssociation).\ filter_by(instance_id=instance_id).\ From fc7fc16cddf8e891aae15c66921db71f51ab95e1 Mon Sep 17 00:00:00 2001 From: Dan Prince <dan.prince@rackspace.com> Date: Mon, 22 Aug 2011 13:04:05 -0400 Subject: [PATCH 04/25] Use 'vm_state' instead of 'state' in instance filters query. --- nova/db/sqlalchemy/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index a5ed2363f..3e690e094 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1239,7 +1239,7 @@ def instance_get_all_by_filters(context, filters): # 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', - 'state', 'instance_type_id', 'deleted'] + 'vm_state', 'instance_type_id', 'deleted'] query_filters = [key for key in filters.iterkeys() if key in exact_match_filter_names] From ed128cd50269578a3495bc680a4b4b2d61a92d24 Mon Sep 17 00:00:00 2001 From: Dan Wendlandt <dan@nicira.com> Date: Mon, 22 Aug 2011 22:18:43 -0700 Subject: [PATCH 05/25] pulling all qmanager changes into a branch based on trunk, as they were previously stacked on top of melange --- nova/db/api.py | 5 +++++ nova/db/sqlalchemy/api.py | 20 +++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/nova/db/api.py b/nova/db/api.py index 2d854f24c..9ff3a1c74 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -419,6 +419,11 @@ def virtual_interface_get_by_address(context, address): return IMPL.virtual_interface_get_by_address(context, address) +def virtual_interface_get_by_uuid(context, vif_uuid): + """Gets a virtual interface from the table filtering on vif uuid.""" + return IMPL.virtual_interface_get_by_uuid(context, vif_uuid) + + def virtual_interface_get_by_fixed_ip(context, fixed_ip_id): """Gets the virtual interface fixed_ip is associated with.""" return IMPL.virtual_interface_get_by_fixed_ip(context, fixed_ip_id) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 04b5405f6..d96b951a1 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -688,10 +688,8 @@ def fixed_ip_associate(context, address, instance_id, network_id=None): def fixed_ip_associate_pool(context, network_id, instance_id=None, host=None): session = get_session() with session.begin(): - network_or_none = or_(models.FixedIp.network_id == network_id, - models.FixedIp.network_id == None) fixed_ip_ref = session.query(models.FixedIp).\ - filter(network_or_none).\ + filter_by(network_id=network_id).\ filter_by(reserved=False).\ filter_by(deleted=False).\ filter_by(instance=None).\ @@ -928,6 +926,22 @@ def virtual_interface_get_by_address(context, address): return vif_ref +@require_context +def virtual_interface_get_by_uuid(context, vif_uuid): + """Gets a virtual interface from the table. + + :param vif_uuid: = the uuid of the interface you're looking to get + """ + session = get_session() + vif_ref = session.query(models.VirtualInterface).\ + filter_by(uuid=vif_uuid).\ + options(joinedload('network')).\ + options(joinedload('instance')).\ + options(joinedload('fixed_ips')).\ + first() + return vif_ref + + @require_context def virtual_interface_get_by_fixed_ip(context, fixed_ip_id): """Gets the virtual interface fixed_ip is associated with. From 8d9735d3c28942ff3ca8237ad93f47aae7301598 Mon Sep 17 00:00:00 2001 From: Brian Lamar <brian.lamar@rackspace.com> Date: Thu, 25 Aug 2011 17:27:10 -0400 Subject: [PATCH 06/25] review feedback --- nova/db/sqlalchemy/api.py | 40 --------------------------------------- 1 file changed, 40 deletions(-) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 08fc81759..7b78e286d 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1484,46 +1484,6 @@ def instance_get_floating_address(context, instance_id): return fixed_ip_refs[0].floating_ips[0]['address'] -@require_admin_context -def instance_set_power_state(context, instance_id, power_state): - session = get_session() - partial = session.query(models.Instance) - - if utils.is_uuid_like(instance_id): - result = partial.filter_by(uuid=instance_id) - else: - result = partial.filter_by(id=instance_id) - - result.update({'power_state': power_state}) - - -@require_admin_context -def instance_set_vm_state(context, instance_id, vm_state): - # vm_state = running, halted, suspended, paused - session = get_session() - partial = session.query(models.Instance) - - if utils.is_uuid_like(instance_id): - result = partial.filter_by(uuid=instance_id) - else: - result = partial.filter_by(id=instance_id) - - result.update({'vm_state': vm_state}) - - -def instance_set_task_state(context, instance_id, task_state): - # task_state = running, halted, suspended, paused - session = get_session() - partial = session.query(models.Instance) - - if utils.is_uuid_like(instance_id): - result = partial.filter_by(uuid=instance_id) - else: - result = partial.filter_by(id=instance_id) - - result.update({'task_state': task_state}) - - @require_context def instance_update(context, instance_id, values): session = get_session() From 655bd7a476596929d63b8841f3690221e70244e4 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Fri, 26 Aug 2011 16:17:40 -0700 Subject: [PATCH 07/25] use db layer for aggregation --- nova/db/api.py | 11 ++++++++--- nova/db/sqlalchemy/api.py | 19 ++++++++++++------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/nova/db/api.py b/nova/db/api.py index 3bb9b4970..f443239c1 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -495,9 +495,14 @@ def instance_get_all_by_filters(context, filters): return IMPL.instance_get_all_by_filters(context, filters) -def instance_get_active_by_window(context, begin, end=None): - """Get instances active during a certain time window.""" - return IMPL.instance_get_active_by_window(context, begin, end) +def instance_get_active_by_window(context, begin, end=None, + project_id=None, fast=False): + """Get instances active during a certain time window. + + Setting fast to true will stop all joinedloads. + Specifying a project_id will filter for a certain project.""" + return IMPL.instance_get_active_by_window(context, begin, end, + project_id, fast) def instance_get_all_by_user(context, user_id): diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index d1fbf8cab..2d50f458f 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1307,20 +1307,25 @@ def instance_get_all_by_filters(context, filters): @require_admin_context -def instance_get_active_by_window(context, begin, end=None): +def instance_get_active_by_window(context, begin, end=None, + project_id=None, fast=False): """Return instances that were continuously active over the given window""" session = get_session() - query = session.query(models.Instance).\ - options(joinedload_all('fixed_ips.floating_ips')).\ - options(joinedload('security_groups')).\ - options(joinedload_all('fixed_ips.network')).\ - options(joinedload('instance_type')).\ - filter(models.Instance.launched_at < begin) + query = session.query(models.Instance) + if not fast: + query = query.options(joinedload_all('fixed_ips.floating_ips')).\ + options(joinedload('security_groups')).\ + options(joinedload_all('fixed_ips.network')).\ + options(joinedload('instance_type')) + + query = query.filter(models.Instance.launched_at < begin) if end: query = query.filter(or_(models.Instance.terminated_at == None, models.Instance.terminated_at > end)) else: query = query.filter(models.Instance.terminated_at == None) + if project_id: + query = query.filter_by(project_id=project_id) return query.all() From ef206acdc7c8d0a4c55711d1fe1f3b41114acd44 Mon Sep 17 00:00:00 2001 From: Dan Wendlandt <dan@nicira.com> Date: Sun, 28 Aug 2011 11:37:19 -0700 Subject: [PATCH 08/25] use 'uuid' field in networks table rather than 'bridge'. Specify project_id when creating instance in unit test --- nova/db/api.py | 5 +++++ nova/db/sqlalchemy/api.py | 13 +++++++++++++ 2 files changed, 18 insertions(+) diff --git a/nova/db/api.py b/nova/db/api.py index 9ff3a1c74..17ef0bd0b 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -708,6 +708,11 @@ def network_get_by_bridge(context, bridge): return IMPL.network_get_by_bridge(context, bridge) +def network_get_by_uuid(context, uuid): + """Get a network by uuid or raise if it does not exist.""" + return IMPL.network_get_by_uuid(context, uuid) + + def network_get_by_cidr(context, cidr): """Get a network by cidr or raise if it does not exist""" return IMPL.network_get_by_cidr(context, cidr) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index d96b951a1..80ce76e8f 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1846,6 +1846,19 @@ def network_get_by_bridge(context, bridge): return result +@require_admin_context +def network_get_by_uuid(context, uuid): + session = get_session() + result = session.query(models.Network).\ + filter_by(uuid=uuid).\ + filter_by(deleted=False).\ + first() + + if not result: + raise exception.NetworkNotFoundForUUID(uuid=uuid) + return result + + @require_admin_context def network_get_by_cidr(context, cidr): session = get_session() From 9fd5d5382aa0ac15d92d31084816e8ce135d622b Mon Sep 17 00:00:00 2001 From: "danwent@gmail.com" <> Date: Sun, 28 Aug 2011 20:00:38 -0700 Subject: [PATCH 09/25] restore fixed_ip_associate_pool in nova/db/sqlalchemy.py to its original form before this branch. Figured out how to make unit tests pass without requiring that this function changes --- nova/db/sqlalchemy/api.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 80ce76e8f..00af62682 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -688,8 +688,10 @@ def fixed_ip_associate(context, address, instance_id, network_id=None): def fixed_ip_associate_pool(context, network_id, instance_id=None, host=None): session = get_session() with session.begin(): + network_or_none = or_(models.FixedIp.network_id == network_id, + models.FixedIp.network_id == None) fixed_ip_ref = session.query(models.FixedIp).\ - filter_by(network_id=network_id).\ + filter(network_or_none).\ filter_by(reserved=False).\ filter_by(deleted=False).\ filter_by(instance=None).\ From 3389c3fd6e42df3358df3caef5f6b18a6d344ff3 Mon Sep 17 00:00:00 2001 From: Brian Waldon <brian.waldon@rackspace.com> Date: Tue, 30 Aug 2011 11:13:25 -0400 Subject: [PATCH 10/25] supporting changes-since --- nova/db/sqlalchemy/api.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 65b09a65d..1685e9928 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -35,6 +35,7 @@ from sqlalchemy.exc import IntegrityError from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload_all from sqlalchemy.sql import func +from sqlalchemy.sql.expression import desc from sqlalchemy.sql.expression import literal_column FLAGS = flags.FLAGS @@ -1250,12 +1251,17 @@ def instance_get_all_by_filters(context, filters): options(joinedload_all('fixed_ips.network')).\ options(joinedload('metadata')).\ options(joinedload('instance_type')).\ - filter_by(deleted=can_read_deleted(context)) + order_by(desc(models.Instance.updated_at)) # Make a copy of the filters dictionary to use going forward, as we'll # be modifying it and we shouldn't affect the caller's use of it. filters = filters.copy() + if 'changes-since' in filters: + changes_since = filters['changes-since'] + query_prefix = query_prefix.\ + filter(models.Instance.updated_at > changes_since) + if not context.is_admin: # If we're not admin context, add appropriate filter.. if context.project_id: @@ -1277,9 +1283,7 @@ def instance_get_all_by_filters(context, filters): query_prefix = _exact_match_filter(query_prefix, filter_name, filters.pop(filter_name)) - instances = query_prefix.\ - filter_by(deleted=can_read_deleted(context)).\ - all() + instances = query_prefix.all() if not instances: return [] From a72cac7bb23bdb634aabad25d945a786ea69d435 Mon Sep 17 00:00:00 2001 From: Brian Waldon <brian.waldon@rackspace.com> Date: Tue, 30 Aug 2011 12:51:02 -0400 Subject: [PATCH 11/25] changing default sort to created_at --- nova/db/sqlalchemy/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 1685e9928..1e55d08e7 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1251,7 +1251,7 @@ def instance_get_all_by_filters(context, filters): options(joinedload_all('fixed_ips.network')).\ options(joinedload('metadata')).\ options(joinedload('instance_type')).\ - order_by(desc(models.Instance.updated_at)) + order_by(desc(models.Instance.created_at)) # Make a copy of the filters dictionary to use going forward, as we'll # be modifying it and we shouldn't affect the caller's use of it. From 1d15b2c33cebaa64adc714ac04f30baf78d1e32e Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Tue, 30 Aug 2011 12:01:18 -0700 Subject: [PATCH 12/25] make two functions instead of fast flag and add compute api commands instead of hitting db directly --- nova/db/api.py | 16 +++++++++++----- nova/db/sqlalchemy/api.py | 36 +++++++++++++++++++++++++----------- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/nova/db/api.py b/nova/db/api.py index 3233985b6..148887635 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -496,14 +496,20 @@ def instance_get_all_by_filters(context, filters): return IMPL.instance_get_all_by_filters(context, filters) -def instance_get_active_by_window(context, begin, end=None, - project_id=None, fast=False): +def instance_get_active_by_window(context, begin, end=None, project_id=None): """Get instances active during a certain time window. - Setting fast to true will stop all joinedloads. Specifying a project_id will filter for a certain project.""" - return IMPL.instance_get_active_by_window(context, begin, end, - project_id, fast) + return IMPL.instance_get_active_by_window(context, begin, end, project_id) + + +def instance_get_active_by_window_joined(context, begin, end=None, + project_id=None): + """Get instances and joins active during a certain time window. + + Specifying a project_id will filter for a certain project.""" + return IMPL.instance_get_active_by_window_joined(context, begin, end, + project_id) def instance_get_all_by_user(context, user_id): diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index c4cc199eb..d76dc22ed 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1306,19 +1306,33 @@ def instance_get_all_by_filters(context, filters): return instances -@require_admin_context -def instance_get_active_by_window(context, begin, end=None, - project_id=None, fast=False): - """Return instances that were continuously active over the given window""" +@require_context +def instance_get_active_by_window(context, begin, end=None, project_id=None): + """Return instances that were continuously active over window.""" session = get_session() - query = session.query(models.Instance) - if not fast: - query = query.options(joinedload_all('fixed_ips.floating_ips')).\ - options(joinedload('security_groups')).\ - options(joinedload_all('fixed_ips.network')).\ - options(joinedload('instance_type')) + query = session.query(models.Instance).\ + filter(models.Instance.launched_at < begin) + if end: + query = query.filter(or_(models.Instance.terminated_at == None, + models.Instance.terminated_at > end)) + else: + query = query.filter(models.Instance.terminated_at == None) + if project_id: + query = query.filter_by(project_id=project_id) + return query.all() - query = query.filter(models.Instance.launched_at < begin) + +@require_admin_context +def instance_get_active_by_window_joined(context, begin, end=None, + project_id=None): + """Return instances and joins that were continuously active over window.""" + session = get_session() + query = session.query(models.Instance).\ + options(joinedload_all('fixed_ips.floating_ips')).\ + options(joinedload('security_groups')).\ + options(joinedload_all('fixed_ips.network')).\ + options(joinedload('instance_type')).\ + filter(models.Instance.launched_at < begin) if end: query = query.filter(or_(models.Instance.terminated_at == None, models.Instance.terminated_at > end)) From 56ceb6f9c5ebf78677a91a2da143704f8e9db324 Mon Sep 17 00:00:00 2001 From: Brian Lamar <brian.lamar@rackspace.com> Date: Wed, 31 Aug 2011 10:14:07 -0400 Subject: [PATCH 13/25] Removed extraneous import and s/vm_state.STOP/vm_states.STOPPED/ --- nova/db/sqlalchemy/api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 24e1772f6..631e53ceb 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -28,6 +28,7 @@ from nova import flags from nova import ipv6 from nova import utils from nova import log as logging +from nova.compute import vm_states from nova.db.sqlalchemy import models from nova.db.sqlalchemy.session import get_session from sqlalchemy import or_ @@ -1102,11 +1103,10 @@ def instance_destroy(context, instance_id): def instance_stop(context, instance_id): session = get_session() with session.begin(): - from nova.compute import power_state session.query(models.Instance).\ filter_by(id=instance_id).\ update({'host': None, - 'vm_state': vm_state.STOP, + 'vm_state': vm_states.STOPPED, 'task_state': None, 'updated_at': literal_column('updated_at')}) session.query(models.SecurityGroupInstanceAssociation).\ From d976fdc30bfe06691feb3ad259cced958c1b0fa6 Mon Sep 17 00:00:00 2001 From: Tushar Patil <tushar.vitthal.patil@gmail.com> Date: Wed, 31 Aug 2011 17:06:15 -0700 Subject: [PATCH 14/25] Fix for LP Bug #838251 --- nova/utils.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/nova/utils.py b/nova/utils.py index 21e6221b2..4855f6fd6 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -901,3 +901,12 @@ def monkey_patch(): func = import_class("%s.%s" % (module, key)) setattr(sys.modules[module], key,\ decorator("%s.%s" % (module, key), func)) + + +def convert_to_set(lst, label): + """Convert a value or list into a set""" + if lst is None or lst == []: + return None + if not isinstance(lst, list): + lst = [lst] + return [{label: x} for x in lst] From e5e2d0be4e0f2abdfcfeb0fa2e51c44320395c73 Mon Sep 17 00:00:00 2001 From: Tushar Patil <tushar.vitthal.patil@gmail.com> Date: Fri, 2 Sep 2011 12:34:14 -0700 Subject: [PATCH 15/25] Fix for LP Bug #839269 --- nova/db/api.py | 6 ++++-- nova/db/sqlalchemy/api.py | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/nova/db/api.py b/nova/db/api.py index 148887635..efc088e35 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -324,13 +324,15 @@ def migration_get_by_instance_and_status(context, instance_uuid, status): #################### -def fixed_ip_associate(context, address, instance_id, network_id=None): +def fixed_ip_associate(context, address, instance_id, network_id=None, + reserved=False): """Associate fixed ip to instance. Raises if fixed ip is not available. """ - return IMPL.fixed_ip_associate(context, address, instance_id, network_id) + return IMPL.fixed_ip_associate(context, address, instance_id, network_id, + reserved) def fixed_ip_associate_pool(context, network_id, instance_id=None, host=None): diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index b99667afc..e0be8454e 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -669,14 +669,15 @@ def floating_ip_update(context, address, values): @require_admin_context -def fixed_ip_associate(context, address, instance_id, network_id=None): +def fixed_ip_associate(context, address, instance_id, network_id=None, + reserved=False): session = get_session() with session.begin(): network_or_none = or_(models.FixedIp.network_id == network_id, models.FixedIp.network_id == None) fixed_ip_ref = session.query(models.FixedIp).\ filter(network_or_none).\ - filter_by(reserved=False).\ + filter_by(reserved=reserved).\ filter_by(deleted=False).\ filter_by(address=address).\ with_lockmode('update').\ From a75101ee660047006875629b0b9316352057c108 Mon Sep 17 00:00:00 2001 From: Dan Wendlandt <dan@nicira.com> Date: Fri, 2 Sep 2011 13:05:24 -0700 Subject: [PATCH 16/25] feedback from jk0's review, including removing a lot of spaces from docstrings --- nova/db/sqlalchemy/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 09356e966..e0da2269d 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -946,7 +946,7 @@ def virtual_interface_get_by_address(context, address): def virtual_interface_get_by_uuid(context, vif_uuid): """Gets a virtual interface from the table. - :param vif_uuid: = the uuid of the interface you're looking to get + :param vif_uuid: the uuid of the interface you're looking to get """ session = get_session() vif_ref = session.query(models.VirtualInterface).\ From 97b2d1b83c4bc44b2ef03119e6f3b24350686e33 Mon Sep 17 00:00:00 2001 From: Keisuke Tagami <tagami.keisuke@lab.ntt.co.jp> Date: Mon, 5 Sep 2011 14:45:41 +0900 Subject: [PATCH 17/25] Fix bug #835919 that output a option file for dnsmasq not to offer a default gateway on second vif. --- nova/db/sqlalchemy/api.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) mode change 100644 => 100755 nova/db/sqlalchemy/api.py diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py old mode 100644 new mode 100755 index b99667afc..aee1c2a55 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1415,6 +1415,21 @@ def instance_get_all_by_reservation(context, reservation_id): filter_by(project_id=context.project_id).\ filter_by(deleted=False).\ all() + +@require_admin_context +def instance_get_all_by_network(context, network_id): + session = get_session() + return session.query(models.Instance).\ + options(joinedload_all('fixed_ips.floating_ips')).\ + options(joinedload('virtual_interfaces')).\ + options(joinedload('security_groups')).\ + options(joinedload_all('fixed_ips.network')).\ + options(joinedload('metadata')).\ + options(joinedload('instance_type')).\ + filter_by(deleted=can_read_deleted(context)).\ + filter_by(network_id=network_id).\ + all() + @require_context From 272fcf91454afda37aa54898d9b9493327b530d6 Mon Sep 17 00:00:00 2001 From: Keisuke Tagami <tagami.keisuke@lab.ntt.co.jp> Date: Mon, 5 Sep 2011 20:23:28 +0900 Subject: [PATCH 18/25] implement unit test for linux_net --- nova/db/api.py | 5 +++++ 1 file changed, 5 insertions(+) mode change 100644 => 100755 nova/db/api.py diff --git a/nova/db/api.py b/nova/db/api.py old mode 100644 new mode 100755 index 148887635..85e9c7669 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -532,6 +532,11 @@ def instance_get_all_by_reservation(context, reservation_id): return IMPL.instance_get_all_by_reservation(context, reservation_id) +def instance_get_all_by_network(context, network_id): + """Get all instances belonging to a network.""" + return IMPL.instance_get_all_by_network(context, network_id) + + def instance_get_by_fixed_ip(context, address): """Get an instance for a fixed ip by address.""" return IMPL.instance_get_by_fixed_ip(context, address) From d193081258f2a3c0cedcc220c49355acc600c7a2 Mon Sep 17 00:00:00 2001 From: Keisuke Tagami <tagami.keisuke@lab.ntt.co.jp> Date: Mon, 5 Sep 2011 21:13:00 +0900 Subject: [PATCH 19/25] format for pep8 --- nova/db/api.py | 4 ++-- nova/db/sqlalchemy/api.py | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/nova/db/api.py b/nova/db/api.py index 85e9c7669..faac13966 100755 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -535,8 +535,8 @@ def instance_get_all_by_reservation(context, reservation_id): def instance_get_all_by_network(context, network_id): """Get all instances belonging to a network.""" return IMPL.instance_get_all_by_network(context, network_id) - - + + def instance_get_by_fixed_ip(context, address): """Get an instance for a fixed ip by address.""" return IMPL.instance_get_by_fixed_ip(context, address) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index aee1c2a55..3194a5231 100755 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1415,8 +1415,8 @@ def instance_get_all_by_reservation(context, reservation_id): filter_by(project_id=context.project_id).\ filter_by(deleted=False).\ all() - -@require_admin_context + + def instance_get_all_by_network(context, network_id): session = get_session() return session.query(models.Instance).\ @@ -1431,7 +1431,6 @@ def instance_get_all_by_network(context, network_id): all() - @require_context def instance_get_by_fixed_ip(context, address): """Return instance ref by exact match of FixedIP""" From e6ab1718de8eaba5ca6282ec291631765fe9c084 Mon Sep 17 00:00:00 2001 From: Keisuke Tagami <tagami.keisuke@lab.ntt.co.jp> Date: Tue, 6 Sep 2011 10:14:27 +0900 Subject: [PATCH 20/25] correct a method to collect instances from db add interface data to test --- nova/db/api.py | 5 ----- nova/db/sqlalchemy/api.py | 14 -------------- 2 files changed, 19 deletions(-) diff --git a/nova/db/api.py b/nova/db/api.py index faac13966..148887635 100755 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -532,11 +532,6 @@ def instance_get_all_by_reservation(context, reservation_id): return IMPL.instance_get_all_by_reservation(context, reservation_id) -def instance_get_all_by_network(context, network_id): - """Get all instances belonging to a network.""" - return IMPL.instance_get_all_by_network(context, network_id) - - def instance_get_by_fixed_ip(context, address): """Get an instance for a fixed ip by address.""" return IMPL.instance_get_by_fixed_ip(context, address) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 3194a5231..b99667afc 100755 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1417,20 +1417,6 @@ def instance_get_all_by_reservation(context, reservation_id): all() -def instance_get_all_by_network(context, network_id): - session = get_session() - return session.query(models.Instance).\ - options(joinedload_all('fixed_ips.floating_ips')).\ - options(joinedload('virtual_interfaces')).\ - options(joinedload('security_groups')).\ - options(joinedload_all('fixed_ips.network')).\ - options(joinedload('metadata')).\ - options(joinedload('instance_type')).\ - filter_by(deleted=can_read_deleted(context)).\ - filter_by(network_id=network_id).\ - all() - - @require_context def instance_get_by_fixed_ip(context, address): """Return instance ref by exact match of FixedIP""" From 23f90a9edd5033a187ca5a971d96d1fc03cd5e6e Mon Sep 17 00:00:00 2001 From: Keisuke Tagami <tagami.keisuke@lab.ntt.co.jp> Date: Tue, 6 Sep 2011 10:20:28 +0900 Subject: [PATCH 21/25] revert codes for db --- nova/db/api.py | 0 nova/db/sqlalchemy/api.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 nova/db/api.py mode change 100755 => 100644 nova/db/sqlalchemy/api.py diff --git a/nova/db/api.py b/nova/db/api.py old mode 100755 new mode 100644 diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py old mode 100755 new mode 100644 From f9431a1f884bc6f93a1a0afee3eee4d7dc2d391b Mon Sep 17 00:00:00 2001 From: Brian Waldon <brian.waldon@rackspace.com> Date: Thu, 8 Sep 2011 11:32:11 -0400 Subject: [PATCH 22/25] adding can_read_deleted back to db api --- nova/db/sqlalchemy/api.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 523258841..1730b4ddb 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1277,6 +1277,10 @@ def instance_get_all_by_filters(context, filters): changes_since = filters['changes-since'] query_prefix = query_prefix.\ filter(models.Instance.updated_at > changes_since) + else: + # filter out deleted instances if no changes-since filter provided + query_prefix = query_prefix.\ + filter_by(deleted=can_read_deleted(context)) if not context.is_admin: # If we're not admin context, add appropriate filter.. From 0873840079e6af51f8c6c43b8d4adea711667c5c Mon Sep 17 00:00:00 2001 From: Brian Waldon <brian.waldon@rackspace.com> Date: Thu, 8 Sep 2011 15:26:44 -0400 Subject: [PATCH 23/25] converting fix to just address ec2; updating test --- nova/db/sqlalchemy/api.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 1730b4ddb..523258841 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1277,10 +1277,6 @@ def instance_get_all_by_filters(context, filters): changes_since = filters['changes-since'] query_prefix = query_prefix.\ filter(models.Instance.updated_at > changes_since) - else: - # filter out deleted instances if no changes-since filter provided - query_prefix = query_prefix.\ - filter_by(deleted=can_read_deleted(context)) if not context.is_admin: # If we're not admin context, add appropriate filter.. From 9403d4e0949fb7e41d4b865e3b4389dc1ab2a333 Mon Sep 17 00:00:00 2001 From: Antony Messerli <amesserl@rackspace.com> Date: Mon, 12 Sep 2011 14:43:15 -0500 Subject: [PATCH 24/25] pep8 fixes --- nova/db/sqlalchemy/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 40e2ca167..e5a661c7f 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -672,7 +672,7 @@ def floating_ip_update(context, address, values): def fixed_ip_associate(context, address, instance_id, network_id=None, reserved=False): """Keyword arguments: - reserved -- should be a boolean value(True or False), exact value will be + reserved -- should be a boolean value(True or False), exact value will be used to filter on the fixed ip address """ session = get_session() From 34092169a293bd50dfd83a2d1a4bc14ce140d72c Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Tue, 13 Sep 2011 16:38:46 -0700 Subject: [PATCH 25/25] makes sure floating addresses are associated with host on associate so they come back --- nova/db/api.py | 8 +++++--- nova/db/sqlalchemy/api.py | 5 ++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/nova/db/api.py b/nova/db/api.py index c03a86671..5b57b178e 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -261,11 +261,13 @@ def floating_ip_disassociate(context, address): return IMPL.floating_ip_disassociate(context, address) -def floating_ip_fixed_ip_associate(context, floating_address, fixed_address): +def floating_ip_fixed_ip_associate(context, floating_address, + fixed_address, host): """Associate an floating ip to a fixed_ip by address.""" return IMPL.floating_ip_fixed_ip_associate(context, floating_address, - fixed_address) + fixed_address, + host) def floating_ip_get_all(context): @@ -365,7 +367,7 @@ def fixed_ip_get_all(context): def fixed_ip_get_all_by_instance_host(context, host): """Get all allocated fixed ips filtered by instance host.""" - return IMPL.fixed_ip_get_all_instance_by_host(context, host) + return IMPL.fixed_ip_get_all_by_instance_host(context, host) def fixed_ip_get_by_address(context, address): diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 523258841..9c3d8413e 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -529,7 +529,8 @@ def floating_ip_count_by_project(context, project_id): @require_context -def floating_ip_fixed_ip_associate(context, floating_address, fixed_address): +def floating_ip_fixed_ip_associate(context, floating_address, + fixed_address, host): session = get_session() with session.begin(): # TODO(devcamcar): How to ensure floating_id belongs to user? @@ -540,6 +541,7 @@ def floating_ip_fixed_ip_associate(context, floating_address, fixed_address): fixed_address, session=session) floating_ip_ref.fixed_ip = fixed_ip_ref + floating_ip_ref.host = host floating_ip_ref.save(session=session) @@ -583,6 +585,7 @@ def floating_ip_disassociate(context, address): else: fixed_ip_address = None floating_ip_ref.fixed_ip = None + floating_ip_ref.host = None floating_ip_ref.save(session=session) return fixed_ip_address