Support V3.2

Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
Daniel Nephin 2017-03-13 15:57:13 -04:00
parent 0ba1f61e9b
commit 2acf286ed6
9 changed files with 49 additions and 48 deletions

View File

@ -13,11 +13,8 @@ import yaml
from cached_property import cached_property
from . import types
from .. import const
from ..const import COMPOSEFILE_V1 as V1
from ..const import COMPOSEFILE_V2_0 as V2_0
from ..const import COMPOSEFILE_V2_1 as V2_1
from ..const import COMPOSEFILE_V3_0 as V3_0
from ..const import COMPOSEFILE_V3_1 as V3_1
from ..utils import build_string_dict
from ..utils import parse_nanoseconds_int
from ..utils import splitdrive
@ -185,10 +182,10 @@ class ConfigFile(namedtuple('_ConfigFile', 'filename config')):
.format(self.filename, VERSION_EXPLANATION))
if version == '2':
version = V2_0
version = const.COMPOSEFILE_V2_0
if version == '3':
version = V3_0
version = const.COMPOSEFILE_V3_0
return version
@ -205,7 +202,7 @@ class ConfigFile(namedtuple('_ConfigFile', 'filename config')):
return {} if self.version == V1 else self.config.get('networks', {})
def get_secrets(self):
return {} if self.version < V3_1 else self.config.get('secrets', {})
return {} if self.version < const.COMPOSEFILE_V3_1 else self.config.get('secrets', {})
class Config(namedtuple('_Config', 'version services volumes networks secrets')):
@ -427,7 +424,7 @@ def load_services(config_details, config_file):
service_dict = process_service(resolver.run())
service_config = service_config._replace(config=service_dict)
validate_service(service_config, service_names, config_file.version)
validate_service(service_config, service_names, config_file)
service_dict = finalize_service(
service_config,
service_names,
@ -480,7 +477,7 @@ def process_config_file(config_file, environment, service_name=None):
'service',
environment)
if config_file.version in (V2_0, V2_1, V3_0, V3_1):
if config_file.version != V1:
processed_config = dict(config_file.config)
processed_config['services'] = services
processed_config['volumes'] = interpolate_config_section(
@ -493,19 +490,13 @@ def process_config_file(config_file, environment, service_name=None):
config_file.get_networks(),
'network',
environment)
if config_file.version in (V3_1,):
processed_config['secrets'] = interpolate_config_section(
config_file,
config_file.get_secrets(),
'secrets',
environment
)
elif config_file.version == V1:
processed_config = services
processed_config['secrets'] = interpolate_config_section(
config_file,
config_file.get_secrets(),
'secrets',
environment)
else:
raise ConfigurationError(
'Version in "{}" is unsupported. {}'
.format(config_file.filename, VERSION_EXPLANATION))
processed_config = services
config_file = config_file._replace(config=processed_config)
validate_against_config_schema(config_file)
@ -642,9 +633,9 @@ def validate_extended_service_dict(service_dict, filename, service):
"%s services with 'depends_on' cannot be extended" % error_prefix)
def validate_service(service_config, service_names, version):
def validate_service(service_config, service_names, config_file):
service_dict, service_name = service_config.config, service_config.name
validate_service_constraints(service_dict, service_name, version)
validate_service_constraints(service_dict, service_name, config_file)
validate_paths(service_dict)
validate_ulimits(service_config)

View File

@ -4,10 +4,10 @@ from __future__ import unicode_literals
import six
import yaml
from compose import const
from compose.config import types
from compose.config.config import V1
from compose.config.config import V2_1
from compose.config.config import V3_1
from compose.const import COMPOSEFILE_V1 as V1
from compose.const import COMPOSEFILE_V2_1 as V2_1
def serialize_config_type(dumper, data):
@ -103,7 +103,7 @@ def denormalize_service_dict(service_dict, version):
service_dict['healthcheck']['timeout']
)
if 'ports' in service_dict and version != V3_1:
if 'ports' in service_dict and version < const.COMPOSEFILE_V3_2:
service_dict['ports'] = map(
lambda p: p.legacy_repr() if isinstance(p, types.ServicePort) else p,
service_dict['ports']

View File

@ -365,7 +365,7 @@ def process_config_schema_errors(error):
def validate_against_config_schema(config_file):
schema = load_jsonschema(config_file.version)
schema = load_jsonschema(config_file)
format_checker = FormatChecker(["ports", "expose"])
validator = Draft4Validator(
schema,
@ -377,11 +377,12 @@ def validate_against_config_schema(config_file):
config_file.filename)
def validate_service_constraints(config, service_name, version):
def validate_service_constraints(config, service_name, config_file):
def handler(errors):
return process_service_constraint_errors(errors, service_name, version)
return process_service_constraint_errors(
errors, service_name, config_file.version)
schema = load_jsonschema(version)
schema = load_jsonschema(config_file)
validator = Draft4Validator(schema['definitions']['constraints']['service'])
handle_errors(validator.iter_errors(config), handler, None)
@ -390,10 +391,15 @@ def get_schema_path():
return os.path.dirname(os.path.abspath(__file__))
def load_jsonschema(version):
def load_jsonschema(config_file):
filename = os.path.join(
get_schema_path(),
"config_schema_v{0}.json".format(version))
"config_schema_v{0}.json".format(config_file.version))
if not os.path.exists(filename):
raise ConfigurationError(
'Version in "{}" is unsupported. {}'
.format(config_file.filename, VERSION_EXPLANATION))
with open(filename, "r") as fh:
return json.load(fh)

