add -e/--env command line argunment

This command line argunment allows someone to pass an environement variable to
gunicorn:

	$ gunicorn --env FOO=1 test:app

With the command line above the application will be able to use the FOO
environment vatriable.
This commit is contained in:
benoitc 2013-08-27 13:21:53 +02:00
parent 054f1135db
commit 4e3428af0e
4 changed files with 71 additions and 2 deletions

View File

@ -5,6 +5,7 @@
#
# Example code from Eventlet sources
import os
from wsgiref.validate import validator
import sys
@ -12,9 +13,12 @@ from gunicorn import __version__
#@validator
def app(environ, start_response):
"""Simplest possible application object"""
data = b'Hello, World!\n'
status = '200 OK'
print("foo=%s" % (os.environ['FOO']))
response_headers = [
('Content-type','text/plain'),
('Content-Length', str(len(data))),

View File

@ -122,6 +122,12 @@ class Arbiter(object):
self.pidfile = Pidfile(self.cfg.pidfile)
self.pidfile.create(self.pid)
self.cfg.on_starting(self)
# set enviroment' variables
if self.cfg.env:
for k, v in self.cfg.env.items():
os.environ[k] = v
self.init_signals()
if not self.LISTENERS:
self.LISTENERS = create_sockets(self.cfg, self.log)
@ -346,17 +352,32 @@ class Arbiter(object):
self.master_name = "Old Master"
return
environ = self.cfg.env_orig.copy()
fds = [l.fileno() for l in self.LISTENERS]
os.environ['GUNICORN_FD'] = ",".join([str(fd) for fd in fds])
environ['GUNICORN_FD'] = ",".join([str(fd) for fd in fds])
os.chdir(self.START_CTX['cwd'])
self.cfg.pre_exec(self)
os.execvpe(self.START_CTX[0], self.START_CTX['args'], os.environ)
# exec the process using the original environnement
os.execvpe(self.START_CTX[0], self.START_CTX['args'], environ)
def reload(self):
old_address = self.cfg.address
# reset old environement
for k in self.cfg.env:
if k in self.cfg.env_orig:
# reset the key to the value it had before
# we launched gunicorn
os.environ[k] = self.cfg.env_orig[k]
else:
# delete the value set by gunicorn
try:
del os.environ[k]
except KeyError:
pass
# reload conf
self.app.reload()
self.setup(self.app)

View File

@ -48,8 +48,12 @@ class Config(object):
self.settings = make_settings()
self.usage = usage
self.prog = prog or os.path.basename(sys.argv[0])
self.env_orig = os.environ.copy()
def __getattr__(self, name):
if name == "env_orig":
return self.env_orig
if name not in self.settings:
raise AttributeError("No configuration setting for: %s" % name)
return self.settings[name].get()
@ -144,6 +148,23 @@ class Config(object):
return opts
@property
def env(self):
env = {}
if not self.settings['raw_env']:
return env
for e in self.settings['raw_env'].get():
s = six.bytes_to_str(e)
try:
k, v = s.split('=')
except ValueError:
raise RuntimeError("environement setting %r invalid" % s)
env[k] = v
return env
class SettingMeta(type):
def __new__(cls, name, bases, attrs):
@ -699,6 +720,23 @@ class Daemon(Setting):
background.
"""
class Env(Setting):
name = "raw_env"
action = "append"
section = "Server Mechanic"
cli = ["-e", "--env"]
meta = "ENV"
validator = validate_list_string
desc = """\
Set environment variable (key=value).
Pass variables to the execution environment. Ex.::
$ gunicorn -b 127.0.0.1:8000 --env FOO=1 test:app
and test for the foo variable environement in your application.
"""
class Pidfile(Setting):
name = "pidfile"

View File

@ -78,6 +78,12 @@ class Worker(object):
super(MyWorkerClass, self).init_process() so that the ``run()``
loop is initiated.
"""
# set enviroment' variables
if self.cfg.env:
for k, v in self.cfg.env.items():
os.environ[k] = v
util.set_owner_process(self.cfg.uid, self.cfg.gid)
# Reseed the random number generator