merged to trunk rev572

This commit is contained in:
Kei Masumoto
2011-01-19 08:50:47 +09:00
9 changed files with 103 additions and 159 deletions

View File

@@ -34,22 +34,53 @@ 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 utils from nova import log as logging
from nova import wsgi from nova import wsgi
logging.basicConfig()
LOG = logging.getLogger('nova.api')
LOG.setLevel(logging.DEBUG)
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') API_ENDPOINTS = ['ec2', 'osapi']
flags.DEFINE_string('ec2api_host', '0.0.0.0', 'EC2 API host')
def run_app(paste_config_file):
LOG.debug(_("Using paste.deploy config at: %s"), paste_config_file)
apps = []
for api in API_ENDPOINTS:
config = wsgi.load_paste_configuration(paste_config_file, api)
if config is None:
LOG.debug(_("No paste configuration for app: %s"), api)
continue
LOG.debug(_("App Config: %s\n%r"), api, config)
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)})
LOG.info(_("Running %s API"), 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:
LOG.error(_("No known API applications configured in %s."),
paste_config_file)
return
# NOTE(todd): redo logging config, verbose could be set in paste config
logging.basicConfig()
server = wsgi.Server()
for app in apps:
server.start(*app)
server.wait()
if __name__ == '__main__': if __name__ == '__main__':
utils.default_flagfile()
FLAGS(sys.argv) FLAGS(sys.argv)
server = wsgi.Server() conf = wsgi.paste_config_file('nova-api.conf')
server.start(api.API('os'), FLAGS.osapi_port, host=FLAGS.osapi_host) if conf:
server.start(api.API('ec2'), FLAGS.ec2api_port, host=FLAGS.ec2api_host) run_app(conf)
server.wait() else:
LOG.error(_("No paste configuration found for: %s"), 'nova-api.conf')

View File

@@ -1,109 +0,0 @@
#!/usr/bin/env python
# pylint: disable-msg=C0103
# 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.
"""Starter script for Nova API."""
import gettext
import os
import sys
from paste import deploy
# 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]),
os.pardir,
os.pardir))
if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
sys.path.insert(0, possible_topdir)
gettext.install('nova', unicode=1)
from nova import flags
from nova import log as logging
from nova import wsgi
LOG = logging.getLogger('nova.api')
LOG.setLevel(logging.DEBUG)
LOG.addHandler(logging.StreamHandler())
FLAGS = flags.FLAGS
API_ENDPOINTS = ['ec2', 'openstack']
def load_configuration(paste_config):
"""Load the paste configuration from the config file and return it."""
config = None
# Try each known name to get the global DEFAULTS, which will give ports
for name in API_ENDPOINTS:
try:
config = deploy.appconfig("config:%s" % paste_config, name=name)
except LookupError:
pass
if config:
verbose = config.get('verbose', None)
if verbose:
FLAGS.verbose = int(verbose) == 1
if FLAGS.verbose:
logging.getLogger().setLevel(logging.DEBUG)
return config
LOG.debug(_("Paste config at %s has no secion for known apis"),
paste_config)
print _("Paste config at %s has no secion for any known apis") % \
paste_config
os.exit(1)
def launch_api(paste_config_file, section, server, port, host):
"""Launch an api server from the specified port and IP."""
LOG.debug(_("Launching %s api on %s:%s"), section, host, port)
app = deploy.loadapp('config:%s' % paste_config_file, name=section)
server.start(app, int(port), host)
def run_app(paste_config_file):
LOG.debug(_("Using paste.deploy config at: %s"), configfile)
config = load_configuration(paste_config_file)
LOG.debug(_("Configuration: %r"), config)
server = wsgi.Server()
ip = config.get('host', '0.0.0.0')
for api in API_ENDPOINTS:
port = config.get("%s_port" % api, None)
if not port:
continue
host = config.get("%s_host" % api, ip)
launch_api(configfile, api, server, port, host)
LOG.debug(_("All api servers launched, now waiting"))
server.wait()
if __name__ == '__main__':
FLAGS(sys.argv)
configfiles = ['/etc/nova/nova-api.conf']
if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
configfiles.insert(0,
os.path.join(possible_topdir, 'etc', 'nova-api.conf'))
for configfile in configfiles:
if os.path.exists(configfile):
run_app(configfile)
break
else:
LOG.debug(_("Skipping missing configuration: %s"), configfile)

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

