W dniu 15.11.2010 17:51, Grzegorz Nosek pisze:
The attached patch adds an option to clear the subprocess environment
before calling exec(). We don't always want to leak supervisor's
environment to its children, which usually run under different UIDs
(plus, they need not and should not care they're running under
supervisor as they can't access it anyway).
(...)
Naturally, I attached the wrong patch ;) (containing only the tests).
Here goes the proper version.
Best regards,
Grzegorz Nosek
>From 3d8e6ab38fd2d587c1fea69c236b35bc92cc1278 Mon Sep 17 00:00:00 2001
From: Grzegorz Nosek <[email protected]>
Date: Mon, 15 Nov 2010 17:42:16 +0100
Subject: [PATCH] Support clear_environment process parameter
When true, the process receives only items explicitly
mentioned in environment= parameter.
Defaults to false.
---
src/supervisor/options.py | 6 +++++-
src/supervisor/process.py | 23 +++++++++++++----------
src/supervisor/tests/base.py | 4 +++-
src/supervisor/tests/test_process.py | 31 +++++++++++++++++++++++++++++++
4 files changed, 52 insertions(+), 12 deletions(-)
diff --git a/src/supervisor/options.py b/src/supervisor/options.py
index 1fe08dc..2fa4973 100644
--- a/src/supervisor/options.py
+++ b/src/supervisor/options.py
@@ -371,6 +371,7 @@ class ServerOptions(Options):
passwdfile = None
nodaemon = None
signal = None
+ clear_environment = False
environment = None
httpservers = ()
unlink_socketfiles = True
@@ -549,6 +550,7 @@ class ServerOptions(Options):
section.pidfile = existing_dirpath(get('pidfile', 'supervisord.pid'))
section.identifier = get('identifier', 'supervisor')
section.nodaemon = boolean(get('nodaemon', 'false'))
+ section.clear_environment = boolean(get('clear_environment', 'false'))
tempdir = tempfile.gettempdir()
section.childlogdir = existing_directory(get('childlogdir', tempdir))
@@ -763,6 +765,7 @@ class ServerOptions(Options):
numprocs = integer(get(section, 'numprocs', 1))
numprocs_start = integer(get(section, 'numprocs_start', 0))
process_name = get(section, 'process_name', '%(program_name)s')
+ clear_environment = boolean(get(section, 'clear_environment', 'false'))
environment_str = get(section, 'environment', '')
stdout_cmaxbytes = byte_size(get(section,'stdout_capture_maxbytes','0'))
stdout_events = boolean(get(section, 'stdout_events_enabled','false'))
@@ -853,6 +856,7 @@ class ServerOptions(Options):
exitcodes=exitcodes,
redirect_stderr=redirect_stderr,
environment=environment,
+ clear_environment=clear_environment,
serverurl=serverurl)
programs.append(pconfig)
@@ -1557,7 +1561,7 @@ class ProcessConfig(Config):
'stderr_logfile_backups', 'stderr_logfile_maxbytes',
'stderr_events_enabled',
'stopsignal', 'stopwaitsecs', 'exitcodes', 'redirect_stderr' ]
- optional_param_names = [ 'environment', 'serverurl' ]
+ optional_param_names = [ 'environment', 'serverurl', 'clear_environment' ]
def __init__(self, options, **params):
self.options = options
diff --git a/src/supervisor/process.py b/src/supervisor/process.py
index 1046a53..ada000f 100644
--- a/src/supervisor/process.py
+++ b/src/supervisor/process.py
@@ -302,16 +302,19 @@ class Subprocess:
s = 'supervisor: error trying to setuid to %s ' % uid
options.write(2, s)
options.write(2, "(%s)\n" % msg)
- env = os.environ.copy()
- env['SUPERVISOR_ENABLED'] = '1'
- serverurl = self.config.serverurl
- if serverurl is None: # unset
- serverurl = self.config.options.serverurl # might still be None
- if serverurl:
- env['SUPERVISOR_SERVER_URL'] = serverurl
- env['SUPERVISOR_PROCESS_NAME'] = self.config.name
- if self.group:
- env['SUPERVISOR_GROUP_NAME'] = self.group.config.name
+ if self.config.clear_environment:
+ env = dict()
+ else:
+ env = os.environ.copy()
+ env['SUPERVISOR_ENABLED'] = '1'
+ serverurl = self.config.serverurl
+ if serverurl is None: # unset
+ serverurl = self.config.options.serverurl # might still be None
+ if serverurl:
+ env['SUPERVISOR_SERVER_URL'] = serverurl
+ env['SUPERVISOR_PROCESS_NAME'] = self.config.name
+ if self.group:
+ env['SUPERVISOR_GROUP_NAME'] = self.group.config.name
if self.config.environment is not None:
env.update(self.config.environment)
try:
diff --git a/src/supervisor/tests/base.py b/src/supervisor/tests/base.py
index f8220de..8f7eac4 100644
--- a/src/supervisor/tests/base.py
+++ b/src/supervisor/tests/base.py
@@ -481,7 +481,8 @@ class DummyPConfig:
stderr_logfile_backups=0, stderr_logfile_maxbytes=0,
redirect_stderr=False,
stopsignal=None, stopwaitsecs=10,
- exitcodes=(0,2), environment=None, serverurl=None):
+ exitcodes=(0,2), environment=None, serverurl=None,
+ clear_environment=False):
self.options = options
self.name = name
self.command = command
@@ -508,6 +509,7 @@ class DummyPConfig:
self.stopsignal = stopsignal
self.stopwaitsecs = stopwaitsecs
self.exitcodes = exitcodes
+ self.clear_environment = clear_environment
self.environment = environment
self.directory = directory
self.umask = umask
diff --git a/src/supervisor/tests/test_process.py b/src/supervisor/tests/test_process.py
index 7185816..740367c 100644
--- a/src/supervisor/tests/test_process.py
+++ b/src/supervisor/tests/test_process.py
@@ -453,6 +453,37 @@ class SubprocessTests(unittest.TestCase):
options.execv_environment['SUPERVISOR_SERVER_URL'],
'http://localhost:9001')
+ def test_spawn_as_child_environment_clear_environment(self):
+ options = DummyOptions()
+ options.forkpid = 0
+ config = DummyPConfig(options, 'cat', '/bin/cat',
+ clear_environment=True)
+ instance = self._makeOne(config)
+ class Dummy:
+ name = 'dummy'
+ instance.group = Dummy()
+ instance.group.config = Dummy()
+ result = instance.spawn()
+ self.assertEqual(result, None)
+ self.assertEqual(options.execv_args, ('/bin/cat', ['/bin/cat']) )
+ self.assertEqual(options.execv_environment, dict())
+
+ def test_spawn_as_child_environment_clear_environment_withvars(self):
+ options = DummyOptions()
+ options.forkpid = 0
+ child_env = dict(_TEST_=1)
+ config = DummyPConfig(options, 'cat', '/bin/cat',
+ clear_environment=True, environment=child_env)
+ instance = self._makeOne(config)
+ class Dummy:
+ name = 'dummy'
+ instance.group = Dummy()
+ instance.group.config = Dummy()
+ result = instance.spawn()
+ self.assertEqual(result, None)
+ self.assertEqual(options.execv_args, ('/bin/cat', ['/bin/cat']) )
+ self.assertEqual(options.execv_environment, child_env)
+
def test_spawn_as_child_stderr_redirected(self):
options = DummyOptions()
options.forkpid = 0
--
1.7.0.4
_______________________________________________
Supervisor-users mailing list
[email protected]
http://lists.supervisord.org/mailman/listinfo/supervisor-users