diff --git a/THANKS b/THANKS index c3b99cecc..f0df49325 100644 --- a/THANKS +++ b/THANKS @@ -163,3 +163,4 @@ Jason Madden Eugene Obukhov Jan-Philip Gehrcke Mark Adams +Hasan Ramezani diff --git a/gunicorn/app/base.py b/gunicorn/app/base.py index f3d3b4f13..4988838ce 100644 --- a/gunicorn/app/base.py +++ b/gunicorn/app/base.py @@ -154,6 +154,17 @@ def load_config(self): if default_config is not None: self.load_config_from_file(default_config) + # Load up environment configuration + env_vars = self.cfg.get_cmd_args_from_env() + if env_vars: + env_args = parser.parse_args(env_vars) + for k, v in vars(env_args).items(): + if v is None: + continue + if k == "args": + continue + self.cfg.set(k.lower(), v) + # Lastly, update the configuration with any command line # settings. for k, v in args.__dict__.items(): diff --git a/gunicorn/config.py b/gunicorn/config.py index 117d677ca..08100e6bc 100644 --- a/gunicorn/config.py +++ b/gunicorn/config.py @@ -18,6 +18,7 @@ import ssl import sys import textwrap +import shlex from gunicorn import __version__ from gunicorn import _compat @@ -69,6 +70,11 @@ def set(self, name, value): raise AttributeError("No configuration setting for: %s" % name) self.settings[name].set(value) + def get_cmd_args_from_env(self): + if 'GUNICORN_CMD_ARGS' in self.env_orig: + return shlex.split(self.env_orig['GUNICORN_CMD_ARGS']) + return [] + def parser(self): kwargs = { "usage": self.usage, diff --git a/tests/test_config.py b/tests/test_config.py index 9f9a2fe97..597a5e679 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -285,3 +285,24 @@ def test_always_use_configured_logger(): c.set('statsd_host', 'localhost:12345') # still uses custom logger over statsd assert c.logger_class == MyLogger + + +def test_load_enviroment_variables_config(monkeypatch): + monkeypatch.setenv("GUNICORN_CMD_ARGS", "--workers=4") + with AltArgs(): + app = NoConfigApp() + assert app.cfg.workers == 4 + + +def test_invalid_enviroment_variables_config(monkeypatch): + monkeypatch.setenv("GUNICORN_CMD_ARGS", "--foo=bar") + with AltArgs(): + with pytest.raises(SystemExit): + NoConfigApp() + + +def test_cli_overrides_enviroment_variables_module(monkeypatch): + monkeypatch.setenv("GUNICORN_CMD_ARGS", "--workers=4") + with AltArgs(["prog_name", "-c", cfg_file(), "--workers", "3"]): + app = NoConfigApp() + assert app.cfg.workers == 3