Przeglądaj źródła

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

silver 13 lat temu
rodzic
commit
31e7953dab
3 zmienionych plików z 40 dodań i 2 usunięć
  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
   expressions are evaluated against a dictionary containing the keys
   ``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
   responsible for daemonizing its subprocesses (see
   :ref:`nondaemonizing_of_subprocesses`).

+ 24 - 1
supervisor/options.py

@@ -542,8 +542,10 @@ class ServerOptions(Options):
         section.nocleanup = boolean(get('nocleanup', 'false'))
         section.strip_ansi = boolean(get('strip_ansi', 'false'))
 
+        expansions = {'here':self.here}
+        expansions.update(environ_expansions())
         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)
         # Process rpcinterface plugins before groups to allow custom events to
         # be registered.
@@ -675,6 +677,7 @@ class ServerOptions(Options):
 
             expansions = {'here':self.here,
                           'program_name':program_name}
+            expansions.update(environ_expansions())
             socket = expand(socket, expansions, 'socket')
             try:
                 socket_config = self.parse_fcgi_socket(socket, proc_uid,
@@ -783,6 +786,7 @@ class ServerOptions(Options):
                           'program_name':program_name,
                           'host_node_name':host_node_name,
                           'group_name':group_name}
+            expansions.update(environ_expansions())
 
             environment = dict_of_key_value_pairs(
                 expand(environment_str, expansions, 'environment'))
@@ -1860,6 +1864,25 @@ def expand(s, expansions, 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):
     # 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

+ 14 - 0
supervisor/tests/test_options.py

@@ -649,6 +649,20 @@ class ServerOptionsTests(unittest.TestCase):
         expected = "/bin/foo --host=" + platform.node()
         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):
         instance = self._makeOne()
         text = lstrip("""\