summaryrefslogtreecommitdiffstats
path: root/nova/db
diff options
context:
space:
mode:
authorMichael Still <mikal@stillhq.com>2012-07-04 14:42:08 +1000
committerMichael Still <mikal@stillhq.com>2012-07-26 21:22:04 +1000
commitfc82c6dbbd0fa1cdc130cefea534967e273d5570 (patch)
treedb0df1ad88ae8eab2f6911de0e63ce13341d351d /nova/db
parente238e07692c747ddcb0c70452578a812836cea67 (diff)
Convert fixed_ips to using instance_uuid.
This should be the second last blueprint finish-uuid-conversion change. Change-Id: Idd47c5ed3c30af24d60eb23b8e3881d61b4c7976
Diffstat (limited to 'nova/db')
-rw-r--r--nova/db/api.py17
-rw-r--r--nova/db/sqlalchemy/api.py60
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/106_add_foreign_keys.py2
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/113_fixed_ips_uses_uuid.py108
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/113_sqlite_downgrade.sql85
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/113_sqlite_upgrade.sql85
-rw-r--r--nova/db/sqlalchemy/models.py2
7 files changed, 327 insertions, 32 deletions
diff --git a/nova/db/api.py b/nova/db/api.py
index 231df02f2..cf87e672c 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)