summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Wolf <throughnothing@gmail.com>2011-08-12 13:07:24 -0400
committerWilliam Wolf <throughnothing@gmail.com>2011-08-12 13:07:24 -0400
commit3cbf0267efdef7d36a88faeb545342619f82f108 (patch)
treec81663c39757891e27de1c64a2f67ab865fb009c
parentcfa71424fd1724b809c0794fb4ae56f1b1c30e8a (diff)
parentbf334c786091ace63dd943e5e5893a239a22d21e (diff)
downloadnova-3cbf0267efdef7d36a88faeb545342619f82f108.tar.gz
nova-3cbf0267efdef7d36a88faeb545342619f82f108.tar.xz
nova-3cbf0267efdef7d36a88faeb545342619f82f108.zip
merge from trunk
-rw-r--r--nova/api/openstack/common.py15
-rw-r--r--nova/db/sqlalchemy/session.py90
-rw-r--r--nova/flags.py6
-rw-r--r--nova/tests/api/openstack/test_common.py4
-rw-r--r--nova/tests/api/openstack/test_servers.py16
-rw-r--r--nova/virt/xenapi/vmops.py2
6 files changed, 104 insertions, 29 deletions
diff --git a/nova/api/openstack/common.py b/nova/api/openstack/common.py
index dfdd62201..b2a675653 100644
--- a/nova/api/openstack/common.py
+++ b/nova/api/openstack/common.py
@@ -169,13 +169,20 @@ def get_id_from_href(href):
Returns: 123
"""
- if re.match(r'\d+$', str(href)):
+ LOG.debug(_("Attempting to treat %(href)s as an integer ID.") % locals())
+
+ try:
return int(href)
+ except ValueError:
+ pass
+
+ LOG.debug(_("Attempting to treat %(href)s as a URL.") % locals())
+
try:
return int(urlparse.urlsplit(href).path.split('/')[-1])
- except ValueError, e:
- LOG.debug(_("Error extracting id from href: %s") % href)
- raise ValueError(_('could not parse id from href'))
+ except ValueError as error:
+ LOG.debug(_("Failed to parse ID from %(href)s: %(error)s") % locals())
+ raise
def remove_version_from_href(href):
diff --git a/nova/db/sqlalchemy/session.py b/nova/db/sqlalchemy/session.py
index 4a9a28f43..07f281938 100644
--- a/nova/db/sqlalchemy/session.py
+++ b/nova/db/sqlalchemy/session.py
@@ -19,37 +19,79 @@
Session Handling for SQLAlchemy backend
"""
-from sqlalchemy import create_engine
-from sqlalchemy import pool
-from sqlalchemy.orm import sessionmaker
+import eventlet.patcher
+eventlet.patcher.monkey_patch()
-from nova import exception
-from nova import flags
+import eventlet.db_pool
+import sqlalchemy.orm
+import sqlalchemy.pool
+
+import nova.exception
+import nova.flags
+import nova.log
+
+
+FLAGS = nova.flags.FLAGS
+LOG = nova.log.getLogger("nova.db.sqlalchemy")
+
+
+try:
+ import MySQLdb
+except ImportError:
+ MySQLdb = None
-FLAGS = flags.FLAGS
_ENGINE = None
_MAKER = None
def get_session(autocommit=True, expire_on_commit=False):
- """Helper method to grab session"""
- global _ENGINE
- global _MAKER
- if not _MAKER:
- if not _ENGINE:
- kwargs = {'pool_recycle': FLAGS.sql_idle_timeout,
- 'echo': False}
-
- if FLAGS.sql_connection.startswith('sqlite'):
- kwargs['poolclass'] = pool.NullPool
-
- _ENGINE = create_engine(FLAGS.sql_connection,
- **kwargs)
- _MAKER = (sessionmaker(bind=_ENGINE,
- autocommit=autocommit,
- expire_on_commit=expire_on_commit))
+ """Return a SQLAlchemy session."""
+ global _ENGINE, _MAKER
+
+ if _MAKER is None or _ENGINE is None:
+ _ENGINE = get_engine()
+ _MAKER = get_maker(_ENGINE, autocommit, expire_on_commit)
+
session = _MAKER()
- session.query = exception.wrap_db_error(session.query)
- session.flush = exception.wrap_db_error(session.flush)
+ session.query = nova.exception.wrap_db_error(session.query)
+ session.flush = nova.exception.wrap_db_error(session.flush)
return session
+
+
+def get_engine():
+ """Return a SQLAlchemy engine."""
+ connection_dict = sqlalchemy.engine.url.make_url(FLAGS.sql_connection)
+
+ engine_args = {
+ "pool_recycle": FLAGS.sql_idle_timeout,
+ "echo": False,
+ }
+
+ if "sqlite" in connection_dict.drivername:
+ engine_args["poolclass"] = sqlalchemy.pool.NullPool
+
+ elif MySQLdb and "mysql" in connection_dict.drivername:
+ LOG.info(_("Using mysql/eventlet db_pool."))
+ pool_args = {
+ "db": connection_dict.database,
+ "passwd": connection_dict.password,
+ "host": connection_dict.host,
+ "user": connection_dict.username,
+ "min_size": FLAGS.sql_min_pool_size,
+ "max_size": FLAGS.sql_max_pool_size,
+ "max_idle": FLAGS.sql_idle_timeout,
+ }
+ creator = eventlet.db_pool.ConnectionPool(MySQLdb, **pool_args)
+ engine_args["pool_size"] = FLAGS.sql_max_pool_size
+ engine_args["pool_timeout"] = FLAGS.sql_pool_timeout
+ engine_args["creator"] = creator.create
+
+ return sqlalchemy.create_engine(FLAGS.sql_connection, **engine_args)
+
+
+def get_maker(engine, autocommit=True, expire_on_commit=False):
+ """Return a SQLAlchemy sessionmaker using the given engine."""
+ return sqlalchemy.orm.sessionmaker(bind=engine,
+ autocommit=autocommit,
+ expire_on_commit=expire_on_commit)
diff --git a/nova/flags.py b/nova/flags.py
index 7916501a4..e994a1665 100644
--- a/nova/flags.py
+++ b/nova/flags.py
@@ -345,6 +345,12 @@ DEFINE_string('logdir', None, 'output to a per-service log file in named '
'directory')
DEFINE_integer('logfile_mode', 0644, 'Default file mode of the logs.')
DEFINE_string('sqlite_db', 'nova.sqlite', 'file name for sqlite')
+DEFINE_integer('sql_pool_timeout', 30,
+ 'seconds to wait for connection from pool before erroring')
+DEFINE_integer('sql_min_pool_size', 10,
+ 'minimum number of SQL connections to pool')
+DEFINE_integer('sql_max_pool_size', 10,
+ 'maximum number of SQL connections to pool')
DEFINE_string('sql_connection',
'sqlite:///$state_path/$sqlite_db',
'connection string for sql database')
diff --git a/nova/tests/api/openstack/test_common.py b/nova/tests/api/openstack/test_common.py
index 5a6e43579..b422bc4d1 100644
--- a/nova/tests/api/openstack/test_common.py
+++ b/nova/tests/api/openstack/test_common.py
@@ -249,6 +249,10 @@ class MiscFunctionsTest(test.TestCase):
common.get_id_from_href,
fixture)
+ def test_get_id_from_href_int(self):
+ fixture = 1
+ self.assertEqual(fixture, common.get_id_from_href(fixture))
+
def test_get_version_from_href(self):
fixture = 'http://www.testsite.com/v1.1/images'
expected = '1.1'
diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py
index f55ecbf1d..4ac1168fe 100644
--- a/nova/tests/api/openstack/test_servers.py
+++ b/nova/tests/api/openstack/test_servers.py
@@ -1653,6 +1653,22 @@ class ServersTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 400)
+ def test_create_instance_v1_1_invalid_flavor_id_int(self):
+ self._setup_for_create_instance()
+
+ image_href = 'http://localhost/v1.1/images/2'
+ flavor_ref = -1
+ body = dict(server=dict(
+ name='server_test', imageRef=image_href, flavorRef=flavor_ref,
+ metadata={'hello': 'world', 'open': 'stack'},
+ personality={}))
+ req = webob.Request.blank('/v1.1/servers')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ res = req.get_response(fakes.wsgi_app())
+ self.assertEqual(res.status_int, 400)
+
def test_create_instance_v1_1_bad_flavor_href(self):
self._setup_for_create_instance()
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index b9cd59946..b1522729a 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -186,7 +186,7 @@ class VMOps(object):
instance.project_id, ImageType.KERNEL)[0]
if instance.ramdisk_id:
ramdisk = VMHelper.fetch_image(context, self._session,
- instance.id, instance.kernel_id, instance.user_id,
+ instance.id, instance.ramdisk_id, instance.user_id,
instance.project_id, ImageType.RAMDISK)[0]
# Create the VM ref and attach the first disk
first_vdi_ref = self._session.call_xenapi('VDI.get_by_uuid',