Merge trunk and fix how nova-combined works with paste.deploy.

Refactor some of the bits of nova-api into nova/wsgi for working with paste,
for a little bit of de-duplication between nova-api and nova-combined.
Makes a cleaner interface for how paste configs can set flags.
This commit is contained in:
Todd Willey
2011-01-13 18:23:18 -05:00
5 changed files with 59 additions and 51 deletions

View File

@@ -24,8 +24,6 @@ import gettext
import os import os
import sys import sys
from paste import deploy
# If ../nova/__init__.py exists, add ../ to Python search path, so that # 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... # 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]), possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
@@ -42,43 +40,38 @@ from nova import wsgi
logging.basicConfig() logging.basicConfig()
LOG = logging.getLogger('nova.api') LOG = logging.getLogger('nova.api')
LOG.setLevel(logging.DEBUG)
FLAGS = flags.FLAGS FLAGS = flags.FLAGS
API_ENDPOINTS = ['ec2', 'osapi'] API_ENDPOINTS = ['ec2', 'osapi']
def load_configuration(paste_config, name):
"""Load the paste configuration from the config file and return it."""
config = None
try:
config = deploy.appconfig("config:%s" % paste_config, name=name)
return config
except LookupError:
return None
def run_app(paste_config_file): def run_app(paste_config_file):
LOG.debug(_("Using paste.deploy config at: %s"), configfile) LOG.debug(_("Using paste.deploy config at: %s"), paste_config_file)
server = wsgi.Server()
apps = [] apps = []
for api in API_ENDPOINTS: for api in API_ENDPOINTS:
config = load_configuration(paste_config_file, api) config = wsgi.load_paste_configuration(paste_config_file, api)
if config is None: if config is None:
LOG.debug(_("No paste configuration for app: %s"), api)
continue continue
if int(config.get('verbose', 0)) == 1: LOG.debug(_("App Config: %s\n%r"), api, config)
FLAGS.verbose = True wsgi.paste_config_to_flags(config, {
host = config.get("%s_host" % api, config.get('host', '0.0.0.0')) "verbose": FLAGS.verbose,
port = config.get("%s_port" % api, getattr(FLAGS, "%s_port" % api)) "%s_host" % api: config.get('host', '0.0.0.0'),
setattr(FLAGS, "%s_host" % api, host) "%s_port" % api: getattr(FLAGS, "%s_port" % api)})
setattr(FLAGS, "%s_port" % api, port)
LOG.info(_("Running %s API"), api) LOG.info(_("Running %s API"), api)
app = deploy.loadapp('config:%s' % paste_config_file, name=api) app = wsgi.load_paste_app(paste_config_file, api)
apps.append((app, int(port), host)) apps.append((app, getattr(FLAGS, "%s_port" % api),
getattr(FLAGS, "%s_host" % api)))
if len(apps) == 0: if len(apps) == 0:
LOG.error(_("No known API applications configured in %s."), LOG.error(_("No known API applications configured in %s."),
paste_config_file) paste_config_file)
else: return
# NOTE(todd): redo logging config, verbose could be set in paste config
logging.basicConfig()
server = wsgi.Server()
for app in apps: for app in apps:
server.start(*app) server.start(*app)
server.wait() server.wait()
@@ -86,13 +79,8 @@ def run_app(paste_config_file):
if __name__ == '__main__': if __name__ == '__main__':
FLAGS(sys.argv) FLAGS(sys.argv)
configfiles = ['/etc/nova/nova-api.conf'] conf = wsgi.paste_config_file('nova-api.conf')
if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): if conf:
configfiles.insert(0, run_app(conf)
os.path.join(possible_topdir, 'etc', 'nova-api.conf'))
for configfile in configfiles:
if os.path.exists(configfile):
run_app(configfile)
break
else: else:
LOG.debug(_("Skipping missing configuration: %s"), configfile) LOG.error(_("No paste configuration found for: %s"), 'nova-api.conf')

View File

