From ffb9361596c1708d7d009c195b4b3bc74d00a01c Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Mon, 19 Mar 2012 09:01:16 -0700 Subject: Improve performance of generating dhcp leases * Dont make 2 * instances queries when generating dhcp leases * Uses some nasty joins to minimize necessary changes * Adds test to verify functionality * Uses old sqlalchemy compatible join syntax * Uses vif_id as nw identifier for single_host_gateway mode * Cleans up tests in linux_net * Fixes bug 959378 Change-Id: I1c74d114dd7caad1781180585bb65691e536bcf9 --- nova/db/api.py | 4 ++-- nova/db/sqlalchemy/api.py | 48 ++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 43 insertions(+), 9 deletions(-) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index 286fdc8d0..2a38d026f 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -782,9 +782,9 @@ def network_get_all_by_uuids(context, network_uuids, project_id=None): # pylint: disable=C0103 -def network_get_associated_fixed_ips(context, network_id): +def network_get_associated_fixed_ips(context, network_id, host=None): """Get all network's ips that have been associated.""" - return IMPL.network_get_associated_fixed_ips(context, network_id) + return IMPL.network_get_associated_fixed_ips(context, network_id, host) def network_get_by_bridge(context, bridge): diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 49810de22..9eda43941 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1990,15 +1990,49 @@ def network_get_all_by_uuids(context, network_uuids, project_id=None): @require_admin_context -def network_get_associated_fixed_ips(context, network_id): +def network_get_associated_fixed_ips(context, network_id, host=None): # FIXME(sirp): since this returns fixed_ips, this would be better named # fixed_ip_get_all_by_network. - return model_query(context, models.FixedIp, read_deleted="no").\ - filter_by(network_id=network_id).\ - filter_by(allocated=True).\ - filter(models.FixedIp.instance_id != None).\ - filter(models.FixedIp.virtual_interface_id != None).\ - all() + # NOTE(vish): The ugly joins here are to solve a performance issue and + # should be removed once we can add and remove leases + # without regenerating the whole list + vif_and = and_(models.VirtualInterface.id == + models.FixedIp.virtual_interface_id, + models.VirtualInterface.deleted == False) + inst_and = and_(models.Instance.id == models.FixedIp.instance_id, + models.Instance.deleted == False) + session = get_session() + query = session.query(models.FixedIp.address, + models.FixedIp.instance_id, + models.FixedIp.network_id, + models.FixedIp.virtual_interface_id, + models.VirtualInterface.address, + models.Instance.hostname, + models.Instance.updated_at, + models.Instance.created_at).\ + filter(models.FixedIp.deleted == False).\ + filter(models.FixedIp.network_id == network_id).\ + filter(models.FixedIp.allocated == True).\ + join((models.VirtualInterface, vif_and)).\ + join((models.Instance, inst_and)).\ + filter(models.FixedIp.instance_id != None).\ + filter(models.FixedIp.virtual_interface_id != None) + if host: + query = query.filter(models.Instance.host == host) + result = query.all() + data = [] + for datum in result: + cleaned = {} + cleaned['address'] = datum[0] + cleaned['instance_id'] = datum[1] + cleaned['network_id'] = datum[2] + cleaned['vif_id'] = datum[3] + cleaned['vif_address'] = datum[4] + cleaned['instance_hostname'] = datum[5] + cleaned['instance_updated'] = datum[6] + cleaned['instance_created'] = datum[7] + data.append(cleaned) + return data @require_admin_context -- cgit