浏览代码

Environment variables might be used in strings expansion (in options).

silver 13 年之前
父节点
当前提交
31e7953dab
共有 3 个文件被更改,包括 40 次插入2 次删除
  1. 2 1
      docs/configuration.rst
  2. 24 1
      supervisor/options.py
  3. 14 0
      supervisor/tests/test_options.py

+ 2 - 1
docs/configuration.rst

@@ -553,7 +553,8 @@ where specified.
   expand to ``/path/to/programname --port=8000`` at runtime.  String
   expand to ``/path/to/programname --port=8000`` at runtime.  String
   expressions are evaluated against a dictionary containing the keys
   expressions are evaluated against a dictionary containing the keys
   ``group_name``, ``host_node_name``, ``process_num``, ``program_name``, 
   ``group_name``, ``host_node_name``, ``process_num``, ``program_name``, 
-  and ``here`` (the directory of the supervisord config file).  Controlled 
+  ``here`` (the directory of the supervisord config file), and all
+  supervisord's environment variables prefixed with ``ENV_``.  Controlled 
   programs should themselves not be daemons, as supervisord assumes it is
   programs should themselves not be daemons, as supervisord assumes it is
   responsible for daemonizing its subprocesses (see
   responsible for daemonizing its subprocesses (see
   :ref:`nondaemonizing_of_subprocesses`).
   :ref:`nondaemonizing_of_subprocesses`).

+ 24 - 1
supervisor/options.py

@@ -542,8 +542,10 @@ class ServerOptions(Options):
         section.nocleanup = boolean(get('nocleanup', 'false'))
         section.nocleanup = boolean(get('nocleanup', 'false'))
         section.strip_ansi = boolean(get('strip_ansi', 'false'))
         section.strip_ansi = boolean(get('strip_ansi', 'false'))
 
 
+        expansions = {'here':self.here}
+        expansions.update(environ_expansions())
         environ_str = get('environment', '')
         environ_str = get('environment', '')
-        environ_str = expand(environ_str, {'here':self.here}, 'environment')
+        environ_str = expand(environ_str, expansions, 'environment')
         section.environment = dict_of_key_value_pairs(environ_str)
         section.environment = dict_of_key_value_pairs(environ_str)
         # Process rpcinterface plugins before groups to allow custom events to
         # Process rpcinterface plugins before groups to allow custom events to
         # be registered.
         # be registered.
@@ -675,6 +677,7 @@ class ServerOptions(Options):
 
 
             expansions = {'here':self.here,
             expansions = {'here':self.here,
                           'program_name':program_name}
                           'program_name':program_name}
+            expansions.update(environ_expansions())
             socket = expand(socket, expansions, 'socket')
             socket = expand(socket, expansions, 'socket')
             try:
             try:
                 socket_config = self.parse_fcgi_socket(socket, proc_uid,
                 socket_config = self.parse_fcgi_socket(socket, proc_uid,
@@ -783,6 +786,7 @@ class ServerOptions(Options):
                           'program_name':program_name,
                           'program_name':program_name,
                           'host_node_name':host_node_name,
                           'host_node_name':host_node_name,
                           'group_name':group_name}
                           'group_name':group_name}
+            expansions.update(environ_expansions())
 
 
             environment = dict_of_key_value_pairs(
             environment = dict_of_key_value_pairs(
                 expand(environment_str, expansions, 'environment'))
                 expand(environment_str, expansions, 'environment'))
@@ -1860,6 +1864,25 @@ def expand(s, expansions, name):
             'Format string %r for %r is badly formatted' % (s, name)
             'Format string %r for %r is badly formatted' % (s, name)
             )
             )
 
 
+_environ_expansions = None
+
+def environ_expansions():
+    """Return dict of environment variables, suitable for use in string
+    expansions.
+
+    Every environment variable is prefixed by 'ENV_'.
+    """
+    global _environ_expansions
+
+    if _environ_expansions:
+        return _environ_expansions
+
+    _environ_expansions = {}
+    for key, value in os.environ.iteritems():
+        _environ_expansions['ENV_%s' % key] = value
+
+    return _environ_expansions
+
 def make_namespec(group_name, process_name):
 def make_namespec(group_name, process_name):
     # we want to refer to the process by its "short name" (a process named
     # we want to refer to the process by its "short name" (a process named
     # process1 in the group process1 has a name "process1").  This is for
     # process1 in the group process1 has a name "process1").  This is for

+ 14 - 0
supervisor/tests/test_options.py

@@ -649,6 +649,20 @@ class ServerOptionsTests(unittest.TestCase):
         expected = "/bin/foo --host=" + platform.node()
         expected = "/bin/foo --host=" + platform.node()
         self.assertEqual(pconfigs[0].command, expected)
         self.assertEqual(pconfigs[0].command, expected)
 
 
+    def test_processes_from_section_environment_variables_expansion(self):
+        instance = self._makeOne()
+        text = lstrip("""\
+        [program:foo]
+        command = /bin/foo --path='%(ENV_PATH)s'
+        """)
+        from supervisor.options import UnhosedConfigParser
+        config = UnhosedConfigParser()
+        config.read_string(text)
+        pconfigs = instance.processes_from_section(config, 'program:foo', 'bar')
+        import platform
+        expected = "/bin/foo --path='%s'" % os.environ['PATH']
+        self.assertEqual(pconfigs[0].command, expected)
+
     def test_processes_from_section_no_procnum_in_processname(self):
     def test_processes_from_section_no_procnum_in_processname(self):
         instance = self._makeOne()
         instance = self._makeOne()
         text = lstrip("""\
         text = lstrip("""\