From 9773d900d35316edbad4468a869ca62a353d3114 Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Fri, 2 Sep 2011 12:34:14 -0700 Subject: Fix for LP Bug #839269 --- nova/db/api.py | 6 ++++-- nova/db/sqlalchemy/api.py | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'nova/db') 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').\ -- cgit From d8abe79da8dde2667936ee97d88d30d5cf0e6d7f Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Sat, 10 Sep 2011 17:11:31 +0900 Subject: api/ec2/ebs: make metadata returns correct swap and ephemeral0 --- .../migrate_repo/versions/046_add_instance_swap.py | 48 ++++++++++++++++++++++ nova/db/sqlalchemy/models.py | 2 + 2 files changed, 50 insertions(+) create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/046_add_instance_swap.py (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/046_add_instance_swap.py b/nova/db/sqlalchemy/migrate_repo/versions/046_add_instance_swap.py new file mode 100644 index 000000000..63e7bc4f9 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/046_add_instance_swap.py @@ -0,0 +1,48 @@ +# Copyright 2011 Isaku Yamahata +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from sqlalchemy import Column, Integer, MetaData, Table, String + +meta = MetaData() + +default_local_device = Column( + 'default_local_device', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False), + nullable=True) + +default_swap_device = Column( + 'default_swap_device', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False), + nullable=True) + +instances = Table('instances', meta, + Column('id', Integer(), primary_key=True, nullable=False), + ) + + +def upgrade(migrate_engine): + # Upgrade operations go here. Don't create your own engine; + # bind migrate_engine to your metadata + meta.bind = migrate_engine + instances.create_column(default_local_device) + instances.create_column(default_swap_device) + + +def downgrade(migrate_engine): + # Operations to reverse the above upgrade go here. + meta.bind = migrate_engine + instances.drop_column('default_swap_device') + instances.drop_column('default_local_device') diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 211049112..b5f30a1e3 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -232,6 +232,8 @@ class Instance(BASE, NovaBase): uuid = Column(String(36)) root_device_name = Column(String(255)) + default_local_device = Column(String(255), nullable=True) + default_swap_device = Column(String(255), nullable=True) config_drive = Column(String(255)) # User editable field meant to represent what ip should be used -- cgit From 81fe8c89061fa15ebcea9d20f39cf79b63cf8522 Mon Sep 17 00:00:00 2001 From: Antony Messerli Date: Mon, 12 Sep 2011 14:43:15 -0500 Subject: pep8 fixes --- nova/db/sqlalchemy/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/db') 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() -- cgit From 2de5870dfaf0671657a6b8c275acc6405d04274c Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Tue, 13 Sep 2011 11:09:27 -0500 Subject: drop the virtual_interfaces key back to instances --- .../versions/046_remove_instances_fk_from_vif.py | 57 ++++++++++++++++++++++ .../migrate_repo/versions/046_sqlite_downgrade.sql | 47 ++++++++++++++++++ .../migrate_repo/versions/046_sqlite_upgrade.sql | 45 +++++++++++++++++ nova/db/sqlalchemy/models.py | 5 +- 4 files changed, 150 insertions(+), 4 deletions(-) create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/046_remove_instances_fk_from_vif.py create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/046_sqlite_downgrade.sql create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/046_sqlite_upgrade.sql (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/046_remove_instances_fk_from_vif.py b/nova/db/sqlalchemy/migrate_repo/versions/046_remove_instances_fk_from_vif.py new file mode 100644 index 000000000..0f4a9b122 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/046_remove_instances_fk_from_vif.py @@ -0,0 +1,57 @@ +# Copyright 2011 OpenStack LLC. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from sqlalchemy import dialect, Column, Integer, MetaData, Table +from migrate import ForeignKeyConstraint + +from nova import log as logging + + +meta = MetaData() + + +instances = Table('instances', meta, + Column('id', Integer(), primary_key=True, nullable=False), + ) + + +vifs = Table('vifs', meta, + Column('id', Integer(), primary_key=True, nullable=False), + Column('instance_id', Integer()), + ) + + +def upgrade(migrate_engine): + # Upgrade operations go here. Don't create your own engine; + # bind migrate_engine to your metadata + meta.bind = migrate_engine + try: + if not dialect.startswith('sqlite'): + ForeignKeyConstraint(columns=[vifs.c.instance_id], + refcolumns=[instances.c.id]).drop() + except Exception: + logging.error(_("foreign key constraint couldn't be removed")) + raise + + +def downgrade(migrate_engine): + # Operations to reverse the above upgrade go here. + meta.bind = migrate_engine + try: + if not dialect.startswith('sqlite'): + ForeignKeyConstraint(columns=[vifs.c.instance_id], + refcolumns=[instances.c.id]).create() + except Exception: + logging.error(_("foreign key constraint couldn't be added")) + raise diff --git a/nova/db/sqlalchemy/migrate_repo/versions/046_sqlite_downgrade.sql b/nova/db/sqlalchemy/migrate_repo/versions/046_sqlite_downgrade.sql new file mode 100644 index 000000000..cf9afbb09 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/046_sqlite_downgrade.sql @@ -0,0 +1,47 @@ +COMMIT; +BEGIN TRANSACTION; + CREATE TEMPORARY TABLE virtual_interfaces_backup ( + created_at DATETIME, + updated_at DATETIME, + deleted_at DATETIME, + deleted BOOLEAN, + id INTEGER NOT NULL, + address VARCHAR(255), + network_id INTEGER, + instance_id INTEGER NOT NULL, + uuid VARCHAR(36), + PRIMARY KEY (id) + ); + + INSERT INTO virtual_interfaces_backup + SELECT created_at, updated_at, deleted_at, deleted, id, address, + network_id, instance_id, uuid + FROM virtual_interfaces; + + DROP TABLE virtual_interfaces; + + CREATE TABLE virtual_interfaces ( + created_at DATETIME, + updated_at DATETIME, + deleted_at DATETIME, + deleted BOOLEAN, + id INTEGER NOT NULL, + address VARCHAR(255), + network_id INTEGER, + instance_id INTEGER NOT NULL, + uuid VARCHAR(36), + PRIMARY KEY (id), + FOREIGN KEY(network_id) REFERENCES networks (id), + FOREIGN KEY(instance_id) REFERENCES instances (id), + UNIQUE (address), + CHECK (deleted IN (0, 1)) + ); + + INSERT INTO virtual_interfaces + SELECT created_at, updated_at, deleted_at, deleted, id, address, + network_id, instance_id, uuid + FROM virtual_interfaces_backup; + + DROP TABLE virtual_interfaces_backup; + +COMMIT; diff --git a/nova/db/sqlalchemy/migrate_repo/versions/046_sqlite_upgrade.sql b/nova/db/sqlalchemy/migrate_repo/versions/046_sqlite_upgrade.sql new file mode 100644 index 000000000..2c0919f1d --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/046_sqlite_upgrade.sql @@ -0,0 +1,45 @@ +BEGIN TRANSACTION; + CREATE TEMPORARY TABLE virtual_interfaces_backup ( + created_at DATETIME, + updated_at DATETIME, + deleted_at DATETIME, + deleted BOOLEAN, + id INTEGER NOT NULL, + address VARCHAR(255), + network_id INTEGER, + instance_id INTEGER NOT NULL, + uuid VARCHAR(36), + PRIMARY KEY (id) + ); + + INSERT INTO virtual_interfaces_backup + SELECT created_at, updated_at, deleted_at, deleted, id, address, + network_id, instance_id, uuid + FROM virtual_interfaces; + + DROP TABLE virtual_interfaces; + + CREATE TABLE virtual_interfaces ( + created_at DATETIME, + updated_at DATETIME, + deleted_at DATETIME, + deleted BOOLEAN, + id INTEGER NOT NULL, + address VARCHAR(255), + network_id INTEGER, + instance_id INTEGER NOT NULL, + uuid VARCHAR(36), + PRIMARY KEY (id), + FOREIGN KEY(network_id) REFERENCES networks (id), + UNIQUE (address), + CHECK (deleted IN (0, 1)) + ); + + INSERT INTO virtual_interfaces + SELECT created_at, updated_at, deleted_at, deleted, id, address, + network_id, instance_id, uuid + FROM virtual_interfaces_backup; + + DROP TABLE virtual_interfaces_backup; + +COMMIT; diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 211049112..054fe30ff 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -640,10 +640,7 @@ class VirtualInterface(BASE, NovaBase): address = Column(String(255), unique=True) network_id = Column(Integer, ForeignKey('networks.id')) network = relationship(Network, backref=backref('virtual_interfaces')) - - # TODO(tr3buchet): cut the cord, removed foreign key and backrefs - instance_id = Column(Integer, ForeignKey('instances.id'), nullable=False) - instance = relationship(Instance, backref=backref('virtual_interfaces')) + instance_id = Column(Integer, nullable=False) uuid = Column(String(36)) -- cgit From de3d94726c980f40181693256c0f650d492451ef Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 13 Sep 2011 16:38:46 -0700 Subject: 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(-) (limited to 'nova/db') 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 -- cgit From ee5ebf5a46de7534d038f17468a254005796684c Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Wed, 14 Sep 2011 10:16:02 -0500 Subject: allow passing in of instances already --- nova/db/api.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index a9d2dc065..c32189cc0 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -498,9 +498,10 @@ def instance_get_all(context): return IMPL.instance_get_all(context) -def instance_get_all_by_filters(context, filters): +def instance_get_all_by_filters(context, filters, instances=None): """Get all instances that match all filters.""" - return IMPL.instance_get_all_by_filters(context, filters) + return IMPL.instance_get_all_by_filters(context, filters, + instances=instances) def instance_get_active_by_window(context, begin, end=None, project_id=None): -- cgit From 08fdbdddc66a616121a6b752af4ae26abbd25027 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Wed, 14 Sep 2011 10:17:01 -0500 Subject: remove the vif joins, some dead code, and the ability to take in some instances for filtering --- nova/db/sqlalchemy/api.py | 84 +++++++---------------------------------------- 1 file changed, 12 insertions(+), 72 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index e5a661c7f..9fbd1b658 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -19,6 +19,7 @@ Implementation of SQLAlchemy backend. """ import re +import types import warnings from nova import block_device @@ -927,7 +928,6 @@ def virtual_interface_get(context, vif_id, session=None): vif_ref = session.query(models.VirtualInterface).\ filter_by(id=vif_id).\ options(joinedload('network')).\ - options(joinedload('instance')).\ options(joinedload('fixed_ips')).\ first() return vif_ref @@ -943,7 +943,6 @@ def virtual_interface_get_by_address(context, address): vif_ref = session.query(models.VirtualInterface).\ filter_by(address=address).\ options(joinedload('network')).\ - options(joinedload('instance')).\ options(joinedload('fixed_ips')).\ first() return vif_ref @@ -959,7 +958,6 @@ def virtual_interface_get_by_uuid(context, vif_uuid): 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 @@ -975,7 +973,6 @@ def virtual_interface_get_by_fixed_ip(context, fixed_ip_id): vif_ref = session.query(models.VirtualInterface).\ filter_by(fixed_ip_id=fixed_ip_id).\ options(joinedload('network')).\ - options(joinedload('instance')).\ options(joinedload('fixed_ips')).\ first() return vif_ref @@ -992,7 +989,6 @@ def virtual_interface_get_by_instance(context, instance_id): vif_refs = session.query(models.VirtualInterface).\ filter_by(instance_id=instance_id).\ options(joinedload('network')).\ - options(joinedload('instance')).\ options(joinedload('fixed_ips')).\ all() return vif_refs @@ -1007,7 +1003,6 @@ def virtual_interface_get_by_instance_and_network(context, instance_id, filter_by(instance_id=instance_id).\ filter_by(network_id=network_id).\ options(joinedload('network')).\ - options(joinedload('instance')).\ options(joinedload('fixed_ips')).\ first() return vif_ref @@ -1023,7 +1018,6 @@ def virtual_interface_get_by_network(context, network_id): vif_refs = session.query(models.VirtualInterface).\ filter_by(network_id=network_id).\ options(joinedload('network')).\ - options(joinedload('instance')).\ options(joinedload('fixed_ips')).\ all() return vif_refs @@ -1169,7 +1163,6 @@ def _build_instance_get(context, session=None): partial = session.query(models.Instance).\ options(joinedload_all('fixed_ips.floating_ips')).\ options(joinedload_all('fixed_ips.network')).\ - options(joinedload('virtual_interfaces')).\ options(joinedload_all('security_groups.rules')).\ options(joinedload('volumes')).\ options(joinedload('metadata')).\ @@ -1188,10 +1181,6 @@ def instance_get_all(context): session = get_session() return session.query(models.Instance).\ options(joinedload_all('fixed_ips.floating_ips')).\ - options(joinedload_all('virtual_interfaces.network')).\ - options(joinedload_all( - 'virtual_interfaces.fixed_ips.floating_ips')).\ - options(joinedload('virtual_interfaces.instance')).\ options(joinedload('security_groups')).\ options(joinedload_all('fixed_ips.network')).\ options(joinedload('metadata')).\ @@ -1201,32 +1190,11 @@ def instance_get_all(context): @require_context -def instance_get_all_by_filters(context, filters): +def instance_get_all_by_filters(context, filters, instances=None): """Return instances that match all filters. Deleted instances will be returned by default, unless there's a filter that says otherwise""" - def _regexp_filter_by_ipv6(instance, filter_re): - for interface in instance['virtual_interfaces']: - fixed_ipv6 = interface.get('fixed_ipv6') - if fixed_ipv6 and filter_re.match(fixed_ipv6): - return True - return False - - def _regexp_filter_by_ip(instance, filter_re): - for interface in instance['virtual_interfaces']: - for fixed_ip in interface['fixed_ips']: - if not fixed_ip or not fixed_ip['address']: - continue - if filter_re.match(fixed_ip['address']): - return True - for floating_ip in fixed_ip.get('floating_ips', []): - if not floating_ip or not floating_ip['address']: - continue - if filter_re.match(floating_ip['address']): - return True - return False - def _regexp_filter_by_metadata(instance, meta): inst_metadata = [{node['key']: node['value']} \ for node in instance['metadata']] @@ -1263,13 +1231,7 @@ def instance_get_all_by_filters(context, filters): session = get_session() query_prefix = session.query(models.Instance).\ - options(joinedload_all('fixed_ips.floating_ips')).\ - options(joinedload_all('virtual_interfaces.network')).\ - options(joinedload_all( - 'virtual_interfaces.fixed_ips.floating_ips')).\ - options(joinedload('virtual_interfaces.instance')).\ options(joinedload('security_groups')).\ - options(joinedload_all('fixed_ips.network')).\ options(joinedload('metadata')).\ options(joinedload('instance_type')).\ order_by(desc(models.Instance.created_at)) @@ -1304,7 +1266,15 @@ def instance_get_all_by_filters(context, filters): query_prefix = _exact_match_filter(query_prefix, filter_name, filters.pop(filter_name)) - instances = query_prefix.all() + # TODO(jkoelker): This is for ID or UUID compat + if instances is None: + instances = [] + elif isinstance(instances, types.StringType): + instances = [instance_get_by_uuid(context, instances)] + elif isinstance(instances, types.IntType): + instances = [instance_get(context, instances)] + + instances.extend(query_prefix.all()) if not instances: return [] @@ -1312,8 +1282,7 @@ def instance_get_all_by_filters(context, filters): # 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.. - regexp_filter_funcs = {'ip6': _regexp_filter_by_ipv6, - 'ip': _regexp_filter_by_ip} + regexp_filter_funcs = {} for filter_name in filters.iterkeys(): filter_func = regexp_filter_funcs.get(filter_name, None) @@ -1373,7 +1342,6 @@ def instance_get_all_by_user(context, user_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')).\ @@ -1388,7 +1356,6 @@ def instance_get_all_by_host(context, host): 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')).\ @@ -1405,7 +1372,6 @@ def instance_get_all_by_project(context, project_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')).\ @@ -1421,7 +1387,6 @@ def instance_get_all_by_reservation(context, reservation_id): query = session.query(models.Instance).\ filter_by(reservation_id=reservation_id).\ options(joinedload_all('fixed_ips.floating_ips')).\ - options(joinedload('virtual_interfaces')).\ options(joinedload('security_groups')).\ options(joinedload_all('fixed_ips.network')).\ options(joinedload('metadata')).\ @@ -1438,36 +1403,11 @@ def instance_get_all_by_reservation(context, reservation_id): all() -@require_context -def instance_get_by_fixed_ip(context, address): - """Return instance ref by exact match of FixedIP""" - fixed_ip_ref = fixed_ip_get_by_address(context, address) - return fixed_ip_ref.instance - - -@require_context -def instance_get_by_fixed_ipv6(context, address): - """Return instance ref by exact match of IPv6""" - session = get_session() - - # convert IPv6 address to mac - mac = ipv6.to_mac(address) - - # get virtual interface - vif_ref = virtual_interface_get_by_address(context, mac) - - # look up instance based on instance_id from vif row - result = session.query(models.Instance).\ - filter_by(id=vif_ref['instance_id']) - return result - - @require_admin_context def instance_get_project_vpn(context, project_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')).\ -- cgit From 269aec5b02d9afef61dab3927d534ab807464ef3 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Wed, 14 Sep 2011 10:23:36 -0500 Subject: bump the migration --- .../versions/046_remove_instances_fk_from_vif.py | 57 ---------------------- .../migrate_repo/versions/046_sqlite_downgrade.sql | 47 ------------------ .../migrate_repo/versions/046_sqlite_upgrade.sql | 45 ----------------- .../versions/047_remove_instances_fk_from_vif.py | 57 ++++++++++++++++++++++ .../migrate_repo/versions/047_sqlite_downgrade.sql | 47 ++++++++++++++++++ .../migrate_repo/versions/047_sqlite_upgrade.sql | 45 +++++++++++++++++ 6 files changed, 149 insertions(+), 149 deletions(-) delete mode 100644 nova/db/sqlalchemy/migrate_repo/versions/046_remove_instances_fk_from_vif.py delete mode 100644 nova/db/sqlalchemy/migrate_repo/versions/046_sqlite_downgrade.sql delete mode 100644 nova/db/sqlalchemy/migrate_repo/versions/046_sqlite_upgrade.sql create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/047_sqlite_downgrade.sql create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/047_sqlite_upgrade.sql (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/046_remove_instances_fk_from_vif.py b/nova/db/sqlalchemy/migrate_repo/versions/046_remove_instances_fk_from_vif.py deleted file mode 100644 index 0f4a9b122..000000000 --- a/nova/db/sqlalchemy/migrate_repo/versions/046_remove_instances_fk_from_vif.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright 2011 OpenStack LLC. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from sqlalchemy import dialect, Column, Integer, MetaData, Table -from migrate import ForeignKeyConstraint - -from nova import log as logging - - -meta = MetaData() - - -instances = Table('instances', meta, - Column('id', Integer(), primary_key=True, nullable=False), - ) - - -vifs = Table('vifs', meta, - Column('id', Integer(), primary_key=True, nullable=False), - Column('instance_id', Integer()), - ) - - -def upgrade(migrate_engine): - # Upgrade operations go here. Don't create your own engine; - # bind migrate_engine to your metadata - meta.bind = migrate_engine - try: - if not dialect.startswith('sqlite'): - ForeignKeyConstraint(columns=[vifs.c.instance_id], - refcolumns=[instances.c.id]).drop() - except Exception: - logging.error(_("foreign key constraint couldn't be removed")) - raise - - -def downgrade(migrate_engine): - # Operations to reverse the above upgrade go here. - meta.bind = migrate_engine - try: - if not dialect.startswith('sqlite'): - ForeignKeyConstraint(columns=[vifs.c.instance_id], - refcolumns=[instances.c.id]).create() - except Exception: - logging.error(_("foreign key constraint couldn't be added")) - raise diff --git a/nova/db/sqlalchemy/migrate_repo/versions/046_sqlite_downgrade.sql b/nova/db/sqlalchemy/migrate_repo/versions/046_sqlite_downgrade.sql deleted file mode 100644 index cf9afbb09..000000000 --- a/nova/db/sqlalchemy/migrate_repo/versions/046_sqlite_downgrade.sql +++ /dev/null @@ -1,47 +0,0 @@ -COMMIT; -BEGIN TRANSACTION; - CREATE TEMPORARY TABLE virtual_interfaces_backup ( - created_at DATETIME, - updated_at DATETIME, - deleted_at DATETIME, - deleted BOOLEAN, - id INTEGER NOT NULL, - address VARCHAR(255), - network_id INTEGER, - instance_id INTEGER NOT NULL, - uuid VARCHAR(36), - PRIMARY KEY (id) - ); - - INSERT INTO virtual_interfaces_backup - SELECT created_at, updated_at, deleted_at, deleted, id, address, - network_id, instance_id, uuid - FROM virtual_interfaces; - - DROP TABLE virtual_interfaces; - - CREATE TABLE virtual_interfaces ( - created_at DATETIME, - updated_at DATETIME, - deleted_at DATETIME, - deleted BOOLEAN, - id INTEGER NOT NULL, - address VARCHAR(255), - network_id INTEGER, - instance_id INTEGER NOT NULL, - uuid VARCHAR(36), - PRIMARY KEY (id), - FOREIGN KEY(network_id) REFERENCES networks (id), - FOREIGN KEY(instance_id) REFERENCES instances (id), - UNIQUE (address), - CHECK (deleted IN (0, 1)) - ); - - INSERT INTO virtual_interfaces - SELECT created_at, updated_at, deleted_at, deleted, id, address, - network_id, instance_id, uuid - FROM virtual_interfaces_backup; - - DROP TABLE virtual_interfaces_backup; - -COMMIT; diff --git a/nova/db/sqlalchemy/migrate_repo/versions/046_sqlite_upgrade.sql b/nova/db/sqlalchemy/migrate_repo/versions/046_sqlite_upgrade.sql deleted file mode 100644 index 2c0919f1d..000000000 --- a/nova/db/sqlalchemy/migrate_repo/versions/046_sqlite_upgrade.sql +++ /dev/null @@ -1,45 +0,0 @@ -BEGIN TRANSACTION; - CREATE TEMPORARY TABLE virtual_interfaces_backup ( - created_at DATETIME, - updated_at DATETIME, - deleted_at DATETIME, - deleted BOOLEAN, - id INTEGER NOT NULL, - address VARCHAR(255), - network_id INTEGER, - instance_id INTEGER NOT NULL, - uuid VARCHAR(36), - PRIMARY KEY (id) - ); - - INSERT INTO virtual_interfaces_backup - SELECT created_at, updated_at, deleted_at, deleted, id, address, - network_id, instance_id, uuid - FROM virtual_interfaces; - - DROP TABLE virtual_interfaces; - - CREATE TABLE virtual_interfaces ( - created_at DATETIME, - updated_at DATETIME, - deleted_at DATETIME, - deleted BOOLEAN, - id INTEGER NOT NULL, - address VARCHAR(255), - network_id INTEGER, - instance_id INTEGER NOT NULL, - uuid VARCHAR(36), - PRIMARY KEY (id), - FOREIGN KEY(network_id) REFERENCES networks (id), - UNIQUE (address), - CHECK (deleted IN (0, 1)) - ); - - INSERT INTO virtual_interfaces - SELECT created_at, updated_at, deleted_at, deleted, id, address, - network_id, instance_id, uuid - FROM virtual_interfaces_backup; - - DROP TABLE virtual_interfaces_backup; - -COMMIT; diff --git a/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py b/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py new file mode 100644 index 000000000..0f4a9b122 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py @@ -0,0 +1,57 @@ +# Copyright 2011 OpenStack LLC. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from sqlalchemy import dialect, Column, Integer, MetaData, Table +from migrate import ForeignKeyConstraint + +from nova import log as logging + + +meta = MetaData() + + +instances = Table('instances', meta, + Column('id', Integer(), primary_key=True, nullable=False), + ) + + +vifs = Table('vifs', meta, + Column('id', Integer(), primary_key=True, nullable=False), + Column('instance_id', Integer()), + ) + + +def upgrade(migrate_engine): + # Upgrade operations go here. Don't create your own engine; + # bind migrate_engine to your metadata + meta.bind = migrate_engine + try: + if not dialect.startswith('sqlite'): + ForeignKeyConstraint(columns=[vifs.c.instance_id], + refcolumns=[instances.c.id]).drop() + except Exception: + logging.error(_("foreign key constraint couldn't be removed")) + raise + + +def downgrade(migrate_engine): + # Operations to reverse the above upgrade go here. + meta.bind = migrate_engine + try: + if not dialect.startswith('sqlite'): + ForeignKeyConstraint(columns=[vifs.c.instance_id], + refcolumns=[instances.c.id]).create() + except Exception: + logging.error(_("foreign key constraint couldn't be added")) + raise diff --git a/nova/db/sqlalchemy/migrate_repo/versions/047_sqlite_downgrade.sql b/nova/db/sqlalchemy/migrate_repo/versions/047_sqlite_downgrade.sql new file mode 100644 index 000000000..cf9afbb09 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/047_sqlite_downgrade.sql @@ -0,0 +1,47 @@ +COMMIT; +BEGIN TRANSACTION; + CREATE TEMPORARY TABLE virtual_interfaces_backup ( + created_at DATETIME, + updated_at DATETIME, + deleted_at DATETIME, + deleted BOOLEAN, + id INTEGER NOT NULL, + address VARCHAR(255), + network_id INTEGER, + instance_id INTEGER NOT NULL, + uuid VARCHAR(36), + PRIMARY KEY (id) + ); + + INSERT INTO virtual_interfaces_backup + SELECT created_at, updated_at, deleted_at, deleted, id, address, + network_id, instance_id, uuid + FROM virtual_interfaces; + + DROP TABLE virtual_interfaces; + + CREATE TABLE virtual_interfaces ( + created_at DATETIME, + updated_at DATETIME, + deleted_at DATETIME, + deleted BOOLEAN, + id INTEGER NOT NULL, + address VARCHAR(255), + network_id INTEGER, + instance_id INTEGER NOT NULL, + uuid VARCHAR(36), + PRIMARY KEY (id), + FOREIGN KEY(network_id) REFERENCES networks (id), + FOREIGN KEY(instance_id) REFERENCES instances (id), + UNIQUE (address), + CHECK (deleted IN (0, 1)) + ); + + INSERT INTO virtual_interfaces + SELECT created_at, updated_at, deleted_at, deleted, id, address, + network_id, instance_id, uuid + FROM virtual_interfaces_backup; + + DROP TABLE virtual_interfaces_backup; + +COMMIT; diff --git a/nova/db/sqlalchemy/migrate_repo/versions/047_sqlite_upgrade.sql b/nova/db/sqlalchemy/migrate_repo/versions/047_sqlite_upgrade.sql new file mode 100644 index 000000000..2c0919f1d --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/047_sqlite_upgrade.sql @@ -0,0 +1,45 @@ +BEGIN TRANSACTION; + CREATE TEMPORARY TABLE virtual_interfaces_backup ( + created_at DATETIME, + updated_at DATETIME, + deleted_at DATETIME, + deleted BOOLEAN, + id INTEGER NOT NULL, + address VARCHAR(255), + network_id INTEGER, + instance_id INTEGER NOT NULL, + uuid VARCHAR(36), + PRIMARY KEY (id) + ); + + INSERT INTO virtual_interfaces_backup + SELECT created_at, updated_at, deleted_at, deleted, id, address, + network_id, instance_id, uuid + FROM virtual_interfaces; + + DROP TABLE virtual_interfaces; + + CREATE TABLE virtual_interfaces ( + created_at DATETIME, + updated_at DATETIME, + deleted_at DATETIME, + deleted BOOLEAN, + id INTEGER NOT NULL, + address VARCHAR(255), + network_id INTEGER, + instance_id INTEGER NOT NULL, + uuid VARCHAR(36), + PRIMARY KEY (id), + FOREIGN KEY(network_id) REFERENCES networks (id), + UNIQUE (address), + CHECK (deleted IN (0, 1)) + ); + + INSERT INTO virtual_interfaces + SELECT created_at, updated_at, deleted_at, deleted, id, address, + network_id, instance_id, uuid + FROM virtual_interfaces_backup; + + DROP TABLE virtual_interfaces_backup; + +COMMIT; -- cgit From ffddc029198b88d0a2cd42e6c5e9d21a6ad259fa Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Wed, 14 Sep 2011 13:47:11 -0500 Subject: get all the vifs --- nova/db/sqlalchemy/api.py | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 9fbd1b658..66f9a9f8f 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1047,6 +1047,17 @@ def virtual_interface_delete_by_instance(context, instance_id): virtual_interface_delete(context, vif_ref['id']) +@require_context +def virtual_interface_get_all(context): + """Get all vifs""" + session = get_session() + vif_refs = session.query(models.VirtualInterface).\ + options(joinedload('network')).\ + options(joinedload('fixed_ips')).\ + all() + return vif_refs + + ################### -- cgit From ee11a4661bb855c354ae567fd18b8b3274d05df8 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Wed, 14 Sep 2011 13:47:35 -0500 Subject: get all the vifs --- nova/db/api.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index c32189cc0..0db4622c9 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -460,6 +460,11 @@ def virtual_interface_delete_by_instance(context, instance_id): return IMPL.virtual_interface_delete_by_instance(context, instance_id) +def virtual_interface_get_all(context): + """Gets all virtual interfaces from the table,""" + return IMPL.virtual_interface_get_all(context) + + #################### -- cgit From 7e379f6a77f53ad4d6ddc98fbb30cd853933bb08 Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Wed, 14 Sep 2011 14:38:40 -0500 Subject: Initial pass at automatically confirming resizes after a given window. --- nova/db/api.py | 5 +++++ nova/db/sqlalchemy/api.py | 22 +++++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index a9d2dc065..53cdc42c2 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -321,6 +321,11 @@ def migration_get_by_instance_and_status(context, instance_uuid, status): status) +def migration_get_all_unconfirmed(context, confirm_window): + """Finds all unconfirmed migrations within the confirmation window.""" + return IMPL.migration_get_all_unconfirmed(context, confirm_window) + + #################### diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index e5a661c7f..58e6aef6e 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -15,9 +15,10 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -""" -Implementation of SQLAlchemy backend. -""" + +"""Implementation of SQLAlchemy backend.""" + +import datetime import re import warnings @@ -3194,6 +3195,21 @@ def migration_get_by_instance_and_status(context, instance_uuid, status): return result +@require_admin_context +def migration_get_all_unconfirmed(context, confirm_window, session=None): + confirm_window = datetime.datetime.utcnow() - datetime.timedelta( + seconds=confirm_window) + + if not session: + session = get_session() + + results = session.query(models.Migration).\ + filter(models.Migration.updated_at <= confirm_window).\ + filter_by(status="VERIFY_RESIZE").all() + + return results + + ################## -- cgit From e8a2a540e574ca2d242b9c2749c1f285498809e7 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Wed, 14 Sep 2011 17:11:21 -0500 Subject: fix up the filtering so it does not return duplicates if both the network and the db filters match --- nova/db/api.py | 4 ++-- nova/db/sqlalchemy/api.py | 24 +++++++++++++++--------- 2 files changed, 17 insertions(+), 11 deletions(-) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index 0db4622c9..10a85d273 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -503,10 +503,10 @@ def instance_get_all(context): return IMPL.instance_get_all(context) -def instance_get_all_by_filters(context, filters, instances=None): +def instance_get_all_by_filters(context, filters, instance_ids=None): """Get all instances that match all filters.""" return IMPL.instance_get_all_by_filters(context, filters, - instances=instances) + instance_ids=instance_ids) def instance_get_active_by_window(context, begin, end=None, project_id=None): diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 66f9a9f8f..d613602b2 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1201,7 +1201,7 @@ def instance_get_all(context): @require_context -def instance_get_all_by_filters(context, filters, instances=None): +def instance_get_all_by_filters(context, filters, instance_ids=None): """Return instances that match all filters. Deleted instances will be returned by default, unless there's a filter that says otherwise""" @@ -1277,15 +1277,21 @@ def instance_get_all_by_filters(context, filters, instances=None): query_prefix = _exact_match_filter(query_prefix, filter_name, filters.pop(filter_name)) + instances = query_prefix.all() + ids = [instance['id'] for instance in instances if instance['id']] + uuids = [instance['uuid'] for instance in instances if instance['uuid']] + + if instance_ids is None: + instance_ids = [] + # TODO(jkoelker): This is for ID or UUID compat - if instances is None: - instances = [] - elif isinstance(instances, types.StringType): - instances = [instance_get_by_uuid(context, instances)] - elif isinstance(instances, types.IntType): - instances = [instance_get(context, instances)] - - instances.extend(query_prefix.all()) + for instance_id in instance_ids: + if isinstance(instance_id, + types.StringType) and instance_id not in uuids: + instances.append(instance_get_by_uuid(context, instance_id)) + elif isinstance(instance_id, + types.IntType) and instance_id not in ids: + instances.append(instance_get(context, instance_id)) if not instances: return [] -- cgit From ae825c5aa9f3741402407c8d8d78a3b1941d1131 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Wed, 14 Sep 2011 17:36:19 -0500 Subject: 0 for the instance id is False ;) --- nova/db/sqlalchemy/api.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index d613602b2..65ea6aba4 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1278,7 +1278,8 @@ def instance_get_all_by_filters(context, filters, instance_ids=None): filters.pop(filter_name)) instances = query_prefix.all() - ids = [instance['id'] for instance in instances if instance['id']] + ids = [instance['id'] for instance in instances \ + if instance['id'] is not None] uuids = [instance['uuid'] for instance in instances if instance['uuid']] if instance_ids is None: -- cgit From 0e492344e49b21fd3e08ab5dcf631012044cef9c Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Thu, 15 Sep 2011 13:30:17 -0500 Subject: update db api for split filterings searches --- nova/db/api.py | 9 +++++++-- nova/db/sqlalchemy/api.py | 48 +++++++++++++++++++++++++++++++---------------- 2 files changed, 39 insertions(+), 18 deletions(-) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index 10a85d273..c8d7479eb 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -503,10 +503,10 @@ def instance_get_all(context): return IMPL.instance_get_all(context) -def instance_get_all_by_filters(context, filters, instance_ids=None): +def instance_get_all_by_filters(context, filters, instance_uuids=None): """Get all instances that match all filters.""" return IMPL.instance_get_all_by_filters(context, filters, - instance_ids=instance_ids) + instance_uuids=instance_uuids) def instance_get_active_by_window(context, begin, end=None, project_id=None): @@ -610,6 +610,11 @@ 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) + + ################### diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 65ea6aba4..dc99834e4 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1201,7 +1201,7 @@ def instance_get_all(context): @require_context -def instance_get_all_by_filters(context, filters, instance_ids=None): +def instance_get_all_by_filters(context, filters, instance_uuids=None): """Return instances that match all filters. Deleted instances will be returned by default, unless there's a filter that says otherwise""" @@ -1277,26 +1277,30 @@ def instance_get_all_by_filters(context, filters, instance_ids=None): query_prefix = _exact_match_filter(query_prefix, filter_name, filters.pop(filter_name)) - instances = query_prefix.all() - ids = [instance['id'] for instance in instances \ - if instance['id'] is not None] - uuids = [instance['uuid'] for instance in instances if instance['uuid']] + db_instances = query_prefix.all() + db_uuids = [instance['uuid'] for instance in db_instances \ + if instance['uuid']] - if instance_ids is None: - instance_ids = [] + if instance_uuids is None: + instance_uuids = [] - # TODO(jkoelker): This is for ID or UUID compat - for instance_id in instance_ids: - if isinstance(instance_id, - types.StringType) and instance_id not in uuids: - instances.append(instance_get_by_uuid(context, instance_id)) - elif isinstance(instance_id, - types.IntType) and instance_id not in ids: - instances.append(instance_get(context, instance_id)) + uuids = [] - if not instances: + # 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: 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.. @@ -1557,6 +1561,18 @@ def instance_get_actions(context, instance_id): all() +@require_context +def instance_get_uuids_by_ids(context, ids): + if not isinstance(ids, types.ListType): + return instance_get(context, ids)['uuid'] + 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] + + ################### -- cgit From 3929ab2f32de6db7fee0394e276a5ceeca356368 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Thu, 15 Sep 2011 13:44:29 -0500 Subject: build the query with the query builder --- nova/db/sqlalchemy/api.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index dc99834e4..8cc56c3f9 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1297,9 +1297,9 @@ def instance_get_all_by_filters(context, filters, instance_uuids=None): if not uuids: return [] - instances = session.query(models.Instance).\ - filter(models.Instance.uuid.in_(uuids)).\ - all() + instances = _build_instance_get(context, session=session).\ + 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 -- cgit From be156e9f2ac58706c7fd69df06cbd5259ec20675 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Thu, 15 Sep 2011 13:47:16 -0500 Subject: revert last change --- nova/db/sqlalchemy/api.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 8cc56c3f9..dc99834e4 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1297,9 +1297,9 @@ def instance_get_all_by_filters(context, filters, instance_uuids=None): if not uuids: return [] - instances = _build_instance_get(context, session=session).\ - filter(models.Instance.uuid.in_(uuids)).\ - all() + 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 -- cgit From af492993cefe514eba3f7569fdfccc3b25162ca8 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Thu, 15 Sep 2011 15:20:05 -0500 Subject: uhh dialect doesn't exist, beavis --- .../migrate_repo/versions/047_remove_instances_fk_from_vif.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py b/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py index 0f4a9b122..3ef09203b 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py @@ -12,7 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. -from sqlalchemy import dialect, Column, Integer, MetaData, Table +from sqlalchemy import Column, Integer, MetaData, Table from migrate import ForeignKeyConstraint from nova import log as logging @@ -36,6 +36,7 @@ def upgrade(migrate_engine): # Upgrade operations go here. Don't create your own engine; # bind migrate_engine to your metadata meta.bind = migrate_engine + dialect = migrate_engine.url.get_dialect().name try: if not dialect.startswith('sqlite'): ForeignKeyConstraint(columns=[vifs.c.instance_id], @@ -48,6 +49,7 @@ def upgrade(migrate_engine): def downgrade(migrate_engine): # Operations to reverse the above upgrade go here. meta.bind = migrate_engine + dialect = migrate_engine.url.get_dialect().name try: if not dialect.startswith('sqlite'): ForeignKeyConstraint(columns=[vifs.c.instance_id], -- cgit From 7151a76f31de9edb82df04daccdb9073d82e7535 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Thu, 15 Sep 2011 15:24:12 -0500 Subject: the table is the table for the reason its a table --- .../migrate_repo/versions/047_remove_instances_fk_from_vif.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py b/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py index 3ef09203b..1b32867fb 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py @@ -26,7 +26,7 @@ instances = Table('instances', meta, ) -vifs = Table('vifs', meta, +vifs = Table('virtual_interfaces', meta, Column('id', Integer(), primary_key=True, nullable=False), Column('instance_id', Integer()), ) -- cgit From 5675ac808e49845b91bca300a67ce4e9ad7f04c8 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Thu, 15 Sep 2011 15:43:32 -0500 Subject: well since sqlalchemy-migrate and sqlalchemy can't agree on what the FK is called, we fall back on just manually dropping it --- .../versions/047_remove_instances_fk_from_vif.py | 25 +++++++++++++++------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py b/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py index 1b32867fb..4b2b9cd9a 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py @@ -37,23 +37,32 @@ def upgrade(migrate_engine): # bind migrate_engine to your metadata meta.bind = migrate_engine dialect = migrate_engine.url.get_dialect().name + if dialect.startswith('sqlite'): + return + try: - if not dialect.startswith('sqlite'): - ForeignKeyConstraint(columns=[vifs.c.instance_id], - refcolumns=[instances.c.id]).drop() + ForeignKeyConstraint(columns=[vifs.c.instance_id], + refcolumns=[instances.c.id]).create() except Exception: - logging.error(_("foreign key constraint couldn't be removed")) - raise + try: + migrate_engine.execute("ALTER TABLE migrations DROP " \ + "FOREIGN KEY " \ + "`virtual_interfaces_ibfk_2`;") + except Exception: + logging.error(_("foreign key constraint couldn't be removed")) + raise def downgrade(migrate_engine): # Operations to reverse the above upgrade go here. meta.bind = migrate_engine dialect = migrate_engine.url.get_dialect().name + if dialect.startswith('sqlite'): + return + try: - if not dialect.startswith('sqlite'): - ForeignKeyConstraint(columns=[vifs.c.instance_id], - refcolumns=[instances.c.id]).create() + ForeignKeyConstraint(columns=[vifs.c.instance_id], + refcolumns=[instances.c.id]).create() except Exception: logging.error(_("foreign key constraint couldn't be added")) raise -- cgit From fea284a8c554cfcc3120fffdc710cc2cfc12c61d Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Thu, 15 Sep 2011 16:20:13 -0500 Subject: pep8 --- .../migrate_repo/versions/047_remove_instances_fk_from_vif.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py b/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py index 4b2b9cd9a..982ac9ffe 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py @@ -45,9 +45,9 @@ def upgrade(migrate_engine): refcolumns=[instances.c.id]).create() except Exception: try: - migrate_engine.execute("ALTER TABLE migrations DROP " \ - "FOREIGN KEY " \ - "`virtual_interfaces_ibfk_2`;") + migrate_engine.execute("ALTER TABLE migrations DROP " \ + "FOREIGN KEY " \ + "`virtual_interfaces_ibfk_2`;") except Exception: logging.error(_("foreign key constraint couldn't be removed")) raise -- cgit From 694ba0aa7f10601746e9fa6c07d9ffeea3f26850 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Thu, 15 Sep 2011 16:23:27 -0500 Subject: was trying to create the FK when Should have been dropping --- .../migrate_repo/versions/047_remove_instances_fk_from_vif.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py b/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py index 982ac9ffe..818925c32 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py @@ -42,7 +42,7 @@ def upgrade(migrate_engine): try: ForeignKeyConstraint(columns=[vifs.c.instance_id], - refcolumns=[instances.c.id]).create() + refcolumns=[instances.c.id]).drop() except Exception: try: migrate_engine.execute("ALTER TABLE migrations DROP " \ -- cgit From 1d2a5bd706736bff2e2d82ebeb813438493cea41 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Fri, 16 Sep 2011 14:28:57 +0200 Subject: Make sure grantee_group is eagerly loaded. --- nova/db/sqlalchemy/api.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index b99667afc..6c3c2d038 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -2790,12 +2790,14 @@ def security_group_rule_get_by_security_group(context, security_group_id, result = session.query(models.SecurityGroupIngressRule).\ filter_by(deleted=can_read_deleted(context)).\ filter_by(parent_group_id=security_group_id).\ + options(joinedload_all('grantee_group')).\ all() else: # TODO(vish): Join to group and check for project_id result = session.query(models.SecurityGroupIngressRule).\ filter_by(deleted=False).\ filter_by(parent_group_id=security_group_id).\ + options(joinedload_all('grantee_group')).\ all() return result -- cgit From bd8133c8a9ca39ae3bb66499975462ccec5f8ca8 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Mon, 19 Sep 2011 09:34:19 -0500 Subject: remove the polymorph --- nova/db/sqlalchemy/api.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 15dcc3e53..a119d813a 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1566,8 +1566,6 @@ def instance_get_actions(context, instance_id): @require_context def instance_get_uuids_by_ids(context, ids): - if not isinstance(ids, types.ListType): - return instance_get(context, ids)['uuid'] session = get_session() instances = session.query(models.Instance).\ filter(models.Instance.id.in_(ids)).\ -- cgit From f2d0001217ec51d323642a6dd1f8fc559702b5e3 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Mon, 19 Sep 2011 09:50:13 -0500 Subject: remove unused import --- nova/db/sqlalchemy/api.py | 1 - 1 file changed, 1 deletion(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 9d8807489..c4bff8308 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -19,7 +19,6 @@ Implementation of SQLAlchemy backend. """ import re -import types import warnings from nova import block_device -- cgit From bd5a0a2bf42686efb81bb08de5d6938e2c076f0b Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Mon, 19 Sep 2011 11:10:50 -0500 Subject: Corrected the status in DB call. --- nova/db/sqlalchemy/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 779f20ae1..6fe46eb88 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -3210,7 +3210,7 @@ def migration_get_all_unconfirmed(context, confirm_window, session=None): results = session.query(models.Migration).\ filter(models.Migration.updated_at <= confirm_window).\ - filter_by(status="VERIFY_RESIZE").all() + filter_by(status="FINISHED").all() return results -- cgit 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/db/api.py | 13 ++++++------- nova/db/sqlalchemy/api.py | 40 ++++++++++++---------------------------- 2 files changed, 18 insertions(+), 35 deletions(-) (limited to 'nova/db') 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 ################### -- cgit From f8d62435f5171ab47aba7d966b2b8b0561c5f5ba Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Mon, 19 Sep 2011 17:27:25 -0500 Subject: run the alter on the right table --- .../migrate_repo/versions/047_remove_instances_fk_from_vif.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py b/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py index 818925c32..ae9486e58 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py @@ -45,7 +45,7 @@ def upgrade(migrate_engine): refcolumns=[instances.c.id]).drop() except Exception: try: - migrate_engine.execute("ALTER TABLE migrations DROP " \ + migrate_engine.execute("ALTER TABLE virtual_interfaces DROP " \ "FOREIGN KEY " \ "`virtual_interfaces_ibfk_2`;") except Exception: -- cgit From 869b0724e897d75695c2a1a559d1447745f9dce8 Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Mon, 19 Sep 2011 22:04:32 -0400 Subject: Update migration 047 to dynamically lookup the name of the instance_id fkey before dropping it. We can't hard code the name of the fkey since we didn't name it explicitly on create. --- .../versions/047_remove_instances_fk_from_vif.py | 32 ++++++++-------------- 1 file changed, 12 insertions(+), 20 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py b/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py index ae9486e58..dadcefc39 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py @@ -17,21 +17,9 @@ from migrate import ForeignKeyConstraint from nova import log as logging - meta = MetaData() -instances = Table('instances', meta, - Column('id', Integer(), primary_key=True, nullable=False), - ) - - -vifs = Table('virtual_interfaces', meta, - Column('id', Integer(), primary_key=True, nullable=False), - Column('instance_id', Integer()), - ) - - def upgrade(migrate_engine): # Upgrade operations go here. Don't create your own engine; # bind migrate_engine to your metadata @@ -40,17 +28,18 @@ def upgrade(migrate_engine): if dialect.startswith('sqlite'): return + instances = Table('instances', meta, autoload=True) + vifs = Table('virtual_interfaces', meta, autoload=True) + try: + fkey_name = vifs.c.instance_id.foreign_keys[0].constraint.name ForeignKeyConstraint(columns=[vifs.c.instance_id], - refcolumns=[instances.c.id]).drop() + refcolumns=[instances.c.id], + name=fkey_name).drop() + except Exception: - try: - migrate_engine.execute("ALTER TABLE virtual_interfaces DROP " \ - "FOREIGN KEY " \ - "`virtual_interfaces_ibfk_2`;") - except Exception: - logging.error(_("foreign key constraint couldn't be removed")) - raise + logging.error(_("foreign key constraint couldn't be removed")) + raise def downgrade(migrate_engine): @@ -60,6 +49,9 @@ def downgrade(migrate_engine): if dialect.startswith('sqlite'): return + instances = Table('instances', meta, autoload=True) + vifs = Table('virtual_interfaces', meta, autoload=True) + try: ForeignKeyConstraint(columns=[vifs.c.instance_id], refcolumns=[instances.c.id]).create() -- cgit