April 17, 2016

Using keystone 9.0.0 (Mitaka) with gunicorn and nginx

by orzel
Categories: Admin, Gentoo
Tags: , , , , , ,
Comments: Leave a Comment

(all of this is done in Gentoo, but this is mostly irrelevant here).

With the Mitaka release, keystone expects a WSGI server of some sort. The ‘canonical’ documentation is focused on apache + uwsgi. Apache is so old school, I haven’t used it at all since .. 2010 or so I think. I have nothing against uwsgi (never really tested it actually), but my server has a very stable gunicorn + supervisord setup I’d like to reuse.

This was not as trivial as expected. I mean, those are all WSGI-compliant stuff you are supposed to swap easily. But not.

First thing is, openstack/keystone provide wsgi scripts with hyphens : /usr/bin/keystone-wsgi-{admin,public}, which is definitely not python friendly (and even less pythonic). You need to provide a python path to gunicorn.

Those scripts are supposed to be usable as executable (using a basic development-only server, not to be used in production) and as wsgi script as well (providing an ‘application’ object). I personnaly would have made those scripts different, be it only to confuse people less.

And at last, there’s a big incompatibility between keystone (wsgi application) and gunicorn. The result is that keystone ‘sees’ arguments sent to gunicorn. As keystone is very strict about arguments (rightfully!), it exits. According to people that know better than me (on #openstack-keystone irc channel), the reason would be that they both use getopt for command line parsing. My stance is that is that I’ve never seen a WSGI script accepting CLI arguments.

This is my solution to all of this, currently running fine on one of my systems. I have created two (wsgi/python) scripts main.py and admin.py :


from keystone.server import wsgi as wsgi_server

# keystone uses sys.argv, finds gunicorn ones and crashes because of them, clean this import

sys sys.argv=sys.argv[:1]

application = wsgi_server.initialize_application("admin")

Use “main” for main.py, of course. You can even make that depend from the filename, but I don’t fancy that.

I use those scripts as usual from gunicorn (starting from proper directory):

 gunicorn admin:application --config /etc/gunicorn/keystone-admin.py