Browse Source

Fix port rendering

Signed-off-by: Ulysses Souza <[email protected]>
Ulysses Souza 5 years ago
parent
commit
ce59a4c223

+ 16 - 9
compose/config/config.py

@@ -20,6 +20,7 @@ from ..utils import json_hash
 from ..utils import parse_bytes
 from ..utils import parse_nanoseconds_int
 from ..utils import splitdrive
+from ..version import ComposeVersion
 from .environment import env_vars_from_file
 from .environment import Environment
 from .environment import split_env
@@ -184,6 +185,13 @@ class ConfigFile(namedtuple('_ConfigFile', 'filename config')):
     def from_filename(cls, filename):
         return cls(filename, load_yaml(filename))
 
+    @cached_property
+    def config_version(self):
+        version = self.config.get('version', None)
+        if isinstance(version, dict):
+            return V1
+        return ComposeVersion(version) if version else self.version
+
     @cached_property
     def version(self):
         version = self.config.get('version', None)
@@ -222,15 +230,13 @@ class ConfigFile(namedtuple('_ConfigFile', 'filename config')):
                     'Version "{}" in "{}" is invalid.'
                     .format(version, self.filename))
 
-            if version.startswith("1"):
-                version = V1
-
-        if version == V1:
+        if version.startswith("1"):
             raise ConfigurationError(
                 'Version in "{}" is invalid. {}'
                 .format(self.filename, VERSION_EXPLANATION)
             )
-        return version
+
+        return VERSION
 
     def get_service(self, name):
         return self.get_service_dicts()[name]
@@ -253,8 +259,10 @@ class ConfigFile(namedtuple('_ConfigFile', 'filename config')):
         return {} if self.version == V1 else self.config.get('configs', {})
 
 
-class Config(namedtuple('_Config', 'version services volumes networks secrets configs')):
+class Config(namedtuple('_Config', 'config_version version services volumes networks secrets configs')):
     """
+    :param config_version: configuration file version
+    :type  config_version: int
     :param version: configuration version
     :type  version: int
     :param services: List of service description dictionaries
@@ -401,9 +409,8 @@ def load(config_details, interpolate=True):
         for service_dict in service_dicts:
             match_named_volumes(service_dict, volumes)
 
-    version = main_file.version
-
-    return Config(version, service_dicts, volumes, networks, secrets, configs)
+    return Config(main_file.config_version, main_file.version,
+                  service_dicts, volumes, networks, secrets, configs)
 
 
 def load_mapping(config_files, get_func, entity_type, working_dir=None):

+ 1 - 1
compose/config/serialize.py

@@ -44,7 +44,7 @@ yaml.SafeDumper.add_representer(types.ServicePort, serialize_dict_type)
 
 
 def denormalize_config(config, image_digests=None):
-    result = {'version': str(config.version)}
+    result = {'version': str(config.config_version)}
     denormalized_services = [
         denormalize_service_dict(
             service_dict,

+ 3 - 3
tests/acceptance/cli_test.py

@@ -359,7 +359,7 @@ services:
                 'web': {
                     'command': 'true',
                     'image': 'alpine:latest',
-                    'ports': ['5643/tcp', '9999/tcp']
+                    'ports': [{'target': 5643}, {'target': 9999}]
                 }
             }
         }
@@ -374,7 +374,7 @@ services:
                 'web': {
                     'command': 'false',
                     'image': 'alpine:latest',
-                    'ports': ['5644/tcp', '9998/tcp']
+                    'ports': [{'target': 5644}, {'target': 9998}]
                 }
             }
         }
@@ -389,7 +389,7 @@ services:
                 'web': {
                     'command': 'echo uwu',
                     'image': 'alpine:3.10.1',
-                    'ports': ['3341/tcp', '4449/tcp']
+                    'ports': [{'target': 3341}, {'target': 4449}]
                 }
             }
         }

+ 1 - 0
tests/integration/project_test.py

@@ -37,6 +37,7 @@ from tests.integration.testcases import no_cluster
 
 def build_config(**kwargs):
     return config.Config(
+        config_version=kwargs.get('version', VERSION),
         version=kwargs.get('version', VERSION),
         services=kwargs.get('services'),
         volumes=kwargs.get('volumes'),

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

@@ -168,12 +168,14 @@ class ConfigTest(unittest.TestCase):
                 }
             })
         )
+        assert cfg.config_version == VERSION
         assert cfg.version == VERSION
 
         for version in ['2', '2.0', '2.1', '2.2', '2.3',
                         '3', '3.0', '3.1', '3.2', '3.3', '3.4', '3.5', '3.6', '3.7', '3.8']:
             cfg = config.load(build_config_details({'version': version}))
-            assert cfg.version == version
+            assert cfg.config_version == version
+            assert cfg.version == VERSION
 
     def test_v1_file_version(self):
         cfg = config.load(build_config_details({'web': {'image': 'busybox'}}))
@@ -5369,7 +5371,7 @@ class SerializeTest(unittest.TestCase):
         assert serialized_config['secrets']['two'] == {'external': True, 'name': 'two'}
 
     def test_serialize_ports(self):
-        config_dict = config.Config(version=VERSION, services=[
+        config_dict = config.Config(config_version=VERSION, version=VERSION, services=[
             {
                 'ports': [types.ServicePort('80', '8080', None, None, None)],
                 'image': 'alpine',
@@ -5380,8 +5382,20 @@ class SerializeTest(unittest.TestCase):
         serialized_config = yaml.safe_load(serialize_config(config_dict))
         assert [{'published': 8080, 'target': 80}] == serialized_config['services']['web']['ports']
 
+    def test_serialize_ports_v1(self):
+        config_dict = config.Config(config_version=V1, version=V1, services=[
+            {
+                'ports': [types.ServicePort('80', '8080', None, None, None)],
+                'image': 'alpine',
+                'name': 'web'
+            }
+        ], volumes={}, networks={}, secrets={}, configs={})
+
+        serialized_config = yaml.safe_load(serialize_config(config_dict))
+        assert ['8080:80/tcp'] == serialized_config['services']['web']['ports']
+
     def test_serialize_ports_with_ext_ip(self):
-        config_dict = config.Config(version=VERSION, services=[
+        config_dict = config.Config(config_version=VERSION, version=VERSION, services=[
             {
                 'ports': [types.ServicePort('80', '8080', None, None, '127.0.0.1')],
                 'image': 'alpine',

+ 1 - 0
tests/unit/project_test.py

@@ -28,6 +28,7 @@ from compose.service import Service
 
 def build_config(**kwargs):
     return Config(
+        config_version=kwargs.get('config_version', VERSION),
         version=kwargs.get('version', VERSION),
         services=kwargs.get('services'),
         volumes=kwargs.get('volumes'),