Initial commit
This commit is contained in:
parent
f38c040d39
commit
5e6a2919bf
|
|
@ -0,0 +1,14 @@
|
||||||
|
FROM debian:8.0
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends python3.4 python3-pip \
|
||||||
|
&& pip3 install docker-py \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
VOLUME ["/dockerfiles"]
|
||||||
|
ENTRYPOINT ["/dockerfiles/entrypoint.sh"]
|
||||||
|
|
||||||
|
CMD ["python3"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,117 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
from docker import Client
|
||||||
|
import argparse
|
||||||
|
import shutil
|
||||||
|
import signal
|
||||||
|
import time
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
label_name = "hoster.domains"
|
||||||
|
enclosing_pattern = "#-----------Docker-Hoster-Domains----------\n"
|
||||||
|
hosts_path = "/tmp/hosts"
|
||||||
|
hosts = {}
|
||||||
|
|
||||||
|
def signal_handler(signal, frame):
|
||||||
|
global hosts
|
||||||
|
hosts = {}
|
||||||
|
update_hosts_file()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# register the exit signals
|
||||||
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
|
signal.signal(signal.SIGTERM, signal_handler)
|
||||||
|
|
||||||
|
args = parse_args()
|
||||||
|
global hosts_path
|
||||||
|
hosts_path = args.file
|
||||||
|
|
||||||
|
docker = Client(base_url='unix://%s'%args.socket)
|
||||||
|
events = docker.events(decode=True)
|
||||||
|
#get running containers
|
||||||
|
for c in docker.containers(quiet=True,all=False):
|
||||||
|
container_id = c["Id"]
|
||||||
|
container = get_container_data(docker, container_id)
|
||||||
|
hosts[container_id] = container
|
||||||
|
|
||||||
|
update_hosts_file()
|
||||||
|
|
||||||
|
#listen for events to keep the hosts file updated
|
||||||
|
for e in events:
|
||||||
|
|
||||||
|
if e["status"]=="start":
|
||||||
|
container_id = e["id"]
|
||||||
|
container = get_container_data(docker, container_id)
|
||||||
|
hosts[container_id] = container
|
||||||
|
update_hosts_file()
|
||||||
|
|
||||||
|
if e["status"]=="stop":
|
||||||
|
container_id = e["id"]
|
||||||
|
hosts.pop(container_id)
|
||||||
|
update_hosts_file()
|
||||||
|
|
||||||
|
|
||||||
|
def get_container_data(docker, container_id):
|
||||||
|
#extract all the info with the docker api
|
||||||
|
info = docker.inspect_container(container_id)
|
||||||
|
container_ip = info["NetworkSettings"]["IPAddress"]
|
||||||
|
container_name = info["Name"].strip("/")
|
||||||
|
labels = info["Config"]["Labels"]
|
||||||
|
domains = set()
|
||||||
|
if label_name in labels:
|
||||||
|
domains = domains.union([d.strip() for d in labels[label_name].split()])
|
||||||
|
|
||||||
|
domains.add("%s.local"%container_name)
|
||||||
|
|
||||||
|
return { "ip": container_ip, "name": container_name, "domains": domains}
|
||||||
|
|
||||||
|
|
||||||
|
def update_hosts_file():
|
||||||
|
if len(hosts)==0:
|
||||||
|
print("Removing all hosts before exit...")
|
||||||
|
else:
|
||||||
|
print("Updating hosts file with:")
|
||||||
|
|
||||||
|
for k,v in hosts.items():
|
||||||
|
print("ip: %s domains: %s"%(v["ip"],v["domains"]))
|
||||||
|
|
||||||
|
#read all the lines of thge original file
|
||||||
|
lines = []
|
||||||
|
with open(hosts_path,"r+") as hosts_file:
|
||||||
|
lines = hosts_file.readlines()
|
||||||
|
|
||||||
|
#remove all the lines after the known pattern
|
||||||
|
for i,line in enumerate(lines):
|
||||||
|
if line==enclosing_pattern:
|
||||||
|
lines = lines[:i]
|
||||||
|
break;
|
||||||
|
|
||||||
|
#remove all the trailing newlines on the line list
|
||||||
|
while lines[-1].strip()=="": lines.pop()
|
||||||
|
|
||||||
|
#append all the domain lines
|
||||||
|
if len(hosts)>0:
|
||||||
|
lines.append("\n\n"+enclosing_pattern)
|
||||||
|
for k,v in hosts.items():
|
||||||
|
lines.append("%s %s\n"%(v["ip"]," ".join(v["domains"])))
|
||||||
|
lines.append("#-----Do-not-add-hosts-after-this-line-----\n\n")
|
||||||
|
|
||||||
|
#write it on the auxiliar file
|
||||||
|
aux_file_path = hosts_path+".aux"
|
||||||
|
with open(aux_file_path,"w") as aux_hosts:
|
||||||
|
aux_hosts.writelines(lines)
|
||||||
|
|
||||||
|
#replace etc/hosts with aux file, making it atomic
|
||||||
|
shutil.move(aux_file_path, hosts_path)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_args():
|
||||||
|
parser = argparse.ArgumentParser(description='Synchronize running docker container IPs with host /etc/hosts file.')
|
||||||
|
parser.add_argument('socket', type=str, nargs="?", default="tmp/docker.sock", help='The docker socket to listen for docker events.')
|
||||||
|
parser.add_argument('file', type=str, nargs="?", default="/tmp/hosts", help='The /etc/hosts file to sync the containers with.')
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
||||||
Loading…
Reference in New Issue