Sfoglia il codice sorgente

Merge pull request #297 from ryanbrainard/resolve-env

Resolve environment without values to values on host
Ben Firshman 11 anni fa
parent
commit
99d7a474af
3 ha cambiato i file con 42 aggiunte e 0 eliminazioni
  1. 3 0
      docs/yml.md
  2. 18 0
      fig/service.py
  3. 21 0
      tests/integration/service_test.py

+ 3 - 0
docs/yml.md

@@ -55,8 +55,11 @@ volumes:
  - cache/:/tmp/cache
 
 -- Add environment variables.
+-- Environment variables with only a key are resolved to values on the host 
+-- machine, which can be helpful for secret or host-specific values.
 environment:
   RACK_ENV: development
+  SESSION_SECRET:
 ```
 
 -- Networking mode. Use the same values as the docker client --net parameter

+ 18 - 0
fig/service.py

@@ -330,6 +330,11 @@ class Service(object):
         if 'volumes' in container_options:
             container_options['volumes'] = dict((split_volume(v)[1], {}) for v in container_options['volumes'])
 
+        if 'environment' in container_options:
+            if isinstance(container_options['environment'], list):
+                container_options['environment'] = dict(split_env(e) for e in container_options['environment'])
+            container_options['environment'] = dict(resolve_env(k,v) for k,v in container_options['environment'].iteritems())
+
         if self.can_be_built():
             if len(self.client.images(name=self._build_tag_name())) == 0:
                 self.build()
@@ -447,3 +452,16 @@ def split_port(port):
             external_port = (external_ip,)
     return internal_port, external_port
 
+def split_env(env):
+    if '=' in env:
+        return env.split('=', 1)
+    else:
+        return env, None
+
+def resolve_env(key,val):
+    if val is not None:
+        return key, val
+    elif key in os.environ:
+        return key, os.environ[key]
+    else:
+        return key, ''

+ 21 - 0
tests/integration/service_test.py

@@ -5,6 +5,7 @@ from fig.service import CannotBeScaledError
 from fig.container import Container
 from fig.packages.docker.errors import APIError
 from .testcases import DockerClientTestCase
+import os
 
 class ServiceTest(DockerClientTestCase):
     def test_containers(self):
@@ -306,3 +307,23 @@ class ServiceTest(DockerClientTestCase):
         service = self.create_service('container', working_dir='/working/dir/sample')
         container = service.create_container().inspect()
         self.assertEqual(container['Config']['WorkingDir'], '/working/dir/sample')
+
+    def test_split_env(self):
+        service = self.create_service('web', environment=['NORMAL=F1', 'CONTAINS_EQUALS=F=2', 'TRAILING_EQUALS='])
+        env = service.start_container().environment
+        for k,v in {'NORMAL': 'F1', 'CONTAINS_EQUALS': 'F=2', 'TRAILING_EQUALS': ''}.iteritems():
+            self.assertEqual(env[k], v)
+
+    def test_resolve_env(self):
+        service = self.create_service('web', environment={'FILE_DEF': 'F1', 'FILE_DEF_EMPTY': '', 'ENV_DEF': None, 'NO_DEF': None})
+        os.environ['FILE_DEF'] = 'E1'
+        os.environ['FILE_DEF_EMPTY'] = 'E2'
+        os.environ['ENV_DEF'] = 'E3'
+        try:
+            env = service.start_container().environment
+            for k,v in {'FILE_DEF': 'F1', 'FILE_DEF_EMPTY': '', 'ENV_DEF': 'E3', 'NO_DEF': ''}.iteritems():
+                self.assertEqual(env[k], v)
+        finally:
+            del os.environ['FILE_DEF']
+            del os.environ['FILE_DEF_EMPTY']
+            del os.environ['ENV_DEF']