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
|
continue
|
||||||
|
|
||||||
worker = Worker(i, self.pid, self.LISTENER, self.modname,
|
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)
|
self.conf.before_fork(self, worker)
|
||||||
pid = os.fork()
|
pid = os.fork()
|
||||||
if pid != 0:
|
if pid != 0:
|
||||||
|
|||||||
@ -3,7 +3,9 @@
|
|||||||
# This file is part of gunicorn released under the MIT license.
|
# This file is part of gunicorn released under the MIT license.
|
||||||
# See the NOTICE for more information.
|
# See the NOTICE for more information.
|
||||||
|
|
||||||
|
import grp
|
||||||
import os
|
import os
|
||||||
|
import pwd
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from gunicorn import util
|
from gunicorn import util
|
||||||
@ -104,13 +106,37 @@ class Config(object):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def umask(self):
|
def umask(self):
|
||||||
if not self.conf['umask']:
|
if not self.conf.get('umask'):
|
||||||
return 0
|
return 0
|
||||||
umask = self.conf['umask']
|
umask = self.conf['umask']
|
||||||
if isinstance(umask, basestring):
|
if isinstance(umask, basestring):
|
||||||
return int(umask, 0)
|
return int(umask, 0)
|
||||||
return umask
|
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):
|
def _hook(self, hookname, *args):
|
||||||
hook = self.conf.get(hookname)
|
hook = self.conf.get(hookname)
|
||||||
|
|||||||
@ -3,12 +3,9 @@
|
|||||||
# This file is part of gunicorn released under the MIT license.
|
# This file is part of gunicorn released under the MIT license.
|
||||||
# See the NOTICE for more information.
|
# See the NOTICE for more information.
|
||||||
|
|
||||||
import ctypes
|
|
||||||
import grp
|
|
||||||
import logging
|
import logging
|
||||||
import optparse as op
|
import optparse as op
|
||||||
import os
|
import os
|
||||||
import pwd
|
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@ -99,26 +96,7 @@ def daemonize(umask):
|
|||||||
os.dup2(0, 1)
|
os.dup2(0, 1)
|
||||||
os.dup2(0, 2)
|
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):
|
def main(usage, get_app):
|
||||||
""" function used by different runners to setup options
|
""" function used by different runners to setup options
|
||||||
@ -137,7 +115,6 @@ def main(usage, get_app):
|
|||||||
else:
|
else:
|
||||||
os.umask(conf['umask'])
|
os.umask(conf['umask'])
|
||||||
os.setpgrp()
|
os.setpgrp()
|
||||||
set_owner_process(conf['user'], conf['group'])
|
|
||||||
configure_logging(conf)
|
configure_logging(conf)
|
||||||
arbiter.run()
|
arbiter.run()
|
||||||
|
|
||||||
@ -173,7 +150,6 @@ def paste_server(app, global_conf=None, host="127.0.0.1", port=None,
|
|||||||
else:
|
else:
|
||||||
os.umask(conf['umask'])
|
os.umask(conf['umask'])
|
||||||
os.setpgrp()
|
os.setpgrp()
|
||||||
set_owner_process(conf["user"], conf["group"])
|
|
||||||
configure_logging(conf)
|
configure_logging(conf)
|
||||||
arbiter.run()
|
arbiter.run()
|
||||||
|
|
||||||
|
|||||||
@ -71,7 +71,6 @@ class Command(BaseCommand):
|
|||||||
else:
|
else:
|
||||||
os.umask(conf['umask'])
|
os.umask(conf['umask'])
|
||||||
os.setpgrp()
|
os.setpgrp()
|
||||||
set_owner_process(conf["user"], conf["group"])
|
|
||||||
configure_logging(conf)
|
configure_logging(conf)
|
||||||
arbiter.run()
|
arbiter.run()
|
||||||
except WSGIServerException, e:
|
except WSGIServerException, e:
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
# This file is part of gunicorn released under the MIT license.
|
# This file is part of gunicorn released under the MIT license.
|
||||||
# See the NOTICE for more information.
|
# See the NOTICE for more information.
|
||||||
|
|
||||||
|
import ctypes
|
||||||
import errno
|
import errno
|
||||||
import fcntl
|
import fcntl
|
||||||
import os
|
import os
|
||||||
@ -29,7 +30,25 @@ monthname = [None,
|
|||||||
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
|
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
|
||||||
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
|
'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):
|
def parse_address(host, port=None, default_port=8000):
|
||||||
if host.startswith("unix:"):
|
if host.startswith("unix:"):
|
||||||
return host.split("unix:")[1]
|
return host.split("unix:")[1]
|
||||||
|
|||||||
@ -27,14 +27,16 @@ class Worker(object):
|
|||||||
|
|
||||||
PIPE = []
|
PIPE = []
|
||||||
|
|
||||||
def __init__(self, workerid, ppid, socket, app, timeout, debug=False):
|
def __init__(self, workerid, ppid, socket, app, timeout, conf):
|
||||||
self.nr = 0
|
self.nr = 0
|
||||||
self.id = workerid
|
self.id = workerid
|
||||||
self.ppid = ppid
|
self.ppid = ppid
|
||||||
self.debug = debug
|
self.debug = conf['debug']
|
||||||
|
self.conf = conf
|
||||||
self.socket = socket
|
self.socket = socket
|
||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
self.fd, self.tmpname = tempfile.mkstemp(prefix="wgunicorn-")
|
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.tmp = os.fdopen(self.fd, "r+b")
|
||||||
self.app = app
|
self.app = app
|
||||||
self.alive = True
|
self.alive = True
|
||||||
@ -81,6 +83,8 @@ class Worker(object):
|
|||||||
os.chmod(self.tmpname, self.spinner)
|
os.chmod(self.tmpname, self.spinner)
|
||||||
|
|
||||||
def init_process(self):
|
def init_process(self):
|
||||||
|
util.set_owner_process(self.conf.uid, self.conf.gid)
|
||||||
|
|
||||||
# init pipe
|
# init pipe
|
||||||
self.PIPE = os.pipe()
|
self.PIPE = os.pipe()
|
||||||
map(util.set_non_blocking, self.PIPE)
|
map(util.set_non_blocking, self.PIPE)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user