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.

monitor.py 1.9KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #!/usr/bin/env python3
  2. from collections import defaultdict
  3. import docker
  4. class Monitor:
  5. def __init__(self, host_name, on_added, on_removed):
  6. self._client = docker.Client(base_url='unix://var/run/docker.sock')
  7. self._containers = defaultdict(dict)
  8. self._host = host_name
  9. self._on_added = on_added
  10. self._on_removed = on_removed
  11. self._events = self._client.events(decode=True,
  12. filters={'type': 'container',
  13. 'event': ['die', 'start']})
  14. def monitor(self):
  15. self._add(self._client.containers())
  16. for event in self._events:
  17. if event['Action'] == 'start':
  18. self._add(self._client.containers(filters={'id': event['id']}))
  19. elif event['Action'] == 'die':
  20. self._remove(event['id'])
  21. else:
  22. print('Monitor.monitor(): unexpected event %s' % event['Action'], flush=True)
  23. def _add(self, infos):
  24. res = []
  25. for info in infos:
  26. container = {
  27. 'host': self._host,
  28. 'image': info['Image'],
  29. 'labels': info['Labels'],
  30. 'name': info['Names'][0][1:],
  31. 'net': {
  32. 'addr': self._get_addresses(info),
  33. 'ports': self._get_ports(info)
  34. }
  35. }
  36. self._containers[info['Id']] = container
  37. res.append(container)
  38. self._on_added(res)
  39. def _remove(self, container_id):
  40. if container_id in self._containers:
  41. container = self._containers[container_id]
  42. del self._containers[container_id]
  43. self._on_removed([container])
  44. def _get_addresses(self, container):
  45. return {k: v['IPAddress'] for k, v in container['NetworkSettings']['Networks'].items()}
  46. def _get_ports(self, container):
  47. ports = defaultdict(dict)
  48. for port in container['Ports']:
  49. ports[port['Type']][port['PrivatePort']] = port['PublicPort'] if 'PublicPort' in port else 0
  50. return ports