Fixes binaries, updates WSGI file to more recent version from Nova, and fixes an issue in SQLAlchemy API that was being hidden by stubs and only showed up when starting up the actual binaries and testing...

This commit is contained in:
jaypipes@gmail.com 2010-12-18 13:00:21 -05:00
parent e1aaaa8f04
commit 9c2a8f25d9
10 changed files with 89 additions and 60 deletions

View File

@ -1,5 +1,4 @@
#!/usr/bin/env python
# pylint: disable-msg=C0103
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2010 United States Government as represented by the
@ -17,20 +16,17 @@
# 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.
"""
Teller API daemon.
Glance API Server
"""
import os
import sys
# If ../parallax/__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, 'teller', '__init__.py')):
sys.path.insert(0, possible_topdir)
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(ROOT_DIR)
from glance.common import flags
from glance.common import utils
@ -38,15 +34,20 @@ from glance.common import server
FLAGS = flags.FLAGS
flags.DEFINE_integer('teller_port', 9292, 'Teller port')
flags.DEFINE_string('api_host', '0.0.0.0', 'API server lives at this address')
flags.DEFINE_integer('api_port', 9292, 'API server listens on this port')
def main(_args):
# NOTE(sirp): importing in main so that eventlet is imported AFTER daemonization
# see https://bugs.launchpad.net/bugs/687661
from glance.common import wsgi
from glance.teller import controllers
wsgi.run_server(controllers.API(), FLAGS.teller_port)
from glance.server import API
server = wsgi.Server()
server.start(API(), FLAGS.api_port, host=FLAGS.api_host)
server.wait()
if __name__ == '__main__':
utils.default_flagfile()
server.serve('teller-server', main)
server.serve('glance-api', main)

View File

@ -1,5 +1,4 @@
#!/usr/bin/env python
# pylint: disable-msg=C0103
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2010 United States Government as represented by the
@ -18,19 +17,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Parallax API daemon.
Reference implementation server for Glance Registry
"""
import os
import sys
# If ../parallax/__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, 'parallax', '__init__.py')):
sys.path.insert(0, possible_topdir)
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(ROOT_DIR)
from glance.common import flags
from glance.common import utils
@ -38,15 +33,21 @@ from glance.common import server
FLAGS = flags.FLAGS
flags.DEFINE_integer('parallax_port', 9191, 'Parallax port')
flags.DEFINE_string('registry_host', '0.0.0.0',
'Registry server lives at this address')
flags.DEFINE_integer('registry_port', 9191,
'Registry server listens on this port')
def main(_args):
# NOTE(sirp): importing in main so that eventlet is imported AFTER daemonization
# see https://bugs.launchpad.net/bugs/687661
from glance.common import wsgi
from glance.parallax import controllers
wsgi.run_server(controllers.API(), FLAGS.parallax_port)
from glance.registry.server import API
server = wsgi.Server()
server.start(API(), FLAGS.registry_port, host=FLAGS.registry_host)
server.wait()
if __name__ == '__main__':
utils.default_flagfile()
server.serve('parallax-server', main)
server.serve('glance-registry', main)

View File

@ -42,6 +42,8 @@ flags.DEFINE_bool('daemonize', False, 'daemonize this process')
# clutter.
flags.DEFINE_bool('use_syslog', True, 'output to syslog when daemonizing')
flags.DEFINE_string('logfile', None, 'log file to output to')
flags.DEFINE_string('logdir', None, 'directory to keep log files in '
'(will be prepended to $logfile)')
flags.DEFINE_string('pidfile', None, 'pid file to output to')
flags.DEFINE_string('working_directory', './', 'working directory...')
flags.DEFINE_integer('uid', os.getuid(), 'uid under which to run')
@ -54,11 +56,11 @@ def stop(pidfile):
"""
# Get the pid from the pidfile
try:
pid = int(open(pidfile,'r').read().strip())
pid = int(open(pidfile, 'r').read().strip())
except IOError:
message = "pidfile %s does not exist. Daemon not running?\n"
sys.stderr.write(message % pidfile)
return # not an error in a restart
return
# Try killing the daemon process
try:
@ -106,6 +108,7 @@ def serve(name, main):
def daemonize(args, name, main):
"""Does the work of daemonizing the process"""
logging.getLogger('amqplib').setLevel(logging.WARN)
files_to_keep = []
if FLAGS.daemonize:
logger = logging.getLogger()
formatter = logging.Formatter(
@ -114,12 +117,16 @@ def daemonize(args, name, main):
syslog = logging.handlers.SysLogHandler(address='/dev/log')
syslog.setFormatter(formatter)
logger.addHandler(syslog)
files_to_keep.append(syslog.socket)
else:
if not FLAGS.logfile:
FLAGS.logfile = '%s.log' % name
if FLAGS.logdir:
FLAGS.logfile = os.path.join(FLAGS.logdir, FLAGS.logfile)
logfile = logging.FileHandler(FLAGS.logfile)
logfile.setFormatter(formatter)
logger.addHandler(logfile)
files_to_keep.append(logfile.stream)
stdin, stdout, stderr = None, None, None
else:
stdin, stdout, stderr = sys.stdin, sys.stdout, sys.stderr
@ -139,6 +146,6 @@ def daemonize(args, name, main):
stdout=stdout,
stderr=stderr,
uid=FLAGS.uid,
gid=FLAGS.gid
):
gid=FLAGS.gid,
files_preserve=files_to_keep):
main(args)

