Implement network_mode in v2
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
This commit is contained in:
parent
a267d8fe3c
commit
e566a4dc1c
16 changed files with 405 additions and 87 deletions
|
|
@ -496,8 +496,29 @@ class CLITestCase(DockerClientTestCase):
|
|||
assert 'Service "web" uses an undefined network "foo"' in result.stderr
|
||||
|
||||
@v2_only()
|
||||
def test_up_predefined_networks(self):
|
||||
filename = 'predefined-networks.yml'
|
||||
def test_up_with_bridge_network_plus_default(self):
|
||||
filename = 'bridge.yml'
|
||||
|
||||
self.base_dir = 'tests/fixtures/networks'
|
||||
self._project = get_project(self.base_dir, [filename])
|
||||
|
||||
self.dispatch(['-f', filename, 'up', '-d'], None)
|
||||
|
||||
container = self.project.containers()[0]
|
||||
|
||||
assert sorted(list(container.get('NetworkSettings.Networks'))) == sorted([
|
||||
'bridge',
|
||||
self.project.default_network.full_name,
|
||||
])
|
||||
|
||||
@v2_only()
|
||||
def test_up_with_network_mode(self):
|
||||
c = self.client.create_container('busybox', 'top', name='composetest_network_mode_container')
|
||||
self.addCleanup(self.client.remove_container, c, force=True)
|
||||
self.client.start(c)
|
||||
container_mode_source = 'container:{}'.format(c['Id'])
|
||||
|
||||
filename = 'network-mode.yml'
|
||||
|
||||
self.base_dir = 'tests/fixtures/networks'
|
||||
self._project = get_project(self.base_dir, [filename])
|
||||
|
|
@ -515,6 +536,16 @@ class CLITestCase(DockerClientTestCase):
|
|||
assert list(container.get('NetworkSettings.Networks')) == [name]
|
||||
assert container.get('HostConfig.NetworkMode') == name
|
||||
|
||||
service_mode_source = 'container:{}'.format(
|
||||
self.project.get_service('bridge').containers()[0].id)
|
||||
service_mode_container = self.project.get_service('service').containers()[0]
|
||||
assert not service_mode_container.get('NetworkSettings.Networks')
|
||||
assert service_mode_container.get('HostConfig.NetworkMode') == service_mode_source
|
||||
|
||||
container_mode_container = self.project.get_service('container').containers()[0]
|
||||
assert not container_mode_container.get('NetworkSettings.Networks')
|
||||
assert container_mode_container.get('HostConfig.NetworkMode') == container_mode_source
|
||||
|
||||
@v2_only()
|
||||
def test_up_external_networks(self):
|
||||
filename = 'external-networks.yml'
|
||||
|
|
|
|||
12
tests/fixtures/extends/invalid-net-v2.yml
vendored
Normal file
12
tests/fixtures/extends/invalid-net-v2.yml
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
version: 2
|
||||
services:
|
||||
myweb:
|
||||
build: '.'
|
||||
extends:
|
||||
service: web
|
||||
command: top
|
||||
web:
|
||||
build: '.'
|
||||
network_mode: "service:net"
|
||||
net:
|
||||
build: '.'
|
||||
9
tests/fixtures/networks/bridge.yml
vendored
Normal file
9
tests/fixtures/networks/bridge.yml
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
version: 2
|
||||
|
||||
services:
|
||||
web:
|
||||
image: busybox
|
||||
command: top
|
||||
networks:
|
||||
- bridge
|
||||
- default
|
||||
27
tests/fixtures/networks/network-mode.yml
vendored
Normal file
27
tests/fixtures/networks/network-mode.yml
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
version: 2
|
||||
|
||||
services:
|
||||
bridge:
|
||||
image: busybox
|
||||
command: top
|
||||
network_mode: bridge
|
||||
|
||||
service:
|
||||
image: busybox
|
||||
command: top
|
||||
network_mode: "service:bridge"
|
||||
|
||||
container:
|
||||
image: busybox
|
||||
command: top
|
||||
network_mode: "container:composetest_network_mode_container"
|
||||
|
||||
host:
|
||||
image: busybox
|
||||
command: top
|
||||
network_mode: host
|
||||
|
||||
none:
|
||||
image: busybox
|
||||
command: top
|
||||
network_mode: none
|
||||
17
tests/fixtures/networks/predefined-networks.yml
vendored
17
tests/fixtures/networks/predefined-networks.yml
vendored
|
|
@ -1,17 +0,0 @@
|
|||
version: 2
|
||||
|
||||
services:
|
||||
bridge:
|
||||
image: busybox
|
||||
command: top
|
||||
networks: ["bridge"]
|
||||
|
||||
host:
|
||||
image: busybox
|
||||
command: top
|
||||
networks: ["host"]
|
||||
|
||||
none:
|
||||
image: busybox
|
||||
command: top
|
||||
networks: []
|
||||
|
|
@ -4,10 +4,12 @@ from __future__ import unicode_literals
|
|||
import random
|
||||
|
||||
import py
|
||||
import pytest
|
||||
from docker.errors import NotFound
|
||||
|
||||
from .testcases import DockerClientTestCase
|
||||
from compose.config import config
|
||||
from compose.config import ConfigurationError
|
||||
from compose.config.types import VolumeFromSpec
|
||||
from compose.config.types import VolumeSpec
|
||||
from compose.const import LABEL_PROJECT
|
||||
|
|
@ -104,7 +106,71 @@ class ProjectTest(DockerClientTestCase):
|
|||
db = project.get_service('db')
|
||||
self.assertEqual(db._get_volumes_from(), [data_container.id + ':rw'])
|
||||
|
||||
def test_net_from_service(self):
|
||||
@v2_only()
|
||||
def test_network_mode_from_service(self):
|
||||
project = Project.from_config(
|
||||
name='composetest',
|
||||
client=self.client,
|
||||
config_data=build_service_dicts({
|
||||
'version': 2,
|
||||
'services': {
|
||||
'net': {
|
||||
'image': 'busybox:latest',
|
||||
'command': ["top"]
|
||||
},
|
||||
'web': {
|
||||
'image': 'busybox:latest',
|
||||
'network_mode': 'service:net',
|
||||
'command': ["top"]
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
project.up()
|
||||
|
||||
web = project.get_service('web')
|
||||
net = project.get_service('net')
|
||||
self.assertEqual(web.net.mode, 'container:' + net.containers()[0].id)
|
||||
|
||||
@v2_only()
|
||||
def test_network_mode_from_container(self):
|
||||
def get_project():
|
||||
return Project.from_config(
|
||||
name='composetest',
|
||||
config_data=build_service_dicts({
|
||||
'version': 2,
|
||||
'services': {
|
||||
'web': {
|
||||
'image': 'busybox:latest',
|
||||
'network_mode': 'container:composetest_net_container'
|
||||
},
|
||||
},
|
||||
}),
|
||||
client=self.client,
|
||||
)
|
||||
|
||||
with pytest.raises(ConfigurationError) as excinfo:
|
||||
get_project()
|
||||
|
||||
assert "container 'composetest_net_container' which does not exist" in excinfo.exconly()
|
||||
|
||||
net_container = Container.create(
|
||||
self.client,
|
||||
image='busybox:latest',
|
||||
name='composetest_net_container',
|
||||
command='top',
|
||||
labels={LABEL_PROJECT: 'composetest'},
|
||||
)
|
||||
net_container.start()
|
||||
|
||||
project = get_project()
|
||||
project.up()
|
||||
|
||||
web = project.get_service('web')
|
||||
self.assertEqual(web.net.mode, 'container:' + net_container.id)
|
||||
|
||||
def test_net_from_service_v1(self):
|
||||
project = Project.from_config(
|
||||
name='composetest',
|
||||
config_data=build_service_dicts({
|
||||
|
|
@ -127,7 +193,24 @@ class ProjectTest(DockerClientTestCase):
|
|||
net = project.get_service('net')
|
||||
self.assertEqual(web.net.mode, 'container:' + net.containers()[0].id)
|
||||
|
||||
def test_net_from_container(self):
|
||||
def test_net_from_container_v1(self):
|
||||
def get_project():
|
||||
return Project.from_config(
|
||||
name='composetest',
|
||||
config_data=build_service_dicts({
|
||||
'web': {
|
||||
'image': 'busybox:latest',
|
||||
'net': 'container:composetest_net_container'
|
||||
},
|
||||
}),
|
||||
client=self.client,
|
||||
)
|
||||
|
||||
with pytest.raises(ConfigurationError) as excinfo:
|
||||
get_project()
|
||||
|
||||
assert "container 'composetest_net_container' which does not exist" in excinfo.exconly()
|
||||
|
||||
net_container = Container.create(
|
||||
self.client,
|
||||
image='busybox:latest',
|
||||
|
|
@ -137,17 +220,7 @@ class ProjectTest(DockerClientTestCase):
|
|||
)
|
||||
net_container.start()
|
||||
|
||||
project = Project.from_config(
|
||||
name='composetest',
|
||||
config_data=build_service_dicts({
|
||||
'web': {
|
||||
'image': 'busybox:latest',
|
||||
'net': 'container:composetest_net_container'
|
||||
},
|
||||
}),
|
||||
client=self.client,
|
||||
)
|
||||
|
||||
project = get_project()
|
||||
project.up()
|
||||
|
||||
web = project.get_service('web')
|
||||
|
|
|
|||
|
|
@ -1015,6 +1015,126 @@ class ConfigTest(unittest.TestCase):
|
|||
assert "Service 'one' depends on service 'three'" in exc.exconly()
|
||||
|
||||
|
||||
class NetworkModeTest(unittest.TestCase):
|
||||
def test_network_mode_standard(self):
|
||||
config_data = config.load(build_config_details({
|
||||
'version': 2,
|
||||
'services': {
|
||||
'web': {
|
||||
'image': 'busybox',
|
||||
'command': "top",
|
||||
'network_mode': 'bridge',
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
assert config_data.services[0]['network_mode'] == 'bridge'
|
||||
|
||||
def test_network_mode_standard_v1(self):
|
||||
config_data = config.load(build_config_details({
|
||||
'web': {
|
||||
'image': 'busybox',
|
||||
'command': "top",
|
||||
'net': 'bridge',
|
||||
},
|
||||
}))
|
||||
|
||||
assert config_data.services[0]['network_mode'] == 'bridge'
|
||||
assert 'net' not in config_data.services[0]
|
||||
|
||||
def test_network_mode_container(self):
|
||||
config_data = config.load(build_config_details({
|
||||
'version': 2,
|
||||
'services': {
|
||||
'web': {
|
||||
'image': 'busybox',
|
||||
'command': "top",
|
||||
'network_mode': 'container:foo',
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
assert config_data.services[0]['network_mode'] == 'container:foo'
|
||||
|
||||
def test_network_mode_container_v1(self):
|
||||
config_data = config.load(build_config_details({
|
||||
'web': {
|
||||
'image': 'busybox',
|
||||
'command': "top",
|
||||
'net': 'container:foo',
|
||||
},
|
||||
}))
|
||||
|
||||
assert config_data.services[0]['network_mode'] == 'container:foo'
|
||||
|
||||
def test_network_mode_service(self):
|
||||
config_data = config.load(build_config_details({
|
||||
'version': 2,
|
||||
'services': {
|
||||
'web': {
|
||||
'image': 'busybox',
|
||||
'command': "top",
|
||||
'network_mode': 'service:foo',
|
||||
},
|
||||
'foo': {
|
||||
'image': 'busybox',
|
||||
'command': "top",
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
assert config_data.services[1]['network_mode'] == 'service:foo'
|
||||
|
||||
def test_network_mode_service_v1(self):
|
||||
config_data = config.load(build_config_details({
|
||||
'web': {
|
||||
'image': 'busybox',
|
||||
'command': "top",
|
||||
'net': 'container:foo',
|
||||
},
|
||||
'foo': {
|
||||
'image': 'busybox',
|
||||
'command': "top",
|
||||
},
|
||||
}))
|
||||
|
||||
assert config_data.services[1]['network_mode'] == 'service:foo'
|
||||
|
||||
def test_network_mode_service_nonexistent(self):
|
||||
with pytest.raises(ConfigurationError) as excinfo:
|
||||
config.load(build_config_details({
|
||||
'version': 2,
|
||||
'services': {
|
||||
'web': {
|
||||
'image': 'busybox',
|
||||
'command': "top",
|
||||
'network_mode': 'service:foo',
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
assert "service 'foo' which is undefined" in excinfo.exconly()
|
||||
|
||||
def test_network_mode_plus_networks_is_invalid(self):
|
||||
with pytest.raises(ConfigurationError) as excinfo:
|
||||
config.load(build_config_details({
|
||||
'version': 2,
|
||||
'services': {
|
||||
'web': {
|
||||
'image': 'busybox',
|
||||
'command': "top",
|
||||
'network_mode': 'bridge',
|
||||
'networks': ['front'],
|
||||
},
|
||||
},
|
||||
'networks': {
|
||||
'front': None,
|
||||
}
|
||||
}))
|
||||
|
||||
assert "'network_mode' and 'networks' cannot be combined" in excinfo.exconly()
|
||||
|
||||
|
||||
class PortsTest(unittest.TestCase):
|
||||
INVALID_PORTS_TYPES = [
|
||||
{"1": "8000"},
|
||||
|
|
@ -1867,11 +1987,18 @@ class ExtendsTest(unittest.TestCase):
|
|||
load_from_filename('tests/fixtures/extends/invalid-volumes.yml')
|
||||
|
||||
def test_invalid_net_in_extended_service(self):
|
||||
expected_error_msg = "services with 'net: container' cannot be extended"
|
||||
with pytest.raises(ConfigurationError) as excinfo:
|
||||
load_from_filename('tests/fixtures/extends/invalid-net-v2.yml')
|
||||
|
||||
with self.assertRaisesRegexp(ConfigurationError, expected_error_msg):
|
||||
assert 'network_mode: service' in excinfo.exconly()
|
||||
assert 'cannot be extended' in excinfo.exconly()
|
||||
|
||||
with pytest.raises(ConfigurationError) as excinfo:
|
||||
load_from_filename('tests/fixtures/extends/invalid-net.yml')
|
||||
|
||||
assert 'net: container' in excinfo.exconly()
|
||||
assert 'cannot be extended' in excinfo.exconly()
|
||||
|
||||
@mock.patch.dict(os.environ)
|
||||
def test_load_config_runs_interpolation_in_extended_service(self):
|
||||
os.environ.update(HOSTNAME_VALUE="penguin")
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ class TestSortService(object):
|
|||
},
|
||||
{
|
||||
'name': 'parent',
|
||||
'net': 'container:child'
|
||||
'network_mode': 'service:child'
|
||||
},
|
||||
{
|
||||
'name': 'child'
|
||||
|
|
@ -137,7 +137,7 @@ class TestSortService(object):
|
|||
def test_sort_service_dicts_7(self):
|
||||
services = [
|
||||
{
|
||||
'net': 'container:three',
|
||||
'network_mode': 'service:three',
|
||||
'name': 'four'
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -365,7 +365,7 @@ class ProjectTest(unittest.TestCase):
|
|||
{
|
||||
'name': 'test',
|
||||
'image': 'busybox:latest',
|
||||
'net': 'container:aaa'
|
||||
'network_mode': 'container:aaa'
|
||||
},
|
||||
],
|
||||
networks=None,
|
||||
|
|
@ -398,7 +398,7 @@ class ProjectTest(unittest.TestCase):
|
|||
{
|
||||
'name': 'test',
|
||||
'image': 'busybox:latest',
|
||||
'net': 'container:aaa'
|
||||
'network_mode': 'service:aaa'
|
||||
},
|
||||
],
|
||||
networks=None,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue