mirror of https://github.com/docker/compose.git
Refactor validating extends file path
Separating out the steps we need to resolve extends, so that it will be clear to insert pre-processing of interpolation and validation. Signed-off-by: Mazz Mosley <mazz@houseofmnowster.com>
This commit is contained in:
parent
02c52ae673
commit
538a501eec
|
@ -11,6 +11,7 @@ from .errors import ComposeFileNotFound
|
||||||
from .errors import ConfigurationError
|
from .errors import ConfigurationError
|
||||||
from .interpolation import interpolate_environment_variables
|
from .interpolation import interpolate_environment_variables
|
||||||
from .validation import validate_against_schema
|
from .validation import validate_against_schema
|
||||||
|
from .validation import validate_extends_file_path
|
||||||
from .validation import validate_service_names
|
from .validation import validate_service_names
|
||||||
from .validation import validate_top_level_object
|
from .validation import validate_top_level_object
|
||||||
from compose.cli.utils import find_candidates_in_parent_dirs
|
from compose.cli.utils import find_candidates_in_parent_dirs
|
||||||
|
@ -171,12 +172,20 @@ class ServiceLoader(object):
|
||||||
|
|
||||||
self.resolve_environment()
|
self.resolve_environment()
|
||||||
|
|
||||||
|
if 'extends' in self.service_dict:
|
||||||
|
validate_extends_file_path(
|
||||||
|
service_name,
|
||||||
|
self.service_dict['extends'],
|
||||||
|
self.filename
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def detect_cycle(self, name):
|
def detect_cycle(self, name):
|
||||||
if self.signature(name) in self.already_seen:
|
if self.signature(name) in self.already_seen:
|
||||||
raise CircularReference(self.already_seen + [self.signature(name)])
|
raise CircularReference(self.already_seen + [self.signature(name)])
|
||||||
|
|
||||||
def make_service_dict(self):
|
def make_service_dict(self):
|
||||||
self.service_dict = self.resolve_extends(self.service_dict)
|
self.service_dict = self.resolve_extends()
|
||||||
return process_container_options(self.service_dict, working_dir=self.working_dir)
|
return process_container_options(self.service_dict, working_dir=self.working_dir)
|
||||||
|
|
||||||
def resolve_environment(self):
|
def resolve_environment(self):
|
||||||
|
@ -199,11 +208,12 @@ class ServiceLoader(object):
|
||||||
|
|
||||||
self.service_dict['environment'] = env
|
self.service_dict['environment'] = env
|
||||||
|
|
||||||
def resolve_extends(self, service_dict):
|
def resolve_extends(self):
|
||||||
if 'extends' not in service_dict:
|
if 'extends' not in self.service_dict:
|
||||||
return service_dict
|
return self.service_dict
|
||||||
|
|
||||||
extends_options = self.validate_extends_options(service_dict['name'], service_dict['extends'])
|
extends_options = self.service_dict['extends']
|
||||||
|
service_name = self.service_dict['name']
|
||||||
|
|
||||||
if 'file' in extends_options:
|
if 'file' in extends_options:
|
||||||
extends_from_filename = extends_options['file']
|
extends_from_filename = extends_options['file']
|
||||||
|
@ -212,7 +222,7 @@ class ServiceLoader(object):
|
||||||
other_config_path = self.filename
|
other_config_path = self.filename
|
||||||
|
|
||||||
other_working_dir = os.path.dirname(other_config_path)
|
other_working_dir = os.path.dirname(other_config_path)
|
||||||
other_already_seen = self.already_seen + [self.signature(service_dict['name'])]
|
other_already_seen = self.already_seen + [self.signature(service_name)]
|
||||||
|
|
||||||
base_service = extends_options['service']
|
base_service = extends_options['service']
|
||||||
other_config = load_yaml(other_config_path)
|
other_config = load_yaml(other_config_path)
|
||||||
|
@ -227,7 +237,7 @@ class ServiceLoader(object):
|
||||||
other_loader = ServiceLoader(
|
other_loader = ServiceLoader(
|
||||||
working_dir=other_working_dir,
|
working_dir=other_working_dir,
|
||||||
filename=other_config_path,
|
filename=other_config_path,
|
||||||
service_name=service_dict['name'],
|
service_name=service_name,
|
||||||
service_dict=other_service_dict,
|
service_dict=other_service_dict,
|
||||||
already_seen=other_already_seen,
|
already_seen=other_already_seen,
|
||||||
)
|
)
|
||||||
|
@ -240,21 +250,11 @@ class ServiceLoader(object):
|
||||||
service=extends_options['service'],
|
service=extends_options['service'],
|
||||||
)
|
)
|
||||||
|
|
||||||
return merge_service_dicts(other_service_dict, service_dict)
|
return merge_service_dicts(other_service_dict, self.service_dict)
|
||||||
|
|
||||||
def signature(self, name):
|
def signature(self, name):
|
||||||
return (self.filename, name)
|
return (self.filename, name)
|
||||||
|
|
||||||
def validate_extends_options(self, service_name, extends_options):
|
|
||||||
error_prefix = "Invalid 'extends' configuration for %s:" % service_name
|
|
||||||
|
|
||||||
if 'file' not in extends_options and self.filename is None:
|
|
||||||
raise ConfigurationError(
|
|
||||||
"%s you need to specify a 'file', e.g. 'file: something.yml'" % error_prefix
|
|
||||||
)
|
|
||||||
|
|
||||||
return extends_options
|
|
||||||
|
|
||||||
|
|
||||||
def validate_extended_service_dict(service_dict, filename, service):
|
def validate_extended_service_dict(service_dict, filename, service):
|
||||||
error_prefix = "Cannot extend service '%s' in %s:" % (service, filename)
|
error_prefix = "Cannot extend service '%s' in %s:" % (service, filename)
|
||||||
|
|
|
@ -66,6 +66,19 @@ def validate_top_level_object(func):
|
||||||
return func_wrapper
|
return func_wrapper
|
||||||
|
|
||||||
|
|
||||||
|
def validate_extends_file_path(service_name, extends_options, filename):
|
||||||
|
"""
|
||||||
|
The service to be extended must either be defined in the config key 'file',
|
||||||
|
or within 'filename'.
|
||||||
|
"""
|
||||||
|
error_prefix = "Invalid 'extends' configuration for %s:" % service_name
|
||||||
|
|
||||||
|
if 'file' not in extends_options and filename is None:
|
||||||
|
raise ConfigurationError(
|
||||||
|
"%s you need to specify a 'file', e.g. 'file: something.yml'" % error_prefix
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_unsupported_config_msg(service_name, error_key):
|
def get_unsupported_config_msg(service_name, error_key):
|
||||||
msg = "Unsupported config option for '{}' service: '{}'".format(service_name, error_key)
|
msg = "Unsupported config option for '{}' service: '{}'".format(service_name, error_key)
|
||||||
if error_key in DOCKER_CONFIG_HINTS:
|
if error_key in DOCKER_CONFIG_HINTS:
|
||||||
|
|
Loading…
Reference in New Issue