Connect services to networks with the 'networks' key
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
This commit is contained in:
parent
3f9038aea9
commit
3eafdbb01b
12 changed files with 195 additions and 78 deletions
|
|
@ -103,8 +103,15 @@ class CLITestCase(DockerClientTestCase):
|
|||
if self.base_dir:
|
||||
self.project.kill()
|
||||
self.project.remove_stopped()
|
||||
|
||||
for container in self.project.containers(stopped=True, one_off=True):
|
||||
container.remove(force=True)
|
||||
|
||||
networks = self.client.networks()
|
||||
for n in networks:
|
||||
if n['Name'].startswith('{}_'.format(self.project.name)):
|
||||
self.client.remove_network(n['Name'])
|
||||
|
||||
super(CLITestCase, self).tearDown()
|
||||
|
||||
@property
|
||||
|
|
@ -357,12 +364,11 @@ class CLITestCase(DockerClientTestCase):
|
|||
services = self.project.get_services()
|
||||
|
||||
networks = self.client.networks(names=[self.project.default_network.full_name])
|
||||
for n in networks:
|
||||
self.addCleanup(self.client.remove_network, n['Id'])
|
||||
self.assertEqual(len(networks), 1)
|
||||
self.assertEqual(networks[0]['Driver'], 'bridge')
|
||||
|
||||
network = self.client.inspect_network(networks[0]['Id'])
|
||||
# print self.project.services[0].containers()[0].get('NetworkSettings')
|
||||
self.assertEqual(len(network['Containers']), len(services))
|
||||
|
||||
for service in services:
|
||||
|
|
@ -374,14 +380,52 @@ class CLITestCase(DockerClientTestCase):
|
|||
self.base_dir = 'tests/fixtures/networks'
|
||||
self.dispatch(['up', '-d'], None)
|
||||
|
||||
networks = self.client.networks(names=[
|
||||
'{}_{}'.format(self.project.name, n)
|
||||
for n in ['foo', 'bar']])
|
||||
back_name = '{}_back'.format(self.project.name)
|
||||
front_name = '{}_front'.format(self.project.name)
|
||||
|
||||
self.assertEqual(len(networks), 2)
|
||||
networks = [
|
||||
n for n in self.client.networks()
|
||||
if n['Name'].startswith('{}_'.format(self.project.name))
|
||||
]
|
||||
|
||||
for net in networks:
|
||||
self.assertEqual(net['Driver'], 'bridge')
|
||||
# Two networks were created: back and front
|
||||
assert sorted(n['Name'] for n in networks) == [back_name, front_name]
|
||||
|
||||
back_network = [n for n in networks if n['Name'] == back_name][0]
|
||||
front_network = [n for n in networks if n['Name'] == front_name][0]
|
||||
|
||||
web_container = self.project.get_service('web').containers()[0]
|
||||
app_container = self.project.get_service('app').containers()[0]
|
||||
db_container = self.project.get_service('db').containers()[0]
|
||||
|
||||
# db and app joined the back network
|
||||
assert sorted(back_network['Containers']) == sorted([db_container.id, app_container.id])
|
||||
|
||||
# web and app joined the front network
|
||||
assert sorted(front_network['Containers']) == sorted([web_container.id, app_container.id])
|
||||
|
||||
def test_up_missing_network(self):
|
||||
self.base_dir = 'tests/fixtures/networks'
|
||||
|
||||
result = self.dispatch(
|
||||
['-f', 'missing-network.yml', 'up', '-d'],
|
||||
returncode=1)
|
||||
|
||||
assert 'Service "web" uses an undefined network "foo"' in result.stderr
|
||||
|
||||
def test_up_no_services(self):
|
||||
self.base_dir = 'tests/fixtures/no-services'
|
||||
self.dispatch(['up', '-d'], None)
|
||||
|
||||
network_names = [
|
||||
n['Name'] for n in self.client.networks()
|
||||
if n['Name'].startswith('{}_'.format(self.project.name))
|
||||
]
|
||||
|
||||
assert sorted(network_names) == [
|
||||
'{}_{}'.format(self.project.name, name)
|
||||
for name in ['bar', 'foo']
|
||||
]
|
||||
|
||||
def test_up_with_links_is_invalid(self):
|
||||
self.base_dir = 'tests/fixtures/v2-simple'
|
||||
|
|
@ -400,9 +444,7 @@ class CLITestCase(DockerClientTestCase):
|
|||
|
||||
# No network was created
|
||||
networks = self.client.networks(names=[self.project.default_network.full_name])
|
||||
for n in networks:
|
||||
self.addCleanup(self.client.remove_network, n['Id'])
|
||||
self.assertEqual(len(networks), 0)
|
||||
assert networks == []
|
||||
|
||||
web = self.project.get_service('web')
|
||||
db = self.project.get_service('db')
|
||||
|
|
@ -731,8 +773,6 @@ class CLITestCase(DockerClientTestCase):
|
|||
service = self.project.get_service('simple')
|
||||
container, = service.containers(stopped=True, one_off=True)
|
||||
networks = self.client.networks(names=[self.project.default_network.full_name])
|
||||
for n in networks:
|
||||
self.addCleanup(self.client.remove_network, n['Id'])
|
||||
self.assertEqual(len(networks), 1)
|
||||
self.assertEqual(container.human_readable_command, u'true')
|
||||
|
||||
|
|
@ -890,7 +930,7 @@ class CLITestCase(DockerClientTestCase):
|
|||
def test_restart(self):
|
||||
service = self.project.get_service('simple')
|
||||
container = service.create_container()
|
||||
container.start()
|
||||
service.start_container(container)
|
||||
started_at = container.dictionary['State']['StartedAt']
|
||||
self.dispatch(['restart', '-t', '1'], None)
|
||||
container.inspect()
|
||||
|
|
|
|||
20
tests/fixtures/networks/docker-compose.yml
vendored
20
tests/fixtures/networks/docker-compose.yml
vendored
|
|
@ -1,7 +1,19 @@
|
|||
version: 2
|
||||
|
||||
networks:
|
||||
foo:
|
||||
driver:
|
||||
services:
|
||||
web:
|
||||
image: busybox
|
||||
command: top
|
||||
networks: ["front"]
|
||||
app:
|
||||
image: busybox
|
||||
command: top
|
||||
networks: ["front", "back"]
|
||||
db:
|
||||
image: busybox
|
||||
command: top
|
||||
networks: ["back"]
|
||||
|
||||
bar: {}
|
||||
networks:
|
||||
front: {}
|
||||
back: {}
|
||||
|
|
|
|||
10
tests/fixtures/networks/missing-network.yml
vendored
Normal file
10
tests/fixtures/networks/missing-network.yml
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
version: 2
|
||||
|
||||
services:
|
||||
web:
|
||||
image: busybox
|
||||
command: top
|
||||
networks: ["foo"]
|
||||
|
||||
networks:
|
||||
bar: {}
|
||||
5
tests/fixtures/no-services/docker-compose.yml
vendored
Normal file
5
tests/fixtures/no-services/docker-compose.yml
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
version: 2
|
||||
|
||||
networks:
|
||||
foo: {}
|
||||
bar: {}
|
||||
|
|
@ -17,7 +17,7 @@ class ResilienceTest(DockerClientTestCase):
|
|||
self.project = Project('composetest', [self.db], self.client)
|
||||
|
||||
container = self.db.create_container()
|
||||
container.start()
|
||||
self.db.start_container(container)
|
||||
self.host_path = container.get_mount('/var/db')['Source']
|
||||
|
||||
def test_successful_recreate(self):
|
||||
|
|
@ -35,7 +35,7 @@ class ResilienceTest(DockerClientTestCase):
|
|||
self.assertEqual(container.get_mount('/var/db')['Source'], self.host_path)
|
||||
|
||||
def test_start_failure(self):
|
||||
with mock.patch('compose.container.Container.start', crash):
|
||||
with mock.patch('compose.service.Service.start_container', crash):
|
||||
with self.assertRaises(Crash):
|
||||
self.project.up(strategy=ConvergenceStrategy.always)
|
||||
|
||||
|
|
|
|||
|
|
@ -32,14 +32,7 @@ from compose.service import Service
|
|||
|
||||
def create_and_start_container(service, **override_options):
|
||||
container = service.create_container(**override_options)
|
||||
container.start()
|
||||
return container
|
||||
|
||||
|
||||
def remove_stopped(service):
|
||||
containers = [c for c in service.containers(stopped=True) if not c.is_running]
|
||||
for container in containers:
|
||||
container.remove()
|
||||
return service.start_container(container)
|
||||
|
||||
|
||||
class ServiceTest(DockerClientTestCase):
|
||||
|
|
@ -88,19 +81,19 @@ class ServiceTest(DockerClientTestCase):
|
|||
def test_create_container_with_unspecified_volume(self):
|
||||
service = self.create_service('db', volumes=[VolumeSpec.parse('/var/db')])
|
||||
container = service.create_container()
|
||||
container.start()
|
||||
service.start_container(container)
|
||||
assert container.get_mount('/var/db')
|
||||
|
||||
def test_create_container_with_volume_driver(self):
|
||||
service = self.create_service('db', volume_driver='foodriver')
|
||||
container = service.create_container()
|
||||
container.start()
|
||||
service.start_container(container)
|
||||
self.assertEqual('foodriver', container.get('HostConfig.VolumeDriver'))
|
||||
|
||||
def test_create_container_with_cpu_shares(self):
|
||||
service = self.create_service('db', cpu_shares=73)
|
||||
container = service.create_container()
|
||||
container.start()
|
||||
service.start_container(container)
|
||||
self.assertEqual(container.get('HostConfig.CpuShares'), 73)
|
||||
|
||||
def test_create_container_with_cpu_quota(self):
|
||||
|
|
@ -113,7 +106,7 @@ class ServiceTest(DockerClientTestCase):
|
|||
extra_hosts = ['somehost:162.242.195.82', 'otherhost:50.31.209.229']
|
||||
service = self.create_service('db', extra_hosts=extra_hosts)
|
||||
container = service.create_container()
|
||||
container.start()
|
||||
service.start_container(container)
|
||||
self.assertEqual(set(container.get('HostConfig.ExtraHosts')), set(extra_hosts))
|
||||
|
||||
def test_create_container_with_extra_hosts_dicts(self):
|
||||
|
|
@ -121,33 +114,33 @@ class ServiceTest(DockerClientTestCase):
|
|||
extra_hosts_list = ['somehost:162.242.195.82', 'otherhost:50.31.209.229']
|
||||
service = self.create_service('db', extra_hosts=extra_hosts)
|
||||
container = service.create_container()
|
||||
container.start()
|
||||
service.start_container(container)
|
||||
self.assertEqual(set(container.get('HostConfig.ExtraHosts')), set(extra_hosts_list))
|
||||
|
||||
def test_create_container_with_cpu_set(self):
|
||||
service = self.create_service('db', cpuset='0')
|
||||
container = service.create_container()
|
||||
container.start()
|
||||
service.start_container(container)
|
||||
self.assertEqual(container.get('HostConfig.CpusetCpus'), '0')
|
||||
|
||||
def test_create_container_with_read_only_root_fs(self):
|
||||
read_only = True
|
||||
service = self.create_service('db', read_only=read_only)
|
||||
container = service.create_container()
|
||||
container.start()
|
||||
service.start_container(container)
|
||||
self.assertEqual(container.get('HostConfig.ReadonlyRootfs'), read_only, container.get('HostConfig'))
|
||||
|
||||
def test_create_container_with_security_opt(self):
|
||||
security_opt = ['label:disable']
|
||||
service = self.create_service('db', security_opt=security_opt)
|
||||
container = service.create_container()
|
||||
container.start()
|
||||
service.start_container(container)
|
||||
self.assertEqual(set(container.get('HostConfig.SecurityOpt')), set(security_opt))
|
||||
|
||||
def test_create_container_with_mac_address(self):
|
||||
service = self.create_service('db', mac_address='02:42:ac:11:65:43')
|
||||
container = service.create_container()
|
||||
container.start()
|
||||
service.start_container(container)
|
||||
self.assertEqual(container.inspect()['Config']['MacAddress'], '02:42:ac:11:65:43')
|
||||
|
||||
def test_create_container_with_specified_volume(self):
|
||||
|
|
@ -158,7 +151,7 @@ class ServiceTest(DockerClientTestCase):
|
|||
'db',
|
||||
volumes=[VolumeSpec(host_path, container_path, 'rw')])
|
||||
container = service.create_container()
|
||||
container.start()
|
||||
service.start_container(container)
|
||||
assert container.get_mount(container_path)
|
||||
|
||||
# Match the last component ("host-path"), because boot2docker symlinks /tmp
|
||||
|
|
@ -229,7 +222,7 @@ class ServiceTest(DockerClientTestCase):
|
|||
]
|
||||
)
|
||||
host_container = host_service.create_container()
|
||||
host_container.start()
|
||||
host_service.start_container(host_container)
|
||||
self.assertIn(volume_container_1.id + ':rw',
|
||||
host_container.get('HostConfig.VolumesFrom'))
|
||||
self.assertIn(volume_container_2.id + ':rw',
|
||||
|
|
@ -248,7 +241,7 @@ class ServiceTest(DockerClientTestCase):
|
|||
self.assertEqual(old_container.get('Config.Cmd'), ['-d', '1'])
|
||||
self.assertIn('FOO=1', old_container.get('Config.Env'))
|
||||
self.assertEqual(old_container.name, 'composetest_db_1')
|
||||
old_container.start()
|
||||
service.start_container(old_container)
|
||||
old_container.inspect() # reload volume data
|
||||
volume_path = old_container.get_mount('/etc')['Source']
|
||||
|
||||
|
|
|
|||
|
|
@ -12,8 +12,6 @@ from compose.config.types import VolumeFromSpec
|
|||
from compose.const import LABEL_SERVICE
|
||||
from compose.container import Container
|
||||
from compose.project import Project
|
||||
from compose.service import ContainerNet
|
||||
from compose.service import Net
|
||||
from compose.service import Service
|
||||
|
||||
|
||||
|
|
@ -412,29 +410,42 @@ class ProjectTest(unittest.TestCase):
|
|||
self.assertEqual(service.net.mode, 'container:' + container_name)
|
||||
|
||||
def test_uses_default_network_true(self):
|
||||
web = Service('web', project='test', image="alpine", net=Net('test_default'))
|
||||
db = Service('web', project='test', image="alpine", net=Net('other'))
|
||||
project = Project('test', [web, db], None)
|
||||
project = Project.from_config(
|
||||
name='test',
|
||||
client=self.mock_client,
|
||||
config_data=Config(
|
||||
version=2,
|
||||
services=[
|
||||
{
|
||||
'name': 'foo',
|
||||
'image': 'busybox:latest'
|
||||
},
|
||||
],
|
||||
networks=None,
|
||||
volumes=None,
|
||||
),
|
||||
)
|
||||
|
||||
assert project.uses_default_network()
|
||||
|
||||
def test_uses_default_network_custom_name(self):
|
||||
web = Service('web', project='test', image="alpine", net=Net('other'))
|
||||
project = Project('test', [web], None)
|
||||
assert not project.uses_default_network()
|
||||
def test_uses_default_network_false(self):
|
||||
project = Project.from_config(
|
||||
name='test',
|
||||
client=self.mock_client,
|
||||
config_data=Config(
|
||||
version=2,
|
||||
services=[
|
||||
{
|
||||
'name': 'foo',
|
||||
'image': 'busybox:latest',
|
||||
'networks': ['custom']
|
||||
},
|
||||
],
|
||||
networks={'custom': {}},
|
||||
volumes=None,
|
||||
),
|
||||
)
|
||||
|
||||
def test_uses_default_network_host(self):
|
||||
web = Service('web', project='test', image="alpine", net=Net('host'))
|
||||
project = Project('test', [web], None)
|
||||
assert not project.uses_default_network()
|
||||
|
||||
def test_uses_default_network_container(self):
|
||||
container = mock.Mock(id='test')
|
||||
web = Service(
|
||||
'web',
|
||||
project='test',
|
||||
image="alpine",
|
||||
net=ContainerNet(container))
|
||||
project = Project('test', [web], None)
|
||||
assert not project.uses_default_network()
|
||||
|
||||
def test_container_without_name(self):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue