From 436306f09d0c3460ba5586d015ec151405f42b12 Mon Sep 17 00:00:00 2001 From: HuyNQ Date: Tue, 7 Nov 2017 16:05:35 +0700 Subject: [PATCH 1/2] Add exit code to exec_run Signed-off-by: HuyNQ --- docker/models/containers.py | 21 ++++++++++++++++----- tests/integration/models_containers_test.py | 15 +++++++++++++-- tests/unit/models_containers_test.py | 11 +++++++++++ 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/docker/models/containers.py b/docker/models/containers.py index 97a08b9d83..d70aa5069f 100644 --- a/docker/models/containers.py +++ b/docker/models/containers.py @@ -149,10 +149,14 @@ def exec_run(self, cmd, stdout=True, stderr=True, stdin=False, tty=False, ``{"PASSWORD": "xxx"}``. Returns: - (generator or str): - If ``stream=True``, a generator yielding response chunks. - If ``socket=True``, a socket object for the connection. - A string containing response data otherwise. + dict: + output: (generator or str): + If ``stream=True``, a generator yielding response chunks. + If ``socket=True``, a socket object for the connection. + A string containing response data otherwise. + exit_code: (int): + Exited code of execution + Raises: :py:class:`docker.errors.APIError` If the server returns an error. @@ -161,9 +165,16 @@ def exec_run(self, cmd, stdout=True, stderr=True, stdin=False, tty=False, self.id, cmd, stdout=stdout, stderr=stderr, stdin=stdin, tty=tty, privileged=privileged, user=user, environment=environment ) - return self.client.api.exec_start( + exec_output = self.client.api.exec_start( resp['Id'], detach=detach, tty=tty, stream=stream, socket=socket ) + exit_code = 0 + if stream is False: + exit_code = self.client.api.exec_inspect(resp['Id'])['ExitCode'] + return { + 'exit_code': exit_code, + 'output': exec_output + } def export(self): """ diff --git a/tests/integration/models_containers_test.py b/tests/integration/models_containers_test.py index ce3349baa7..1055a26fd8 100644 --- a/tests/integration/models_containers_test.py +++ b/tests/integration/models_containers_test.py @@ -153,13 +153,24 @@ def test_diff(self): container.wait() assert container.diff() == [{'Path': '/test', 'Kind': 1}] - def test_exec_run(self): + def test_exec_run_success(self): client = docker.from_env(version=TEST_API_VERSION) container = client.containers.run( "alpine", "sh -c 'echo \"hello\" > /test; sleep 60'", detach=True ) self.tmp_containers.append(container.id) - assert container.exec_run("cat /test") == b"hello\n" + exec_output = container.exec_run("cat /test") + assert exec_output["output"] == b"hello\n" + assert exec_output["exit_code"] == 0 + + def test_exec_run_failed(self): + client = docker.from_env(version=TEST_API_VERSION) + container = client.containers.run( + "alpine", "sh -c 'sleep 60'", detach=True + ) + self.tmp_containers.append(container.id) + exec_output = container.exec_run("docker ps") + assert exec_output["exit_code"] == 126 def test_kill(self): client = docker.from_env(version=TEST_API_VERSION) diff --git a/tests/unit/models_containers_test.py b/tests/unit/models_containers_test.py index 5eaa45ac66..75d128a149 100644 --- a/tests/unit/models_containers_test.py +++ b/tests/unit/models_containers_test.py @@ -400,6 +400,17 @@ def test_exec_run(self): client.api.exec_start.assert_called_with( FAKE_EXEC_ID, detach=False, tty=False, stream=True, socket=False ) + container.exec_run("docker ps", privileged=True, stream=False) + client.api.exec_create.assert_called_with( + FAKE_CONTAINER_ID, "docker ps", stdout=True, stderr=True, + stdin=False, tty=False, privileged=True, user='', environment=None + ) + client.api.exec_start.assert_called_with( + FAKE_EXEC_ID, detach=False, tty=False, stream=False, socket=False + ) + client.api.exec_start.assert_called_with( + FAKE_EXEC_ID, detach=False, tty=False, stream=False, socket=False + ) def test_export(self): client = make_fake_client() From 6e6eaece81ebeb43f644a14e498189a9d27d647e Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Fri, 26 Jan 2018 14:21:23 -0800 Subject: [PATCH 2/2] Return tuple instead of dict in exec_run Signed-off-by: Joffrey F --- docker/models/containers.py | 11 ++++------- tests/integration/models_containers_test.py | 6 +++--- tests/unit/models_containers_test.py | 10 ++++++---- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/docker/models/containers.py b/docker/models/containers.py index 343535bab5..9644b00236 100644 --- a/docker/models/containers.py +++ b/docker/models/containers.py @@ -150,13 +150,13 @@ def exec_run(self, cmd, stdout=True, stderr=True, stdin=False, tty=False, workdir (str): Path to working directory for this exec session Returns: - dict: + (tuple): A tuple of (exit_code, output) + exit_code: (int): + Exit code for the executed command output: (generator or str): If ``stream=True``, a generator yielding response chunks. If ``socket=True``, a socket object for the connection. A string containing response data otherwise. - exit_code: (int): - Exited code of execution Raises: :py:class:`docker.errors.APIError` @@ -173,10 +173,7 @@ def exec_run(self, cmd, stdout=True, stderr=True, stdin=False, tty=False, exit_code = 0 if stream is False: exit_code = self.client.api.exec_inspect(resp['Id'])['ExitCode'] - return { - 'exit_code': exit_code, - 'output': exec_output - } + return (exit_code, exec_output) def export(self): """ diff --git a/tests/integration/models_containers_test.py b/tests/integration/models_containers_test.py index fd052bef19..3c33cb0721 100644 --- a/tests/integration/models_containers_test.py +++ b/tests/integration/models_containers_test.py @@ -189,8 +189,8 @@ def test_exec_run_success(self): ) self.tmp_containers.append(container.id) exec_output = container.exec_run("cat /test") - assert exec_output["output"] == b"hello\n" - assert exec_output["exit_code"] == 0 + assert exec_output[0] == 0 + assert exec_output[1] == b"hello\n" def test_exec_run_failed(self): client = docker.from_env(version=TEST_API_VERSION) @@ -199,7 +199,7 @@ def test_exec_run_failed(self): ) self.tmp_containers.append(container.id) exec_output = container.exec_run("docker ps") - assert exec_output["exit_code"] == 126 + assert exec_output[0] == 126 def test_kill(self): client = docker.from_env(version=TEST_API_VERSION) diff --git a/tests/unit/models_containers_test.py b/tests/unit/models_containers_test.py index f94c5cfa35..d7457ba4a1 100644 --- a/tests/unit/models_containers_test.py +++ b/tests/unit/models_containers_test.py @@ -400,13 +400,15 @@ def test_exec_run(self): client.api.exec_start.assert_called_with( FAKE_EXEC_ID, detach=False, tty=False, stream=True, socket=False ) + + def test_exec_run_failure(self): + client = make_fake_client() + container = client.containers.get(FAKE_CONTAINER_ID) container.exec_run("docker ps", privileged=True, stream=False) client.api.exec_create.assert_called_with( FAKE_CONTAINER_ID, "docker ps", stdout=True, stderr=True, - stdin=False, tty=False, privileged=True, user='', environment=None - ) - client.api.exec_start.assert_called_with( - FAKE_EXEC_ID, detach=False, tty=False, stream=False, socket=False + stdin=False, tty=False, privileged=True, user='', environment=None, + workdir=None ) client.api.exec_start.assert_called_with( FAKE_EXEC_ID, detach=False, tty=False, stream=False, socket=False