From b689c4a21888b751eb566630f6d441128d196cdd Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Thu, 14 Jan 2016 11:39:16 -0500 Subject: [PATCH 1/2] Move service validation to validate_service(). Signed-off-by: Daniel Nephin --- compose/config/config.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/compose/config/config.py b/compose/config/config.py index 4684161e3..a378f2762 100644 --- a/compose/config/config.py +++ b/compose/config/config.py @@ -312,15 +312,11 @@ def load_services(working_dir, filename, service_configs, version): resolver = ServiceExtendsResolver(service_config, version) service_dict = process_service(resolver.run()) - # TODO: move to validate_service() - validate_against_service_schema(service_dict, service_config.name, version) - validate_paths(service_dict) - + validate_service(service_dict, service_config.name, version) service_dict = finalize_service( service_config._replace(config=service_dict), service_names, version) - service_dict['name'] = service_config.name return service_dict def build_services(service_config): @@ -494,7 +490,14 @@ def validate_ulimits(ulimit_config): "than 'hard' value".format(ulimit_config)) -# TODO: rename to normalize_service +def validate_service(service_dict, service_name, version): + validate_against_service_schema(service_dict, service_name, version) + validate_paths(service_dict) + + if 'ulimits' in service_dict: + validate_ulimits(service_dict['ulimits']) + + def process_service(service_config): working_dir = service_config.working_dir service_dict = dict(service_config.config) @@ -525,10 +528,6 @@ def process_service(service_config): if field in service_dict: service_dict[field] = to_list(service_dict[field]) - # TODO: move to a validate_service() - if 'ulimits' in service_dict: - validate_ulimits(service_dict['ulimits']) - return service_dict @@ -554,6 +553,7 @@ def finalize_service(service_config, service_names, version): normalize_build(service_dict, service_config.working_dir) + service_dict['name'] = service_config.name return normalize_v1_service_format(service_dict) From b98e2169e6aebd786dab5554e91dce55c248abb9 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Thu, 14 Jan 2016 13:28:53 -0500 Subject: [PATCH 2/2] Error when the project name is invalid for the image name. Signed-off-by: Daniel Nephin --- compose/config/config.py | 12 ++++++++++++ tests/unit/config/config_test.py | 7 +++++++ 2 files changed, 19 insertions(+) diff --git a/compose/config/config.py b/compose/config/config.py index a378f2762..b38942253 100644 --- a/compose/config/config.py +++ b/compose/config/config.py @@ -6,6 +6,7 @@ import functools import logging import operator import os +import string import sys from collections import namedtuple @@ -497,6 +498,13 @@ def validate_service(service_dict, service_name, version): if 'ulimits' in service_dict: validate_ulimits(service_dict['ulimits']) + if not service_dict.get('image') and has_uppercase(service_name): + raise ConfigurationError( + "Service '{name}' contains uppercase characters which are not valid " + "as part of an image name. Either use a lowercase service name or " + "use the `image` field to set a custom name for the service image." + .format(name=service_name)) + def process_service(service_config): working_dir = service_config.working_dir @@ -861,6 +869,10 @@ def to_list(value): return value +def has_uppercase(name): + return any(char in string.ascii_uppercase for char in name) + + def load_yaml(filename): try: with open(filename, 'r') as fh: diff --git a/tests/unit/config/config_test.py b/tests/unit/config/config_test.py index 10c5bbb7b..e24dc9041 100644 --- a/tests/unit/config/config_test.py +++ b/tests/unit/config/config_test.py @@ -544,6 +544,13 @@ class ConfigTest(unittest.TestCase): ) ) + def test_load_errors_on_uppercase_with_no_image(self): + with pytest.raises(ConfigurationError) as exc: + config.load(build_config_details({ + 'Foo': {'build': '.'}, + }, 'tests/fixtures/build-ctx')) + assert "Service 'Foo' contains uppercase characters" in exc.exconly() + def test_invalid_config_build_and_image_specified(self): expected_error_msg = "Service 'foo' has both an image and build path specified." with self.assertRaisesRegexp(ConfigurationError, expected_error_msg):