aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKelley Spoon <kelley.spoon@linaro.org>2018-05-22 15:17:31 -0500
committerKelley Spoon <kelley.spoon@linaro.org>2018-05-23 11:33:15 -0500
commit407c8d90bef8eafc585386f9383e1db4356d6497 (patch)
tree42f0eb6f8435bfe8a88d154e6899da4fc48b440c
parentec45a9fdef272835e457bafda29385e28e907535 (diff)
EventWatcher: upgrade to be version independent of docker python module
This change also cleans up host entries for all docker containers upon exit until run in the "one shot" mode (-o) Change-Id: I5924512ab61c1f67e0d921c69e83f0708a34cf1e
-rwxr-xr-xhostsdns/event-watcher.py92
1 files changed, 61 insertions, 31 deletions
diff --git a/hostsdns/event-watcher.py b/hostsdns/event-watcher.py
index 3446777..4158ba2 100755
--- a/hostsdns/event-watcher.py
+++ b/hostsdns/event-watcher.py
@@ -3,8 +3,22 @@
import os, sys, json, re
import docker
import argparse
+import atexit
-parser = argparse.ArgumentParser( description="Manage host entries for docker containers")
+def get_name(cobj):
+ return re.sub('^/', '', cobj["Names"][0])
+
+def find_by_id(id):
+ for c in client.containers():
+ if c.has_key("Id") and c["Id"] == id:
+ return c
+
+def find_by_name(name):
+ for c in client.containers():
+ if "/%s" % name in c["Names"]:
+ return c
+
+parser = argparse.ArgumentParser(description="Manage host entries for docker containers")
parser.add_argument('-n', '--native', help='run service on docker host', action='store_true' , dest='NATIVE_MODE')
parser.add_argument('-o','-1', '--once', help='run once and exit (no continuous polling)', action='store_true', dest='ONCE_MODE')
args = parser.parse_args()
@@ -16,30 +30,34 @@ else:
print "Running in native mode... reading from /etc/hosts"
HOSTS_FILE="/etc/hosts"
-if os.environ.get("DOCKER_HOST"):
- client = docker.from_env()
-else:
- try:
- client = docker.DockerClient(base_url='unix://var/run/docker.sock')
- except:
- print "Sorry, I can't find a dockerd to connect to."
- sys.exit(1)
+try:
+ # version dependent. If it's pre 2.0, then we have to use the lower
+ # level APIClient class, but in version 1.x APIClient was the base
+ if int(docker.__version__.split('.')[0]) > 1:
+ client = docker.APIClient( base_url='unix://var/run/docker.sock')
+ else:
+ client = docker.from_env()
+except:
+ print "Sorry, I can't find a dockerd to connect to."
+ sys.exit(1)
def get_ip(c):
try:
- networks = c.attrs.get("NetworkSettings").get("Networks")
+ networks = c["NetworkSettings"]["Networks"]
for n in networks:
ip = networks[n]["IPAddress"]
if ip is not None:
return ip
- except:
+
+ except Exception as e:
+ print e
return None
def get_aliases(c):
aliases = []
try:
- envs = c.attrs.get("Config").get("Env")
+ envs = client.inspect_container(c)["Config"]["Env"]
for e in envs:
m = re.match('ALIAS=(?P<aliases>.*)', e)
@@ -48,32 +66,37 @@ def get_aliases(c):
aliases.append(a)
return aliases
except KeyError as e:
+ print e
return None
def event_remove(event):
- container = client.containers.get(event.get("id"))
- container_remove(container.name)
+ container = find_by_id(event["id"])
+ if container is not None:
+ container_remove(get_name(container))
def event_add(event):
- container = client.containers.get(event.get("id"))
- container_add(container.name)
+ container = find_by_id(event["id"])
+ container_add(get_name(container))
def container_add(name):
try:
- container = client.containers.get(name)
- except:
+ container = find_by_name(name)
+ except Exception as e:
+ print e
return
- container_remove(container.name)
+ container_remove(name)
ip = get_ip(container)
if ip:
- entry = "%s %s" % (ip, container.name)
+ entry = "%s %s" % (ip, name)
aliases = get_aliases(container)
if aliases:
entry += " %s" % ' '.join(aliases)
open(HOSTS_FILE, 'a').write(entry+'\n')
print "Added: %s" % entry
+ else:
+ print "WHUPS!!!! No IP found for %s" % name
def container_remove(name):
if name is None and len(name) > 0:
@@ -87,25 +110,32 @@ def container_remove(name):
if re.match(entry, line) is None:
outfile.write(line)
outfile.close()
-
print "removed entry for pattern %s" % name
+def cleanup():
+ for container in client.containers():
+ container_remove(get_name(container))
+if not args.ONCE_MODE:
+ atexit.register(cleanup)
### Let's start doing something useful.
# first, we catch up with any existing containers that are already deployed.
-for container in client.containers.list():
- container_add(container.name)
+for container in client.containers():
+ container_add(get_name(container))
if args.ONCE_MODE:
sys.exit(0)
# calling events will basically poll forever, so after this we're
# essentially in not-quite-a-daemon mode
-for event_json in client.events():
- print "SAW: %s" % str(event_json)
- event = json.loads(str(event_json))
-
- if event.get("status") == "start":
- event_add(event)
- elif event.get("status") == "kill":
- event_remove(event)
+try:
+ for event_json in client.events():
+ print "SAW: %s" % str(event_json)
+ event = json.loads(str(event_json))
+
+ if event.get("status") == "start":
+ event_add(event)
+ elif event.get("status") in ["kill","destroy","die"]:
+ event_remove(event)
+except KeyboardInterrupt as ki:
+ print "Exiting."