Update to new ambassador code

This commit is contained in:
Jerome Petazzoni
2015-09-24 16:51:04 +00:00
parent d9829f55ea
commit 55ad3f2733
6 changed files with 130 additions and 78 deletions

68
configure-ambassadors.py Executable file
View File

@@ -0,0 +1,68 @@
#!/usr/bin/env python
import os
import subprocess
import sys
import yaml
stack = yaml.load(open(sys.argv[1]))
project_name = os.path.basename(os.path.realpath("."))
# Get all services and backends in our compose application
containers_data = subprocess.check_output([
"docker", "ps",
"--filter", "label=com.docker.compose.project={}".format(project_name),
"--format", '{{ .ID }} '
'{{ .Label "com.docker.compose.service" }} '
'{{ .Ports }}',
])
# Build list of backends
frontend_ports = dict()
backends = dict()
for container in containers_data.split('\n'):
if not container:
continue
# TODO: support services with multiple ports!
container_id, service_name, port = container.split(' ')
if not port:
continue
backend, frontend = port.split("->")
backend_addr, backend_port = backend.split(':')
frontend_port, frontend_proto = frontend.split('/')
# TODO: deal with udp (mostly skip it?)
assert frontend_proto == "tcp"
# TODO: check inconsistencies between port mappings
frontend_ports[service_name] = frontend_port
if service_name not in backends:
backends[service_name] = []
backends[service_name].append((backend_addr, backend_port))
# Get all existing ambassadors for this application
ambassadors_data = subprocess.check_output([
"docker", "ps",
"--filter", "label=ambassador.project={}".format(project_name),
"--format", '{{ .ID }} '
'{{ .Label "ambassador.service" }} '
'{{ .Label "ambassador.bindaddr" }}',
])
# Update ambassadors
for ambassador in ambassadors_data.split('\n'):
if not ambassador:
continue
ambassador_id, service_name, bind_address = ambassador.split()
print("Updating configuration for {}/{} -> {}:{} -> {}"
.format(service_name, ambassador_id,
bind_address, frontend_ports[service_name],
backends[service_name]))
command = [
"docker", "run", "--rm", "--volumes-from", ambassador_id,
"jpetazzo/hamba", "reconfigure",
"{}:{}".format(bind_address, frontend_ports[service_name])
]
for backend_addr, backend_port in backends[service_name]:
command.extend([backend_addr, backend_port])
print command
subprocess.check_call(command)

View File

@@ -1,73 +0,0 @@
#!/usr/bin/env python
import os
import subprocess
import sys
import yaml
stack = yaml.load(open(sys.argv[1]))
ports = yaml.load(open("ports.yml"))
project_name = os.path.basename(os.path.realpath("."))
ambassadors = []
service_instances = {}
# Generate container names for all instances
for service_name in stack:
service_instances[service_name] = []
n = 0
while True:
n += 1
try:
container_name = "{}_{}_{}".format(project_name, service_name, n)
subprocess.check_call(
[ "docker", "inspect", container_name ],
stdout=-1, stderr=-1
)
service_instances[service_name].append(container_name)
except subprocess.CalledProcessError:
break
for service_name, service in stack.items():
extra_hosts = service.get("extra_hosts", {})
for link_name, link_addr in extra_hosts.items():
if link_name not in ports:
print("# Skipping link {} in service {} "
"(no port mapping defined). "
"Your code will probably break."
.format(link, service_name))
continue
port = str(ports[link_name])
endpoints = []
for container_name in service_instances[link_name]:
endpoint = subprocess.check_output(
["docker", "port", container_name, port]
)
endpoints.append(endpoint.strip())
for container_name in service_instances[service_name]:
ambassador = {}
ambassador["image"] = "jpetazzo/hamba"
ambassador["net"] = "container:"+container_name
command = "{}:{}".format(link_addr, port)
for endpoint in endpoints:
command = command + " {} {}".format(*endpoint.split(':'))
ambassador["command"] = command
n = len(ambassadors)
ambassador["name"] = "amba{}".format(n)
ambassadors.append(ambassador)
for service_name, service in stack.items():
for container_name in service_instances[service_name]:
print("docker exec {} sh -c 'sed /^127.127/d /etc/hosts >/tmp/hosts && cat /tmp/hosts >/etc/hosts && rm /tmp/hosts'"
.format(container_name))
extra_hosts = service.get("extra_hosts", {})
for link_name, link_addr in extra_hosts.items():
print("docker exec {} sh -c 'echo {} {} >> /etc/hosts'"
.format(container_name, link_addr, link_name))
for amba in ambassadors:
print("docker run -d --name {name} --net {net} {image} {command}".format(**amba))

59
create-ambassadors.py Executable file
View File

@@ -0,0 +1,59 @@
#!/usr/bin/env python
import os
import subprocess
import sys
import yaml
stack = yaml.load(open(sys.argv[1]))
project_name = os.path.basename(os.path.realpath("."))
# Get all services in our compose application
containers_data = subprocess.check_output([
"docker", "ps",
"--filter", "label=com.docker.compose.project={}".format(project_name),
"--format", '{{ .ID }} {{ .Label "com.docker.compose.service" }}',
])
# Get all existing ambassadors for this application
ambassadors_data = subprocess.check_output([
"docker", "ps",
"--filter", "label=ambassador.project={}".format(project_name),
"--format", '{{ .ID }} '
'{{ .Label "ambassador.container" }} '
'{{ .Label "ambassador.service" }}',
])
# Build a set of existing ambassadors
ambassadors = dict()
for ambassador in ambassadors_data.split('\n'):
if not ambassador:
continue
ambassador_id, container_id, linked_service = ambassador.split()
ambassadors[container_id, linked_service] = ambassador_id
# Start the missing ambassadors
for container in containers_data.split('\n'):
if not container:
continue
container_id, service_name = container.split()
extra_hosts = stack[service_name].get("extra_hosts", {})
for linked_service, bind_address in extra_hosts.items():
description = "Ambassador {}/{}/{}".format(
service_name, container_id, linked_service)
ambassador_id = ambassadors.get((container_id, linked_service))
if ambassador_id:
print("{} already exists: {}".format(description, ambassador_id))
else:
print("{} not found, creating it:".format(description))
subprocess.check_call([
"docker", "run", "-d",
"--net", "container:{}".format(container_id),
"--label", "ambassador.project={}".format(project_name),
"--label", "ambassador.container={}".format(container_id),
"--label", "ambassador.service={}".format(linked_service),
"--label", "ambassador.bindaddr={}".format(bind_address),
"jpetazzo/hamba", "run"
])

3
delete-ambassadors.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/sh
docker ps -q --filter label=ambassador.project=dockercoins |
xargs docker rm -f

View File

@@ -1,5 +0,0 @@
#!/bin/sh
N=0
while docker rm -f amba$N; do
N=$(($N+1))
done