mirror of
https://github.com/docker/compose.git
synced 2025-07-20 04:04:29 +02:00
Support V3.2
Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
parent
0ba1f61e9b
commit
2acf286ed6
@ -13,11 +13,8 @@ import yaml
|
|||||||
from cached_property import cached_property
|
from cached_property import cached_property
|
||||||
|
|
||||||
from . import types
|
from . import types
|
||||||
|
from .. import const
|
||||||
from ..const import COMPOSEFILE_V1 as V1
|
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 build_string_dict
|
||||||
from ..utils import parse_nanoseconds_int
|
from ..utils import parse_nanoseconds_int
|
||||||
from ..utils import splitdrive
|
from ..utils import splitdrive
|
||||||
@ -185,10 +182,10 @@ class ConfigFile(namedtuple('_ConfigFile', 'filename config')):
|
|||||||
.format(self.filename, VERSION_EXPLANATION))
|
.format(self.filename, VERSION_EXPLANATION))
|
||||||
|
|
||||||
if version == '2':
|
if version == '2':
|
||||||
version = V2_0
|
version = const.COMPOSEFILE_V2_0
|
||||||
|
|
||||||
if version == '3':
|
if version == '3':
|
||||||
version = V3_0
|
version = const.COMPOSEFILE_V3_0
|
||||||
|
|
||||||
return version
|
return version
|
||||||
|
|
||||||
@ -205,7 +202,7 @@ class ConfigFile(namedtuple('_ConfigFile', 'filename config')):
|
|||||||
return {} if self.version == V1 else self.config.get('networks', {})
|
return {} if self.version == V1 else self.config.get('networks', {})
|
||||||
|
|
||||||
def get_secrets(self):
|
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')):
|
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_dict = process_service(resolver.run())
|
||||||
|
|
||||||
service_config = service_config._replace(config=service_dict)
|
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_dict = finalize_service(
|
||||||
service_config,
|
service_config,
|
||||||
service_names,
|
service_names,
|
||||||
@ -480,7 +477,7 @@ def process_config_file(config_file, environment, service_name=None):
|
|||||||
'service',
|
'service',
|
||||||
environment)
|
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 = dict(config_file.config)
|
||||||
processed_config['services'] = services
|
processed_config['services'] = services
|
||||||
processed_config['volumes'] = interpolate_config_section(
|
processed_config['volumes'] = interpolate_config_section(
|
||||||
@ -493,19 +490,13 @@ def process_config_file(config_file, environment, service_name=None):
|
|||||||
config_file.get_networks(),
|
config_file.get_networks(),
|
||||||
'network',
|
'network',
|
||||||
environment)
|
environment)
|
||||||
if config_file.version in (V3_1,):
|
processed_config['secrets'] = interpolate_config_section(
|
||||||
processed_config['secrets'] = interpolate_config_section(
|
config_file,
|
||||||
config_file,
|
config_file.get_secrets(),
|
||||||
config_file.get_secrets(),
|
'secrets',
|
||||||
'secrets',
|
environment)
|
||||||
environment
|
|
||||||
)
|
|
||||||
elif config_file.version == V1:
|
|
||||||
processed_config = services
|
|
||||||
else:
|
else:
|
||||||
raise ConfigurationError(
|
processed_config = services
|
||||||
'Version in "{}" is unsupported. {}'
|
|
||||||
.format(config_file.filename, VERSION_EXPLANATION))
|
|
||||||
|
|
||||||
config_file = config_file._replace(config=processed_config)
|
config_file = config_file._replace(config=processed_config)
|
||||||
validate_against_config_schema(config_file)
|
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)
|
"%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
|
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_paths(service_dict)
|
||||||
|
|
||||||
validate_ulimits(service_config)
|
validate_ulimits(service_config)
|
||||||
|
@ -4,10 +4,10 @@ from __future__ import unicode_literals
|
|||||||
import six
|
import six
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
|
from compose import const
|
||||||
from compose.config import types
|
from compose.config import types
|
||||||
from compose.config.config import V1
|
from compose.const import COMPOSEFILE_V1 as V1
|
||||||
from compose.config.config import V2_1
|
from compose.const import COMPOSEFILE_V2_1 as V2_1
|
||||||
from compose.config.config import V3_1
|
|
||||||
|
|
||||||
|
|
||||||
def serialize_config_type(dumper, data):
|
def serialize_config_type(dumper, data):
|
||||||
@ -103,7 +103,7 @@ def denormalize_service_dict(service_dict, version):
|
|||||||
service_dict['healthcheck']['timeout']
|
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(
|
service_dict['ports'] = map(
|
||||||
lambda p: p.legacy_repr() if isinstance(p, types.ServicePort) else p,
|
lambda p: p.legacy_repr() if isinstance(p, types.ServicePort) else p,
|
||||||
service_dict['ports']
|
service_dict['ports']
|
||||||
|
@ -365,7 +365,7 @@ def process_config_schema_errors(error):
|
|||||||
|
|
||||||
|
|
||||||
def validate_against_config_schema(config_file):
|
def validate_against_config_schema(config_file):
|
||||||
schema = load_jsonschema(config_file.version)
|
schema = load_jsonschema(config_file)
|
||||||
format_checker = FormatChecker(["ports", "expose"])
|
format_checker = FormatChecker(["ports", "expose"])
|
||||||
validator = Draft4Validator(
|
validator = Draft4Validator(
|
||||||
schema,
|
schema,
|
||||||
@ -377,11 +377,12 @@ def validate_against_config_schema(config_file):
|
|||||||
config_file.filename)
|
config_file.filename)
|
||||||
|
|
||||||
|
|
||||||
def validate_service_constraints(config, service_name, version):
|
def validate_service_constraints(config, service_name, config_file):
|
||||||
def handler(errors):
|
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'])
|
validator = Draft4Validator(schema['definitions']['constraints']['service'])
|
||||||
handle_errors(validator.iter_errors(config), handler, None)
|
handle_errors(validator.iter_errors(config), handler, None)
|
||||||
|
|
||||||
@ -390,10 +391,15 @@ def get_schema_path():
|
|||||||
return os.path.dirname(os.path.abspath(__file__))
|
return os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
|
||||||
def load_jsonschema(version):
|
def load_jsonschema(config_file):
|
||||||
filename = os.path.join(
|
filename = os.path.join(
|
||||||
get_schema_path(),
|
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:
|
with open(filename, "r") as fh:
|
||||||
return json.load(fh)
|
return json.load(fh)
|
||||||
|
@ -21,8 +21,10 @@ SECRETS_PATH = '/run/secrets'
|
|||||||
COMPOSEFILE_V1 = '1'
|
COMPOSEFILE_V1 = '1'
|
||||||
COMPOSEFILE_V2_0 = '2.0'
|
COMPOSEFILE_V2_0 = '2.0'
|
||||||
COMPOSEFILE_V2_1 = '2.1'
|
COMPOSEFILE_V2_1 = '2.1'
|
||||||
|
|
||||||
COMPOSEFILE_V3_0 = '3.0'
|
COMPOSEFILE_V3_0 = '3.0'
|
||||||
COMPOSEFILE_V3_1 = '3.1'
|
COMPOSEFILE_V3_1 = '3.1'
|
||||||
|
COMPOSEFILE_V3_2 = '3.2'
|
||||||
|
|
||||||
API_VERSIONS = {
|
API_VERSIONS = {
|
||||||
COMPOSEFILE_V1: '1.21',
|
COMPOSEFILE_V1: '1.21',
|
||||||
@ -30,6 +32,7 @@ API_VERSIONS = {
|
|||||||
COMPOSEFILE_V2_1: '1.24',
|
COMPOSEFILE_V2_1: '1.24',
|
||||||
COMPOSEFILE_V3_0: '1.25',
|
COMPOSEFILE_V3_0: '1.25',
|
||||||
COMPOSEFILE_V3_1: '1.25',
|
COMPOSEFILE_V3_1: '1.25',
|
||||||
|
COMPOSEFILE_V3_2: '1.25',
|
||||||
}
|
}
|
||||||
|
|
||||||
API_VERSION_TO_ENGINE_VERSION = {
|
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_V2_1]: '1.12.0',
|
||||||
API_VERSIONS[COMPOSEFILE_V3_0]: '1.13.0',
|
API_VERSIONS[COMPOSEFILE_V3_0]: '1.13.0',
|
||||||
API_VERSIONS[COMPOSEFILE_V3_1]: '1.13.0',
|
API_VERSIONS[COMPOSEFILE_V3_1]: '1.13.0',
|
||||||
|
API_VERSIONS[COMPOSEFILE_V3_2]: '1.13.0',
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
version: '3.1'
|
version: '3.2'
|
||||||
services:
|
services:
|
||||||
simple:
|
simple:
|
||||||
image: busybox:latest
|
image: busybox:latest
|
||||||
|
@ -15,11 +15,11 @@ from .testcases import DockerClientTestCase
|
|||||||
from compose.config import config
|
from compose.config import config
|
||||||
from compose.config import ConfigurationError
|
from compose.config import ConfigurationError
|
||||||
from compose.config import types
|
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 VolumeFromSpec
|
||||||
from compose.config.types import VolumeSpec
|
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_PROJECT
|
||||||
from compose.const import LABEL_SERVICE
|
from compose.const import LABEL_SERVICE
|
||||||
from compose.container import Container
|
from compose.container import Container
|
||||||
|
@ -10,12 +10,12 @@ from pytest import skip
|
|||||||
from .. import unittest
|
from .. import unittest
|
||||||
from compose.cli.docker_client import docker_client
|
from compose.cli.docker_client import docker_client
|
||||||
from compose.config.config import resolve_environment
|
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.config.environment import Environment
|
||||||
from compose.const import API_VERSIONS
|
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.const import LABEL_PROJECT
|
||||||
from compose.progress_stream import stream_output
|
from compose.progress_stream import stream_output
|
||||||
from compose.service import Service
|
from compose.service import Service
|
||||||
|
@ -17,11 +17,6 @@ from compose.config import config
|
|||||||
from compose.config import types
|
from compose.config import types
|
||||||
from compose.config.config import resolve_build_args
|
from compose.config.config import resolve_build_args
|
||||||
from compose.config.config import resolve_environment
|
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.environment import Environment
|
||||||
from compose.config.errors import ConfigurationError
|
from compose.config.errors import ConfigurationError
|
||||||
from compose.config.errors import VERSION_EXPLANATION
|
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_config
|
||||||
from compose.config.serialize import serialize_ns_time_value
|
from compose.config.serialize import serialize_ns_time_value
|
||||||
from compose.config.types import VolumeSpec
|
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.const import IS_WINDOWS_PLATFORM
|
||||||
from compose.utils import nanoseconds_from_time_seconds
|
from compose.utils import nanoseconds_from_time_seconds
|
||||||
from tests import mock
|
from tests import mock
|
||||||
|
@ -3,13 +3,13 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from compose.config.config import V1
|
|
||||||
from compose.config.config import V2_0
|
|
||||||
from compose.config.errors import ConfigurationError
|
from compose.config.errors import ConfigurationError
|
||||||
from compose.config.types import parse_extra_hosts
|
from compose.config.types import parse_extra_hosts
|
||||||
from compose.config.types import ServicePort
|
from compose.config.types import ServicePort
|
||||||
from compose.config.types import VolumeFromSpec
|
from compose.config.types import VolumeFromSpec
|
||||||
from compose.config.types import VolumeSpec
|
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():
|
def test_parse_extra_hosts_list():
|
||||||
|
Loading…
x
Reference in New Issue
Block a user