Bläddra i källkod

Merge pull request #46 from silver-/master

Using environment variables as strings expansion in options
Mike Naberezny 13 år sedan
förälder
incheckning
f51f1d0d92
3 ändrade filer med 39 tillägg och 2 borttagningar
  1. 2 1
      docs/configuration.rst
  2. 24 1
      supervisor/options.py
  3. 13 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

+ 13 - 0
supervisor/tests/test_options.py

@@ -649,6 +649,19 @@ 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')
+        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("""\