Commits

Jason R. Coombs  committed 08e6bf1

Added support in monster_run for getting the config path from an environment variable.

  • Participants
  • Parent commits 6a17ce5
  • Branches default
  • Tags 5.1

Comments (0)

Files changed (4)

 Eggmonster Change Notes
 =======================
 
+5.1
+---
+
+* `monster_run` now accepts "ENVIRONMENT" or "ENVIRONMENT:<var name>" to
+  indicate the configuration path, allowing an environment variable to
+  dictate the location of the config.
+
 5.0
 ---
 

File docs/dev/monster_run.rst

 monster_run
 ^^^^^^^^^^^
 
-Usage: ``monster_run [options] <config.yaml> <entry_point>``
+Usage: ``monster_run [options] <config_path> <entry_point>``
 
 Arguments
 ~~~~~~~~~
 
-config.yaml:
-	the path to the configuration file
+config_path:
+	the path to the configuration file.
+
+	In addition to a file-system path, `config_path` may also take two special
+	forms::
+
+	 - "REMOTE" means load the configuration from the eggmonster master
+	   (as defined in environment variables).
+	 - "ENVIRONMENT" means get the configuration path from the environment
+	   variable "EGGMONSTER_CONFIG_PATH". One may override the environment var
+	   name with "ENVIRONMENT:<var name>".
+
 
 entry_point:
 	the function to run
 -u/--update:
 	Update dependencies and other egg info using `sudo python setup.py develop`
 	before running (setup.py must be in cwd, user must have sudo permission)
-	
+
 -i/--interact:
 	action="store_true", dest="interact", default=False,
 	help="Open up an interactive prompt with the correct environment.")
 
 --spawn:
 	Used internally when spawning processes.
-
-
-Discussion
-~~~~~~~~~~
-
-
-
-
-

File eggmonster/runner.py

 import subprocess
 import importlib
+import os
 
 try:
     import IPython.Shell
             'python', 'setup.py', 'develop',
             ] + emenv.get_easy_install_params())
 
-    # Grab the configuration settings from the Eggmonster master.
-    if config_path == 'REMOTE':
-        cfg = eggmonster.config.ClusterConfig.from_yaml(getjson('config')[1])
-    else:
-        cfg = eggmonster.config.ClusterConfig.from_file(config_path)
+    cfg = _load_config(config_path)
 
     # Pull the appropriate environment from the configuration.
     pkgname, __sep, entry_point = app.rpartition('.')
         else:
             app_func()
 
+def _load_config(config_path):
+    """
+    Given a config path, load the ClusterConfig from it.
+
+    In addition to a file-system path, `config_path` may also take two special
+    forms:
+
+     - "REMOTE" means load the configuration from the eggmonster master
+       (as defined in environment variables).
+     - "ENVIRONMENT" means get the configuration path from the environment
+       variable "EGGMONSTER_CONFIG_PATH". One may override the environment var
+       name with "ENVIRONMENT:<var name>".
+    """
+    if config_path == 'REMOTE':
+        # Grab the configuration settings from the Eggmonster master.
+        return eggmonster.config.ClusterConfig.from_yaml(getjson('config')[1])
+
+    if config_path.startswith('ENVIRONMENT'):
+        key, sep, env_var = config_path.partition(':')
+        if not env_var:
+            env_var = 'EGGMONSTER_CONFIG_PATH'
+        config_path = os.environ[env_var]
+    return eggmonster.config.ClusterConfig.from_file(config_path)
+
+
 def can_take_app_args(app_func):
     # Let's see if we pass args across or not.
     import inspect

File eggmonster/test/test_runner.py

+import os
+import contextlib
+import tempfile
+import textwrap
+
+from eggmonster import runner
+
+@contextlib.contextmanager
+def environment_context(**kwargs):
+    env = os.environ.copy()
+    os.environ.update(**kwargs)
+    try:
+        yield
+    finally:
+        for k in kwargs:
+            del os.environ[k]
+        os.environ.update(env)
+
+
+@contextlib.contextmanager
+def sample_config():
+    _config = textwrap.dedent("""
+        test_project:
+            Package: == 1.1
+            Directory: "."
+            Environment:
+                production: 1
+            Applications:
+                - Name: main
+                  Environment:
+                    foo: bar
+                    baz: other
+                    port: 7083
+                  Nodes:
+                    jam: 1
+        """).lstrip()
+    tf = tempfile.NamedTemporaryFile(delete=False)
+    tf.write(_config)
+    tf.close()
+    try:
+        yield tf.name
+    finally:
+        os.remove(tf.name)
+
+def test_load_config_from_environment_var():
+    with sample_config() as config_path:
+        with environment_context(EGGMONSTER_CONFIG_PATH=config_path):
+            config = runner._load_config("ENVIRONMENT")
+            assert 'test_project.main' in config.apps
+
+def test_load_config_from_specific_environment_var():
+    with sample_config() as config_path:
+        with environment_context(SOME_CONFIG=config_path):
+            config = runner._load_config("ENVIRONMENT:SOME_CONFIG")
+            assert 'test_project.main' in config.apps