Skip to content

Commit 436306f

Browse files
committed
Add exit code to exec_run
Signed-off-by: HuyNQ <[email protected]>
1 parent c7f1b5f commit 436306f

File tree

3 files changed

+40
-7
lines changed

3 files changed

+40
-7
lines changed

docker/models/containers.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,14 @@ def exec_run(self, cmd, stdout=True, stderr=True, stdin=False, tty=False,
149149
``{"PASSWORD": "xxx"}``.
150150
151151
Returns:
152-
(generator or str):
153-
If ``stream=True``, a generator yielding response chunks.
154-
If ``socket=True``, a socket object for the connection.
155-
A string containing response data otherwise.
152+
dict:
153+
output: (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.
157+
exit_code: (int):
158+
Exited code of execution
159+
156160
Raises:
157161
:py:class:`docker.errors.APIError`
158162
If the server returns an error.
@@ -161,9 +165,16 @@ def exec_run(self, cmd, stdout=True, stderr=True, stdin=False, tty=False,
161165
self.id, cmd, stdout=stdout, stderr=stderr, stdin=stdin, tty=tty,
162166
privileged=privileged, user=user, environment=environment
163167
)
164-
return self.client.api.exec_start(
168+
exec_output = self.client.api.exec_start(
165169
resp['Id'], detach=detach, tty=tty, stream=stream, socket=socket
166170
)
171+
exit_code = 0
172+
if stream is False:
173+
exit_code = self.client.api.exec_inspect(resp['Id'])['ExitCode']
174+
return {
175+
'exit_code': exit_code,
176+
'output': exec_output
177+
}
167178

168179
def export(self):
169180
"""

tests/integration/models_containers_test.py

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

156-
def test_exec_run(self):
156+
def test_exec_run_success(self):
157157
client = docker.from_env(version=TEST_API_VERSION)
158158
container = client.containers.run(
159159
"alpine", "sh -c 'echo \"hello\" > /test; sleep 60'", detach=True
160160
)
161161
self.tmp_containers.append(container.id)
162-
assert container.exec_run("cat /test") == b"hello\n"
162+
exec_output = container.exec_run("cat /test")
163+
assert exec_output["output"] == b"hello\n"
164+
assert exec_output["exit_code"] == 0
165+
166+
def test_exec_run_failed(self):
167+
client = docker.from_env(version=TEST_API_VERSION)
168+
container = client.containers.run(
169+
"alpine", "sh -c 'sleep 60'", detach=True
170+
)
171+
self.tmp_containers.append(container.id)
172+
exec_output = container.exec_run("docker ps")
173+
assert exec_output["exit_code"] == 126
163174

164175
def test_kill(self):
165176
client = docker.from_env(version=TEST_API_VERSION)

tests/unit/models_containers_test.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,17 @@ def test_exec_run(self):
400400
client.api.exec_start.assert_called_with(
401401
FAKE_EXEC_ID, detach=False, tty=False, stream=True, socket=False
402402
)
403+
container.exec_run("docker ps", privileged=True, stream=False)
404+
client.api.exec_create.assert_called_with(
405+
FAKE_CONTAINER_ID, "docker ps", stdout=True, stderr=True,
406+
stdin=False, tty=False, privileged=True, user='', environment=None
407+
)
408+
client.api.exec_start.assert_called_with(
409+
FAKE_EXEC_ID, detach=False, tty=False, stream=False, socket=False
410+
)
411+
client.api.exec_start.assert_called_with(
412+
FAKE_EXEC_ID, detach=False, tty=False, stream=False, socket=False
413+
)
403414

404415
def test_export(self):
405416
client = make_fake_client()

0 commit comments

Comments
 (0)