Skip to content

Instantly share code, notes, and snippets.

@josegonzalez
Last active August 29, 2015 14:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save josegonzalez/440e44f2a065b7a75c2a to your computer and use it in GitHub Desktop.
Save josegonzalez/440e44f2a065b7a75c2a to your computer and use it in GitHub Desktop.
wait until a docker container has no more incoming traffic
#!/usr/bin/env python
#
# Returns once a container no longer has open connections
# Only works for containers using internal dns
# Sleeps 2 seconds between checks
#
# Usage:
#
# # wait until all traffic drains from a container before killing it
# docker_sleep $CONTAINER_ID $MAX_WAIT
# docker stop $CONTAINER_ID &> /dev/null
# docker kill $CONTAINER_ID &> /dev/null
import datetime
import json
import psutil
import subprocess
import sys
import time
def proc_connections(proc):
# psutil 2.x
if hasattr(socket, 'get_connections'):
return proc.get_connections()
# psutil 3.x
if hasattr(socket, 'connections'):
return proc.connections()
return []
def get_open_connections():
connections = []
for proc in psutil.process_iter():
if proc.is_running() and proc.name() == 'nginx':
connections.extend([conn for conn in proc_connections(proc) if conn.status != CLOSE_WAIT])
return connections
def has_open_connections(container_ip)
for connection in get_connections():
if not connection.laddr or not connection.raddr:
continue
if connection.raddr[0] == container_ip:
return True
return False
def get_container_ip(container_id):
container_ip = None
try:
container_ip = subprocess.check_output([
'docker',
'inspect',
'--format',
'{{ .NetworkSettings.IPAddress }}'
container_id
])
except subprocess.CalledProcessError:
return None
return container_ip
def main(container_ip, max_wait=60):
# consider bombing out somehow...
if not container_ip:
return
started_at = datetime.datetime.now()
while True:
# kill the process after a max_wait delay
current_time = datetime.datetime.now()
if (current_time - started_at).total_seconds >= max_wait:
break
if has_open_connections(container_ip):
time.sleep(2)
continue
break
if __name__ == "__main__":
container_ip = get_container_ip(sys.argv[1])
max_wait = 60
if len(sys.argv) >= 3:
max_wait = int(sys.argv[2])
main(container_ip, max_wait)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment