diff options
author | Kelley Spoon <kelley.spoon@linaro.org> | 2018-05-22 15:17:31 -0500 |
---|---|---|
committer | Kelley Spoon <kelley.spoon@linaro.org> | 2018-05-23 11:33:15 -0500 |
commit | 407c8d90bef8eafc585386f9383e1db4356d6497 (patch) | |
tree | 42f0eb6f8435bfe8a88d154e6899da4fc48b440c | |
parent | ec45a9fdef272835e457bafda29385e28e907535 (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-x | hostsdns/event-watcher.py | 92 |
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." |