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:
parent
e1aaaa8f04
commit
9c2a8f25d9
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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():
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user