Skip to content

Commit 84d4545

Browse files
authored
Merge pull request #1872 from docker/hnq90-add_exit_code_to_exec_run
Also return exit code in exec_run
2 parents 04eb7a2 + 6e6eaec commit 84d4545

File tree

3 files changed

+39
-7
lines changed

3 files changed

+39
-7
lines changed

docker/models/containers.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,14 @@ def exec_run(self, cmd, stdout=True, stderr=True, stdin=False, tty=False,
150150
workdir (str): Path to working directory for this exec session
151151
152152
Returns:
153-
(generator or str):
154-
If ``stream=True``, a generator yielding response chunks.
155-
If ``socket=True``, a socket object for the connection.
156-
A string containing response data otherwise.
153+
(tuple): A tuple of (exit_code, output)
154+
exit_code: (int):
155+
Exit code for the executed command
156+
output: (generator or str):
157+
If ``stream=True``, a generator yielding response chunks.
158+
If ``socket=True``, a socket object for the connection.
159+
A string containing response data otherwise.
160+
157161
Raises:
158162
:py:class:`docker.errors.APIError`
159163
If the server returns an error.
@@ -163,9 +167,13 @@ def exec_run(self, cmd, stdout=True, stderr=True, stdin=False, tty=False,
163167
privileged=privileged, user=user, environment=environment,
164168
workdir=workdir
165169
)
166-
return self.client.api.exec_start(
170+
exec_output = self.client.api.exec_start(
167171
resp['Id'], detach=detach, tty=tty, stream=stream, socket=socket
168172
)
173+
exit_code = 0
174+
if stream is False:
175+
exit_code = self.client.api.exec_inspect(resp['Id'])['ExitCode']
176+
return (exit_code, exec_output)
169177

170178
def export(self):
171179
"""

tests/integration/models_containers_test.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,13 +182,24 @@ def test_diff(self):
182182
container.wait()
183183
assert container.diff() == [{'Path': '/test', 'Kind': 1}]
184184

185-
def test_exec_run(self):
185+
def test_exec_run_success(self):
186186
client = docker.from_env(version=TEST_API_VERSION)
187187
container = client.containers.run(
188188
"alpine", "sh -c 'echo \"hello\" > /test; sleep 60'", detach=True
189189
)
190190
self.tmp_containers.append(container.id)
191-
assert container.exec_run("cat /test") == b"hello\n"
191+
exec_output = container.exec_run("cat /test")
192+
assert exec_output[0] == 0
193+
assert exec_output[1] == b"hello\n"
194+
195+
def test_exec_run_failed(self):
196+
client = docker.from_env(version=TEST_API_VERSION)
197+
container = client.containers.run(
198+
"alpine", "sh -c 'sleep 60'", detach=True
199+
)
200+
self.tmp_containers.append(container.id)
201+
exec_output = container.exec_run("docker ps")
202+
assert exec_output[0] == 126
192203

193204
def test_kill(self):
194205
client = docker.from_env(version=TEST_API_VERSION)

tests/unit/models_containers_test.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,19 @@ def test_exec_run(self):
401401
FAKE_EXEC_ID, detach=False, tty=False, stream=True, socket=False
402402
)
403403

404+
def test_exec_run_failure(self):
405+
client = make_fake_client()
406+
container = client.containers.get(FAKE_CONTAINER_ID)
407+
container.exec_run("docker ps", privileged=True, stream=False)
408+
client.api.exec_create.assert_called_with(
409+
FAKE_CONTAINER_ID, "docker ps", stdout=True, stderr=True,
410+
stdin=False, tty=False, privileged=True, user='', environment=None,
411+
workdir=None
412+
)
413+
client.api.exec_start.assert_called_with(
414+
FAKE_EXEC_ID, detach=False, tty=False, stream=False, socket=False
415+
)
416+
404417
def test_export(self):
405418
client = make_fake_client()
406419
container = client.containers.get(FAKE_CONTAINER_ID)

0 commit comments

Comments
 (0)