diff options
| author | Rick Harris <rconradharris@gmail.com> | 2011-09-21 03:33:55 +0000 |
|---|---|---|
| committer | Rick Harris <rconradharris@gmail.com> | 2011-09-21 03:33:55 +0000 |
| commit | 9e1f1f91c3c66febcb2d624d32d2a3639f0d0598 (patch) | |
| tree | c599e9e42876e893d7674e61902c1b3e71b26010 /nova/db | |
| parent | 827d3593452c2892d5076fb0d2548b73a39ab262 (diff) | |
| parent | 67420a537ba6bdf19aaada3ca25be30559965742 (diff) | |
Merging trunk
Diffstat (limited to 'nova/db')
| -rw-r--r-- | nova/db/api.py | 15 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/api.py | 123 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py | 60 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/migrate_repo/versions/047_sqlite_downgrade.sql | 47 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/migrate_repo/versions/047_sqlite_upgrade.sql | 45 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/models.py | 5 |
6 files changed, 215 insertions, 80 deletions
diff --git a/nova/db/api.py b/nova/db/api.py index 05d81d8b2..8c4c78374 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -323,6 +323,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) + + #################### @@ -462,6 +467,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) + + #################### @@ -606,6 +616,11 @@ def instance_get_actions(context, instance_id): return IMPL.instance_get_actions(context, instance_id) +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 a46037fba..447dbec22 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 @@ -930,7 +931,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 @@ -946,7 +946,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 @@ -962,7 +961,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 @@ -978,7 +976,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 @@ -995,7 +992,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 @@ -1010,7 +1006,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 @@ -1026,7 +1021,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 @@ -1056,6 +1050,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 + + ################### @@ -1172,7 +1177,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')).\ @@ -1191,10 +1195,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')).\ @@ -1209,27 +1209,6 @@ def instance_get_all_by_filters(context, filters): 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']] @@ -1256,7 +1235,7 @@ def instance_get_all_by_filters(context, filters): """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: @@ -1266,13 +1245,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)) @@ -1296,7 +1269,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', - '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] @@ -1308,15 +1281,13 @@ def instance_get_all_by_filters(context, filters): filters.pop(filter_name)) instances = query_prefix.all() - if not instances: return [] # 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) @@ -1330,6 +1301,8 @@ def instance_get_all_by_filters(context, filters): filter_l = lambda instance: _regexp_filter_by_column(instance, filter_name, filter_re) instances = filter(filter_l, instances) + if not instances: + break return instances @@ -1376,7 +1349,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')).\ @@ -1391,7 +1363,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')).\ @@ -1408,7 +1379,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')).\ @@ -1424,7 +1394,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')).\ @@ -1441,36 +1410,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')).\ @@ -1602,6 +1546,18 @@ def instance_get_actions(context, instance_id): all() +@require_context +def instance_get_id_to_uuid_mapping(context, ids): + session = get_session() + instances = session.query(models.Instance).\ + filter(models.Instance.id.in_(ids)).\ + all() + mapping = {} + for instance in instances: + mapping[instance['id']] = instance['uuid'] + return mapping + + ################### @@ -3199,6 +3155,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="FINISHED").all() + + return results + + ################## 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..dadcefc39 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py @@ -0,0 +1,60 @@ +# 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 Column, Integer, MetaData, Table +from migrate import ForeignKeyConstraint + +from nova import log as logging + +meta = MetaData() + + +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 + 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], + name=fkey_name).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 + dialect = migrate_engine.url.get_dialect().name + 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() + 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; diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index b5f30a1e3..089cd5450 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -642,10 +642,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)) |
