Просмотр исходного кода

Add partial support (docker-compose config and warnings) for v3.3 credential_spec

Signed-off-by: Joffrey F <[email protected]>
Joffrey F 8 лет назад
Родитель
Сommit
909ef7f435
2 измененных файлов с 47 добавлено и 12 удалено
  1. 30 12
      compose/config/config.py
  2. 17 0
      tests/unit/config/config_test.py

+ 30 - 12
compose/config/config.py

@@ -108,6 +108,7 @@ DOCKER_CONFIG_KEYS = [
 ALLOWED_KEYS = DOCKER_CONFIG_KEYS + [
     'build',
     'container_name',
+    'credential_spec',
     'dockerfile',
     'log_driver',
     'log_opt',
@@ -320,6 +321,27 @@ def find_candidates_in_parent_dirs(filenames, path):
     return (candidates, path)
 
 
+def check_swarm_only_config(service_dicts):
+    warning_template = (
+        "Some services ({services}) use the '{key}' key, which will be ignored. "
+        "Compose does not support '{key}' configuration - use "
+        "`docker stack deploy` to deploy to a swarm."
+    )
+
+    def check_swarm_only_key(service_dicts, key):
+        services = [s for s in service_dicts if s.get(key)]
+        if services:
+            log.warn(
+                warning_template.format(
+                    services=", ".join(sorted(s['name'] for s in services)),
+                    key=key
+                )
+            )
+
+    check_swarm_only_key(service_dicts, 'deploy')
+    check_swarm_only_key(service_dicts, 'credential_spec')
+
+
 def load(config_details):
     """Load the configuration from a working directory and a list of
     configuration files.  Files are loaded in order, and merged on top
@@ -349,13 +371,7 @@ def load(config_details):
         for service_dict in service_dicts:
             match_named_volumes(service_dict, volumes)
 
-    services_using_deploy = [s for s in service_dicts if s.get('deploy')]
-    if services_using_deploy:
-        log.warn(
-            "Some services ({}) use the 'deploy' key, which will be ignored. "
-            "Compose does not support deploy configuration - use "
-            "`docker stack deploy` to deploy to a swarm."
-            .format(", ".join(sorted(s['name'] for s in services_using_deploy))))
+    check_swarm_only_config(service_dicts)
 
     return Config(main_file.version, service_dicts, volumes, networks, secrets)
 
@@ -884,7 +900,7 @@ def merge_service_dicts(base, override, version):
 
     md.merge_mapping('environment', parse_environment)
     md.merge_mapping('labels', parse_labels)
-    md.merge_mapping('ulimits', parse_ulimits)
+    md.merge_mapping('ulimits', parse_flat_dict)
     md.merge_mapping('networks', parse_networks)
     md.merge_mapping('sysctls', parse_sysctls)
     md.merge_mapping('depends_on', parse_depends_on)
@@ -1020,12 +1036,14 @@ parse_depends_on = functools.partial(
 parse_deploy = functools.partial(parse_dict_or_list, split_kv, 'deploy')
 
 
-def parse_ulimits(ulimits):
-    if not ulimits:
+def parse_flat_dict(d):
+    if not d:
         return {}
 
-    if isinstance(ulimits, dict):
-        return dict(ulimits)
+    if isinstance(d, dict):
+        return dict(d)
+
+    raise ConfigurationError("Invalid type: expected mapping")
 
 
 def resolve_env_var(key, val, environment):

+ 17 - 0
tests/unit/config/config_test.py

@@ -2033,6 +2033,23 @@ class ConfigTest(unittest.TestCase):
             }
         }
 
+    def test_merge_credential_spec(self):
+        base = {
+            'image': 'bb',
+            'credential_spec': {
+                'file': '/hello-world',
+            }
+        }
+
+        override = {
+            'credential_spec': {
+                'registry': 'revolution.com',
+            }
+        }
+
+        actual = config.merge_service_dicts(base, override, V3_3)
+        assert actual['credential_spec'] == override['credential_spec']
+
     def test_external_volume_config(self):
         config_details = build_config_details({
             'version': '2',