summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKelley Spoon <kelley.spoon@linaro.org>2018-02-21 19:11:34 -0600
committerKelley Spoon <kelley.spoon@linaro.org>2018-02-28 15:24:28 +0000
commit52061c6d3fbd59df13e88f310846fef314e8cfac (patch)
tree92e88fca1427a43952f0ef25c645797a6bec89c7
parentc9f023127cb7b310cedc1ce1fb9200d86da10f66 (diff)
Docker: Add a dynamic inventory of docker hosts script
This change adds the docker_hosts script that will build an inventory file from running docker containers. See the script comments for information on requirments, usage, and an example. Change-Id: I80478db3d691d34fc00ee201318e38014bbf726f Reviewed-on: https://review.linaro.org/23990 Reviewed-by: Benjamin Copeland <ben.copeland@linaro.org>
-rwxr-xr-xdocker_hosts109
1 files changed, 109 insertions, 0 deletions
diff --git a/docker_hosts b/docker_hosts
new file mode 100755
index 00000000..6f78ac6f
--- /dev/null
+++ b/docker_hosts
@@ -0,0 +1,109 @@
+#!/usr/bin/env python
+
+import docker
+import re
+import json
+import sys
+
+"""
+ Ansible Docker Dynamic Inventory Script
+
+External components:
+ https://git.linaro.org/infrastructure/docker-ansible-baseimage.git/
+
+Requirements:
+ pip install docker
+ chmod 755 docker_hosts
+
+Example:
+
+ docker-compose -f linaro_dev up -d
+ docker run -d \
+ -e ANSIBLE_GROUP=gerrit \
+ -e ANSIBLE_HOST=review.linaro.org \
+ -e ALIAS=review.linaro.org \
+ --name review ansible/baseimage:14.04
+ ansible-playbook -u root -v -i docker_hosts \
+ -c local -l review.linaro.org gerrit.yml
+
+Options:
+
+ANSIBLE_HOST overrides the container's name in the inventory
+ Let's you use the host_vars for a real server for testing.
+ANSIBLE_GROUP is a comma separated list of groups that the host
+ should belong to.
+ALIAS is a feature of the linaro/devdns container that replaces the
+ local DNS entry for the target with the container's IP address
+
+"""
+
+class DockerInventory():
+ client = None
+ ip_table = {}
+ hosts = {}
+ groups = {}
+
+ def __init__(self):
+ self.client = docker.from_env()
+
+ # build ip lookup table
+ for network_entry in self.client.networks.list():
+ network = self.client.networks.get( network_entry.name )
+ for entry in network.attrs["Containers"]:
+ ip = network.attrs["Containers"][entry]["IPv4Address"]
+ name = network.attrs["Containers"][entry]["Name"]
+ self.ip_table[ name ] = re.sub( u"/\d+$", '', ip)
+
+ # build up all inventory
+ for container in self.client.containers.list():
+
+ # if ANSIBLE_HOST is set, use that instead of the container.name
+ # We should only add hosts that have an ANSIBLE_HOST set
+ #TODO: find a way to set other hostvars
+ hostname = container.name
+ for env_var in container.attrs["Config"]["Env"]:
+ found_ansible = re.match( 'ANSIBLE_HOST=(?P<ansible_host>.*)', env_var )
+ if found_ansible:
+ hostname = found_ansible.group("ansible_host")
+ self.hosts[hostname] = { "ansible_host": self.ip_table[container.name] }
+
+ # add in any groups listed in ANSIBLE_GROUP and make this
+ # container a member
+ for env_var in container.attrs["Config"]["Env"]:
+ found_ansible = re.match( 'ANSIBLE_GROUP=(?P<ansible_group>.*)', env_var )
+
+ if found_ansible:
+ groups = found_ansible.group("ansible_group")
+ for group in groups.split(','):
+ if not self.groups.has_key( group ):
+ self.groups[group] = []
+ self.groups[group].append( hostname )
+ #TODO: find a way to add in groupvars
+
+ def build_meta(self):
+ meta = {'_meta': { 'hostvars' : {} } }
+
+ for key in self.hosts.keys():
+ meta['_meta']['hostvars'][key] = self.hosts[key]
+
+ return meta
+
+ def list(self):
+ full = self.groups
+ full["_meta"] = self.build_meta()["_meta"]
+ return json.dumps( full )
+
+ def host(self, hostname):
+ try:
+ return json.dumps( self.hosts[hostname] )
+ except IndexError as e:
+ return json.dumps( {} )
+
+if __name__ == '__main__':
+
+ inventory = DockerInventory()
+
+ if len( sys.argv ) <= 2:
+ print inventory.list()
+ elif len(sys.argv ) >= 3:
+ print inventory.host( sys.argv[2] )