summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MANIFEST.in1
-rwxr-xr-xbin/nova-manage100
-rw-r--r--nova/api/ec2/cloud.py2
-rw-r--r--nova/compute/manager.py118
-rw-r--r--nova/db/api.py30
-rw-r--r--nova/db/migration.py38
-rw-r--r--nova/db/sqlalchemy/__init__.py28
-rw-r--r--nova/db/sqlalchemy/api.py64
-rw-r--r--nova/db/sqlalchemy/migrate_repo/README4
-rw-r--r--nova/db/sqlalchemy/migrate_repo/__init__.py0
-rw-r--r--nova/db/sqlalchemy/migrate_repo/manage.py4
-rw-r--r--nova/db/sqlalchemy/migrate_repo/migrate.cfg20
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/001_austin.py547
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/002_bexar.py209
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/__init__.py0
-rw-r--r--nova/db/sqlalchemy/migration.py72
-rw-r--r--nova/db/sqlalchemy/models.py71
-rw-r--r--nova/network/manager.py16
-rw-r--r--nova/scheduler/driver.py183
-rw-r--r--nova/scheduler/manager.py48
-rw-r--r--nova/service.py17
-rw-r--r--nova/tests/__init__.py5
-rw-r--r--nova/tests/fake_flags.py1
-rw-r--r--nova/virt/cpuinfo.xml.template9
-rw-r--r--nova/virt/fake.py32
-rw-r--r--nova/virt/libvirt_conn.py287
-rw-r--r--nova/virt/xenapi_conn.py30
-rw-r--r--nova/volume/driver.py30
-rw-r--r--nova/volume/manager.py12
-rw-r--r--run_tests.py2
-rw-r--r--setup.py1
-rw-r--r--tools/pip-requires1
32 files changed, 941 insertions, 1041 deletions
diff --git a/MANIFEST.in b/MANIFEST.in
index 199ce30b6..07e4dd516 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -12,6 +12,7 @@ include nova/cloudpipe/bootscript.sh
include nova/cloudpipe/client.ovpn.template
include nova/compute/fakevirtinstance.xml
include nova/compute/interfaces.template
+include nova/db/sqlalchemy/migrate_repo/migrate.cfg
include nova/virt/interfaces.template
include nova/virt/libvirt*.xml.template
include nova/tests/CA/
diff --git a/bin/nova-manage b/bin/nova-manage
index 654a13820..a347e86ce 100755
--- a/bin/nova-manage
+++ b/bin/nova-manage
@@ -62,7 +62,6 @@ import time
import IPy
-
# If ../nova/__init__.py exists, add ../ to Python search path, so that
# it will override what happens to be installed in /usr/(local/)lib/python...
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
@@ -84,9 +83,9 @@ from nova import rpc
from nova import utils
from nova.api.ec2.cloud import ec2_id_to_id
from nova.auth import manager
-from nova import rpc
from nova.cloudpipe import pipelib
-from nova.api.ec2 import cloud
+from nova.db import migration
+
logging.basicConfig()
FLAGS = flags.FLAGS
@@ -479,82 +478,6 @@ class NetworkCommands(object):
int(vpn_start), fixed_range_v6)
-class InstanceCommands(object):
- """Class for mangaging VM instances."""
-
- def live_migration(self, ec2_id, dest):
- """live_migration"""
-
- ctxt = context.get_admin_context()
- instance_id = cloud.ec2_id_to_id(ec2_id)
-
- if FLAGS.connection_type != 'libvirt':
- msg = _('Only KVM is supported for now. Sorry!')
- raise exception.Error(msg)
-
- if FLAGS.volume_driver != 'nova.volume.driver.AOEDriver':
- instance_ref = db.instance_get(ctxt, instance_id)
- if len(instance_ref['volumes']) != 0:
- msg = _(("""Volumes attached by ISCSIDriver"""
- """ are not supported. Sorry!"""))
- raise exception.Error(msg)
-
- rpc.call(ctxt,
- FLAGS.scheduler_topic,
- {"method": "live_migration",
- "args": {"instance_id": instance_id,
- "dest": dest,
- "topic": FLAGS.compute_topic}})
-
- msg = 'Migration of %s initiated. ' % ec2_id
- msg += 'Check its progress using euca-describe-instances.'
- print msg
-
-
-class HostCommands(object):
- """Class for mangaging host(physical nodes)."""
-
- def list(self):
- """describe host list."""
-
- # To supress msg: No handlers could be found for logger "amqplib"
- logging.basicConfig()
-
- service_refs = db.service_get_all(context.get_admin_context())
- hosts = [h['host'] for h in service_refs]
- hosts = list(set(hosts))
- for host in hosts:
- print host
-
- def show(self, host):
- """describe cpu/memory/hdd info for host."""
-
- result = rpc.call(context.get_admin_context(),
- FLAGS.scheduler_topic,
- {"method": "show_host_resource",
- "args": {"host": host}})
-
- # Checking result msg format is necessary, that will have done
- # when this feture is included in API.
- if type(result) != dict:
- print 'Unexpected error occurs'
- elif not result['ret']:
- print '%s' % result['msg']
- else:
- cpu = result['phy_resource']['vcpus']
- mem = result['phy_resource']['memory_mb']
- hdd = result['phy_resource']['local_gb']
-
- print 'HOST\t\tPROJECT\t\tcpu\tmem(mb)\tdisk(gb)'
- print '%s\t\t\t%s\t%s\t%s' % (host, cpu, mem, hdd)
- for p_id, val in result['usage'].items():
- print '%s\t%s\t\t%s\t%s\t%s' % (host,
- p_id,
- val['vcpus'],
- val['memory_mb'],
- val['local_gb'])
-
-
class ServiceCommands(object):
"""Enable and disable running services"""
@@ -609,6 +532,21 @@ class LogCommands(object):
print re.sub('#012', "\n", "\n".join(lines))
+class DbCommands(object):
+ """Class for managing the database."""
+
+ def __init__(self):
+ pass
+
+ def sync(self, version=None):
+ """Sync the database up to the most recent version."""
+ return migration.db_sync(version)
+
+ def version(self):
+ """Print the current database version."""
+ print migration.db_version()
+
+
class VolumeCommands(object):
"""Methods for dealing with a cloud in an odd state"""
@@ -648,6 +586,7 @@ class VolumeCommands(object):
"volume_id": volume['id'],
"mountpoint": volume['mountpoint']}})
+
CATEGORIES = [
('user', UserCommands),
('project', ProjectCommands),
@@ -656,10 +595,9 @@ CATEGORIES = [
('vpn', VpnCommands),
('floating', FloatingIpCommands),
('network', NetworkCommands),
- ('instance', InstanceCommands),
- ('host', HostCommands),
('service', ServiceCommands),
('log', LogCommands),
+ ('db', DbCommands),
('volume', VolumeCommands)]
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py
index c94540793..57d41ed67 100644
--- a/nova/api/ec2/cloud.py
+++ b/nova/api/ec2/cloud.py
@@ -729,7 +729,7 @@ class CloudController(object):
ec2_id = None
if (floating_ip_ref['fixed_ip']
and floating_ip_ref['fixed_ip']['instance']):
- instance_id = floating_ip_ref['fixed_ip']['instance']['id']
+ instance_id = floating_ip_ref['fixed_ip']['instance']['ec2_id']
ec2_id = id_to_ec2_id(instance_id)
address_rv = {'public_ip': address,
'instance_id': ec2_id}
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index efb5753aa..6f09ce674 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -41,7 +41,6 @@ import logging
import socket
import functools
-from nova import db
from nova import exception
from nova import flags
from nova import log as logging
@@ -121,35 +120,6 @@ class ComputeManager(manager.Manager):
"""
self.driver.init_host()
- def update_service(self, ctxt, host, binary):
- """Insert compute node specific information to DB."""
-
- try:
- service_ref = db.service_get_by_args(ctxt,
- host,
- binary)
- except exception.NotFound:
- msg = _(("""Cannot insert compute manager specific info"""
- """Because no service record found."""))
- raise exception.Invalid(msg)
-
- # Updating host information
- vcpu = self.driver.get_vcpu_number()
- memory_mb = self.driver.get_memory_mb()
- local_gb = self.driver.get_local_gb()
- hypervisor = self.driver.get_hypervisor_type()
- version = self.driver.get_hypervisor_version()
- cpu_info = self.driver.get_cpu_info()
-
- db.service_update(ctxt,
- service_ref['id'],
- {'vcpus': vcpu,
- 'memory_mb': memory_mb,
- 'local_gb': local_gb,
- 'hypervisor_type': hypervisor,
- 'hypervisor_version': version,
- 'cpu_info': cpu_info})
-
def _update_state(self, context, instance_id):
"""Update the state of an instance from the driver info."""
# FIXME(ja): include other fields from state?
@@ -208,10 +178,9 @@ class ComputeManager(manager.Manager):
raise exception.Error(_("Instance has already been created"))
LOG.audit(_("instance %s: starting..."), instance_id,
context=context)
-
self.db.instance_update(context,
instance_id,
- {'host': self.host, 'launched_on': self.host})
+ {'host': self.host})
self.db.instance_set_state(context,
instance_id,
@@ -591,88 +560,3 @@ class ComputeManager(manager.Manager):
self.volume_manager.remove_compute_volume(context, volume_id)
self.db.volume_detached(context, volume_id)
return True
-
- def compare_cpu(self, context, cpu_info):
- """ Check the host cpu is compatible to a cpu given by xml."""
- return self.driver.compare_cpu(cpu_info)
-
- def pre_live_migration(self, context, instance_id, dest):
- """Any preparation for live migration at dst host."""
-
- # Getting instance info
- instance_ref = db.instance_get(context, instance_id)
- ec2_id = instance_ref['hostname']
-
- # Getting fixed ips
- fixed_ip = db.instance_get_fixed_address(context, instance_id)
- if not fixed_ip:
- msg = _('%s(%s) doesnt have fixed_ip') % (instance_id, ec2_id)
- raise exception.NotFound(msg)
-
- # If any volume is mounted, prepare here.
- if len(instance_ref['volumes']) == 0:
- logging.info(_("%s has no volume.") % ec2_id)
- else:
- for v in instance_ref['volumes']:
- self.volume_manager.setup_compute_volume(context, v['id'])
-
- # Bridge settings
- # call this method prior to ensure_filtering_rules_for_instance,
- # since bridge is not set up, ensure_filtering_rules_for instance
- # fails.
- self.network_manager.setup_compute_network(context, instance_id)
-
- # Creating filters to hypervisors and firewalls.
- # An example is that nova-instance-instance-xxx,
- # which is written to libvirt.xml( check "virsh nwfilter-list )
- # On destination host, this nwfilter is necessary.
- # In addition, this method is creating filtering rule
- # onto destination host.
- self.driver.ensure_filtering_rules_for_instance(instance_ref)
-
- def live_migration(self, context, instance_id, dest):
- """executes live migration."""
-
- # Get instance for error handling.
- instance_ref = db.instance_get(context, instance_id)
- ec2_id = instance_ref['hostname']
-
- try:
- # Checking volume node is working correctly when any volumes
- # are attached to instances.
- if len(instance_ref['volumes']) != 0:
- rpc.call(context,
- FLAGS.volume_topic,
- {"method": "check_for_export",
- "args": {'instance_id': instance_id}})
-
- # Asking dest host to preparing live migration.
- compute_topic = db.queue_get_for(context,
- FLAGS.compute_topic,
- dest)
- rpc.call(context,
- compute_topic,
- {"method": "pre_live_migration",
- "args": {'instance_id': instance_id,
- 'dest': dest}})
-
- except Exception, e:
- msg = _('Pre live migration for %s failed at %s')
- logging.error(msg, ec2_id, dest)
- db.instance_set_state(context,
- instance_id,
- power_state.RUNNING,
- 'running')
-
- for v in instance_ref['volumes']:
- db.volume_update(context,
- v['id'],
- {'status': 'in-use'})
-
- # e should be raised. just calling "raise" may raise NotFound.
- raise e
-
- # Executing live migration
- # live_migration might raises exceptions, but
- # nothing must be recovered in this version.
- self.driver.live_migration(context, instance_ref, dest)
diff --git a/nova/db/api.py b/nova/db/api.py
index 6277cbac5..f9d561587 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -253,10 +253,6 @@ def floating_ip_get_by_address(context, address):
return IMPL.floating_ip_get_by_address(context, address)
-def floating_ip_update(context, address, values):
- """update floating ip information."""
- return IMPL.floating_ip_update(context, address, values)
-
####################
@@ -409,32 +405,6 @@ def instance_add_security_group(context, instance_id, security_group_id):
security_group_id)
-def instance_get_all_by_host(context, hostname):
- """Get instances by host"""
- return IMPL.instance_get_all_by_host(context, hostname)
-
-
-def instance_get_vcpu_sum_by_host_and_project(context, hostname, proj_id):
- """Get instances.vcpus by host and project"""
- return IMPL.instance_get_vcpu_sum_by_host_and_project(context,
- hostname,
- proj_id)
-
-
-def instance_get_memory_sum_by_host_and_project(context, hostname, proj_id):
- """Get amount of memory by host and project """
- return IMPL.instance_get_memory_sum_by_host_and_project(context,
- hostname,
- proj_id)
-
-
-def instance_get_disk_sum_by_host_and_project(context, hostname, proj_id):
- """Get total amount of disk by host and project """
- return IMPL.instance_get_disk_sum_by_host_and_project(context,
- hostname,
- proj_id)
-
-
def instance_action_create(context, values):
"""Create an instance action from the values dictionary."""
return IMPL.instance_action_create(context, values)
diff --git a/nova/db/migration.py b/nova/db/migration.py
new file mode 100644
index 000000000..e54b90cd8
--- /dev/null
+++ b/nova/db/migration.py
@@ -0,0 +1,38 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2010 United States Government as represented by the
+# Administrator of the National Aeronautics and Space Administration.
+# 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.
+"""Database setup and migration commands."""
+
+from nova import flags
+from nova import utils
+
+FLAGS = flags.FLAGS
+flags.DECLARE('db_backend', 'nova.db.api')
+
+
+IMPL = utils.LazyPluggable(FLAGS['db_backend'],
+ sqlalchemy='nova.db.sqlalchemy.migration')
+
+
+def db_sync(version=None):
+ """Migrate the database to `version` or the most recent version."""
+ return IMPL.db_sync(version=version)
+
+
+def db_version():
+ """Display the current database version."""
+ return IMPL.db_version()
diff --git a/nova/db/sqlalchemy/__init__.py b/nova/db/sqlalchemy/__init__.py
index 501373942..747015af5 100644
--- a/nova/db/sqlalchemy/__init__.py
+++ b/nova/db/sqlalchemy/__init__.py
@@ -15,31 +15,3 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
-
-"""
-SQLAlchemy database backend
-"""
-import time
-
-from sqlalchemy.exc import OperationalError
-
-from nova import flags
-from nova import log as logging
-from nova.db.sqlalchemy import models
-
-
-FLAGS = flags.FLAGS
-LOG = logging.getLogger('nova.db.sqlalchemy')
-
-
-for i in xrange(FLAGS.sql_max_retries):
- if i > 0:
- time.sleep(FLAGS.sql_retry_interval)
-
- try:
- models.register_models()
- break
- except OperationalError:
- LOG.exception(_("Data store %s is unreachable."
- " Trying again in %d seconds."),
- FLAGS.sql_connection, FLAGS.sql_retry_interval)
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 248a46f65..b63b84bed 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -495,16 +495,6 @@ def floating_ip_get_by_address(context, address, session=None):
return result
-@require_context
-def floating_ip_update(context, address, values):
- session = get_session()
- with session.begin():
- floating_ip_ref = floating_ip_get_by_address(context, address, session)
- for (key, value) in values.iteritems():
- floating_ip_ref[key] = value
- floating_ip_ref.save(session=session)
-
-
###################
@@ -868,7 +858,6 @@ def instance_update(context, instance_id, values):
return instance_ref
-@require_context
def instance_add_security_group(context, instance_id, security_group_id):
"""Associate the given security group with the given instance"""
session = get_session()
@@ -882,59 +871,6 @@ def instance_add_security_group(context, instance_id, security_group_id):
@require_context
-def instance_get_all_by_host(context, hostname):
- session = get_session()
- if not session:
- session = get_session()
-
- result = session.query(models.Instance).\
- filter_by(host=hostname).\
- filter_by(deleted=can_read_deleted(context)).\
- all()
- if not result:
- return []
- return result
-
-
-@require_context
-def _instance_get_sum_by_host_and_project(context, column, hostname, proj_id):
- session = get_session()
-
- result = session.query(models.Instance).\
- filter_by(host=hostname).\
- filter_by(project_id=proj_id).\
- filter_by(deleted=can_read_deleted(context)).\
- value(column)
- if not result:
- return 0
- return result
-
-
-@require_context
-def instance_get_vcpu_sum_by_host_and_project(context, hostname, proj_id):
- return _instance_get_sum_by_host_and_project(context,
- 'vcpus',
- hostname,
- proj_id)
-
-
-@require_context
-def instance_get_memory_sum_by_host_and_project(context, hostname, proj_id):
- return _instance_get_sum_by_host_and_project(context,
- 'memory_mb',
- hostname,
- proj_id)
-
-
-@require_context
-def instance_get_disk_sum_by_host_and_project(context, hostname, proj_id):
- return _instance_get_sum_by_host_and_project(context,
- 'local_gb',
- hostname,
- proj_id)
-
-
-@require_context
def instance_action_create(context, values):
"""Create an instance action from the values dictionary."""
action_ref = models.InstanceActions()
diff --git a/nova/db/sqlalchemy/migrate_repo/README b/nova/db/sqlalchemy/migrate_repo/README
new file mode 100644
index 000000000..6218f8cac
--- /dev/null
+++ b/nova/db/sqlalchemy/migrate_repo/README
@@ -0,0 +1,4 @@
+This is a database migration repository.
+
+More information at
+http://code.google.com/p/sqlalchemy-migrate/
diff --git a/nova/db/sqlalchemy/migrate_repo/__init__.py b/nova/db/sqlalchemy/migrate_repo/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/nova/db/sqlalchemy/migrate_repo/__init__.py
diff --git a/nova/db/sqlalchemy/migrate_repo/manage.py b/nova/db/sqlalchemy/migrate_repo/manage.py
new file mode 100644
index 000000000..09e340f44
--- /dev/null
+++ b/nova/db/sqlalchemy/migrate_repo/manage.py
@@ -0,0 +1,4 @@
+#!/usr/bin/env python
+from migrate.versioning.shell import main
+if __name__ == '__main__':
+ main(debug='False', repository='.')
diff --git a/nova/db/sqlalchemy/migrate_repo/migrate.cfg b/nova/db/sqlalchemy/migrate_repo/migrate.cfg
new file mode 100644
index 000000000..2c75fb763
--- /dev/null
+++ b/nova/db/sqlalchemy/migrate_repo/migrate.cfg
@@ -0,0 +1,20 @@
+[db_settings]
+# Used to identify which repository this database is versioned under.
+# You can use the name of your project.
+repository_id=nova
+
+# The name of the database table used to track the schema version.
+# This name shouldn't already be used by your project.
+# If this is changed once a database is under version control, you'll need to
+# change the table name in each database too.
+version_table=migrate_version
+
+# When committing a change script, Migrate will attempt to generate the
+# sql for all supported databases; normally, if one of them fails - probably
+# because you don't have that database installed - it is ignored and the
+# commit continues, perhaps ending successfully.
+# Databases in this list MUST compile successfully during a commit, or the
+# entire commit will fail. List the databases your application will actually
+# be using to ensure your updates to that database work properly.
+# This must be a list; example: ['postgres','sqlite']
+required_dbs=[]
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/001_austin.py b/nova/db/sqlalchemy/migrate_repo/versions/001_austin.py
new file mode 100644
index 000000000..a312a7190
--- /dev/null
+++ b/nova/db/sqlalchemy/migrate_repo/versions/001_austin.py
@@ -0,0 +1,547 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2010 United States Government as represented by the
+# Administrator of the National Aeronautics and Space Administration.
+# 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.
+
+## Table code mostly autogenerated by genmodel.py
+from sqlalchemy import *
+from migrate import *
+
+from nova import log as logging
+
+
+meta = MetaData()
+
+
+auth_tokens = Table('auth_tokens', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('token_hash',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False),
+ primary_key=True,
+ nullable=False),
+ Column('user_id', Integer()),
+ Column('server_manageent_url',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('storage_url',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('cdn_management_url',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ )
+
+
+export_devices = Table('export_devices', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('id', Integer(), primary_key=True, nullable=False),
+ Column('shelf_id', Integer()),
+ Column('blade_id', Integer()),
+ Column('volume_id',
+ Integer(),
+ ForeignKey('volumes.id'),
+ nullable=True),
+ )
+
+
+fixed_ips = Table('fixed_ips', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('id', Integer(), primary_key=True, nullable=False),
+ Column('address',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('network_id',
+ Integer(),
+ ForeignKey('networks.id'),
+ nullable=True),
+ Column('instance_id',
+ Integer(),
+ ForeignKey('instances.id'),
+ nullable=True),
+ Column('allocated', Boolean(create_constraint=True, name=None)),
+ Column('leased', Boolean(create_constraint=True, name=None)),
+ Column('reserved', Boolean(create_constraint=True, name=None)),
+ )
+
+
+floating_ips = Table('floating_ips', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('id', Integer(), primary_key=True, nullable=False),
+ Column('address',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('fixed_ip_id',
+ Integer(),
+ ForeignKey('fixed_ips.id'),
+ nullable=True),
+ Column('project_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('host',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ )
+
+
+instances = Table('instances', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('id', Integer(), primary_key=True, nullable=False),
+ Column('internal_id', Integer()),
+ Column('admin_pass',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('user_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('project_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('image_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('kernel_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('ramdisk_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('launch_index', Integer()),
+ Column('key_name',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('key_data',
+ Text(length=None, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('state', Integer()),
+ Column('state_description',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('memory_mb', Integer()),
+ Column('vcpus', Integer()),
+ Column('local_gb', Integer()),
+ Column('hostname',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('host',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('instance_type',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('user_data',
+ Text(length=None, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('reservation_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('mac_address',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('scheduled_at', DateTime(timezone=False)),
+ Column('launched_at', DateTime(timezone=False)),
+ Column('terminated_at', DateTime(timezone=False)),
+ Column('display_name',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('display_description',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ )
+
+
+iscsi_targets = Table('iscsi_targets', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('id', Integer(), primary_key=True, nullable=False),
+ Column('target_num', Integer()),
+ Column('host',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('volume_id',
+ Integer(),
+ ForeignKey('volumes.id'),
+ nullable=True),
+ )
+
+
+key_pairs = Table('key_pairs', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('id', Integer(), primary_key=True, nullable=False),
+ Column('name',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('user_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('fingerprint',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('public_key',
+ Text(length=None, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ )
+
+
+networks = Table('networks', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('id', Integer(), primary_key=True, nullable=False),
+ Column('injected', Boolean(create_constraint=True, name=None)),
+ Column('cidr',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('netmask',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('bridge',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('gateway',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('broadcast',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('dns',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('vlan', Integer()),
+ Column('vpn_public_address',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('vpn_public_port', Integer()),
+ Column('vpn_private_address',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('dhcp_start',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('project_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('host',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ )
+
+
+projects = Table('projects', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False),
+ primary_key=True,
+ nullable=False),
+ Column('name',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('description',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('project_manager',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False),
+ ForeignKey('users.id')),
+ )
+
+
+quotas = Table('quotas', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('id', Integer(), primary_key=True, nullable=False),
+ Column('project_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('instances', Integer()),
+ Column('cores', Integer()),
+ Column('volumes', Integer()),
+ Column('gigabytes', Integer()),
+ Column('floating_ips', Integer()),
+ )
+
+
+security_groups = Table('security_groups', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('id', Integer(), primary_key=True, nullable=False),
+ Column('name',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('description',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('user_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('project_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ )
+
+
+security_group_inst_assoc = Table('security_group_instance_association', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('id', Integer(), primary_key=True, nullable=False),
+ Column('security_group_id',
+ Integer(),
+ ForeignKey('security_groups.id')),
+ Column('instance_id', Integer(), ForeignKey('instances.id')),
+ )
+
+
+security_group_rules = Table('security_group_rules', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('id', Integer(), primary_key=True, nullable=False),
+ Column('parent_group_id',
+ Integer(),
+ ForeignKey('security_groups.id')),
+ Column('protocol',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('from_port', Integer()),
+ Column('to_port', Integer()),
+ Column('cidr',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('group_id',
+ Integer(),
+ ForeignKey('security_groups.id')),
+ )
+
+
+services = Table('services', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('id', Integer(), primary_key=True, nullable=False),
+ Column('host',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('binary',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('topic',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('report_count', Integer(), nullable=False),
+ Column('disabled', Boolean(create_constraint=True, name=None)),
+ )
+
+
+users = Table('users', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False),
+ primary_key=True,
+ nullable=False),
+ Column('name',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('access_key',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('secret_key',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('is_admin', Boolean(create_constraint=True, name=None)),
+ )
+
+
+user_project_association = Table('user_project_association', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('user_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False),
+ ForeignKey('users.id'),
+ primary_key=True,
+ nullable=False),
+ Column('project_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False),
+ ForeignKey('projects.id'),
+ primary_key=True,
+ nullable=False),
+ )
+
+
+user_project_role_association = Table('user_project_role_association', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('user_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False),
+ primary_key=True,
+ nullable=False),
+ Column('project_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False),
+ primary_key=True,
+ nullable=False),
+ Column('role',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False),
+ primary_key=True,
+ nullable=False),
+ ForeignKeyConstraint(['user_id',
+ 'project_id'],
+ ['user_project_association.user_id',
+ 'user_project_association.project_id']),
+ )
+
+
+user_role_association = Table('user_role_association', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('user_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False),
+ ForeignKey('users.id'),
+ primary_key=True,
+ nullable=False),
+ Column('role',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False),
+ primary_key=True,
+ nullable=False),
+ )
+
+
+volumes = Table('volumes', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('id', Integer(), primary_key=True, nullable=False),
+ Column('ec2_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('user_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('project_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('host',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('size', Integer()),
+ Column('availability_zone',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('instance_id',
+ Integer(),
+ ForeignKey('instances.id'),
+ nullable=True),
+ Column('mountpoint',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('attach_time',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('status',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('attach_status',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('scheduled_at', DateTime(timezone=False)),
+ Column('launched_at', DateTime(timezone=False)),
+ Column('terminated_at', DateTime(timezone=False)),
+ Column('display_name',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('display_description',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=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
+
+ for table in (auth_tokens, export_devices, fixed_ips, floating_ips,
+ instances, iscsi_targets, key_pairs, networks,
+ projects, quotas, security_groups, security_group_inst_assoc,
+ security_group_rules, services, users,
+ user_project_association, user_project_role_association,
+ user_role_association, volumes):
+ try:
+ table.create()
+ except Exception:
+ logging.info(repr(table))
+ logging.exception('Exception while creating table')
+ raise
+
+
+def downgrade(migrate_engine):
+ # Operations to reverse the above upgrade go here.
+ for table in (auth_tokens, export_devices, fixed_ips, floating_ips,
+ instances, iscsi_targets, key_pairs, networks,
+ projects, quotas, security_groups, security_group_inst_assoc,
+ security_group_rules, services, users,
+ user_project_association, user_project_role_association,
+ user_role_association, volumes):
+ table.drop()
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/002_bexar.py b/nova/db/sqlalchemy/migrate_repo/versions/002_bexar.py
new file mode 100644
index 000000000..bd3a3e6f8
--- /dev/null
+++ b/nova/db/sqlalchemy/migrate_repo/versions/002_bexar.py
@@ -0,0 +1,209 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2010 United States Government as represented by the
+# Administrator of the National Aeronautics and Space Administration.
+# 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 sqlalchemy import *
+from migrate import *
+
+from nova import log as logging
+
+
+meta = MetaData()
+
+
+# Just for the ForeignKey and column creation to succeed, these are not the
+# actual definitions of instances or services.
+instances = Table('instances', meta,
+ Column('id', Integer(), primary_key=True, nullable=False),
+ )
+
+
+services = Table('services', meta,
+ Column('id', Integer(), primary_key=True, nullable=False),
+ )
+
+
+networks = Table('networks', meta,
+ Column('id', Integer(), primary_key=True, nullable=False),
+ )
+
+
+#
+# New Tables
+#
+certificates = Table('certificates', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('id', Integer(), primary_key=True, nullable=False),
+ Column('user_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('project_id',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('file_name',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ )
+
+
+consoles = Table('consoles', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('id', Integer(), primary_key=True, nullable=False),
+ Column('instance_name',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('instance_id', Integer()),
+ Column('password',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('port', Integer(), nullable=True),
+ Column('pool_id',
+ Integer(),
+ ForeignKey('console_pools.id')),
+ )
+
+
+console_pools = Table('console_pools', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('id', Integer(), primary_key=True, nullable=False),
+ Column('address',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('username',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('password',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('console_type',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('public_hostname',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('host',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('compute_host',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ )
+
+
+instance_actions = Table('instance_actions', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('id', Integer(), primary_key=True, nullable=False),
+ Column('instance_id',
+ Integer(),
+ ForeignKey('instances.id')),
+ Column('action',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('error',
+ Text(length=None, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ )
+
+
+#
+# Tables to alter
+#
+auth_tokens = Table('auth_tokens', meta,
+ Column('created_at', DateTime(timezone=False)),
+ Column('updated_at', DateTime(timezone=False)),
+ Column('deleted_at', DateTime(timezone=False)),
+ Column('deleted', Boolean(create_constraint=True, name=None)),
+ Column('token_hash',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False),
+ primary_key=True,
+ nullable=False),
+ Column('user_id', Integer()),
+ Column('server_manageent_url',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('storage_url',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ Column('cdn_management_url',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False)),
+ )
+
+
+instances_availability_zone = Column(
+ 'availability_zone',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False))
+
+
+instances_locked = Column('locked',
+ Boolean(create_constraint=True, name=None))
+
+
+networks_cidr_v6 = Column(
+ 'cidr_v6',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False))
+
+networks_ra_server = Column(
+ 'ra_server',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False))
+
+
+services_availability_zone = Column(
+ 'availability_zone',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=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
+ for table in (certificates, consoles, console_pools, instance_actions):
+ try:
+ table.create()
+ except Exception:
+ logging.info(repr(table))
+ logging.exception('Exception while creating table')
+ raise
+
+ auth_tokens.c.user_id.alter(type=String(length=255,
+ convert_unicode=False,
+ assert_unicode=None,
+ unicode_error=None,
+ _warn_on_bytestring=False))
+
+ instances.create_column(instances_availability_zone)
+ instances.create_column(instances_locked)
+ networks.create_column(networks_cidr_v6)
+ networks.create_column(networks_ra_server)
+ services.create_column(services_availability_zone)
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/__init__.py b/nova/db/sqlalchemy/migrate_repo/versions/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/nova/db/sqlalchemy/migrate_repo/versions/__init__.py
diff --git a/nova/db/sqlalchemy/migration.py b/nova/db/sqlalchemy/migration.py
new file mode 100644
index 000000000..33d14827b
--- /dev/null
+++ b/nova/db/sqlalchemy/migration.py
@@ -0,0 +1,72 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2010 United States Government as represented by the
+# Administrator of the National Aeronautics and Space Administration.
+# 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.
+
+import os
+
+from nova import flags
+
+import sqlalchemy
+from migrate.versioning import api as versioning_api
+from migrate.versioning import exceptions as versioning_exceptions
+
+FLAGS = flags.FLAGS
+
+
+def db_sync(version=None):
+ db_version()
+ repo_path = _find_migrate_repo()
+ return versioning_api.upgrade(FLAGS.sql_connection, repo_path, version)
+
+
+def db_version():
+ repo_path = _find_migrate_repo()
+ try:
+ return versioning_api.db_version(FLAGS.sql_connection, repo_path)
+ except versioning_exceptions.DatabaseNotControlledError:
+ # If we aren't version controlled we may already have the database
+ # in the state from before we started version control, check for that
+ # and set up version_control appropriately
+ meta = sqlalchemy.MetaData()
+ engine = sqlalchemy.create_engine(FLAGS.sql_connection, echo=False)
+ meta.reflect(bind=engine)
+ try:
+ for table in ('auth_tokens', 'export_devices', 'fixed_ips',
+ 'floating_ips', 'instances', 'iscsi_targets',
+ 'key_pairs', 'networks', 'projects', 'quotas',
+ 'security_group_rules',
+ 'security_group_instance_association', 'services',
+ 'users', 'user_project_association',
+ 'user_project_role_association', 'volumes'):
+ assert table in meta.tables
+ return db_version_control(1)
+ except AssertionError:
+ return db_version_control(0)
+
+
+def db_version_control(version=None):
+ repo_path = _find_migrate_repo()
+ versioning_api.version_control(FLAGS.sql_connection, repo_path, version)
+ return version
+
+
+def _find_migrate_repo():
+ """Get the path for the migrate repository."""
+ path = os.path.join(os.path.abspath(os.path.dirname(__file__)),
+ 'migrate_repo')
+ assert os.path.exists(path)
+ return path
diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py
index b28c64b59..c54ebe3ba 100644
--- a/nova/db/sqlalchemy/models.py
+++ b/nova/db/sqlalchemy/models.py
@@ -100,82 +100,18 @@ class NovaBase(object):
return local.iteritems()
-# TODO(vish): Store images in the database instead of file system
-#class Image(BASE, NovaBase):
-# """Represents an image in the datastore"""
-# __tablename__ = 'images'
-# id = Column(Integer, primary_key=True)
-# ec2_id = Column(String(12), unique=True)
-# user_id = Column(String(255))
-# project_id = Column(String(255))
-# image_type = Column(String(255))
-# public = Column(Boolean, default=False)
-# state = Column(String(255))
-# location = Column(String(255))
-# arch = Column(String(255))
-# default_kernel_id = Column(String(255))
-# default_ramdisk_id = Column(String(255))
-#
-# @validates('image_type')
-# def validate_image_type(self, key, image_type):
-# assert(image_type in ['machine', 'kernel', 'ramdisk', 'raw'])
-#
-# @validates('state')
-# def validate_state(self, key, state):
-# assert(state in ['available', 'pending', 'disabled'])
-#
-# @validates('default_kernel_id')
-# def validate_kernel_id(self, key, val):
-# if val != 'machine':
-# assert(val is None)
-#
-# @validates('default_ramdisk_id')
-# def validate_ramdisk_id(self, key, val):
-# if val != 'machine':
-# assert(val is None)
-#
-#
-# TODO(vish): To make this into its own table, we need a good place to
-# create the host entries. In config somwhere? Or the first
-# time any object sets host? This only becomes particularly
-# important if we need to store per-host data.
-#class Host(BASE, NovaBase):
-# """Represents a host where services are running"""
-# __tablename__ = 'hosts'
-# id = Column(String(255), primary_key=True)
-
-
class Service(BASE, NovaBase):
"""Represents a running service on a host."""
__tablename__ = 'services'
id = Column(Integer, primary_key=True)
- #host_id = Column(Integer, ForeignKey('hosts.id'), nullable=True)
- #host = relationship(Host, backref=backref('services'))
- host = Column(String(255))
+ host = Column(String(255)) # , ForeignKey('hosts.id'))
binary = Column(String(255))
topic = Column(String(255))
report_count = Column(Integer, nullable=False, default=0)
disabled = Column(Boolean, default=False)
availability_zone = Column(String(255), default='nova')
- # The below items are compute node only.
- # -1 or None is inserted for other service.
- vcpus = Column(Integer, nullable=False, default=-1)
- memory_mb = Column(Integer, nullable=False, default=-1)
- local_gb = Column(Integer, nullable=False, default=-1)
- hypervisor_type = Column(String(128))
- hypervisor_version = Column(Integer, nullable=False, default=-1)
- # Note(masumotok): Expected Strings example:
- #
- # '{"arch":"x86_64", "model":"Nehalem",
- # "topology":{"sockets":1, "threads":2, "cores":3},
- # features:[ "tdtscp", "xtpr"]}'
- #
- # Points are "json translatable" and it must have all
- # dictionary keys above.
- cpu_info = Column(String(512))
-
class Certificate(BASE, NovaBase):
"""Represents a an x509 certificate"""
@@ -250,9 +186,6 @@ class Instance(BASE, NovaBase):
display_name = Column(String(255))
display_description = Column(String(255))
- # To remember on which host a instance booted.
- # An instance may moved to other host by live migraiton.
- launched_on = Column(String(255))
locked = Column(Boolean)
# TODO(vish): see Ewan's email about state improvements, probably
@@ -610,7 +543,7 @@ def register_models():
Volume, ExportDevice, IscsiTarget, FixedIp, FloatingIp,
Network, SecurityGroup, SecurityGroupIngressRule,
SecurityGroupInstanceAssociation, AuthToken, User,
- Project, Certificate, ConsolePool, Console) # , Host, Image
+ Project, Certificate, ConsolePool, Console) # , Image, Host
engine = create_engine(FLAGS.sql_connection, echo=False)
for model in models:
model.metadata.create_all(engine)
diff --git a/nova/network/manager.py b/nova/network/manager.py
index 932c77d31..61de8055a 100644
--- a/nova/network/manager.py
+++ b/nova/network/manager.py
@@ -92,7 +92,7 @@ flags.DEFINE_bool('update_dhcp_on_disassociate', False,
flags.DEFINE_integer('fixed_ip_disassociate_timeout', 600,
'Seconds after which a deallocated ip is disassociated')
-flags.DEFINE_bool('use_ipv6', True,
+flags.DEFINE_bool('use_ipv6', False,
'use the ipv6')
flags.DEFINE_string('network_host', socket.gethostname(),
'Network host to use for ip allocation in flat modes')
@@ -159,7 +159,7 @@ class NetworkManager(manager.Manager):
"""Called when this host becomes the host for a network."""
raise NotImplementedError()
- def setup_compute_network(self, context, instance_id, network_ref=None):
+ def setup_compute_network(self, context, instance_id):
"""Sets up matching network for compute hosts."""
raise NotImplementedError()
@@ -320,7 +320,7 @@ class FlatManager(NetworkManager):
self.db.fixed_ip_update(context, address, {'allocated': False})
self.db.fixed_ip_disassociate(context.elevated(), address)
- def setup_compute_network(self, context, instance_id, network_ref=None):
+ def setup_compute_network(self, context, instance_id):
"""Network is created manually."""
pass
@@ -395,10 +395,9 @@ class FlatDHCPManager(FlatManager):
super(FlatDHCPManager, self).init_host()
self.driver.metadata_forward()
- def setup_compute_network(self, context, instance_id, network_ref=None):
+ def setup_compute_network(self, context, instance_id):
"""Sets up matching network for compute hosts."""
- if network_ref is None:
- network_ref = db.network_get_by_instance(context, instance_id)
+ network_ref = db.network_get_by_instance(context, instance_id)
self.driver.ensure_bridge(network_ref['bridge'],
FLAGS.flat_interface)
@@ -488,10 +487,9 @@ class VlanManager(NetworkManager):
"""Returns a fixed ip to the pool."""
self.db.fixed_ip_update(context, address, {'allocated': False})
- def setup_compute_network(self, context, instance_id, network_ref=None):
+ def setup_compute_network(self, context, instance_id):
"""Sets up matching network for compute hosts."""
- if network_ref is None:
- network_ref = db.network_get_by_instance(context, instance_id)
+ network_ref = db.network_get_by_instance(context, instance_id)
self.driver.ensure_vlan_bridge(network_ref['vlan'],
network_ref['bridge'])
diff --git a/nova/scheduler/driver.py b/nova/scheduler/driver.py
index 65745093b..66e46c1b9 100644
--- a/nova/scheduler/driver.py
+++ b/nova/scheduler/driver.py
@@ -26,9 +26,6 @@ import datetime
from nova import db
from nova import exception
from nova import flags
-from nova import log as logging
-from nova import rpc
-from nova.compute import power_state
FLAGS = flags.FLAGS
flags.DEFINE_integer('service_down_time', 60,
@@ -67,183 +64,3 @@ class Scheduler(object):
def schedule(self, context, topic, *_args, **_kwargs):
"""Must override at least this method for scheduler to work."""
raise NotImplementedError(_("Must implement a fallback schedule"))
-
- def schedule_live_migration(self, context, instance_id, dest):
- """ live migration method """
-
- # Whether instance exists and running
- instance_ref = db.instance_get(context, instance_id)
- ec2_id = instance_ref['hostname']
-
- # Checking instance.
- self._live_migration_src_check(context, instance_ref)
-
- # Checking destination host.
- self._live_migration_dest_check(context, instance_ref, dest)
-
- # Common checking.
- self._live_migration_common_check(context, instance_ref, dest)
-
- # Changing instance_state.
- db.instance_set_state(context,
- instance_id,
- power_state.PAUSED,
- 'migrating')
-
- # Changing volume state
- for v in instance_ref['volumes']:
- db.volume_update(context,
- v['id'],
- {'status': 'migrating'})
-
- # Return value is necessary to send request to src
- # Check _schedule() in detail.
- src = instance_ref['host']
- return src
-
- def _live_migration_src_check(self, context, instance_ref):
- """Live migration check routine (for src host)"""
-
- # Checking instance is running.
- if power_state.RUNNING != instance_ref['state'] or \
- 'running' != instance_ref['state_description']:
- msg = _('Instance(%s) is not running')
- ec2_id = instance_ref['hostname']
- raise exception.Invalid(msg % ec2_id)
-
- # Checing volume node is running when any volumes are mounted
- # to the instance.
- if len(instance_ref['volumes']) != 0:
- services = db.service_get_all_by_topic(context, 'volume')
- if len(services) < 1 or not self.service_is_up(services[0]):
- msg = _('volume node is not alive(time synchronize problem?)')
- raise exception.Invalid(msg)
-
- # Checking src host is alive.
- src = instance_ref['host']
- services = db.service_get_all_by_topic(context, 'compute')
- services = [service for service in services if service.host == src]
- if len(services) < 1 or not self.service_is_up(services[0]):
- msg = _('%s is not alive(time synchronize problem?)')
- raise exception.Invalid(msg % src)
-
- def _live_migration_dest_check(self, context, instance_ref, dest):
- """Live migration check routine (for destination host)"""
-
- # Checking dest exists and compute node.
- dservice_refs = db.service_get_all_by_host(context, dest)
- if len(dservice_refs) <= 0:
- msg = _('%s does not exists.')
- raise exception.Invalid(msg % dest)
-
- dservice_ref = dservice_refs[0]
- if dservice_ref['topic'] != 'compute':
- msg = _('%s must be compute node')
- raise exception.Invalid(msg % dest)
-
- # Checking dest host is alive.
- if not self.service_is_up(dservice_ref):
- msg = _('%s is not alive(time synchronize problem?)')
- raise exception.Invalid(msg % dest)
-
- # Checking whether The host where instance is running
- # and dest is not same.
- src = instance_ref['host']
- if dest == src:
- ec2_id = instance_ref['hostname']
- msg = _('%s is where %s is running now. choose other host.')
- raise exception.Invalid(msg % (dest, ec2_id))
-
- # Checking dst host still has enough capacities.
- self.has_enough_resource(context, instance_ref, dest)
-
- def _live_migration_common_check(self, context, instance_ref, dest):
- """
- Live migration check routine.
- Below pre-checkings are followed by
- http://wiki.libvirt.org/page/TodoPreMigrationChecks
-
- """
-
- # Checking dest exists.
- dservice_refs = db.service_get_all_by_host(context, dest)
- if len(dservice_refs) <= 0:
- msg = _('%s does not exists.')
- raise exception.Invalid(msg % dest)
- dservice_ref = dservice_refs[0]
-
- # Checking original host( where instance was launched at) exists.
- orighost = instance_ref['launched_on']
- oservice_refs = db.service_get_all_by_host(context, orighost)
- if len(oservice_refs) <= 0:
- msg = _('%s(where instance was launched at) does not exists.')
- raise exception.Invalid(msg % orighost)
- oservice_ref = oservice_refs[0]
-
- # Checking hypervisor is same.
- otype = oservice_ref['hypervisor_type']
- dtype = dservice_ref['hypervisor_type']
- if otype != dtype:
- msg = _('Different hypervisor type(%s->%s)')
- raise exception.Invalid(msg % (otype, dtype))
-
- # Checkng hypervisor version.
- oversion = oservice_ref['hypervisor_version']
- dversion = dservice_ref['hypervisor_version']
- if oversion > dversion:
- msg = _('Older hypervisor version(%s->%s)')
- raise exception.Invalid(msg % (oversion, dversion))
-
- # Checking cpuinfo.
- cpu_info = oservice_ref['cpu_info']
- try:
- rpc.call(context,
- db.queue_get_for(context, FLAGS.compute_topic, dest),
- {"method": 'compare_cpu',
- "args": {'cpu_info': cpu_info}})
-
- except rpc.RemoteError, e:
- msg = _(("""%s doesnt have compatibility to %s"""
- """(where %s was launched at)"""))
- ec2_id = instance_ref['hostname']
- src = instance_ref['host']
- logging.error(msg % (dest, src, ec2_id))
- raise e
-
- def has_enough_resource(self, context, instance_ref, dest):
- """ Check if destination host has enough resource for live migration"""
-
- # Getting instance information
- ec2_id = instance_ref['hostname']
- vcpus = instance_ref['vcpus']
- mem = instance_ref['memory_mb']
- hdd = instance_ref['local_gb']
-
- # Gettin host information
- service_refs = db.service_get_all_by_host(context, dest)
- if len(service_refs) <= 0:
- msg = _('%s does not exists.')
- raise exception.Invalid(msg % dest)
- service_ref = service_refs[0]
-
- total_cpu = int(service_ref['vcpus'])
- total_mem = int(service_ref['memory_mb'])
- total_hdd = int(service_ref['local_gb'])
-
- instances_ref = db.instance_get_all_by_host(context, dest)
- for i_ref in instances_ref:
- total_cpu -= int(i_ref['vcpus'])
- total_mem -= int(i_ref['memory_mb'])
- total_hdd -= int(i_ref['local_gb'])
-
- # Checking host has enough information
- logging.debug('host(%s) remains vcpu:%s mem:%s hdd:%s,' %
- (dest, total_cpu, total_mem, total_hdd))
- logging.debug('instance(%s) has vcpu:%s mem:%s hdd:%s,' %
- (ec2_id, vcpus, mem, hdd))
-
- if total_cpu <= vcpus or total_mem <= mem or total_hdd <= hdd:
- msg = '%s doesnt have enough resource for %s' % (dest, ec2_id)
- raise exception.NotEmpty(msg)
-
- logging.debug(_('%s has_enough_resource() for %s') % (dest, ec2_id))
diff --git a/nova/scheduler/manager.py b/nova/scheduler/manager.py
index 1cc767a03..a4d6dd574 100644
--- a/nova/scheduler/manager.py
+++ b/nova/scheduler/manager.py
@@ -29,7 +29,6 @@ from nova import log as logging
from nova import manager
from nova import rpc
from nova import utils
-from nova import exception
LOG = logging.getLogger('nova.scheduler.manager')
FLAGS = flags.FLAGS
@@ -68,50 +67,3 @@ class SchedulerManager(manager.Manager):
{"method": method,
"args": kwargs})
LOG.debug(_("Casting to %s %s for %s"), topic, host, method)
-
- # NOTE (masumotok) : This method should be moved to nova.api.ec2.admin.
- # Based on bear design summit discussion,
- # just put this here for bexar release.
- def show_host_resource(self, context, host, *args):
- """ show the physical/usage resource given by hosts."""
-
- services = db.service_get_all_by_host(context, host)
- if len(services) == 0:
- return {'ret': False, 'msg': 'No such Host'}
-
- compute = [s for s in services if s['topic'] == 'compute']
- if 0 == len(compute):
- service_ref = services[0]
- else:
- service_ref = compute[0]
-
- # Getting physical resource information
- h_resource = {'vcpus': service_ref['vcpus'],
- 'memory_mb': service_ref['memory_mb'],
- 'local_gb': service_ref['local_gb']}
-
- # Getting usage resource information
- u_resource = {}
- instances_ref = db.instance_get_all_by_host(context,
- service_ref['host'])
-
- if 0 == len(instances_ref):
- return {'ret': True, 'phy_resource': h_resource, 'usage': {}}
-
- project_ids = [i['project_id'] for i in instances_ref]
- project_ids = list(set(project_ids))
- for p_id in project_ids:
- vcpus = db.instance_get_vcpu_sum_by_host_and_project(context,
- host,
- p_id)
- mem = db.instance_get_memory_sum_by_host_and_project(context,
- host,
- p_id)
- hdd = db.instance_get_disk_sum_by_host_and_project(context,
- host,
- p_id)
- u_resource[p_id] = {'vcpus': vcpus,
- 'memory_mb': mem,
- 'local_gb': hdd}
-
- return {'ret': True, 'phy_resource': h_resource, 'usage': u_resource}
diff --git a/nova/service.py b/nova/service.py
index a8d52e93b..efc08fd63 100644
--- a/nova/service.py
+++ b/nova/service.py
@@ -80,7 +80,6 @@ class Service(object):
self.manager.init_host()
self.model_disconnected = False
ctxt = context.get_admin_context()
-
try:
service_ref = db.service_get_by_args(ctxt,
self.host,
@@ -89,9 +88,6 @@ class Service(object):
except exception.NotFound:
self._create_service_ref(ctxt)
- if 'nova-compute' == self.binary:
- self.manager.update_service(ctxt, self.host, self.binary)
-
conn1 = rpc.Connection.instance(new=True)
conn2 = rpc.Connection.instance(new=True)
if self.report_interval:
@@ -213,19 +209,6 @@ class Service(object):
self.model_disconnected = True
logging.exception(_("model server went away"))
- try:
- # NOTE(vish): This is late-loaded to make sure that the
- # database is not created before flags have
- # been loaded.
- from nova.db.sqlalchemy import models
- models.register_models()
- except OperationalError:
- logging.exception(_("Data store %s is unreachable."
- " Trying again in %d seconds.") %
- (FLAGS.sql_connection,
- FLAGS.sql_retry_interval))
- time.sleep(FLAGS.sql_retry_interval)
-
def serve(*services):
FLAGS(sys.argv)
diff --git a/nova/tests/__init__.py b/nova/tests/__init__.py
index 8dc87d0e2..592d5bea9 100644
--- a/nova/tests/__init__.py
+++ b/nova/tests/__init__.py
@@ -34,3 +34,8 @@
# The code below enables nosetests to work with i18n _() blocks
import __builtin__
setattr(__builtin__, '_', lambda x: x)
+
+
+def setup():
+ from nova.db import migration
+ migration.db_sync()
diff --git a/nova/tests/fake_flags.py b/nova/tests/fake_flags.py
index 7376a11dd..1097488ec 100644
--- a/nova/tests/fake_flags.py
+++ b/nova/tests/fake_flags.py
@@ -40,3 +40,4 @@ FLAGS.blades_per_shelf = 4
FLAGS.iscsi_num_targets = 8
FLAGS.verbose = True
FLAGS.sql_connection = 'sqlite:///nova.sqlite'
+FLAGS.use_ipv6 = True
diff --git a/nova/virt/cpuinfo.xml.template b/nova/virt/cpuinfo.xml.template
deleted file mode 100644
index 48842b29d..000000000
--- a/nova/virt/cpuinfo.xml.template
+++ /dev/null
@@ -1,9 +0,0 @@
-<cpu>
- <arch>$arch</arch>
- <model>$model</model>
- <vendor>$vendor</vendor>
- <topology sockets="$topology.sockets" cores="$topology.cores" threads="$topology.threads"/>
-#for $var in $features
- <features name="$var" />
-#end for
-</cpu>
diff --git a/nova/virt/fake.py b/nova/virt/fake.py
index 037cf83f7..f8b3c7807 100644
--- a/nova/virt/fake.py
+++ b/nova/virt/fake.py
@@ -358,38 +358,6 @@ class FakeConnection(object):
"""
return True
- def get_cpu_info(self):
- """This method is supported only libvirt. """
- return
-
- def get_vcpu_number(self):
- """This method is supported only libvirt. """
- return -1
-
- def get_memory_mb(self):
- """This method is supported only libvirt.."""
- return -1
-
- def get_local_gb(self):
- """This method is supported only libvirt.."""
- return -1
-
- def get_hypervisor_type(self):
- """This method is supported only libvirt.."""
- return
-
- def get_hypervisor_version(self):
- """This method is supported only libvirt.."""
- return -1
-
- def compare_cpu(self, xml):
- """This method is supported only libvirt.."""
- raise NotImplementedError('This method is supported only libvirt.')
-
- def live_migration(self, context, instance_ref, dest):
- """This method is supported only libvirt.."""
- raise NotImplementedError('This method is supported only libvirt.')
-
class FakeInstance(object):
diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py
index ab4ceb6a4..f5b0bd365 100644
--- a/nova/virt/libvirt_conn.py
+++ b/nova/virt/libvirt_conn.py
@@ -36,11 +36,8 @@ Supports KVM, QEMU, UML, and XEN.
"""
-import json
import os
import shutil
-import re
-import time
import random
import subprocess
import uuid
@@ -83,9 +80,6 @@ flags.DEFINE_string('injected_network_template',
flags.DEFINE_string('libvirt_xml_template',
utils.abspath('virt/libvirt.xml.template'),
'Libvirt XML Template')
-flags.DEFINE_string('cpuinfo_xml_template',
- utils.abspath('virt/cpuinfo.xml.template'),
- 'CpuInfo XML Template (used only live migration now)')
flags.DEFINE_string('libvirt_type',
'kvm',
'Libvirt domain type (valid options are: '
@@ -94,16 +88,6 @@ flags.DEFINE_string('libvirt_uri',
'',
'Override the default libvirt URI (which is dependent'
' on libvirt_type)')
-flags.DEFINE_string('live_migration_uri',
- "qemu+tcp://%s/system",
- 'Define protocol used by live_migration feature')
-flags.DEFINE_string('live_migration_flag',
- "VIR_MIGRATE_UNDEFINE_SOURCE, VIR_MIGRATE_PEER2PEER",
- 'Define live migration behavior.')
-flags.DEFINE_integer('live_migration_bandwidth', 0,
- 'Define live migration behavior')
-flags.DEFINE_string('live_migration_timeout_sec', 10,
- 'Timeout second for pre_live_migration is completed.')
flags.DEFINE_bool('allow_project_net_traffic',
True,
'Whether to allow in project network traffic')
@@ -162,7 +146,6 @@ class LibvirtConnection(object):
self.libvirt_uri = self.get_uri()
self.libvirt_xml = open(FLAGS.libvirt_xml_template).read()
- self.cpuinfo_xml = open(FLAGS.cpuinfo_xml_template).read()
self._wrapped_conn = None
self.read_only = read_only
@@ -835,74 +818,6 @@ class LibvirtConnection(object):
return interfaces
- def get_vcpu_number(self):
- """ Get vcpu number of physical computer. """
- return self._conn.getMaxVcpus(None)
-
- def get_memory_mb(self):
- """Get the memory size of physical computer ."""
- meminfo = open('/proc/meminfo').read().split()
- idx = meminfo.index('MemTotal:')
- # transforming kb to mb.
- return int(meminfo[idx + 1]) / 1024
-
- def get_local_gb(self):
- """Get the hdd size of physical computer ."""
- hddinfo = os.statvfs(FLAGS.instances_path)
- return hddinfo.f_bsize * hddinfo.f_blocks / 1024 / 1024 / 1024
-
- def get_hypervisor_type(self):
- """ Get hypervisor type """
- return self._conn.getType()
-
- def get_hypervisor_version(self):
- """ Get hypervisor version """
- return self._conn.getVersion()
-
- def get_cpu_info(self):
- """ Get cpuinfo information """
- xmlstr = self._conn.getCapabilities()
- xml = libxml2.parseDoc(xmlstr)
- nodes = xml.xpathEval('//cpu')
- if len(nodes) != 1:
- msg = 'Unexpected xml format. tag "cpu" must be 1, but %d.' \
- % len(nodes)
- msg += '\n' + xml.serialize()
- raise exception.Invalid(_(msg))
-
- arch = xml.xpathEval('//cpu/arch')[0].getContent()
- model = xml.xpathEval('//cpu/model')[0].getContent()
- vendor = xml.xpathEval('//cpu/vendor')[0].getContent()
-
- topology_node = xml.xpathEval('//cpu/topology')[0].get_properties()
- topology = dict()
- while topology_node != None:
- name = topology_node.get_name()
- topology[name] = topology_node.getContent()
- topology_node = topology_node.get_next()
-
- keys = ['cores', 'sockets', 'threads']
- tkeys = topology.keys()
- if list(set(tkeys)) != list(set(keys)):
- msg = _('Invalid xml: topology(%s) must have %s')
- raise exception.Invalid(msg % (str(topology), ', '.join(keys)))
-
- feature_nodes = xml.xpathEval('//cpu/feature')
- features = list()
- for nodes in feature_nodes:
- feature_name = nodes.get_properties().getContent()
- features.append(feature_name)
-
- template = ("""{"arch":"%s", "model":"%s", "vendor":"%s", """
- """"topology":{"cores":"%s", "threads":"%s", """
- """"sockets":"%s"}, "features":[%s]}""")
- c = topology['cores']
- s = topology['sockets']
- t = topology['threads']
- f = ['"%s"' % x for x in features]
- cpu_info = template % (arch, model, vendor, c, s, t, ', '.join(f))
- return cpu_info
-
def block_stats(self, instance_name, disk):
"""
Note that this function takes an instance name, not an Instance, so
@@ -933,208 +848,6 @@ class LibvirtConnection(object):
def refresh_security_group_members(self, security_group_id):
self.firewall_driver.refresh_security_group_members(security_group_id)
- def compare_cpu(self, cpu_info):
- """
- Check the host cpu is compatible to a cpu given by xml.
- "xml" must be a part of libvirt.openReadonly().getCapabilities().
- return values follows by virCPUCompareResult.
- if 0 > return value, do live migration.
-
- 'http://libvirt.org/html/libvirt-libvirt.html#virCPUCompareResult'
- """
- msg = _('Checking cpu_info: instance was launched this cpu.\n: %s ')
- LOG.info(msg % cpu_info)
- dic = json.loads(cpu_info)
- xml = str(Template(self.cpuinfo_xml, searchList=dic))
- msg = _('to xml...\n: %s ')
- LOG.info(msg % xml)
-
- url = 'http://libvirt.org/html/libvirt-libvirt.html'
- url += '#virCPUCompareResult\n'
- msg = 'CPU does not have compativility.\n'
- msg += 'result:%d \n'
- msg += 'Refer to %s'
- msg = _(msg)
-
- # unknown character exists in xml, then libvirt complains
- try:
- ret = self._conn.compareCPU(xml, 0)
- except libvirt.libvirtError, e:
- LOG.error(msg % (ret, url))
- raise e
-
- if ret <= 0:
- raise exception.Invalid(msg % (ret, url))
-
- return
-
- def ensure_filtering_rules_for_instance(self, instance_ref):
- """ Setting up inevitable filtering rules on compute node,
- and waiting for its completion.
- To migrate an instance, filtering rules to hypervisors
- and firewalls are inevitable on destination host.
- ( Waiting only for filterling rules to hypervisor,
- since filtering rules to firewall rules can be set faster).
-
- Concretely, the below method must be called.
- - setup_basic_filtering (for nova-basic, etc.)
- - prepare_instance_filter(for nova-instance-instance-xxx, etc.)
-
- to_xml may have to be called since it defines PROJNET, PROJMASK.
- but libvirt migrates those value through migrateToURI(),
- so , no need to be called.
-
- Don't use thread for this method since migration should
- not be started when setting-up filtering rules operations
- are not completed."""
-
- # Tf any instances never launch at destination host,
- # basic-filtering must be set here.
- self.nwfilter.setup_basic_filtering(instance_ref)
- # setting up n)ova-instance-instance-xx mainly.
- self.firewall_driver.prepare_instance_filter(instance_ref)
-
- # wait for completion
- timeout_count = range(FLAGS.live_migration_timeout_sec * 2)
- while len(timeout_count) != 0:
- try:
- filter_name = 'nova-instance-%s' % instance_ref.name
- self._conn.nwfilterLookupByName(filter_name)
- break
- except libvirt.libvirtError:
- timeout_count.pop()
- if len(timeout_count) == 0:
- ec2_id = instance_ref['hostname']
- msg = _('Timeout migrating for %s(%s)')
- raise exception.Error(msg % (ec2_id, instance_ref.name))
- time.sleep(0.5)
-
- def live_migration(self, context, instance_ref, dest):
- """
- Just spawning live_migration operation for
- distributing high-load.
- """
- greenthread.spawn(self._live_migration, context, instance_ref, dest)
-
- def _live_migration(self, context, instance_ref, dest):
- """ Do live migration."""
-
- # Do live migration.
- try:
- duri = FLAGS.live_migration_uri % dest
-
- flaglist = FLAGS.live_migration_flag.split(',')
- flagvals = [getattr(libvirt, x.strip()) for x in flaglist]
- logical_sum = reduce(lambda x, y: x | y, flagvals)
-
- bandwidth = FLAGS.live_migration_bandwidth
-
- if self.read_only:
- tmpconn = self._connect(self.libvirt_uri, False)
- dom = tmpconn.lookupByName(instance_ref.name)
- dom.migrateToURI(duri, logical_sum, None, bandwidth)
- tmpconn.close()
- else:
- dom = self._conn.lookupByName(instance_ref.name)
- dom.migrateToURI(duri, logical_sum, None, bandwidth)
-
- except Exception, e:
- id = instance_ref['id']
- db.instance_set_state(context, id, power_state.RUNNING, 'running')
- for v in instance_ref['volumes']:
- db.volume_update(context,
- v['id'],
- {'status': 'in-use'})
-
- raise e
-
- # Waiting for completion of live_migration.
- timer = utils.LoopingCall(f=None)
-
- def wait_for_live_migration():
-
- try:
- state = self.get_info(instance_ref.name)['state']
- except exception.NotFound:
- timer.stop()
- self._post_live_migration(context, instance_ref, dest)
-
- timer.f = wait_for_live_migration
- timer.start(interval=0.5, now=True)
-
- def _post_live_migration(self, context, instance_ref, dest):
- """
- Post operations for live migration.
- Mainly, database updating.
- """
- LOG.info('post livemigration operation is started..')
- # Detaching volumes.
- # (not necessary in current version )
-
- # Releasing vlan.
- # (not necessary in current implementation?)
-
- # Releasing security group ingress rule.
- if FLAGS.firewall_driver == \
- 'nova.virt.libvirt_conn.IptablesFirewallDriver':
- try:
- self.firewall_driver.unfilter_instance(instance_ref)
- except KeyError, e:
- pass
-
- # Database updating.
- ec2_id = instance_ref['hostname']
-
- instance_id = instance_ref['id']
- fixed_ip = db.instance_get_fixed_address(context, instance_id)
- # Not return if fixed_ip is not found, otherwise,
- # instance never be accessible..
- if None == fixed_ip:
- logging.warn('fixed_ip is not found for %s ' % ec2_id)
- db.fixed_ip_update(context, fixed_ip, {'host': dest})
- network_ref = db.fixed_ip_get_network(context, fixed_ip)
- db.network_update(context, network_ref['id'], {'host': dest})
-
- try:
- floating_ip \
- = db.instance_get_floating_address(context, instance_id)
- # Not return if floating_ip is not found, otherwise,
- # instance never be accessible..
- if None == floating_ip:
- logging.error('floating_ip is not found for %s ' % ec2_id)
- else:
- floating_ip_ref = db.floating_ip_get_by_address(context,
- floating_ip)
- db.floating_ip_update(context,
- floating_ip_ref['address'],
- {'host': dest})
- except exception.NotFound:
- logging.debug('%s doesnt have floating_ip.. ' % ec2_id)
- except:
- msg = 'Live migration: Unexpected error:'
- msg += '%s cannot inherit floating ip.. ' % ec2_id
- logging.error(_(msg))
-
- # Restore instance/volume state
- db.instance_update(context,
- instance_id,
- {'state_description': 'running',
- 'state': power_state.RUNNING,
- 'host': dest})
-
- for v in instance_ref['volumes']:
- db.volume_update(context,
- v['id'],
- {'status': 'in-use'})
-
- logging.info(_('Live migrating %s to %s finishes successfully')
- % (ec2_id, dest))
- msg = _(("""Known error: the below error is nomally occurs.\n"""
- """Just check if iinstance is successfully migrated.\n"""
- """libvir: QEMU error : Domain not found: no domain """
- """with matching name.."""))
- logging.info(msg)
-
class FirewallDriver(object):
def prepare_instance_filter(self, instance):
diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py
index 72ec6bddb..c57c883c9 100644
--- a/nova/virt/xenapi_conn.py
+++ b/nova/virt/xenapi_conn.py
@@ -212,36 +212,6 @@ class XenAPIConnection(object):
'username': FLAGS.xenapi_connection_username,
'password': FLAGS.xenapi_connection_password}
- def get_cpu_info(self):
- """This method is supported only libvirt. """
- return
-
- def get_vcpu_number(self):
- """This method is supported only libvirt. """
- return -1
-
- def get_memory_mb(self):
- """This method is supported only libvirt.."""
- return -1
-
- def get_local_gb(self):
- """This method is supported only libvirt.."""
- return -1
-
- def get_hypervisor_type(self):
- """This method is supported only libvirt.."""
- return
-
- def get_hypervisor_version(self):
- """This method is supported only libvirt.."""
- return -1
-
- def compare_cpu(self, xml):
- raise NotImplementedError('This method is supported only libvirt.')
-
- def live_migration(self, context, instance_ref, dest):
- raise NotImplementedError('This method is supported only libvirt.')
-
class XenAPISession(object):
"""The session to invoke XenAPI SDK calls"""
diff --git a/nova/volume/driver.py b/nova/volume/driver.py
index de018b573..da7307733 100644
--- a/nova/volume/driver.py
+++ b/nova/volume/driver.py
@@ -130,7 +130,7 @@ class VolumeDriver(object):
"""Removes an export for a logical volume."""
raise NotImplementedError()
- def discover_volume(self, _context, volume):
+ def discover_volume(self, volume):
"""Discover volume on a remote host."""
raise NotImplementedError()
@@ -192,35 +192,15 @@ class AOEDriver(VolumeDriver):
self._try_execute("sudo vblade-persist destroy %s %s" %
(shelf_id, blade_id))
- def discover_volume(self, context, volume):
+ def discover_volume(self, _volume):
"""Discover volume on a remote host."""
self._execute("sudo aoe-discover")
self._execute("sudo aoe-stat", check_exit_code=False)
- shelf_id, blade_id = self.db.volume_get_shelf_and_blade(context,
- volume['id'])
- return "/dev/etherd/e%s.%s" % (shelf_id, blade_id)
def undiscover_volume(self, _volume):
"""Undiscover volume on a remote host."""
pass
- def check_for_export(self, context, volume_id):
- """Make sure whether volume is exported."""
- (shelf_id,
- blade_id) = self.db.volume_get_shelf_and_blade(context,
- volume_id)
- (out, _err) = self._execute("sudo vblade-persist ls --no-header")
- exists = False
- for line in out.split('\n'):
- param = line.split(' ')
- if len(param) == 6 and param[0] == str(shelf_id) \
- and param[1] == str(blade_id) and param[-1] == "run":
- exists = True
- break
- if not exists:
- logging.warning(_("vblade process for e%s.%s isn't running.")
- % (shelf_id, blade_id))
-
class FakeAOEDriver(AOEDriver):
"""Logs calls instead of executing."""
@@ -325,7 +305,7 @@ class ISCSIDriver(VolumeDriver):
iscsi_portal = location.split(",")[0]
return (iscsi_name, iscsi_portal)
- def discover_volume(self, _context, volume):
+ def discover_volume(self, volume):
"""Discover volume on a remote host."""
iscsi_name, iscsi_portal = self._get_name_and_portal(volume['name'],
volume['host'])
@@ -414,7 +394,7 @@ class RBDDriver(VolumeDriver):
"""Removes an export for a logical volume"""
pass
- def discover_volume(self, _context, volume):
+ def discover_volume(self, volume):
"""Discover volume on a remote host"""
return "rbd:%s/%s" % (FLAGS.rbd_pool, volume['name'])
@@ -463,7 +443,7 @@ class SheepdogDriver(VolumeDriver):
"""Removes an export for a logical volume"""
pass
- def discover_volume(self, _context, volume):
+ def discover_volume(self, volume):
"""Discover volume on a remote host"""
return "sheepdog:%s" % volume['name']
diff --git a/nova/volume/manager.py b/nova/volume/manager.py
index da949df9e..82e3521a8 100644
--- a/nova/volume/manager.py
+++ b/nova/volume/manager.py
@@ -138,7 +138,8 @@ class VolumeManager(manager.Manager):
self.driver.delete_volume(volume_ref)
except Exception as e:
self.db.volume_update(context,
- volume_ref['id'], {'status': 'error_deleting'})
+ volume_ref['id'],
+ {'status': 'error_deleting'})
raise e
self.db.volume_destroy(context, volume_id)
@@ -154,7 +155,7 @@ class VolumeManager(manager.Manager):
if volume_ref['host'] == self.host and FLAGS.use_local_volumes:
path = self.driver.local_path(volume_ref)
else:
- path = self.driver.discover_volume(context, volume_ref)
+ path = self.driver.discover_volume(volume_ref)
return path
def remove_compute_volume(self, context, volume_id):
@@ -165,10 +166,3 @@ class VolumeManager(manager.Manager):
return True
else:
self.driver.undiscover_volume(volume_ref)
-
- def check_for_export(self, context, instance_id):
- """Make sure whether volume is exported."""
- if FLAGS.volume_driver == 'nova.volume.driver.AOEDriver':
- instance_ref = self.db.instance_get(instance_id)
- for v in instance_ref['volumes']:
- self.driver.check_for_export(context, v['id'])
diff --git a/run_tests.py b/run_tests.py
index 5b8617f63..7b5e2192a 100644
--- a/run_tests.py
+++ b/run_tests.py
@@ -17,7 +17,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
+import gettext
import os
import unittest
import sys
diff --git a/setup.py b/setup.py
index a20802e8b..3608ff805 100644
--- a/setup.py
+++ b/setup.py
@@ -34,7 +34,6 @@ if os.path.isdir('.bzr'):
version_file.write(vcsversion)
-
class local_BuildDoc(BuildDoc):
def run(self):
for builder in ['html', 'man']:
diff --git a/tools/pip-requires b/tools/pip-requires
index a6676a5e9..895e81eb3 100644
--- a/tools/pip-requires
+++ b/tools/pip-requires
@@ -25,5 +25,6 @@ bzr
Twisted>=10.1.0
PasteDeploy
paste
+sqlalchemy-migrate
netaddr
glance