mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
on irc jbergstroem noticed that gunicorn behavior is different than
nginx one in the way it manages processes uid/gid. Only nginx workers get uid/gid and master if launch as root stay root. This patch give ti gunicorn the same behavior.
This commit is contained in:
parent
0a2585fdc0
commit
6c12f313e3
@ -356,7 +356,7 @@ class Arbiter(object):
|
||||
continue
|
||||
|
||||
worker = Worker(i, self.pid, self.LISTENER, self.modname,
|
||||
self.timeout/2.0, self.debug)
|
||||
self.timeout/2.0, self.conf)
|
||||
self.conf.before_fork(self, worker)
|
||||
pid = os.fork()
|
||||
if pid != 0:
|
||||
|
||||
@ -3,7 +3,9 @@
|
||||
# This file is part of gunicorn released under the MIT license.
|
||||
# See the NOTICE for more information.
|
||||
|
||||
import grp
|
||||
import os
|
||||
import pwd
|
||||
import sys
|
||||
|
||||
from gunicorn import util
|
||||
@ -104,13 +106,37 @@ class Config(object):
|
||||
|
||||
@property
|
||||
def umask(self):
|
||||
if not self.conf['umask']:
|
||||
if not self.conf.get('umask'):
|
||||
return 0
|
||||
umask = self.conf['umask']
|
||||
if isinstance(umask, basestring):
|
||||
return int(umask, 0)
|
||||
return umask
|
||||
|
||||
@property
|
||||
def uid(self):
|
||||
if not self.conf.get('user'):
|
||||
return os.geteuid()
|
||||
|
||||
user = self.conf.get('user')
|
||||
if user.isdigit() or isinstance(user, int):
|
||||
uid = int(user)
|
||||
else:
|
||||
uid = pwd.getpwnam(user).pw_uid
|
||||
return uid
|
||||
|
||||
@property
|
||||
def gid(self):
|
||||
if not self.conf.get('group'):
|
||||
return os.getegid()
|
||||
group = self.conf.get('group')
|
||||
if group.isdigit() or isinstance(group, int):
|
||||
gid = int(group)
|
||||
else:
|
||||
gid = grp.getgrnam(group).gr_gid
|
||||
|
||||
return gid
|
||||
|
||||
|
||||
def _hook(self, hookname, *args):
|
||||
hook = self.conf.get(hookname)
|
||||
|
||||
@ -3,12 +3,9 @@
|
||||
# This file is part of gunicorn released under the MIT license.
|
||||
# See the NOTICE for more information.
|
||||
|
||||
import ctypes
|
||||
import grp
|
||||
import logging
|
||||
import optparse as op
|
||||
import os
|
||||
import pwd
|
||||
import pkg_resources
|
||||
import sys
|
||||
|
||||
@ -99,26 +96,7 @@ def daemonize(umask):
|
||||
os.dup2(0, 1)
|
||||
os.dup2(0, 2)
|
||||
|
||||
def set_owner_process(user,group):
|
||||
""" set user and group of workers processes """
|
||||
if group:
|
||||
if group.isdigit() or isinstance(group, int):
|
||||
gid = int(group)
|
||||
else:
|
||||
gid = grp.getgrnam(group).gr_gid
|
||||
|
||||
try:
|
||||
os.setgid(gid)
|
||||
except OverflowError:
|
||||
# versions of python < 2.6.2 don't manage unsigned int for
|
||||
# groups like on osx or fedora
|
||||
os.setgid(-ctypes.c_int(-gid).value)
|
||||
if user:
|
||||
if user.isdigit() or isinstance(user, int):
|
||||
uid = int(user)
|
||||
else:
|
||||
uid = pwd.getpwnam(user).pw_uid
|
||||
os.setuid(uid)
|
||||
|
||||
|
||||
def main(usage, get_app):
|
||||
""" function used by different runners to setup options
|
||||
@ -137,7 +115,6 @@ def main(usage, get_app):
|
||||
else:
|
||||
os.umask(conf['umask'])
|
||||
os.setpgrp()
|
||||
set_owner_process(conf['user'], conf['group'])
|
||||
configure_logging(conf)
|
||||
arbiter.run()
|
||||
|
||||
@ -173,7 +150,6 @@ def paste_server(app, global_conf=None, host="127.0.0.1", port=None,
|
||||
else:
|
||||
os.umask(conf['umask'])
|
||||
os.setpgrp()
|
||||
set_owner_process(conf["user"], conf["group"])
|
||||
configure_logging(conf)
|
||||
arbiter.run()
|
||||
|
||||
|
||||
@ -71,7 +71,6 @@ class Command(BaseCommand):
|
||||
else:
|
||||
os.umask(conf['umask'])
|
||||
os.setpgrp()
|
||||
set_owner_process(conf["user"], conf["group"])
|
||||
configure_logging(conf)
|
||||
arbiter.run()
|
||||
except WSGIServerException, e:
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
# This file is part of gunicorn released under the MIT license.
|
||||
# See the NOTICE for more information.
|
||||
|
||||
import ctypes
|
||||
import errno
|
||||
import fcntl
|
||||
import os
|
||||
@ -29,7 +30,25 @@ monthname = [None,
|
||||
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
|
||||
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
|
||||
|
||||
|
||||
def set_owner_process(uid,gid):
|
||||
""" set user and group of workers processes """
|
||||
if gid:
|
||||
try:
|
||||
os.setgid(gid)
|
||||
except OverflowError:
|
||||
# versions of python < 2.6.2 don't manage unsigned int for
|
||||
# groups like on osx or fedora
|
||||
os.setgid(-ctypes.c_int(-gid).value)
|
||||
|
||||
if uid:
|
||||
os.setuid(uid)
|
||||
|
||||
def chown(path, uid, gid):
|
||||
try:
|
||||
os.chown(path, uid, gid)
|
||||
except OverflowError:
|
||||
os.chown(path, uid, -ctypes.c_int(-gid).value)
|
||||
|
||||
def parse_address(host, port=None, default_port=8000):
|
||||
if host.startswith("unix:"):
|
||||
return host.split("unix:")[1]
|
||||
|
||||
@ -27,14 +27,16 @@ class Worker(object):
|
||||
|
||||
PIPE = []
|
||||
|
||||
def __init__(self, workerid, ppid, socket, app, timeout, debug=False):
|
||||
def __init__(self, workerid, ppid, socket, app, timeout, conf):
|
||||
self.nr = 0
|
||||
self.id = workerid
|
||||
self.ppid = ppid
|
||||
self.debug = debug
|
||||
self.debug = conf['debug']
|
||||
self.conf = conf
|
||||
self.socket = socket
|
||||
self.timeout = timeout
|
||||
self.fd, self.tmpname = tempfile.mkstemp(prefix="wgunicorn-")
|
||||
util.chown(self.tmpname, conf.uid, conf.gid)
|
||||
self.tmp = os.fdopen(self.fd, "r+b")
|
||||
self.app = app
|
||||
self.alive = True
|
||||
@ -81,6 +83,8 @@ class Worker(object):
|
||||
os.chmod(self.tmpname, self.spinner)
|
||||
|
||||
def init_process(self):
|
||||
util.set_owner_process(self.conf.uid, self.conf.gid)
|
||||
|
||||
# init pipe
|
||||
self.PIPE = os.pipe()
|
||||
map(util.set_non_blocking, self.PIPE)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user