|
@@ -77,10 +77,12 @@ class Project(object):
|
|
|
"""
|
|
|
A collection of services.
|
|
|
"""
|
|
|
- def __init__(self, name, services, client):
|
|
|
+ def __init__(self, name, services, client, use_networking=False, network_driver=None):
|
|
|
self.name = name
|
|
|
self.services = services
|
|
|
self.client = client
|
|
|
+ self.use_networking = use_networking
|
|
|
+ self.network_driver = network_driver or 'bridge'
|
|
|
|
|
|
def labels(self, one_off=False):
|
|
|
return [
|
|
@@ -89,11 +91,15 @@ class Project(object):
|
|
|
]
|
|
|
|
|
|
@classmethod
|
|
|
- def from_dicts(cls, name, service_dicts, client):
|
|
|
+ def from_dicts(cls, name, service_dicts, client, use_networking=False, network_driver=None):
|
|
|
"""
|
|
|
Construct a ServiceCollection from a list of dicts representing services.
|
|
|
"""
|
|
|
- project = cls(name, [], client)
|
|
|
+ project = cls(name, [], client, use_networking=use_networking, network_driver=network_driver)
|
|
|
+
|
|
|
+ if use_networking:
|
|
|
+ remove_links(service_dicts)
|
|
|
+
|
|
|
for service_dict in sort_service_dicts(service_dicts):
|
|
|
links = project.get_links(service_dict)
|
|
|
volumes_from = project.get_volumes_from(service_dict)
|
|
@@ -103,6 +109,7 @@ class Project(object):
|
|
|
Service(
|
|
|
client=client,
|
|
|
project=name,
|
|
|
+ use_networking=use_networking,
|
|
|
links=links,
|
|
|
net=net,
|
|
|
volumes_from=volumes_from,
|
|
@@ -207,6 +214,8 @@ class Project(object):
|
|
|
def get_net(self, service_dict):
|
|
|
net = service_dict.pop('net', None)
|
|
|
if not net:
|
|
|
+ if self.use_networking:
|
|
|
+ return Net(self.name)
|
|
|
return Net(None)
|
|
|
|
|
|
net_name = get_service_name_from_net(net)
|
|
@@ -289,6 +298,9 @@ class Project(object):
|
|
|
|
|
|
plans = self._get_convergence_plans(services, strategy)
|
|
|
|
|
|
+ if self.use_networking:
|
|
|
+ self.ensure_network_exists()
|
|
|
+
|
|
|
return [
|
|
|
container
|
|
|
for service in services
|
|
@@ -350,6 +362,26 @@ class Project(object):
|
|
|
|
|
|
return [c for c in containers if matches_service_names(c)]
|
|
|
|
|
|
+ def get_network(self):
|
|
|
+ networks = self.client.networks(names=[self.name])
|
|
|
+ if networks:
|
|
|
+ return networks[0]
|
|
|
+ return None
|
|
|
+
|
|
|
+ def ensure_network_exists(self):
|
|
|
+ # TODO: recreate network if driver has changed?
|
|
|
+ if self.get_network() is None:
|
|
|
+ log.info(
|
|
|
+ 'Creating network "{}" with driver "{}"'
|
|
|
+ .format(self.name, self.network_driver)
|
|
|
+ )
|
|
|
+ self.client.create_network(self.name, driver=self.network_driver)
|
|
|
+
|
|
|
+ def remove_network(self):
|
|
|
+ network = self.get_network()
|
|
|
+ if network:
|
|
|
+ self.client.remove_network(network['id'])
|
|
|
+
|
|
|
def _inject_deps(self, acc, service):
|
|
|
dep_names = service.get_dependency_names()
|
|
|
|
|
@@ -365,6 +397,26 @@ class Project(object):
|
|
|
return acc + dep_services
|
|
|
|
|
|
|
|
|
+def remove_links(service_dicts):
|
|
|
+ services_with_links = [s for s in service_dicts if 'links' in s]
|
|
|
+ if not services_with_links:
|
|
|
+ return
|
|
|
+
|
|
|
+ if len(services_with_links) == 1:
|
|
|
+ prefix = '"{}" defines'.format(services_with_links[0]['name'])
|
|
|
+ else:
|
|
|
+ prefix = 'Some services ({}) define'.format(
|
|
|
+ ", ".join('"{}"'.format(s['name']) for s in services_with_links))
|
|
|
+
|
|
|
+ log.warn(
|
|
|
+ '\n{} links, which are not compatible with Docker networking and will be ignored.\n'
|
|
|
+ 'Future versions of Docker will not support links - you should remove them for '
|
|
|
+ 'forwards-compatibility.\n'.format(prefix))
|
|
|
+
|
|
|
+ for s in services_with_links:
|
|
|
+ del s['links']
|
|
|
+
|
|
|
+
|
|
|
class NoSuchService(Exception):
|
|
|
def __init__(self, name):
|
|
|
self.name = name
|