mirror of https://github.com/docker/compose.git
Make 'version' a string
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
This commit is contained in:
parent
a8de582425
commit
aeef61fcd8
|
@ -14,6 +14,8 @@ import six
|
||||||
import yaml
|
import yaml
|
||||||
from cached_property import cached_property
|
from cached_property import cached_property
|
||||||
|
|
||||||
|
from ..const import COMPOSEFILE_V1 as V1
|
||||||
|
from ..const import COMPOSEFILE_V2_0 as V2_0
|
||||||
from ..const import COMPOSEFILE_VERSIONS
|
from ..const import COMPOSEFILE_VERSIONS
|
||||||
from .errors import CircularReference
|
from .errors import CircularReference
|
||||||
from .errors import ComposeFileNotFound
|
from .errors import ComposeFileNotFound
|
||||||
|
@ -129,25 +131,34 @@ class ConfigFile(namedtuple('_ConfigFile', 'filename config')):
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def version(self):
|
def version(self):
|
||||||
version = self.config.get('version', 1)
|
version = self.config.get('version', V1)
|
||||||
|
|
||||||
if isinstance(version, dict):
|
if isinstance(version, dict):
|
||||||
log.warn("Unexpected type for field 'version', in file {} assuming "
|
log.warn("Unexpected type for field 'version', in file {} assuming "
|
||||||
"version is the name of a service, and defaulting to "
|
"version is the name of a service, and defaulting to "
|
||||||
"Compose file version 1".format(self.filename))
|
"Compose file version 1".format(self.filename))
|
||||||
return 1
|
return V1
|
||||||
|
|
||||||
|
if version == '2':
|
||||||
|
version = V2_0
|
||||||
|
|
||||||
|
if version not in COMPOSEFILE_VERSIONS:
|
||||||
|
raise ConfigurationError(
|
||||||
|
'Invalid Compose file version: {0}'.format(version))
|
||||||
|
|
||||||
return version
|
return version
|
||||||
|
|
||||||
def get_service(self, name):
|
def get_service(self, name):
|
||||||
return self.get_service_dicts()[name]
|
return self.get_service_dicts()[name]
|
||||||
|
|
||||||
def get_service_dicts(self):
|
def get_service_dicts(self):
|
||||||
return self.config if self.version == 1 else self.config.get('services', {})
|
return self.config if self.version == V1 else self.config.get('services', {})
|
||||||
|
|
||||||
def get_volumes(self):
|
def get_volumes(self):
|
||||||
return {} if self.version == 1 else self.config.get('volumes', {})
|
return {} if self.version == V1 else self.config.get('volumes', {})
|
||||||
|
|
||||||
def get_networks(self):
|
def get_networks(self):
|
||||||
return {} if self.version == 1 else self.config.get('networks', {})
|
return {} if self.version == V1 else self.config.get('networks', {})
|
||||||
|
|
||||||
|
|
||||||
class Config(namedtuple('_Config', 'version services volumes networks')):
|
class Config(namedtuple('_Config', 'version services volumes networks')):
|
||||||
|
@ -209,10 +220,6 @@ def validate_config_version(config_files):
|
||||||
next_file.filename,
|
next_file.filename,
|
||||||
next_file.version))
|
next_file.version))
|
||||||
|
|
||||||
if main_file.version not in COMPOSEFILE_VERSIONS:
|
|
||||||
raise ConfigurationError(
|
|
||||||
'Invalid Compose file version: {0}'.format(main_file.version))
|
|
||||||
|
|
||||||
|
|
||||||
def get_default_config_files(base_dir):
|
def get_default_config_files(base_dir):
|
||||||
(candidates, path) = find_candidates_in_parent_dirs(SUPPORTED_FILENAMES, base_dir)
|
(candidates, path) = find_candidates_in_parent_dirs(SUPPORTED_FILENAMES, base_dir)
|
||||||
|
@ -276,7 +283,7 @@ def load(config_details):
|
||||||
main_file,
|
main_file,
|
||||||
[file.get_service_dicts() for file in config_details.config_files])
|
[file.get_service_dicts() for file in config_details.config_files])
|
||||||
|
|
||||||
if main_file.version >= 2:
|
if main_file.version != V1:
|
||||||
for service_dict in service_dicts:
|
for service_dict in service_dicts:
|
||||||
match_named_volumes(service_dict, volumes)
|
match_named_volumes(service_dict, volumes)
|
||||||
|
|
||||||
|
@ -361,7 +368,7 @@ def process_config_file(config_file, service_name=None):
|
||||||
|
|
||||||
interpolated_config = interpolate_environment_variables(service_dicts, 'service')
|
interpolated_config = interpolate_environment_variables(service_dicts, 'service')
|
||||||
|
|
||||||
if config_file.version == 2:
|
if config_file.version == V2_0:
|
||||||
processed_config = dict(config_file.config)
|
processed_config = dict(config_file.config)
|
||||||
processed_config['services'] = services = interpolated_config
|
processed_config['services'] = services = interpolated_config
|
||||||
processed_config['volumes'] = interpolate_environment_variables(
|
processed_config['volumes'] = interpolate_environment_variables(
|
||||||
|
@ -369,7 +376,7 @@ def process_config_file(config_file, service_name=None):
|
||||||
processed_config['networks'] = interpolate_environment_variables(
|
processed_config['networks'] = interpolate_environment_variables(
|
||||||
config_file.get_networks(), 'network')
|
config_file.get_networks(), 'network')
|
||||||
|
|
||||||
if config_file.version == 1:
|
if config_file.version == V1:
|
||||||
processed_config = services = interpolated_config
|
processed_config = services = interpolated_config
|
||||||
|
|
||||||
config_file = config_file._replace(config=processed_config)
|
config_file = config_file._replace(config=processed_config)
|
||||||
|
@ -653,7 +660,7 @@ def merge_service_dicts(base, override, version):
|
||||||
if field in base or field in override:
|
if field in base or field in override:
|
||||||
d[field] = override.get(field, base.get(field))
|
d[field] = override.get(field, base.get(field))
|
||||||
|
|
||||||
if version == 1:
|
if version == V1:
|
||||||
legacy_v1_merge_image_or_build(d, base, override)
|
legacy_v1_merge_image_or_build(d, base, override)
|
||||||
else:
|
else:
|
||||||
merge_build(d, base, override)
|
merge_build(d, base, override)
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
{
|
{
|
||||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"id": "fields_schema_v2.json",
|
"id": "fields_schema_v2.0.json",
|
||||||
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"version": {
|
"version": {
|
||||||
"enum": [2]
|
"type": "string"
|
||||||
},
|
},
|
||||||
"services": {
|
"services": {
|
||||||
"id": "#/properties/services",
|
"id": "#/properties/services",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"patternProperties": {
|
"patternProperties": {
|
||||||
"^[a-zA-Z0-9._-]+$": {
|
"^[a-zA-Z0-9._-]+$": {
|
||||||
"$ref": "service_schema_v2.json#/definitions/service"
|
"$ref": "service_schema_v2.0.json#/definitions/service"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||||
"id": "service_schema_v2.json",
|
"id": "service_schema_v2.0.json",
|
||||||
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
|
|
@ -7,6 +7,7 @@ from __future__ import unicode_literals
|
||||||
import os
|
import os
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
|
from compose.config.config import V1
|
||||||
from compose.config.errors import ConfigurationError
|
from compose.config.errors import ConfigurationError
|
||||||
from compose.const import IS_WINDOWS_PLATFORM
|
from compose.const import IS_WINDOWS_PLATFORM
|
||||||
|
|
||||||
|
@ -16,7 +17,7 @@ class VolumeFromSpec(namedtuple('_VolumeFromSpec', 'source mode type')):
|
||||||
# TODO: drop service_names arg when v1 is removed
|
# TODO: drop service_names arg when v1 is removed
|
||||||
@classmethod
|
@classmethod
|
||||||
def parse(cls, volume_from_config, service_names, version):
|
def parse(cls, volume_from_config, service_names, version):
|
||||||
func = cls.parse_v1 if version == 1 else cls.parse_v2
|
func = cls.parse_v1 if version == V1 else cls.parse_v2
|
||||||
return func(service_names, volume_from_config)
|
return func(service_names, volume_from_config)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
@ -14,9 +14,12 @@ LABEL_PROJECT = 'com.docker.compose.project'
|
||||||
LABEL_SERVICE = 'com.docker.compose.service'
|
LABEL_SERVICE = 'com.docker.compose.service'
|
||||||
LABEL_VERSION = 'com.docker.compose.version'
|
LABEL_VERSION = 'com.docker.compose.version'
|
||||||
LABEL_CONFIG_HASH = 'com.docker.compose.config-hash'
|
LABEL_CONFIG_HASH = 'com.docker.compose.config-hash'
|
||||||
COMPOSEFILE_VERSIONS = (1, 2)
|
|
||||||
|
COMPOSEFILE_V1 = '1'
|
||||||
|
COMPOSEFILE_V2_0 = '2.0'
|
||||||
|
COMPOSEFILE_VERSIONS = (COMPOSEFILE_V1, COMPOSEFILE_V2_0)
|
||||||
|
|
||||||
API_VERSIONS = {
|
API_VERSIONS = {
|
||||||
1: '1.21',
|
COMPOSEFILE_V1: '1.21',
|
||||||
2: '1.22',
|
COMPOSEFILE_V2_0: '1.22',
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ from docker.errors import NotFound
|
||||||
|
|
||||||
from . import parallel
|
from . import parallel
|
||||||
from .config import ConfigurationError
|
from .config import ConfigurationError
|
||||||
|
from .config.config import V1
|
||||||
from .config.sort_services import get_container_name_from_network_mode
|
from .config.sort_services import get_container_name_from_network_mode
|
||||||
from .config.sort_services import get_service_name_from_network_mode
|
from .config.sort_services import get_service_name_from_network_mode
|
||||||
from .const import DEFAULT_TIMEOUT
|
from .const import DEFAULT_TIMEOUT
|
||||||
|
@ -56,7 +57,7 @@ class Project(object):
|
||||||
"""
|
"""
|
||||||
Construct a Project from a config.Config object.
|
Construct a Project from a config.Config object.
|
||||||
"""
|
"""
|
||||||
use_networking = (config_data.version and config_data.version >= 2)
|
use_networking = (config_data.version and config_data.version != V1)
|
||||||
project = cls(name, [], client, use_networking=use_networking)
|
project = cls(name, [], client, use_networking=use_networking)
|
||||||
|
|
||||||
network_config = config_data.networks or {}
|
network_config = config_data.networks or {}
|
||||||
|
@ -94,7 +95,7 @@ class Project(object):
|
||||||
network_mode = project.get_network_mode(service_dict, networks)
|
network_mode = project.get_network_mode(service_dict, networks)
|
||||||
volumes_from = get_volumes_from(project, service_dict)
|
volumes_from = get_volumes_from(project, service_dict)
|
||||||
|
|
||||||
if config_data.version == 2:
|
if config_data.version != V1:
|
||||||
service_volumes = service_dict.get('volumes', [])
|
service_volumes = service_dict.get('volumes', [])
|
||||||
for volume_spec in service_volumes:
|
for volume_spec in service_volumes:
|
||||||
if volume_spec.is_named_volume:
|
if volume_spec.is_named_volume:
|
||||||
|
|
|
@ -23,8 +23,8 @@ exe = EXE(pyz,
|
||||||
'DATA'
|
'DATA'
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
'compose/config/fields_schema_v2.json',
|
'compose/config/fields_schema_v2.0.json',
|
||||||
'compose/config/fields_schema_v2.json',
|
'compose/config/fields_schema_v2.0.json',
|
||||||
'DATA'
|
'DATA'
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
@ -33,8 +33,8 @@ exe = EXE(pyz,
|
||||||
'DATA'
|
'DATA'
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
'compose/config/service_schema_v2.json',
|
'compose/config/service_schema_v2.0.json',
|
||||||
'compose/config/service_schema_v2.json',
|
'compose/config/service_schema_v2.0.json',
|
||||||
'DATA'
|
'DATA'
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
|
|
@ -177,7 +177,7 @@ class CLITestCase(DockerClientTestCase):
|
||||||
|
|
||||||
output = yaml.load(result.stdout)
|
output = yaml.load(result.stdout)
|
||||||
expected = {
|
expected = {
|
||||||
'version': 2,
|
'version': '2.0',
|
||||||
'volumes': {'data': {'driver': 'local'}},
|
'volumes': {'data': {'driver': 'local'}},
|
||||||
'networks': {'front': {}},
|
'networks': {'front': {}},
|
||||||
'services': {
|
'services': {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
version: 2
|
version: "2"
|
||||||
services:
|
services:
|
||||||
myweb:
|
myweb:
|
||||||
build: '.'
|
build: '.'
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
version: 2
|
version: "2"
|
||||||
services:
|
services:
|
||||||
simple:
|
simple:
|
||||||
image: busybox:latest
|
image: busybox:latest
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
version: 2
|
version: "2"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
foo:
|
foo:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
version: 2
|
version: "2"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
web:
|
web:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
version: 2
|
version: "2"
|
||||||
services:
|
services:
|
||||||
simple:
|
simple:
|
||||||
image: busybox:latest
|
image: busybox:latest
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
version: 2
|
version: "2"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
web:
|
web:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
version: 2
|
version: "2"
|
||||||
services:
|
services:
|
||||||
simple:
|
simple:
|
||||||
image: busybox:latest
|
image: busybox:latest
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
version: 2
|
version: "2"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
web:
|
web:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
version: 2
|
version: "2"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
web:
|
web:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
version: 2
|
version: "2"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
bridge:
|
bridge:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
version: 2
|
version: "2"
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
foo: {}
|
foo: {}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
version: 2
|
version: "2"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
simple:
|
simple:
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
version: 2
|
version: "2"
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
data:
|
data:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
version: 2
|
version: "2"
|
||||||
services:
|
services:
|
||||||
simple:
|
simple:
|
||||||
image: busybox:latest
|
image: busybox:latest
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
version: 2
|
version: "2"
|
||||||
services:
|
services:
|
||||||
simple:
|
simple:
|
||||||
image: busybox:latest
|
image: busybox:latest
|
||||||
|
|
|
@ -10,6 +10,7 @@ from docker.errors import NotFound
|
||||||
from .testcases import DockerClientTestCase
|
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.config import V2_0
|
||||||
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 LABEL_PROJECT
|
from compose.const import LABEL_PROJECT
|
||||||
|
@ -112,7 +113,7 @@ class ProjectTest(DockerClientTestCase):
|
||||||
name='composetest',
|
name='composetest',
|
||||||
client=self.client,
|
client=self.client,
|
||||||
config_data=build_service_dicts({
|
config_data=build_service_dicts({
|
||||||
'version': 2,
|
'version': V2_0,
|
||||||
'services': {
|
'services': {
|
||||||
'net': {
|
'net': {
|
||||||
'image': 'busybox:latest',
|
'image': 'busybox:latest',
|
||||||
|
@ -139,7 +140,7 @@ class ProjectTest(DockerClientTestCase):
|
||||||
return Project.from_config(
|
return Project.from_config(
|
||||||
name='composetest',
|
name='composetest',
|
||||||
config_data=build_service_dicts({
|
config_data=build_service_dicts({
|
||||||
'version': 2,
|
'version': V2_0,
|
||||||
'services': {
|
'services': {
|
||||||
'web': {
|
'web': {
|
||||||
'image': 'busybox:latest',
|
'image': 'busybox:latest',
|
||||||
|
@ -559,7 +560,7 @@ class ProjectTest(DockerClientTestCase):
|
||||||
@v2_only()
|
@v2_only()
|
||||||
def test_project_up_networks(self):
|
def test_project_up_networks(self):
|
||||||
config_data = config.Config(
|
config_data = config.Config(
|
||||||
version=2,
|
version=V2_0,
|
||||||
services=[{
|
services=[{
|
||||||
'name': 'web',
|
'name': 'web',
|
||||||
'image': 'busybox:latest',
|
'image': 'busybox:latest',
|
||||||
|
@ -592,7 +593,7 @@ class ProjectTest(DockerClientTestCase):
|
||||||
@v2_only()
|
@v2_only()
|
||||||
def test_up_with_ipam_config(self):
|
def test_up_with_ipam_config(self):
|
||||||
config_data = config.Config(
|
config_data = config.Config(
|
||||||
version=2,
|
version=V2_0,
|
||||||
services=[],
|
services=[],
|
||||||
volumes={},
|
volumes={},
|
||||||
networks={
|
networks={
|
||||||
|
@ -651,7 +652,7 @@ class ProjectTest(DockerClientTestCase):
|
||||||
vol_name = '{0:x}'.format(random.getrandbits(32))
|
vol_name = '{0:x}'.format(random.getrandbits(32))
|
||||||
full_vol_name = 'composetest_{0}'.format(vol_name)
|
full_vol_name = 'composetest_{0}'.format(vol_name)
|
||||||
config_data = config.Config(
|
config_data = config.Config(
|
||||||
version=2,
|
version=V2_0,
|
||||||
services=[{
|
services=[{
|
||||||
'name': 'web',
|
'name': 'web',
|
||||||
'image': 'busybox:latest',
|
'image': 'busybox:latest',
|
||||||
|
@ -677,7 +678,7 @@ class ProjectTest(DockerClientTestCase):
|
||||||
base_file = config.ConfigFile(
|
base_file = config.ConfigFile(
|
||||||
'base.yml',
|
'base.yml',
|
||||||
{
|
{
|
||||||
'version': 2,
|
'version': V2_0,
|
||||||
'services': {
|
'services': {
|
||||||
'simple': {'image': 'busybox:latest', 'command': 'top'},
|
'simple': {'image': 'busybox:latest', 'command': 'top'},
|
||||||
'another': {
|
'another': {
|
||||||
|
@ -696,7 +697,7 @@ class ProjectTest(DockerClientTestCase):
|
||||||
override_file = config.ConfigFile(
|
override_file = config.ConfigFile(
|
||||||
'override.yml',
|
'override.yml',
|
||||||
{
|
{
|
||||||
'version': 2,
|
'version': V2_0,
|
||||||
'services': {
|
'services': {
|
||||||
'another': {
|
'another': {
|
||||||
'logging': {
|
'logging': {
|
||||||
|
@ -729,7 +730,7 @@ class ProjectTest(DockerClientTestCase):
|
||||||
vol_name = '{0:x}'.format(random.getrandbits(32))
|
vol_name = '{0:x}'.format(random.getrandbits(32))
|
||||||
full_vol_name = 'composetest_{0}'.format(vol_name)
|
full_vol_name = 'composetest_{0}'.format(vol_name)
|
||||||
config_data = config.Config(
|
config_data = config.Config(
|
||||||
version=2,
|
version=V2_0,
|
||||||
services=[{
|
services=[{
|
||||||
'name': 'web',
|
'name': 'web',
|
||||||
'image': 'busybox:latest',
|
'image': 'busybox:latest',
|
||||||
|
@ -754,7 +755,7 @@ class ProjectTest(DockerClientTestCase):
|
||||||
vol_name = '{0:x}'.format(random.getrandbits(32))
|
vol_name = '{0:x}'.format(random.getrandbits(32))
|
||||||
full_vol_name = 'composetest_{0}'.format(vol_name)
|
full_vol_name = 'composetest_{0}'.format(vol_name)
|
||||||
config_data = config.Config(
|
config_data = config.Config(
|
||||||
version=2,
|
version=V2_0,
|
||||||
services=[{
|
services=[{
|
||||||
'name': 'web',
|
'name': 'web',
|
||||||
'image': 'busybox:latest',
|
'image': 'busybox:latest',
|
||||||
|
@ -779,7 +780,7 @@ class ProjectTest(DockerClientTestCase):
|
||||||
vol_name = '{0:x}'.format(random.getrandbits(32))
|
vol_name = '{0:x}'.format(random.getrandbits(32))
|
||||||
|
|
||||||
config_data = config.Config(
|
config_data = config.Config(
|
||||||
version=2,
|
version=V2_0,
|
||||||
services=[{
|
services=[{
|
||||||
'name': 'web',
|
'name': 'web',
|
||||||
'image': 'busybox:latest',
|
'image': 'busybox:latest',
|
||||||
|
@ -802,7 +803,7 @@ class ProjectTest(DockerClientTestCase):
|
||||||
full_vol_name = 'composetest_{0}'.format(vol_name)
|
full_vol_name = 'composetest_{0}'.format(vol_name)
|
||||||
|
|
||||||
config_data = config.Config(
|
config_data = config.Config(
|
||||||
version=2,
|
version=V2_0,
|
||||||
services=[{
|
services=[{
|
||||||
'name': 'web',
|
'name': 'web',
|
||||||
'image': 'busybox:latest',
|
'image': 'busybox:latest',
|
||||||
|
@ -841,7 +842,7 @@ class ProjectTest(DockerClientTestCase):
|
||||||
full_vol_name = 'composetest_{0}'.format(vol_name)
|
full_vol_name = 'composetest_{0}'.format(vol_name)
|
||||||
self.client.create_volume(vol_name)
|
self.client.create_volume(vol_name)
|
||||||
config_data = config.Config(
|
config_data = config.Config(
|
||||||
version=2,
|
version=V2_0,
|
||||||
services=[{
|
services=[{
|
||||||
'name': 'web',
|
'name': 'web',
|
||||||
'image': 'busybox:latest',
|
'image': 'busybox:latest',
|
||||||
|
@ -866,7 +867,7 @@ class ProjectTest(DockerClientTestCase):
|
||||||
vol_name = '{0:x}'.format(random.getrandbits(32))
|
vol_name = '{0:x}'.format(random.getrandbits(32))
|
||||||
|
|
||||||
config_data = config.Config(
|
config_data = config.Config(
|
||||||
version=2,
|
version=V2_0,
|
||||||
services=[{
|
services=[{
|
||||||
'name': 'web',
|
'name': 'web',
|
||||||
'image': 'busybox:latest',
|
'image': 'busybox:latest',
|
||||||
|
@ -895,7 +896,7 @@ class ProjectTest(DockerClientTestCase):
|
||||||
base_file = config.ConfigFile(
|
base_file = config.ConfigFile(
|
||||||
'base.yml',
|
'base.yml',
|
||||||
{
|
{
|
||||||
'version': 2,
|
'version': V2_0,
|
||||||
'services': {
|
'services': {
|
||||||
'simple': {
|
'simple': {
|
||||||
'image': 'busybox:latest',
|
'image': 'busybox:latest',
|
||||||
|
|
|
@ -10,6 +10,8 @@ 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.const import API_VERSIONS
|
from compose.const import API_VERSIONS
|
||||||
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
|
||||||
|
@ -54,9 +56,9 @@ class DockerClientTestCase(unittest.TestCase):
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
if engine_version_too_low_for_v2():
|
if engine_version_too_low_for_v2():
|
||||||
version = API_VERSIONS[1]
|
version = API_VERSIONS[V1]
|
||||||
else:
|
else:
|
||||||
version = API_VERSIONS[2]
|
version = API_VERSIONS[V2_0]
|
||||||
|
|
||||||
cls.client = docker_client(version)
|
cls.client = docker_client(version)
|
||||||
|
|
||||||
|
|
|
@ -14,14 +14,15 @@ import pytest
|
||||||
from compose.config import config
|
from compose.config import config
|
||||||
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.errors import ConfigurationError
|
from compose.config.errors import ConfigurationError
|
||||||
from compose.config.types import VolumeSpec
|
from compose.config.types import VolumeSpec
|
||||||
from compose.const import IS_WINDOWS_PLATFORM
|
from compose.const import IS_WINDOWS_PLATFORM
|
||||||
from tests import mock
|
from tests import mock
|
||||||
from tests import unittest
|
from tests import unittest
|
||||||
|
|
||||||
DEFAULT_VERSION = V2 = 2
|
DEFAULT_VERSION = V2_0
|
||||||
V1 = 1
|
|
||||||
|
|
||||||
|
|
||||||
def make_service_dict(name, service_dict, working_dir, filename=None):
|
def make_service_dict(name, service_dict, working_dir, filename=None):
|
||||||
|
@ -78,7 +79,7 @@ class ConfigTest(unittest.TestCase):
|
||||||
def test_load_v2(self):
|
def test_load_v2(self):
|
||||||
config_data = config.load(
|
config_data = config.load(
|
||||||
build_config_details({
|
build_config_details({
|
||||||
'version': 2,
|
'version': '2',
|
||||||
'services': {
|
'services': {
|
||||||
'foo': {'image': 'busybox'},
|
'foo': {'image': 'busybox'},
|
||||||
'bar': {'image': 'busybox', 'environment': ['FOO=1']},
|
'bar': {'image': 'busybox', 'environment': ['FOO=1']},
|
||||||
|
@ -143,9 +144,55 @@ class ConfigTest(unittest.TestCase):
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
def test_valid_versions(self):
|
||||||
|
for version in ['2', '2.0']:
|
||||||
|
cfg = config.load(build_config_details({'version': version}))
|
||||||
|
assert cfg.version == V2_0
|
||||||
|
|
||||||
|
def test_v1_file_version(self):
|
||||||
|
cfg = config.load(build_config_details({'web': {'image': 'busybox'}}))
|
||||||
|
assert cfg.version == V1
|
||||||
|
assert list(s['name'] for s in cfg.services) == ['web']
|
||||||
|
|
||||||
|
cfg = config.load(build_config_details({'version': {'image': 'busybox'}}))
|
||||||
|
assert cfg.version == V1
|
||||||
|
assert list(s['name'] for s in cfg.services) == ['version']
|
||||||
|
|
||||||
|
def test_wrong_version_type(self):
|
||||||
|
for version in [None, 2, 2.0]:
|
||||||
|
with pytest.raises(ConfigurationError):
|
||||||
|
config.load(
|
||||||
|
build_config_details(
|
||||||
|
{'version': version},
|
||||||
|
filename='filename.yml',
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_unsupported_version(self):
|
||||||
|
with pytest.raises(ConfigurationError):
|
||||||
|
config.load(
|
||||||
|
build_config_details(
|
||||||
|
{'version': '2.1'},
|
||||||
|
filename='filename.yml',
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_v1_file_with_version_is_invalid(self):
|
||||||
|
for version in [1, "1"]:
|
||||||
|
with pytest.raises(ConfigurationError):
|
||||||
|
config.load(
|
||||||
|
build_config_details(
|
||||||
|
{
|
||||||
|
'version': version,
|
||||||
|
'web': {'image': 'busybox'},
|
||||||
|
},
|
||||||
|
filename='filename.yml',
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def test_named_volume_config_empty(self):
|
def test_named_volume_config_empty(self):
|
||||||
config_details = build_config_details({
|
config_details = build_config_details({
|
||||||
'version': 2,
|
'version': '2',
|
||||||
'services': {
|
'services': {
|
||||||
'simple': {'image': 'busybox'}
|
'simple': {'image': 'busybox'}
|
||||||
},
|
},
|
||||||
|
@ -214,7 +261,7 @@ class ConfigTest(unittest.TestCase):
|
||||||
with self.assertRaises(ConfigurationError):
|
with self.assertRaises(ConfigurationError):
|
||||||
config.load(
|
config.load(
|
||||||
build_config_details(
|
build_config_details(
|
||||||
{'version': 2, 'services': {'web': 'busybox:latest'}},
|
{'version': '2', 'services': {'web': 'busybox:latest'}},
|
||||||
'working_dir',
|
'working_dir',
|
||||||
'filename.yml'
|
'filename.yml'
|
||||||
)
|
)
|
||||||
|
@ -224,7 +271,7 @@ class ConfigTest(unittest.TestCase):
|
||||||
with self.assertRaises(ConfigurationError):
|
with self.assertRaises(ConfigurationError):
|
||||||
config.load(
|
config.load(
|
||||||
build_config_details({
|
build_config_details({
|
||||||
'version': 2,
|
'version': '2',
|
||||||
'services': {'web': 'busybox:latest'},
|
'services': {'web': 'busybox:latest'},
|
||||||
'networks': {
|
'networks': {
|
||||||
'invalid': {'foo', 'bar'}
|
'invalid': {'foo', 'bar'}
|
||||||
|
@ -246,7 +293,7 @@ class ConfigTest(unittest.TestCase):
|
||||||
with pytest.raises(ConfigurationError) as exc:
|
with pytest.raises(ConfigurationError) as exc:
|
||||||
config.load(
|
config.load(
|
||||||
build_config_details({
|
build_config_details({
|
||||||
'version': 2,
|
'version': '2',
|
||||||
'services': {invalid_name: {'image': 'busybox'}}
|
'services': {invalid_name: {'image': 'busybox'}}
|
||||||
}, 'working_dir', 'filename.yml')
|
}, 'working_dir', 'filename.yml')
|
||||||
)
|
)
|
||||||
|
@ -256,7 +303,7 @@ class ConfigTest(unittest.TestCase):
|
||||||
with pytest.raises(ConfigurationError) as exc:
|
with pytest.raises(ConfigurationError) as exc:
|
||||||
config.load(build_config_details(
|
config.load(build_config_details(
|
||||||
{
|
{
|
||||||
'version': 2,
|
'version': '2',
|
||||||
'services': {
|
'services': {
|
||||||
'web': {'image': 'busybox', 'name': 'bogus'},
|
'web': {'image': 'busybox', 'name': 'bogus'},
|
||||||
}
|
}
|
||||||
|
@ -307,7 +354,7 @@ class ConfigTest(unittest.TestCase):
|
||||||
config.load(
|
config.load(
|
||||||
build_config_details(
|
build_config_details(
|
||||||
{
|
{
|
||||||
'version': 2,
|
'version': '2',
|
||||||
'services': {1: {'image': 'busybox'}}
|
'services': {1: {'image': 'busybox'}}
|
||||||
},
|
},
|
||||||
'working_dir',
|
'working_dir',
|
||||||
|
@ -370,7 +417,7 @@ class ConfigTest(unittest.TestCase):
|
||||||
def test_load_with_multiple_files_and_empty_override_v2(self):
|
def test_load_with_multiple_files_and_empty_override_v2(self):
|
||||||
base_file = config.ConfigFile(
|
base_file = config.ConfigFile(
|
||||||
'base.yml',
|
'base.yml',
|
||||||
{'version': 2, 'services': {'web': {'image': 'example/web'}}})
|
{'version': '2', 'services': {'web': {'image': 'example/web'}}})
|
||||||
override_file = config.ConfigFile('override.yml', None)
|
override_file = config.ConfigFile('override.yml', None)
|
||||||
details = config.ConfigDetails('.', [base_file, override_file])
|
details = config.ConfigDetails('.', [base_file, override_file])
|
||||||
|
|
||||||
|
@ -394,7 +441,7 @@ class ConfigTest(unittest.TestCase):
|
||||||
base_file = config.ConfigFile('base.yml', None)
|
base_file = config.ConfigFile('base.yml', None)
|
||||||
override_file = config.ConfigFile(
|
override_file = config.ConfigFile(
|
||||||
'override.tml',
|
'override.tml',
|
||||||
{'version': 2, 'services': {'web': {'image': 'example/web'}}}
|
{'version': '2', 'services': {'web': {'image': 'example/web'}}}
|
||||||
)
|
)
|
||||||
details = config.ConfigDetails('.', [base_file, override_file])
|
details = config.ConfigDetails('.', [base_file, override_file])
|
||||||
with pytest.raises(ConfigurationError) as exc:
|
with pytest.raises(ConfigurationError) as exc:
|
||||||
|
@ -494,7 +541,7 @@ class ConfigTest(unittest.TestCase):
|
||||||
config.load(
|
config.load(
|
||||||
build_config_details(
|
build_config_details(
|
||||||
{
|
{
|
||||||
'version': 2,
|
'version': '2',
|
||||||
'services': {
|
'services': {
|
||||||
'web': {
|
'web': {
|
||||||
'build': '.',
|
'build': '.',
|
||||||
|
@ -509,7 +556,7 @@ class ConfigTest(unittest.TestCase):
|
||||||
|
|
||||||
service = config.load(
|
service = config.load(
|
||||||
build_config_details({
|
build_config_details({
|
||||||
'version': 2,
|
'version': '2',
|
||||||
'services': {
|
'services': {
|
||||||
'web': {
|
'web': {
|
||||||
'build': '.'
|
'build': '.'
|
||||||
|
@ -522,7 +569,7 @@ class ConfigTest(unittest.TestCase):
|
||||||
service = config.load(
|
service = config.load(
|
||||||
build_config_details(
|
build_config_details(
|
||||||
{
|
{
|
||||||
'version': 2,
|
'version': '2',
|
||||||
'services': {
|
'services': {
|
||||||
'web': {
|
'web': {
|
||||||
'build': {
|
'build': {
|
||||||
|
@ -543,7 +590,7 @@ class ConfigTest(unittest.TestCase):
|
||||||
base_file = config.ConfigFile(
|
base_file = config.ConfigFile(
|
||||||
'base.yaml',
|
'base.yaml',
|
||||||
{
|
{
|
||||||
'version': 2,
|
'version': '2',
|
||||||
'services': {
|
'services': {
|
||||||
'web': {
|
'web': {
|
||||||
'image': 'example/web',
|
'image': 'example/web',
|
||||||
|
@ -556,7 +603,7 @@ class ConfigTest(unittest.TestCase):
|
||||||
override_file = config.ConfigFile(
|
override_file = config.ConfigFile(
|
||||||
'override.yaml',
|
'override.yaml',
|
||||||
{
|
{
|
||||||
'version': 2,
|
'version': '2',
|
||||||
'services': {
|
'services': {
|
||||||
'web': {
|
'web': {
|
||||||
'build': '/',
|
'build': '/',
|
||||||
|
@ -585,7 +632,7 @@ class ConfigTest(unittest.TestCase):
|
||||||
base_file = config.ConfigFile(
|
base_file = config.ConfigFile(
|
||||||
'base.yaml',
|
'base.yaml',
|
||||||
{
|
{
|
||||||
'version': 2,
|
'version': '2',
|
||||||
'services': {
|
'services': {
|
||||||
'web': {
|
'web': {
|
||||||
'image': 'busybox:latest',
|
'image': 'busybox:latest',
|
||||||
|
@ -601,7 +648,7 @@ class ConfigTest(unittest.TestCase):
|
||||||
base_file = config.ConfigFile(
|
base_file = config.ConfigFile(
|
||||||
'base.yaml',
|
'base.yaml',
|
||||||
{
|
{
|
||||||
'version': 2,
|
'version': '2',
|
||||||
'services': {
|
'services': {
|
||||||
'web': {
|
'web': {
|
||||||
'image': 'busybox:latest',
|
'image': 'busybox:latest',
|
||||||
|
@ -681,7 +728,7 @@ class ConfigTest(unittest.TestCase):
|
||||||
config.load(
|
config.load(
|
||||||
build_config_details(
|
build_config_details(
|
||||||
{
|
{
|
||||||
'version': 2,
|
'version': '2',
|
||||||
'services': {
|
'services': {
|
||||||
'foo': {'image': 1},
|
'foo': {'image': 1},
|
||||||
},
|
},
|
||||||
|
@ -1016,7 +1063,7 @@ class ConfigTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_external_volume_config(self):
|
def test_external_volume_config(self):
|
||||||
config_details = build_config_details({
|
config_details = build_config_details({
|
||||||
'version': 2,
|
'version': '2',
|
||||||
'services': {
|
'services': {
|
||||||
'bogus': {'image': 'busybox'}
|
'bogus': {'image': 'busybox'}
|
||||||
},
|
},
|
||||||
|
@ -1034,7 +1081,7 @@ class ConfigTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_external_volume_invalid_config(self):
|
def test_external_volume_invalid_config(self):
|
||||||
config_details = build_config_details({
|
config_details = build_config_details({
|
||||||
'version': 2,
|
'version': '2',
|
||||||
'services': {
|
'services': {
|
||||||
'bogus': {'image': 'busybox'}
|
'bogus': {'image': 'busybox'}
|
||||||
},
|
},
|
||||||
|
@ -1047,7 +1094,7 @@ class ConfigTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_depends_on_orders_services(self):
|
def test_depends_on_orders_services(self):
|
||||||
config_details = build_config_details({
|
config_details = build_config_details({
|
||||||
'version': 2,
|
'version': '2',
|
||||||
'services': {
|
'services': {
|
||||||
'one': {'image': 'busybox', 'depends_on': ['three', 'two']},
|
'one': {'image': 'busybox', 'depends_on': ['three', 'two']},
|
||||||
'two': {'image': 'busybox', 'depends_on': ['three']},
|
'two': {'image': 'busybox', 'depends_on': ['three']},
|
||||||
|
@ -1062,7 +1109,7 @@ class ConfigTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_depends_on_unknown_service_errors(self):
|
def test_depends_on_unknown_service_errors(self):
|
||||||
config_details = build_config_details({
|
config_details = build_config_details({
|
||||||
'version': 2,
|
'version': '2',
|
||||||
'services': {
|
'services': {
|
||||||
'one': {'image': 'busybox', 'depends_on': ['three']},
|
'one': {'image': 'busybox', 'depends_on': ['three']},
|
||||||
},
|
},
|
||||||
|
@ -1075,7 +1122,7 @@ class ConfigTest(unittest.TestCase):
|
||||||
class NetworkModeTest(unittest.TestCase):
|
class NetworkModeTest(unittest.TestCase):
|
||||||
def test_network_mode_standard(self):
|
def test_network_mode_standard(self):
|
||||||
config_data = config.load(build_config_details({
|
config_data = config.load(build_config_details({
|
||||||
'version': 2,
|
'version': '2',
|
||||||
'services': {
|
'services': {
|
||||||
'web': {
|
'web': {
|
||||||
'image': 'busybox',
|
'image': 'busybox',
|
||||||
|
@ -1101,7 +1148,7 @@ class NetworkModeTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_network_mode_container(self):
|
def test_network_mode_container(self):
|
||||||
config_data = config.load(build_config_details({
|
config_data = config.load(build_config_details({
|
||||||
'version': 2,
|
'version': '2',
|
||||||
'services': {
|
'services': {
|
||||||
'web': {
|
'web': {
|
||||||
'image': 'busybox',
|
'image': 'busybox',
|
||||||
|
@ -1126,7 +1173,7 @@ class NetworkModeTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_network_mode_service(self):
|
def test_network_mode_service(self):
|
||||||
config_data = config.load(build_config_details({
|
config_data = config.load(build_config_details({
|
||||||
'version': 2,
|
'version': '2',
|
||||||
'services': {
|
'services': {
|
||||||
'web': {
|
'web': {
|
||||||
'image': 'busybox',
|
'image': 'busybox',
|
||||||
|
@ -1160,7 +1207,7 @@ class NetworkModeTest(unittest.TestCase):
|
||||||
def test_network_mode_service_nonexistent(self):
|
def test_network_mode_service_nonexistent(self):
|
||||||
with pytest.raises(ConfigurationError) as excinfo:
|
with pytest.raises(ConfigurationError) as excinfo:
|
||||||
config.load(build_config_details({
|
config.load(build_config_details({
|
||||||
'version': 2,
|
'version': '2',
|
||||||
'services': {
|
'services': {
|
||||||
'web': {
|
'web': {
|
||||||
'image': 'busybox',
|
'image': 'busybox',
|
||||||
|
@ -1175,7 +1222,7 @@ class NetworkModeTest(unittest.TestCase):
|
||||||
def test_network_mode_plus_networks_is_invalid(self):
|
def test_network_mode_plus_networks_is_invalid(self):
|
||||||
with pytest.raises(ConfigurationError) as excinfo:
|
with pytest.raises(ConfigurationError) as excinfo:
|
||||||
config.load(build_config_details({
|
config.load(build_config_details({
|
||||||
'version': 2,
|
'version': '2',
|
||||||
'services': {
|
'services': {
|
||||||
'web': {
|
'web': {
|
||||||
'image': 'busybox',
|
'image': 'busybox',
|
||||||
|
@ -2202,7 +2249,7 @@ class ExtendsTest(unittest.TestCase):
|
||||||
tmpdir = py.test.ensuretemp('test_extends_with_mixed_version')
|
tmpdir = py.test.ensuretemp('test_extends_with_mixed_version')
|
||||||
self.addCleanup(tmpdir.remove)
|
self.addCleanup(tmpdir.remove)
|
||||||
tmpdir.join('docker-compose.yml').write("""
|
tmpdir.join('docker-compose.yml').write("""
|
||||||
version: 2
|
version: "2"
|
||||||
services:
|
services:
|
||||||
web:
|
web:
|
||||||
extends:
|
extends:
|
||||||
|
@ -2224,7 +2271,7 @@ class ExtendsTest(unittest.TestCase):
|
||||||
tmpdir = py.test.ensuretemp('test_extends_with_defined_version')
|
tmpdir = py.test.ensuretemp('test_extends_with_defined_version')
|
||||||
self.addCleanup(tmpdir.remove)
|
self.addCleanup(tmpdir.remove)
|
||||||
tmpdir.join('docker-compose.yml').write("""
|
tmpdir.join('docker-compose.yml').write("""
|
||||||
version: 2
|
version: "2"
|
||||||
services:
|
services:
|
||||||
web:
|
web:
|
||||||
extends:
|
extends:
|
||||||
|
@ -2233,7 +2280,7 @@ class ExtendsTest(unittest.TestCase):
|
||||||
image: busybox
|
image: busybox
|
||||||
""")
|
""")
|
||||||
tmpdir.join('base.yml').write("""
|
tmpdir.join('base.yml').write("""
|
||||||
version: 2
|
version: "2"
|
||||||
services:
|
services:
|
||||||
base:
|
base:
|
||||||
volumes: ['/foo']
|
volumes: ['/foo']
|
||||||
|
|
|
@ -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 VolumeFromSpec
|
from compose.config.types import VolumeFromSpec
|
||||||
from compose.config.types import VolumeSpec
|
from compose.config.types import VolumeSpec
|
||||||
from compose.const import IS_WINDOWS_PLATFORM
|
from compose.const import IS_WINDOWS_PLATFORM
|
||||||
from tests.unit.config.config_test import V1
|
|
||||||
from tests.unit.config.config_test import V2
|
|
||||||
|
|
||||||
|
|
||||||
def test_parse_extra_hosts_list():
|
def test_parse_extra_hosts_list():
|
||||||
|
@ -91,26 +91,26 @@ class TestVolumesFromSpec(object):
|
||||||
VolumeFromSpec.parse('unknown:format:ro', self.services, V1)
|
VolumeFromSpec.parse('unknown:format:ro', self.services, V1)
|
||||||
|
|
||||||
def test_parse_v2_from_service(self):
|
def test_parse_v2_from_service(self):
|
||||||
volume_from = VolumeFromSpec.parse('servicea', self.services, V2)
|
volume_from = VolumeFromSpec.parse('servicea', self.services, V2_0)
|
||||||
assert volume_from == VolumeFromSpec('servicea', 'rw', 'service')
|
assert volume_from == VolumeFromSpec('servicea', 'rw', 'service')
|
||||||
|
|
||||||
def test_parse_v2_from_service_with_mode(self):
|
def test_parse_v2_from_service_with_mode(self):
|
||||||
volume_from = VolumeFromSpec.parse('servicea:ro', self.services, V2)
|
volume_from = VolumeFromSpec.parse('servicea:ro', self.services, V2_0)
|
||||||
assert volume_from == VolumeFromSpec('servicea', 'ro', 'service')
|
assert volume_from == VolumeFromSpec('servicea', 'ro', 'service')
|
||||||
|
|
||||||
def test_parse_v2_from_container(self):
|
def test_parse_v2_from_container(self):
|
||||||
volume_from = VolumeFromSpec.parse('container:foo', self.services, V2)
|
volume_from = VolumeFromSpec.parse('container:foo', self.services, V2_0)
|
||||||
assert volume_from == VolumeFromSpec('foo', 'rw', 'container')
|
assert volume_from == VolumeFromSpec('foo', 'rw', 'container')
|
||||||
|
|
||||||
def test_parse_v2_from_container_with_mode(self):
|
def test_parse_v2_from_container_with_mode(self):
|
||||||
volume_from = VolumeFromSpec.parse('container:foo:ro', self.services, V2)
|
volume_from = VolumeFromSpec.parse('container:foo:ro', self.services, V2_0)
|
||||||
assert volume_from == VolumeFromSpec('foo', 'ro', 'container')
|
assert volume_from == VolumeFromSpec('foo', 'ro', 'container')
|
||||||
|
|
||||||
def test_parse_v2_invalid_type(self):
|
def test_parse_v2_invalid_type(self):
|
||||||
with pytest.raises(ConfigurationError) as exc:
|
with pytest.raises(ConfigurationError) as exc:
|
||||||
VolumeFromSpec.parse('bogus:foo:ro', self.services, V2)
|
VolumeFromSpec.parse('bogus:foo:ro', self.services, V2_0)
|
||||||
assert "Unknown volumes_from type 'bogus'" in exc.exconly()
|
assert "Unknown volumes_from type 'bogus'" in exc.exconly()
|
||||||
|
|
||||||
def test_parse_v2_invalid(self):
|
def test_parse_v2_invalid(self):
|
||||||
with pytest.raises(ConfigurationError):
|
with pytest.raises(ConfigurationError):
|
||||||
VolumeFromSpec.parse('unknown:format:ro', self.services, V2)
|
VolumeFromSpec.parse('unknown:format:ro', self.services, V2_0)
|
||||||
|
|
Loading…
Reference in New Issue