Docker container that lists running containers and stores information on them in etcd
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

report.py 2.5KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #!/usr/bin/env python3
  2. from collections import defaultdict
  3. import argparse
  4. import docker
  5. import etcd
  6. import sys
  7. def etcd_put(client, prefix, obj):
  8. for key, value in obj.items():
  9. new_prefix = "%s/%s" % (prefix, key)
  10. if isinstance(value, dict):
  11. etcd_put(client, new_prefix, value)
  12. else:
  13. client.write(new_prefix, str(value))
  14. def get_addresses(container):
  15. return {k: v['IPAddress'] for k, v in container['NetworkSettings']['Networks'].items()}
  16. def get_ports(container):
  17. ports = defaultdict(dict)
  18. for port in container['Ports']:
  19. ports[port['Type']][port['PrivatePort']] = port['PublicPort'] if 'PublicPort' in port else 0
  20. return ports
  21. def add_containers(infos):
  22. global containers, label_index, network_index
  23. for info in infos:
  24. container = {
  25. 'image': info['Image'],
  26. 'labels': info['Labels'],
  27. 'net': {
  28. 'addr': get_addresses(info),
  29. 'ports': get_ports(info)
  30. }
  31. }
  32. name = info['Names'][0][1:]
  33. containers[name] = container
  34. for k, v in container['labels'].items():
  35. label_index[k][name] = v
  36. for k, v in container['net']['addr'].items():
  37. network_index[k][name] = v
  38. parser = argparse.ArgumentParser()
  39. parser.add_argument('--name', help='Name of this docker host', default='unknown')
  40. parser.add_argument('--etcd-port', type=int, help='Port to connect to etcd on', default=2379)
  41. parser.add_argument('--etcd-host', help='Host to connect to etcd on', default='etcd')
  42. parser.add_argument('--etcd-prefix', help='Prefix to use when adding keys to etcd', default='/docker')
  43. args = parser.parse_args()
  44. docker_client = docker.Client(base_url='unix://var/run/docker.sock')
  45. etcd_client = etcd.Client(host=args.etcd_host, port=args.etcd_port)
  46. prefix = args.etcd_prefix
  47. event_gen = docker_client.events(decode=True, filters={'type': 'container', 'event': ['die', 'start']})
  48. containers = {}
  49. label_index = defaultdict(dict)
  50. network_index = defaultdict(dict)
  51. add_containers(docker_client.containers())
  52. try:
  53. etcd_client.delete(prefix, recursive=True)
  54. except etcd.EtcdKeyNotFound:
  55. pass
  56. etcd_put(etcd_client, prefix + '/containers', containers)
  57. etcd_put(etcd_client, prefix + '/labels', label_index)
  58. etcd_put(etcd_client, prefix + '/networks', network_index)
  59. for event in event_gen:
  60. if event['Action'] == 'start':
  61. print('New container %s' % event['id'])
  62. add_containers(docker_client.containers(filters={'id': event['id']}))
  63. elif event['Action'] == 'die':
  64. print('Dead container %s' % event['id'])
  65. else:
  66. print('Unexpected event %s' % event['Action'])