@@ -682,7 +682,7 @@ class AuthManager(object):
region, _sep, region_host = item.partition("=") region, _sep, region_host = item.partition("=")
regions[region] = region_host regions[region] = region_host
else: else:
regions = {'nova': FLAGS.cc_host} regions = {'nova': FLAGS.ec2_host}
for region, host in regions.iteritems(): for region, host in regions.iteritems():
rc = self.__generate_rc(user, rc = self.__generate_rc(user,
pid, pid,
@@ -727,28 +727,28 @@ class AuthManager(object):
def __generate_rc(user, pid, use_dmz=True, host=None): def __generate_rc(user, pid, use_dmz=True, host=None):
"""Generate rc file for user""" """Generate rc file for user"""
if use_dmz: if use_dmz:
cc_host = FLAGS.cc_dmz ec2_host = FLAGS.ec2_dmz_host
else: else:
cc_host = FLAGS.cc_host ec2_host = FLAGS.ec2_host
# NOTE(vish): Always use the dmz since it is used from inside the # NOTE(vish): Always use the dmz since it is used from inside the
# instance # instance
s3_host = FLAGS.s3_dmz s3_host = FLAGS.s3_dmz
if host: if host:
s3_host = host s3_host = host
cc_host = host ec2_host = host
rc = open(FLAGS.credentials_template).read() rc = open(FLAGS.credentials_template).read()
rc = rc % {'access': user.access, rc = rc % {'access': user.access,
'project': pid, 'project': pid,
'secret': user.secret, 'secret': user.secret,
'ec2': '%s://%s:%s%s' % (FLAGS.ec2_prefix, 'ec2': '%s://%s:%s%s' % (FLAGS.ec2_scheme,
cc_host, ec2_host,
FLAGS.cc_port, FLAGS.ec2_port,
FLAGS.ec2_suffix), FLAGS.ec2_path),
's3': 'http://%s:%s' % (s3_host, FLAGS.s3_port), 's3': 'http://%s:%s' % (s3_host, FLAGS.s3_port),
'os': '%s://%s:%s%s' % (FLAGS.os_prefix, 'os': '%s://%s:%s%s' % (FLAGS.osapi_scheme,
cc_host, ec2_host,
FLAGS.osapi_port, FLAGS.osapi_port,
FLAGS.os_suffix), FLAGS.osapi_path),
'user': user.name, 'user': user.name,
'nova': FLAGS.ca_file, 'nova': FLAGS.ca_file,
'cert': FLAGS.credential_cert_file, 'cert': FLAGS.credential_cert_file,

View File

@@ -254,14 +254,15 @@ DEFINE_string('rabbit_virtual_host', '/', 'rabbit virtual host')
DEFINE_integer('rabbit_retry_interval', 10, 'rabbit connection retry interval') DEFINE_integer('rabbit_retry_interval', 10, 'rabbit connection retry interval')
DEFINE_integer('rabbit_max_retries', 12, 'rabbit connection attempts') DEFINE_integer('rabbit_max_retries', 12, 'rabbit connection attempts')
DEFINE_string('control_exchange', 'nova', 'the main exchange to connect to') DEFINE_string('control_exchange', 'nova', 'the main exchange to connect to')
DEFINE_string('ec2_prefix', 'http', 'prefix for ec2') DEFINE_string('ec2_host', '$my_ip', 'ip of api server')
DEFINE_string('os_prefix', 'http', 'prefix for openstack') DEFINE_string('ec2_dmz_host', '$my_ip', 'internal ip of api server')
DEFINE_string('cc_host', '$my_ip', 'ip of api server') DEFINE_integer('ec2_port', 8773, 'cloud controller port')
DEFINE_string('cc_dmz', '$my_ip', 'internal ip of api server') DEFINE_string('ec2_scheme', 'http', 'prefix for ec2')
DEFINE_integer('cc_port', 8773, 'cloud controller port') DEFINE_string('ec2_path', '/services/Cloud', 'suffix for ec2')
DEFINE_string('osapi_host', '$my_ip', 'ip of api server')
DEFINE_string('osapi_scheme', 'http', 'prefix for openstack')
DEFINE_integer('osapi_port', 8774, 'OpenStack API port') DEFINE_integer('osapi_port', 8774, 'OpenStack API port')
DEFINE_string('ec2_suffix', '/services/Cloud', 'suffix for ec2') DEFINE_string('osapi_path', '/v1.0/', 'suffix for openstack')
DEFINE_string('os_suffix', '/v1.0/', 'suffix for openstack')
DEFINE_string('default_project', 'openstack', 'default project for openstack') DEFINE_string('default_project', 'openstack', 'default project for openstack')
DEFINE_string('default_image', 'ami-11111', DEFINE_string('default_image', 'ami-11111',

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

@@ -20,21 +20,31 @@ import unittest
import webob import webob
from nova import context from nova import context
from nova import exception
from nova import flags from nova import flags
from nova import test from nova import test
from nova.api import ec2 from nova.api import ec2
from nova.auth import manager from nova.auth import manager
FLAGS = flags.FLAGS FLAGS = flags.FLAGS
class Context(object): class FakeControllerClass(object):
pass pass
class FakeApiRequest(object):
def __init__(self, action):
self.controller = FakeControllerClass()
self.action = action
class AccessTestCase(test.TestCase): class AccessTestCase(test.TestCase):
def _env_for(self, ctxt, action):
env = {}
env['ec2.context'] = ctxt
env['ec2.request'] = FakeApiRequest(action)
return env
def setUp(self): def setUp(self):
super(AccessTestCase, self).setUp() super(AccessTestCase, self).setUp()
um = manager.AuthManager() um = manager.AuthManager()
@@ -64,7 +74,7 @@ class AccessTestCase(test.TestCase):
return [''] return ['']
self.mw = ec2.Authorizer(noopWSGIApp) self.mw = ec2.Authorizer(noopWSGIApp)
self.mw.action_roles = {'str': { self.mw.action_roles = {'FakeControllerClass': {
'_allow_all': ['all'], '_allow_all': ['all'],
'_allow_none': [], '_allow_none': [],
'_allow_project_manager': ['projectmanager'], '_allow_project_manager': ['projectmanager'],
@@ -84,9 +94,7 @@ class AccessTestCase(test.TestCase):
def response_status(self, user, methodName): def response_status(self, user, methodName):
ctxt = context.RequestContext(user, self.project) ctxt = context.RequestContext(user, self.project)
environ = {'ec2.context': ctxt, environ = self._env_for(ctxt, methodName)
'ec2.controller': 'some string',
'ec2.action': methodName}
req = webob.Request.blank('/', environ) req = webob.Request.blank('/', environ)
resp = req.get_response(self.mw) resp = req.get_response(self.mw)
return resp.status_int return resp.status_int

View File

@@ -26,9 +26,8 @@ import StringIO
import webob import webob
from nova import context from nova import context
from nova import flags
from nova import test from nova import test
from nova import api from nova.api import ec2
from nova.api.ec2 import cloud from nova.api.ec2 import cloud
from nova.api.ec2 import apirequest from nova.api.ec2 import apirequest
from nova.auth import manager from nova.auth import manager
@@ -100,12 +99,10 @@ class ApiEc2TestCase(test.TestCase):
"""Unit test for the cloud controller on an EC2 API""" """Unit test for the cloud controller on an EC2 API"""
def setUp(self): def setUp(self):
super(ApiEc2TestCase, self).setUp() super(ApiEc2TestCase, self).setUp()
self.manager = manager.AuthManager() self.manager = manager.AuthManager()
self.host = '127.0.0.1' self.host = '127.0.0.1'
self.app = ec2.Authenticate(ec2.Requestify(ec2.Executor(),
self.app = api.API('ec2') 'nova.api.ec2.cloud.CloudController'))
def expect_http(self, host=None, is_secure=False): def expect_http(self, host=None, is_secure=False):
"""Returns a new EC2 connection""" """Returns a new EC2 connection"""

View File

@@ -32,8 +32,9 @@ from nova import utils
from nova.auth import manager from nova.auth import manager
FLAGS = flags.FLAGS
LOG = logging.getLogger('nova.tests.compute') LOG = logging.getLogger('nova.tests.compute')
FLAGS = flags.FLAGS
flags.DECLARE('stub_network', 'nova.compute.manager')
class ComputeTestCase(test.TestCase): class ComputeTestCase(test.TestCase):