View File

@ -43,6 +43,29 @@ def run_server(application, port):
eventlet.wsgi.server(sock, application)
class Server(object):
"""Server class to manage multiple WSGI sockets and applications."""
def __init__(self, threads=1000):
self.pool = eventlet.GreenPool(threads)
def start(self, application, port, host='0.0.0.0', backlog=128):
"""Run a WSGI server with the given application."""
socket = eventlet.listen((host, port), backlog=backlog)
self.pool.spawn_n(self._run, application, socket)
def wait(self):
"""Wait until all servers have completed running."""
try:
self.pool.waitall()
except KeyboardInterrupt:
pass
def _run(self, application, socket):
"""Start a WSGI server in a new green thread."""
eventlet.wsgi.server(socket, application, custom_pool=self.pool)
class Application(object):
# TODO(gundlach): I think we should toss this class, now that it has no
# purpose.

View File

@ -69,7 +69,6 @@ def image_get(context, image_id):
session = get_session()
try:
return session.query(models.Image
).options(joinedload(models.Image.files)
).options(joinedload(models.Image.properties)
).filter_by(deleted=_deleted(context)
).filter_by(id=image_id
@ -82,7 +81,6 @@ def image_get(context, image_id):
def image_get_all(context):
session = get_session()
return session.query(models.Image
).options(joinedload(models.Image.files)
).options(joinedload(models.Image.properties)
).filter_by(deleted=_deleted(context)
).all()
@ -91,7 +89,6 @@ def image_get_all(context):
def image_get_all_public(context, public):
session = get_session()
return session.query(models.Image
).options(joinedload(models.Image.files)
).options(joinedload(models.Image.properties)
).filter_by(deleted=_deleted(context)
).filter_by(is_public=public

View File

@ -28,7 +28,7 @@ import stubout
import webob
from glance.common import exception
from glance.registry import controllers as registry_controllers
from glance.registry import server as rserver
from glance import server
import glance.store
import glance.store.filesystem
@ -199,7 +199,7 @@ def stub_out_registry_and_store_server(stubs):
self.req.body = body
def getresponse(self):
res = self.req.get_response(registry_controllers.API())
res = self.req.get_response(rserver.API())
# httplib.Response has a read() method...fake it out
def fake_reader():

View File

@ -22,7 +22,7 @@ import stubout
import webob
from glance import server
from glance.registry import controllers
from glance.registry import server as rserver
from tests import stubs
@ -47,7 +47,7 @@ class TestImageController(unittest.TestCase):
fixture = {'id': 2,
'name': 'fake image #2'}
req = webob.Request.blank('/')
res = req.get_response(controllers.API())
res = req.get_response(rserver.API())
res_dict = json.loads(res.body)
self.assertEquals(res.status_int, 200)
@ -65,7 +65,7 @@ class TestImageController(unittest.TestCase):
fixture = {'id': 2,
'name': 'fake image #2'}
req = webob.Request.blank('/images')
res = req.get_response(controllers.API())
res = req.get_response(rserver.API())
res_dict = json.loads(res.body)
self.assertEquals(res.status_int, 200)
@ -87,7 +87,7 @@ class TestImageController(unittest.TestCase):
'status': 'available'
}
req = webob.Request.blank('/images/detail')
res = req.get_response(controllers.API())
res = req.get_response(rserver.API())
res_dict = json.loads(res.body)
self.assertEquals(res.status_int, 200)
@ -109,7 +109,7 @@ class TestImageController(unittest.TestCase):
req.method = 'POST'
req.body = json.dumps(dict(image=fixture))
res = req.get_response(controllers.API())
res = req.get_response(rserver.API())
self.assertEquals(res.status_int, 200)
@ -141,7 +141,7 @@ class TestImageController(unittest.TestCase):
# TODO(jaypipes): Port Nova's Fault infrastructure
# over to Glance to support exception catching into
# standard HTTP errors.
res = req.get_response(controllers.API())
res = req.get_response(rserver.API())
self.assertEquals(res.status_int, webob.exc.HTTPBadRequest.code)
def test_update_image(self):
@ -155,7 +155,7 @@ class TestImageController(unittest.TestCase):
req.method = 'PUT'
req.body = json.dumps(dict(image=fixture))
res = req.get_response(controllers.API())
res = req.get_response(rserver.API())
self.assertEquals(res.status_int, 200)
@ -182,7 +182,7 @@ class TestImageController(unittest.TestCase):
# TODO(jaypipes): Port Nova's Fault infrastructure
# over to Glance to support exception catching into
# standard HTTP errors.
res = req.get_response(controllers.API())
res = req.get_response(rserver.API())
self.assertEquals(res.status_int,
webob.exc.HTTPNotFound.code)
@ -191,7 +191,7 @@ class TestImageController(unittest.TestCase):
# Grab the original number of images
req = webob.Request.blank('/images')
res = req.get_response(controllers.API())
res = req.get_response(rserver.API())
res_dict = json.loads(res.body)
self.assertEquals(res.status_int, 200)
@ -202,13 +202,13 @@ class TestImageController(unittest.TestCase):
req.method = 'DELETE'
res = req.get_response(controllers.API())
res = req.get_response(rserver.API())
self.assertEquals(res.status_int, 200)
# Verify one less image
req = webob.Request.blank('/images')
res = req.get_response(controllers.API())
res = req.get_response(rserver.API())
res_dict = json.loads(res.body)
self.assertEquals(res.status_int, 200)
@ -226,7 +226,7 @@ class TestImageController(unittest.TestCase):
# TODO(jaypipes): Port Nova's Fault infrastructure
# over to Glance to support exception catching into
# standard HTTP errors.
res = req.get_response(controllers.API())
res = req.get_response(rserver.API())
self.assertEquals(res.status_int,
webob.exc.HTTPNotFound.code)

View File

@ -21,7 +21,7 @@ import unittest
import webob
from glance.common import exception
from glance.registry import controllers
from glance.registry import server
from tests import stubs
@ -43,7 +43,7 @@ class TestImageController(unittest.TestCase):
fixture = {'id': 2,
'name': 'fake image #2'}
req = webob.Request.blank('/')
res = req.get_response(controllers.API())
res = req.get_response(server.API())
res_dict = json.loads(res.body)
self.assertEquals(res.status_int, 200)
@ -61,7 +61,7 @@ class TestImageController(unittest.TestCase):
fixture = {'id': 2,
'name': 'fake image #2'}
req = webob.Request.blank('/images')
res = req.get_response(controllers.API())
res = req.get_response(server.API())
res_dict = json.loads(res.body)
self.assertEquals(res.status_int, 200)
@ -83,7 +83,7 @@ class TestImageController(unittest.TestCase):
'status': 'available'
}
req = webob.Request.blank('/images/detail')
res = req.get_response(controllers.API())
res = req.get_response(server.API())
res_dict = json.loads(res.body)
self.assertEquals(res.status_int, 200)
@ -105,7 +105,7 @@ class TestImageController(unittest.TestCase):
req.method = 'POST'
req.body = json.dumps(dict(image=fixture))
res = req.get_response(controllers.API())
res = req.get_response(server.API())
self.assertEquals(res.status_int, 200)
@ -137,7 +137,7 @@ class TestImageController(unittest.TestCase):
# TODO(jaypipes): Port Nova's Fault infrastructure
# over to Glance to support exception catching into
# standard HTTP errors.
res = req.get_response(controllers.API())
res = req.get_response(server.API())
self.assertEquals(res.status_int, webob.exc.HTTPBadRequest.code)
def test_update_image(self):
@ -151,7 +151,7 @@ class TestImageController(unittest.TestCase):
req.method = 'PUT'
req.body = json.dumps(dict(image=fixture))
res = req.get_response(controllers.API())
res = req.get_response(server.API())
self.assertEquals(res.status_int, 200)
@ -178,7 +178,7 @@ class TestImageController(unittest.TestCase):
# TODO(jaypipes): Port Nova's Fault infrastructure
# over to Glance to support exception catching into
# standard HTTP errors.
res = req.get_response(controllers.API())
res = req.get_response(server.API())
self.assertEquals(res.status_int,
webob.exc.HTTPNotFound.code)
@ -187,7 +187,7 @@ class TestImageController(unittest.TestCase):
# Grab the original number of images
req = webob.Request.blank('/images')
res = req.get_response(controllers.API())
res = req.get_response(server.API())
res_dict = json.loads(res.body)
self.assertEquals(res.status_int, 200)
@ -198,13 +198,13 @@ class TestImageController(unittest.TestCase):
req.method = 'DELETE'
res = req.get_response(controllers.API())
res = req.get_response(server.API())
self.assertEquals(res.status_int, 200)
# Verify one less image
req = webob.Request.blank('/images')
res = req.get_response(controllers.API())
res = req.get_response(server.API())
res_dict = json.loads(res.body)
self.assertEquals(res.status_int, 200)
@ -222,6 +222,6 @@ class TestImageController(unittest.TestCase):
# TODO(jaypipes): Port Nova's Fault infrastructure
# over to Glance to support exception catching into
# standard HTTP errors.
res = req.get_response(controllers.API())
res = req.get_response(server.API())
self.assertEquals(res.status_int,
webob.exc.HTTPNotFound.code)

View File

@ -4,7 +4,7 @@ pep8==0.5.0
pylint==0.19
anyjson
eventlet>=0.9.12
lockfile
lockfile==0.8
python-daemon==1.5.5
python-gflags>=1.3
routes