View File

@ -21,8 +21,10 @@ SECRETS_PATH = '/run/secrets'
COMPOSEFILE_V1 = '1'
COMPOSEFILE_V2_0 = '2.0'
COMPOSEFILE_V2_1 = '2.1'
COMPOSEFILE_V3_0 = '3.0'
COMPOSEFILE_V3_1 = '3.1'
COMPOSEFILE_V3_2 = '3.2'
API_VERSIONS = {
COMPOSEFILE_V1: '1.21',
@ -30,6 +32,7 @@ API_VERSIONS = {
COMPOSEFILE_V2_1: '1.24',
COMPOSEFILE_V3_0: '1.25',
COMPOSEFILE_V3_1: '1.25',
COMPOSEFILE_V3_2: '1.25',
}
API_VERSION_TO_ENGINE_VERSION = {
@ -38,4 +41,5 @@ API_VERSION_TO_ENGINE_VERSION = {
API_VERSIONS[COMPOSEFILE_V2_1]: '1.12.0',
API_VERSIONS[COMPOSEFILE_V3_0]: '1.13.0',
API_VERSIONS[COMPOSEFILE_V3_1]: '1.13.0',
API_VERSIONS[COMPOSEFILE_V3_2]: '1.13.0',
}

View File

@ -1,4 +1,4 @@
version: '3.1'
version: '3.2'
services:
simple:
image: busybox:latest

View File

@ -15,11 +15,11 @@ from .testcases import DockerClientTestCase
from compose.config import config
from compose.config import ConfigurationError
from compose.config import types
from compose.config.config import V2_0
from compose.config.config import V2_1
from compose.config.config import V3_1
from compose.config.types import VolumeFromSpec
from compose.config.types import VolumeSpec
from compose.const import COMPOSEFILE_V2_0 as V2_0
from compose.const import COMPOSEFILE_V2_1 as V2_1
from compose.const import COMPOSEFILE_V3_1 as V3_1
from compose.const import LABEL_PROJECT
from compose.const import LABEL_SERVICE
from compose.container import Container

View File

@ -10,12 +10,12 @@ from pytest import skip
from .. import unittest
from compose.cli.docker_client import docker_client
from compose.config.config import resolve_environment
from compose.config.config import V1
from compose.config.config import V2_0
from compose.config.config import V2_1
from compose.config.config import V3_0
from compose.config.environment import Environment
from compose.const import API_VERSIONS
from compose.const import COMPOSEFILE_V1 as V1
from compose.const import COMPOSEFILE_V2_0 as V2_0
from compose.const import COMPOSEFILE_V2_0 as V2_1
from compose.const import COMPOSEFILE_V3_0 as V3_0
from compose.const import LABEL_PROJECT
from compose.progress_stream import stream_output
from compose.service import Service

View File

@ -17,11 +17,6 @@ from compose.config import config
from compose.config import types
from compose.config.config import resolve_build_args
from compose.config.config import resolve_environment
from compose.config.config import V1
from compose.config.config import V2_0
from compose.config.config import V2_1
from compose.config.config import V3_0
from compose.config.config import V3_1
from compose.config.environment import Environment
from compose.config.errors import ConfigurationError
from compose.config.errors import VERSION_EXPLANATION
@ -29,6 +24,11 @@ from compose.config.serialize import denormalize_service_dict
from compose.config.serialize import serialize_config
from compose.config.serialize import serialize_ns_time_value
from compose.config.types import VolumeSpec
from compose.const import COMPOSEFILE_V1 as V1
from compose.const import COMPOSEFILE_V2_0 as V2_0
from compose.const import COMPOSEFILE_V2_1 as V2_1
from compose.const import COMPOSEFILE_V3_0 as V3_0
from compose.const import COMPOSEFILE_V3_1 as V3_1
from compose.const import IS_WINDOWS_PLATFORM
from compose.utils import nanoseconds_from_time_seconds
from tests import mock

View File

@ -3,13 +3,13 @@ from __future__ import unicode_literals
import pytest
from compose.config.config import V1
from compose.config.config import V2_0
from compose.config.errors import ConfigurationError
from compose.config.types import parse_extra_hosts
from compose.config.types import ServicePort
from compose.config.types import VolumeFromSpec
from compose.config.types import VolumeSpec
from compose.const import COMPOSEFILE_V1 as V1
from compose.const import COMPOSEFILE_V2_0 as V2_0
def test_parse_extra_hosts_list():