From e908ec33594f50619b7aae2d29e6fc15454a9338 Mon Sep 17 00:00:00 2001 From: Chris Streeter Date: Tue, 19 Feb 2013 18:38:29 -0800 Subject: [PATCH] Consistently get CWD across apps and arbiter. The Arbiter is smart about getting the CWD; first it checks the CWD environment (which doesn't resolve symlinks), then it falls back to the python os.getcwd() (which does resolve symlinks). However, the Arbiter is the only place that does this, which will then do the right thing when we reexec. However, when reloading the Arbiter, it won't pick up changes if the symlink has changed. By changing the *app.py entry points to also use the same method for determining the CWD, we'll insert a symlink path into the first location in sys.path. Then our reloaded app will correctly pull in any new changes. --- gunicorn/app/djangoapp.py | 3 ++- gunicorn/app/pasterapp.py | 4 +++- gunicorn/app/wsgiapp.py | 4 +++- gunicorn/arbiter.py | 11 +---------- gunicorn/util.py | 14 ++++++++++++++ 5 files changed, 23 insertions(+), 13 deletions(-) diff --git a/gunicorn/app/djangoapp.py b/gunicorn/app/djangoapp.py index e89df001..c9cbb00e 100644 --- a/gunicorn/app/djangoapp.py +++ b/gunicorn/app/djangoapp.py @@ -55,7 +55,8 @@ def make_default_env(cfg): os.environ['DJANGO_SETTINGS_MODULE'] except KeyError: # not settings env set, try to build one. - project_path, settings_name = find_settings_module(os.getcwd()) + cwd = util.getcwd() + project_path, settings_name = find_settings_module(cwd) if not project_path: raise RuntimeError("django project not found") diff --git a/gunicorn/app/pasterapp.py b/gunicorn/app/pasterapp.py index cdd02fd9..b6e4f0e9 100644 --- a/gunicorn/app/pasterapp.py +++ b/gunicorn/app/pasterapp.py @@ -17,6 +17,7 @@ SERVER = loadwsgi.SERVER from gunicorn.app.base import Application from gunicorn.config import Config +from gunicorn import util class PasterBaseApplication(Application): @@ -68,7 +69,8 @@ class PasterApplication(PasterBaseApplication): if len(args) != 1: parser.error("No application name specified.") - cfgfname = os.path.normpath(os.path.join(os.getcwd(), args[0])) + cwd = util.getcwd() + cfgfname = os.path.normpath(os.path.join(cwd, args[0])) cfgfname = os.path.abspath(cfgfname) if not os.path.exists(cfgfname): parser.error("Config file not found: %s" % cfgfname) diff --git a/gunicorn/app/wsgiapp.py b/gunicorn/app/wsgiapp.py index b469ab7d..4ef27ef5 100644 --- a/gunicorn/app/wsgiapp.py +++ b/gunicorn/app/wsgiapp.py @@ -19,7 +19,9 @@ class WSGIApplication(Application): self.cfg.set("default_proc_name", args[0]) self.app_uri = args[0] - sys.path.insert(0, os.getcwd()) + cwd = util.getcwd() + + sys.path.insert(0, cwd) def load(self): return util.import_app(self.app_uri) diff --git a/gunicorn/arbiter.py b/gunicorn/arbiter.py index 098a7be2..707f1bf9 100644 --- a/gunicorn/arbiter.py +++ b/gunicorn/arbiter.py @@ -59,16 +59,7 @@ class Arbiter(object): self.reexec_pid = 0 self.master_name = "Master" - # get current path, try to use PWD env first - try: - a = os.stat(os.environ['PWD']) - b = os.stat(os.getcwd()) - if a.st_ino == b.st_ino and a.st_dev == b.st_dev: - cwd = os.environ['PWD'] - else: - cwd = os.getcwd() - except: - cwd = os.getcwd() + cwd = util.getcwd() args = sys.argv[:] args.insert(0, sys.executable) diff --git a/gunicorn/util.py b/gunicorn/util.py index 42e47d52..f472cf5a 100644 --- a/gunicorn/util.py +++ b/gunicorn/util.py @@ -364,6 +364,20 @@ def import_app(module): return app +def getcwd(): + # get current path, try to use PWD env first + try: + a = os.stat(os.environ['PWD']) + b = os.stat(os.getcwd()) + if a.st_ino == b.st_ino and a.st_dev == b.st_dev: + cwd = os.environ['PWD'] + else: + cwd = os.getcwd() + except: + cwd = os.getcwd() + return cwd + + def http_date(timestamp=None): """Return the current date and time formatted for a message header.""" if timestamp is None: