14 """Helpers to run docker instances as jobs."""
16 from __future__
import print_function
26 sys.path.append(os.path.dirname(os.path.abspath(__file__)))
29 _DEVNULL =
open(os.devnull,
'w')
33 """Randomizes given base name."""
34 return '%s_%s' % (base_name, uuid.uuid4())
38 """Kills a docker container. Returns True if successful."""
39 return subprocess.call([
'docker',
'kill',
str(cid)],
40 stdin=subprocess.PIPE,
42 stderr=subprocess.STDOUT) == 0
46 """Get port mapped to internal given internal port for given container."""
48 while time.time() - started < timeout_seconds:
50 output = subprocess.check_output(
'docker port %s %s' % (cid, port),
53 return int(output.split(
':', 2)[1])
54 except subprocess.CalledProcessError
as e:
56 raise Exception(
'Failed to get exposed port %s for container %s.' %
61 """Get port mapped to internal given internal port for given container."""
63 while time.time() - started < timeout_seconds:
64 cmd =
'docker inspect %s' % cid
66 output = subprocess.check_output(cmd, stderr=_DEVNULL,
68 json_info = json.loads(output)
69 assert len(json_info) == 1
70 out = json_info[0][
'NetworkSettings'][
'IPAddress']
74 except subprocess.CalledProcessError
as e:
77 'Non-retryable error: Failed to get ip address of container %s.' % cid)
81 """Wait timeout_seconds for the container to become healthy"""
83 while time.time() - started < timeout_seconds:
85 output = subprocess.check_output([
86 'docker',
'inspect',
'--format="{{.State.Health.Status}}"', cid
89 if output.strip(
'\n') ==
'healthy':
91 except subprocess.CalledProcessError
as e:
94 raise Exception(
'Timed out waiting for %s (%s) to pass health check' %
99 """Kills given docker containers and waits for corresponding jobs to finish"""
101 job.kill(suppress_failure=suppress_failure)
103 while any(job.is_running()
for job
in jobs):
108 """Returns True if given docker image exists."""
109 return subprocess.call([
'docker',
'inspect', image],
110 stdin=subprocess.PIPE,
112 stderr=subprocess.STDOUT) == 0
116 """Attempts to remove docker image with retries."""
119 for attempt
in range(0, max_retries):
120 if subprocess.call([
'docker',
'rmi',
'-f', image],
121 stdin=subprocess.PIPE,
123 stderr=subprocess.STDOUT) == 0:
126 print(
'Failed to remove docker image %s' % image)
131 """Encapsulates a job"""
136 newline_on_success=
True,
151 def kill(self, suppress_failure=False):
152 """Sends kill signal to the container."""
154 self.
_job.suppress_failure_message()
158 """Polls a job and returns True if given job is still running."""
159 return self.
_job.
state() == jobset._RUNNING