@@ -36,22 +36,20 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
gettext.install('nova', unicode=1) gettext.install('nova', unicode=1)
from nova import api
from nova import flags from nova import flags
from nova import log as logging
from nova import service from nova import service
from nova import utils from nova import utils
from nova import wsgi from nova import wsgi
FLAGS = flags.FLAGS FLAGS = flags.FLAGS
flags.DEFINE_string('osapi_host', '0.0.0.0', 'OpenStack API host')
flags.DEFINE_integer('ec2api_port', 8773, 'EC2 API port')
flags.DEFINE_string('ec2api_host', '0.0.0.0', 'EC2 API host')
if __name__ == '__main__': if __name__ == '__main__':
utils.default_flagfile() utils.default_flagfile()
FLAGS(sys.argv) FLAGS(sys.argv)
logging.basicConfig()
compute = service.Service.create(binary='nova-compute') compute = service.Service.create(binary='nova-compute')
network = service.Service.create(binary='nova-network') network = service.Service.create(binary='nova-network')
@@ -61,7 +59,22 @@ if __name__ == '__main__':
service.serve(compute, network, volume, scheduler) service.serve(compute, network, volume, scheduler)
apps = []
paste_config_file = wsgi.paste_config_file('nova-api.conf')
for api in ['osapi', 'ec2']:
config = wsgi.load_paste_configuration(paste_config_file, api)
if config is None:
continue
wsgi.paste_config_to_flags(config, {
"verbose": FLAGS.verbose,
"%s_host" % api: config.get('host', '0.0.0.0'),
"%s_port" % api: getattr(FLAGS, "%s_port" % api)})
app = wsgi.load_paste_app(paste_config_file, api)
apps.append((app, getattr(FLAGS, "%s_port" % api),
getattr(FLAGS, "%s_host" % api)))
if len(apps) > 0:
logging.basicConfig()
server = wsgi.Server() server = wsgi.Server()
server.start(api.API('os'), FLAGS.osapi_port, host=FLAGS.osapi_host) for app in apps:
server.start(api.API('ec2'), FLAGS.ec2api_port, host=FLAGS.ec2api_host) server.start(*app)
server.wait() server.wait()

View File

@@ -721,7 +721,7 @@ class AuthManager(object):
if project is None: if project is None:
project = user.id project = user.id
pid = Project.safe_id(project) pid = Project.safe_id(project)
return self.__generate_rc(user.access, user.secret, pid, use_dmz) return self.__generate_rc(user, pid, use_dmz)
@staticmethod @staticmethod
def __generate_rc(user, pid, use_dmz=True, host=None): def __generate_rc(user, pid, use_dmz=True, host=None):

View File

@@ -116,6 +116,8 @@ def basicConfig():
handler.setFormatter(_formatter) handler.setFormatter(_formatter)
if FLAGS.verbose: if FLAGS.verbose:
logging.root.setLevel(logging.DEBUG) logging.root.setLevel(logging.DEBUG)
else:
logging.root.setLevel(logging.INFO)
if FLAGS.use_syslog: if FLAGS.use_syslog:
syslog = SysLogHandler(address='/dev/log') syslog = SysLogHandler(address='/dev/log')
syslog.setFormatter(_formatter) syslog.setFormatter(_formatter)

View File

@@ -126,10 +126,13 @@ class CloudTestCase(test.TestCase):
vol2 = db.volume_create(self.context, {}) vol2 = db.volume_create(self.context, {})
result = self.cloud.describe_volumes(self.context) result = self.cloud.describe_volumes(self.context)
self.assertEqual(len(result['volumeSet']), 2) self.assertEqual(len(result['volumeSet']), 2)
volume_id = cloud.id_to_ec2_id(vol2['id'], 'vol-%08x')
result = self.cloud.describe_volumes(self.context, result = self.cloud.describe_volumes(self.context,
volume_id=[vol2['id']]) volume_id=[volume_id])
self.assertEqual(len(result['volumeSet']), 1) self.assertEqual(len(result['volumeSet']), 1)
self.assertEqual(result['volumeSet'][0]['volumeId'], vol2['id']) self.assertEqual(
cloud.ec2_id_to_id(result['volumeSet'][0]['volumeId']),
vol2['id'])
db.volume_destroy(self.context, vol1['id']) db.volume_destroy(self.context, vol1['id'])
db.volume_destroy(self.context, vol2['id']) db.volume_destroy(self.context, vol2['id'])
@@ -385,7 +388,8 @@ class CloudTestCase(test.TestCase):
def test_update_of_volume_display_fields(self): def test_update_of_volume_display_fields(self):
vol = db.volume_create(self.context, {}) vol = db.volume_create(self.context, {})
self.cloud.update_volume(self.context, vol['id'], self.cloud.update_volume(self.context,
cloud.id_to_ec2_id(vol['id'], 'vol-%08x'),
display_name='c00l v0lum3') display_name='c00l v0lum3')
vol = db.volume_get(self.context, vol['id']) vol = db.volume_get(self.context, vol['id'])
self.assertEqual('c00l v0lum3', vol['display_name']) self.assertEqual('c00l v0lum3', vol['display_name'])
@@ -393,7 +397,8 @@ class CloudTestCase(test.TestCase):
def test_update_of_volume_wont_update_private_fields(self): def test_update_of_volume_wont_update_private_fields(self):
vol = db.volume_create(self.context, {}) vol = db.volume_create(self.context, {})
self.cloud.update_volume(self.context, vol['id'], self.cloud.update_volume(self.context,
cloud.id_to_ec2_id(vol['id'], 'vol-%08x'),
mountpoint='/not/here') mountpoint='/not/here')
vol = db.volume_get(self.context, vol['id']) vol = db.volume_get(self.context, vol['id'])
self.assertEqual(None, vol['mountpoint']) self.assertEqual(None, vol['mountpoint'])