summaryrefslogtreecommitdiffstats
path: root/nova/db
diff options
context:
space:
mode:
authorChris Behrens <cbehrens@codestud.com>2011-09-21 09:00:18 +0000
committerChris Behrens <cbehrens@codestud.com>2011-09-21 09:00:18 +0000
commita63ca427e75c73611dd129bc7b5a625f6c06fa44 (patch)
treed80bef65fe63bb45fbf201f0c0475d3d699fa045 /nova/db
parent4d0bb8730a076b44d0a37fd0770c743b834e5751 (diff)
parentd9752d46554ffa87360bfd740177b40871cfbea6 (diff)
downloadnova-a63ca427e75c73611dd129bc7b5a625f6c06fa44.tar.gz
nova-a63ca427e75c73611dd129bc7b5a625f6c06fa44.tar.xz
nova-a63ca427e75c73611dd129bc7b5a625f6c06fa44.zip
Merged trunk
Diffstat (limited to 'nova/db')
-rw-r--r--nova/db/api.py29
-rw-r--r--nova/db/sqlalchemy/api.py139
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/046_add_instance_swap.py48
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/047_remove_instances_fk_from_vif.py60
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/047_sqlite_downgrade.sql47
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/047_sqlite_upgrade.sql45
-rw-r--r--nova/db/sqlalchemy/models.py7
7 files changed, 287 insertions, 88 deletions
diff --git a/nova/db/api.py b/nova/db/api.py
index c03a86671..8c4c78374 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):
@@ -321,16 +323,23 @@ 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)
+
+
####################
-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):
@@ -365,7 +374,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):
@@ -458,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)
+
+
####################
@@ -602,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 6aebe22f6..aa9fbda75 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
@@ -529,7 +530,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():
floating_ip_ref = floating_ip_get_by_address(context,
@@ -539,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)
@@ -578,6 +581,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
@@ -670,14 +674,19 @@ 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):
+ """Keyword arguments:
+ reserved -- should be a boolean value(True or False), exact value will be
+ used to filter on the fixed ip address
+ """
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').\
@@ -923,7 +932,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
@@ -939,7 +947,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
@@ -955,7 +962,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
@@ -971,7 +977,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
@@ -988,7 +993,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
@@ -1003,7 +1007,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
@@ -1019,7 +1022,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
@@ -1049,6 +1051,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
+
+
###################
@@ -1165,7 +1178,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')).\
@@ -1184,10 +1196,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')).\
@@ -1202,27 +1210,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']]
@@ -1249,7 +1236,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:
@@ -1259,13 +1246,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))
@@ -1289,7 +1270,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]
@@ -1301,15 +1282,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)
@@ -1323,6 +1302,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
@@ -1369,7 +1350,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')).\
@@ -1384,7 +1364,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')).\
@@ -1401,7 +1380,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')).\
@@ -1417,7 +1395,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')).\
@@ -1434,36 +1411,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')).\
@@ -1595,6 +1547,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
+
+
###################
@@ -2820,12 +2784,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
@@ -3190,6 +3156,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/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/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 211049112..089cd5450 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
@@ -640,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))