diff options
| author | Jenkins <jenkins@review.openstack.org> | 2012-07-26 21:50:36 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2012-07-26 21:50:36 +0000 |
| commit | 66f9e085aae73ecfbf9ac3a1447917fa99d8a606 (patch) | |
| tree | dcb53582c55d51e634c8d55bc03943dc91e8f6e4 /nova/db | |
| parent | c8ee0c36e5e25c95403e2a49e989c2fcf447f7ff (diff) | |
| parent | fc82c6dbbd0fa1cdc130cefea534967e273d5570 (diff) | |
Merge "Convert fixed_ips to using instance_uuid."
Diffstat (limited to 'nova/db')
| -rw-r--r-- | nova/db/api.py | 17 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/api.py | 60 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/migrate_repo/versions/106_add_foreign_keys.py | 2 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/migrate_repo/versions/113_fixed_ips_uses_uuid.py | 108 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/migrate_repo/versions/113_sqlite_downgrade.sql | 85 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/migrate_repo/versions/113_sqlite_upgrade.sql | 85 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/models.py | 2 |
7 files changed, 327 insertions, 32 deletions
diff --git a/nova/db/api.py b/nova/db/api.py index 4e7f61208..6e99ad636 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -418,25 +418,26 @@ def migration_get_all_unconfirmed(context, confirm_window): #################### -def fixed_ip_associate(context, address, instance_id, network_id=None, +def fixed_ip_associate(context, address, instance_uuid, 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_uuid, network_id, reserved) -def fixed_ip_associate_pool(context, network_id, instance_id=None, host=None): +def fixed_ip_associate_pool(context, network_id, instance_uuid=None, + host=None): """Find free ip in network and associate it to instance or host. Raises if one is not available. """ return IMPL.fixed_ip_associate_pool(context, network_id, - instance_id, host) + instance_uuid, host) def fixed_ip_create(context, values): @@ -474,14 +475,14 @@ def fixed_ip_get_by_address(context, address): return IMPL.fixed_ip_get_by_address(context, address) -def fixed_ip_get_by_instance(context, instance_id): +def fixed_ip_get_by_instance(context, instance_uuid): """Get fixed ips by instance or raise if none exist.""" - return IMPL.fixed_ip_get_by_instance(context, instance_id) + return IMPL.fixed_ip_get_by_instance(context, instance_uuid) -def fixed_ip_get_by_network_host(context, network_id, host): +def fixed_ip_get_by_network_host(context, network_uuid, host): """Get fixed ip for a host in a network.""" - return IMPL.fixed_ip_get_by_network_host(context, network_id, host) + return IMPL.fixed_ip_get_by_network_host(context, network_uuid, host) def fixed_ips_by_virtual_interface(context, vif_id): diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 6d002b5db..ac56e5983 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -993,12 +993,15 @@ def dnsdomain_list(context): @require_admin_context -def fixed_ip_associate(context, address, instance_id, network_id=None, +def fixed_ip_associate(context, address, instance_uuid, network_id=None, reserved=False): """Keyword arguments: reserved -- should be a boolean value(True or False), exact value will be used to filter on the fixed ip address """ + if not utils.is_uuid_like(instance_uuid): + raise exception.InvalidUUID(uuid=instance_uuid) + session = get_session() with session.begin(): network_or_none = or_(models.FixedIp.network_id == network_id, @@ -1015,18 +1018,22 @@ def fixed_ip_associate(context, address, instance_id, network_id=None, if fixed_ip_ref is None: raise exception.FixedIpNotFoundForNetwork(address=address, network_id=network_id) - if fixed_ip_ref.instance_id: + if fixed_ip_ref.instance_uuid: raise exception.FixedIpAlreadyInUse(address=address) if not fixed_ip_ref.network_id: fixed_ip_ref.network_id = network_id - fixed_ip_ref.instance_id = instance_id + fixed_ip_ref.instance_uuid = instance_uuid session.add(fixed_ip_ref) return fixed_ip_ref['address'] @require_admin_context -def fixed_ip_associate_pool(context, network_id, instance_id=None, host=None): +def fixed_ip_associate_pool(context, network_id, instance_uuid=None, + host=None): + if not utils.is_uuid_like(instance_uuid): + raise exception.InvalidUUID(uuid=instance_uuid) + session = get_session() with session.begin(): network_or_none = or_(models.FixedIp.network_id == network_id, @@ -1035,7 +1042,7 @@ def fixed_ip_associate_pool(context, network_id, instance_id=None, host=None): read_deleted="no").\ filter(network_or_none).\ filter_by(reserved=False).\ - filter_by(instance_id=None).\ + filter_by(instance_uuid=None).\ filter_by(host=None).\ with_lockmode('update').\ first() @@ -1047,8 +1054,8 @@ def fixed_ip_associate_pool(context, network_id, instance_id=None, host=None): if fixed_ip_ref['network_id'] is None: fixed_ip_ref['network'] = network_id - if instance_id: - fixed_ip_ref['instance_id'] = instance_id + if instance_uuid: + fixed_ip_ref['instance_uuid'] = instance_uuid if host: fixed_ip_ref['host'] = host @@ -1081,7 +1088,7 @@ def fixed_ip_disassociate(context, address): fixed_ip_ref = fixed_ip_get_by_address(context, address, session=session) - fixed_ip_ref['instance_id'] = None + fixed_ip_ref['instance_uuid'] = None fixed_ip_ref.save(session=session) @@ -1102,7 +1109,8 @@ def fixed_ip_disassociate_all_by_timeout(context, host, time): join((models.Network, models.Network.id == models.FixedIp.network_id)).\ join((models.Instance, - models.Instance.id == models.FixedIp.instance_id)).\ + models.Instance.uuid == \ + models.FixedIp.instance_uuid)).\ filter(host_filter).\ all() fixed_ip_ids = [fip[0] for fip in result] @@ -1110,7 +1118,7 @@ def fixed_ip_disassociate_all_by_timeout(context, host, time): return 0 result = model_query(context, models.FixedIp, session=session).\ filter(models.FixedIp.id.in_(fixed_ip_ids)).\ - update({'instance_id': None, + update({'instance_uuid': None, 'leased': False, 'updated_at': timeutils.utcnow()}, synchronize_session='fetch') @@ -1127,8 +1135,9 @@ def fixed_ip_get(context, id, session=None): # FIXME(sirp): shouldn't we just use project_only here to restrict the # results? - if is_user_context(context) and result['instance_id'] is not None: - instance = instance_get(context, result['instance_id'], session) + if is_user_context(context) and result['instance_uuid'] is not None: + instance = instance_get_by_uuid(context, result['instance_uuid'], + session) authorize_project_context(context, instance.project_id) return result @@ -1155,21 +1164,25 @@ def fixed_ip_get_by_address(context, address, session=None): # NOTE(sirp): shouldn't we just use project_only here to restrict the # results? - if is_user_context(context) and result['instance_id'] is not None: - instance = instance_get(context, result['instance_id'], session) + if is_user_context(context) and result['instance_uuid'] is not None: + instance = instance_get_by_uuid(context, result['instance_uuid'], + session) authorize_project_context(context, instance.project_id) return result @require_context -def fixed_ip_get_by_instance(context, instance_id): +def fixed_ip_get_by_instance(context, instance_uuid): + if not utils.is_uuid_like(instance_uuid): + raise exception.InvalidUUID(uuid=instance_uuid) + result = model_query(context, models.FixedIp, read_deleted="no").\ - filter_by(instance_id=instance_id).\ + filter_by(instance_uuid=instance_uuid).\ all() if not result: - raise exception.FixedIpNotFoundForInstance(instance_id=instance_id) + raise exception.FixedIpNotFoundForInstance(instance_uuid=instance_uuid) return result @@ -1671,9 +1684,12 @@ def instance_get_all_by_reservation(context, reservation_id): # go away @require_context def instance_get_floating_address(context, instance_id): - fixed_ips = fixed_ip_get_by_instance(context, instance_id) + instance = instance_get(context, instance_id) + fixed_ips = fixed_ip_get_by_instance(context, instance['uuid']) + if not fixed_ips: return None + # NOTE(tr3buchet): this only gets the first fixed_ip # won't find floating ips associated with other fixed_ips floating_ips = floating_ip_get_by_fixed_address(context, @@ -2136,11 +2152,11 @@ def network_get_associated_fixed_ips(context, network_id, host=None): 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, + inst_and = and_(models.Instance.uuid == models.FixedIp.instance_uuid, models.Instance.deleted == False) session = get_session() query = session.query(models.FixedIp.address, - models.FixedIp.instance_id, + models.FixedIp.instance_uuid, models.FixedIp.network_id, models.FixedIp.virtual_interface_id, models.VirtualInterface.address, @@ -2152,7 +2168,7 @@ def network_get_associated_fixed_ips(context, network_id, host=None): filter(models.FixedIp.allocated == True).\ join((models.VirtualInterface, vif_and)).\ join((models.Instance, inst_and)).\ - filter(models.FixedIp.instance_id != None).\ + filter(models.FixedIp.instance_uuid != None).\ filter(models.FixedIp.virtual_interface_id != None) if host: query = query.filter(models.Instance.host == host) @@ -2161,7 +2177,7 @@ def network_get_associated_fixed_ips(context, network_id, host=None): for datum in result: cleaned = {} cleaned['address'] = datum[0] - cleaned['instance_id'] = datum[1] + cleaned['instance_uuid'] = datum[1] cleaned['network_id'] = datum[2] cleaned['vif_id'] = datum[3] cleaned['vif_address'] = datum[4] diff --git a/nova/db/sqlalchemy/migrate_repo/versions/106_add_foreign_keys.py b/nova/db/sqlalchemy/migrate_repo/versions/106_add_foreign_keys.py index 8d867609c..2874b4042 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/106_add_foreign_keys.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/106_add_foreign_keys.py @@ -64,5 +64,5 @@ def downgrade(migrate_engine): columns=[t.c.instance_uuid], refcolumns=[instances.c.uuid]).drop() except Exception: - LOG.error(_("foreign key constraint couldn't be created")) + LOG.error(_("foreign key constraint couldn't be dropped")) raise diff --git a/nova/db/sqlalchemy/migrate_repo/versions/113_fixed_ips_uses_uuid.py b/nova/db/sqlalchemy/migrate_repo/versions/113_fixed_ips_uses_uuid.py new file mode 100644 index 000000000..d51bbb912 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/113_fixed_ips_uses_uuid.py @@ -0,0 +1,108 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# Copyright 2012 Michael Still and Canonical Inc +# All Rights Reserved. +# +# 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 migrate import ForeignKeyConstraint +from sqlalchemy import MetaData, String, Table +from sqlalchemy import select, Column, ForeignKey, Integer + +from nova.openstack.common import log as logging + + +LOG = logging.getLogger(__name__) + + +def upgrade(migrate_engine): + meta = MetaData() + meta.bind = migrate_engine + fixed_ips = Table('fixed_ips', meta, autoload=True) + instances = Table('instances', meta, autoload=True) + uuid_column = Column('instance_uuid', String(36)) + uuid_column.create(fixed_ips) + + try: + fixed_ips.update().values( + instance_uuid=select( + [instances.c.uuid], + instances.c.id == fixed_ips.c.instance_id) + ).execute() + except Exception: + uuid_column.drop() + raise + + fkeys = list(fixed_ips.c.instance_id.foreign_keys) + if fkeys: + try: + fkey_name = fkeys[0].constraint.name + ForeignKeyConstraint( + columns=[fixed_ips.c.instance_id], + refcolumns=[instances.c.id], + name=fkey_name).drop() + except Exception: + LOG.error(_("foreign key constraint couldn't be removed")) + raise + + fixed_ips.c.instance_id.drop() + + try: + ForeignKeyConstraint( + columns=[fixed_ips.c.instance_uuid], + refcolumns=[instances.c.uuid]).create() + except Exception: + LOG.error(_("foreign key constraint couldn't be created")) + raise + + +def downgrade(migrate_engine): + meta = MetaData() + meta.bind = migrate_engine + fixed_ips = Table('fixed_ips', meta, autoload=True) + instances = Table('instances', meta, autoload=True) + id_column = Column('instance_id', Integer, ForeignKey('instances.id')) + id_column.create(fixed_ips) + + fkeys = list(fixed_ips.c.instance_uuid.foreign_keys) + if fkeys: + try: + fkey_name = fkeys[0].constraint.name + ForeignKeyConstraint( + columns=[fixed_ips.c.instance_uuid], + refcolumns=[instances.c.uuid], + name=fkey_name).drop() + except Exception: + LOG.error(_("foreign key constraint couldn't be removed")) + raise + + try: + fixed_ips.update().values( + instance_id=select( + [instances.c.id], + instances.c.uuid == fixed_ips.c.instance_uuid) + ).execute() + except Exception: + id_column.drop() + raise + + fixed_ips.c.instance_uuid.drop() + + try: + ForeignKeyConstraint( + columns=[fixed_ips.c.instance_id], + refcolumns=[instances.c.id]).create() + except Exception: + LOG.error(_("foreign key constraint couldn't be created")) + raise diff --git a/nova/db/sqlalchemy/migrate_repo/versions/113_sqlite_downgrade.sql b/nova/db/sqlalchemy/migrate_repo/versions/113_sqlite_downgrade.sql new file mode 100644 index 000000000..0a7a7bed9 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/113_sqlite_downgrade.sql @@ -0,0 +1,85 @@ +BEGIN TRANSACTION; + CREATE TEMPORARY TABLE fixed_ips_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, + instance_uuid VARCHAR(36), + allocated BOOLEAN, + leased BOOLEAN, + reserved BOOLEAN, + virtual_interface_id INTEGER, + host VARCHAR(255), + PRIMARY KEY (id) + ); + + INSERT INTO fixed_ips_backup + SELECT created_at, + updated_at, + deleted_at, + deleted, + id, + address, + network_id, + NULL, + instance_uuid, + allocated, + leased, + reserved, + virtual_interface_id, + host + FROM fixed_ips; + + UPDATE fixed_ips_backup + SET instance_id= + (SELECT id + FROM instances + WHERE fixed_ips_backup.instance_uuid = instances.uuid + ); + + DROP TABLE fixed_ips; + + CREATE TABLE fixed_ips ( + created_at DATETIME, + updated_at DATETIME, + deleted_at DATETIME, + deleted BOOLEAN, + id INTEGER NOT NULL, + address VARCHAR(255), + network_id INTEGER, + instance_id INTEGER, + allocated BOOLEAN, + leased BOOLEAN, + reserved BOOLEAN, + virtual_interface_id INTEGER, + host VARCHAR(255), + PRIMARY KEY (id), + FOREIGN KEY(instance_id) REFERENCES instances (id) + ); + + CREATE INDEX fixed_ips_id ON fixed_ips(id); + CREATE INDEX address ON fixed_ips(address); + + INSERT INTO fixed_ips + SELECT created_at, + updated_at, + deleted_at, + deleted, + id, + address, + network_id, + instance_id, + allocated, + leased, + reserved, + virtual_interface_id, + host + FROM fixed_ips_backup; + + DROP TABLE fixed_ips_backup; + +COMMIT;
\ No newline at end of file diff --git a/nova/db/sqlalchemy/migrate_repo/versions/113_sqlite_upgrade.sql b/nova/db/sqlalchemy/migrate_repo/versions/113_sqlite_upgrade.sql new file mode 100644 index 000000000..417b5bfe3 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/113_sqlite_upgrade.sql @@ -0,0 +1,85 @@ +BEGIN TRANSACTION; + CREATE TEMPORARY TABLE fixed_ips_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, + instance_uuid VARCHAR(36), + allocated BOOLEAN, + leased BOOLEAN, + reserved BOOLEAN, + virtual_interface_id INTEGER, + host VARCHAR(255), + PRIMARY KEY (id) + ); + + INSERT INTO fixed_ips_backup + SELECT created_at, + updated_at, + deleted_at, + deleted, + id, + address, + network_id, + instance_id, + NULL, + allocated, + leased, + reserved, + virtual_interface_id, + host + FROM fixed_ips; + + UPDATE fixed_ips_backup + SET instance_uuid= + (SELECT uuid + FROM instances + WHERE fixed_ips_backup.instance_id = instances.id + ); + + DROP TABLE fixed_ips; + + CREATE TABLE fixed_ips ( + created_at DATETIME, + updated_at DATETIME, + deleted_at DATETIME, + deleted BOOLEAN, + id INTEGER NOT NULL, + address VARCHAR(255), + network_id INTEGER, + instance_uuid VARCHAR(36), + allocated BOOLEAN, + leased BOOLEAN, + reserved BOOLEAN, + virtual_interface_id INTEGER, + host VARCHAR(255), + PRIMARY KEY (id), + FOREIGN KEY(instance_uuid) REFERENCES instances (uuid) + ); + + CREATE INDEX fixed_ips_id ON fixed_ips(id); + CREATE INDEX address ON fixed_ips(address); + + INSERT INTO fixed_ips + SELECT created_at, + updated_at, + deleted_at, + deleted, + id, + address, + network_id, + instance_uuid, + allocated, + leased, + reserved, + virtual_interface_id, + host + FROM fixed_ips_backup; + + DROP TABLE fixed_ips_backup; + +COMMIT; diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 5f7e85511..21644ce18 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -717,7 +717,7 @@ class FixedIp(BASE, NovaBase): address = Column(String(255)) network_id = Column(Integer, nullable=True) virtual_interface_id = Column(Integer, nullable=True) - instance_id = Column(Integer, nullable=True) + instance_uuid = Column(String(36), nullable=True) # associated means that a fixed_ip has its instance_id column set # allocated means that a fixed_ip has its virtual_interface_id column set allocated = Column(Boolean, default=False) |
