Created
November 5, 2016 16:17
-
-
Save lentschi/63d073467a7c59c1c0dac8c1951341f0 to your computer and use it in GitHub Desktop.
alias a docker container's ip to /ect/hosts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# Script to alias a docker container's primary IPv4 address | |
# with the desired host_name in /ect/hosts | |
# | |
# Usage: add_container_to_hosts <container_name> <host_name> | |
# | |
# CAVEAT: Currently won't work for IPv6 addresses and will only work | |
# on platforms, where the hosts file can be found under /etc/hosts | |
# | |
# | |
# Note: Could easily be replaced by https://github.com/gliderlabs/resolvable | |
# but that won't work, when one container requires being addressed using | |
# more than two domain names | |
# | |
# Author: Florian Lentsch <office@florian-lentsch.at> | |
import sys, re, os | |
from subprocess import Popen, PIPE, call | |
from os.path import isfile | |
HOSTS_FILE = '/etc/hosts' | |
def die(msg): | |
sys.stderr.write("Error: " + msg + "\n") | |
exit(1) | |
def cmd(cmd_arr): | |
p = Popen(cmd_arr, stdout=PIPE) | |
out, err = p.communicate() | |
if err: | |
return None | |
return out | |
class HostsFileModifier: | |
def __init__(self, container_name, host_name): | |
self.host_name = host_name | |
self.container_name = container_name | |
def get_container_ip(self): | |
ip = cmd(["docker", "inspect", "-f", "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}", self.container_name]) | |
if isinstance(ip, basestring) and re.match(r"^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$", ip.strip()): | |
return ip.strip() | |
ip = cmd(["docker", "inspect", "--format", "{{ .NetworkSettings.IPAddress }}", self.container_name]) | |
if isinstance(ip, basestring) and re.match(r"^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$", ip.strip()): | |
return ip.strip() | |
die("Could not determine container IPv4 address of container id/name " + self.container_name) | |
def read_hosts_file(self): | |
if not isfile(HOSTS_FILE): | |
die(HOSTS_FILE + " not found") | |
try: | |
self.hosts_file = open(HOSTS_FILE, 'r') | |
return self.hosts_file.read() | |
except IOError: | |
die("Could not read from " + HOSTS_FILE) | |
def replace_or_add_domain_ip(self, hosts_str, new_ip): | |
correct_content = new_ip + "\t" + self.host_name | |
regex = re.compile("^((?:[0-9]{1,3}\.){3}[0-9]{1,3})\s+(" + re.escape(self.host_name) + ")$", flags=re.MULTILINE) | |
md = regex.search(hosts_str) | |
if md: | |
if md.group(1) == new_ip: | |
return hosts_str | |
if os.getuid() == 0: | |
print "Changing '%s' into '%s'" % (md.group(0), correct_content) | |
return regex.sub(correct_content, hosts_str) | |
else: | |
# in case the host is present in a line with many other hosts | |
# just remove it from there before adding it back in at the bottom: | |
hosts_str = re.sub("\s+" + re.escape(self.host_name), '', hosts_str) | |
if os.getuid() == 0: | |
print "Appending '%s'" % correct_content | |
return hosts_str + "\n" + correct_content + "\n" | |
def change_hosts_file(self, content): | |
self.hosts_file.close | |
if os.getuid() != 0: | |
print "re-running as root (required to change hosts file)... " | |
call(['sudo', sys.argv[0], sys.argv[1], sys.argv[2] ]) | |
exit(0) | |
try: | |
with open(HOSTS_FILE, 'w') as self.hosts_file: | |
self.hosts_file.write(content) | |
except IOError: | |
die("Change required, but could not write " + HOSTS_FILE + ". Did you forget to use sudo?") | |
def set_domain_ip(self,ip): | |
hosts_str = self.read_hosts_file() | |
modified_hosts_str = self.replace_or_add_domain_ip(hosts_str, ip) | |
if not modified_hosts_str: | |
die("Error parsing hosts file") | |
if hosts_str == modified_hosts_str: | |
print "Hosts file does not need changing" | |
exit(0) | |
self.change_hosts_file(modified_hosts_str) | |
exit(0) | |
if len(sys.argv) != 3: | |
die('Usage: ' + sys.argv[0] + ' <container_name> <host_name>') | |
modifier = HostsFileModifier(sys.argv[1], sys.argv[2]) | |
ip = modifier.get_container_ip() | |
modifier.set_domain_ip(ip) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment