Skip to content

Commit 62fda98

Browse files
bolshakovshin-
authored andcommitted
client.containers.run returns None if none of json-file or journald logging drivers used
Signed-off-by: Artem Bolshakov <[email protected]>
1 parent 48377d5 commit 62fda98

File tree

5 files changed

+80
-4
lines changed

5 files changed

+80
-4
lines changed

docker/errors.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,14 @@ def __init__(self, container, exit_status, command, image, stderr):
127127
self.command = command
128128
self.image = image
129129
self.stderr = stderr
130-
msg = ("Command '{}' in image '{}' returned non-zero exit status {}: "
131-
"{}").format(command, image, exit_status, stderr)
130+
131+
if stderr is None:
132+
msg = ("Command '{}' in image '{}' returned non-zero exit "
133+
"status {}").format(command, image, exit_status, stderr)
134+
else:
135+
msg = ("Command '{}' in image '{}' returned non-zero exit "
136+
"status {}: {}").format(command, image, exit_status, stderr)
137+
132138
super(ContainerError, self).__init__(msg)
133139

134140

docker/models/containers.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,13 @@ def run(self, image, command=None, stdout=True, stderr=False,
667667
The container logs, either ``STDOUT``, ``STDERR``, or both,
668668
depending on the value of the ``stdout`` and ``stderr`` arguments.
669669
670+
``STDOUT`` and ``STDERR`` may be read only if either ``json-file``
671+
or ``journald`` logging driver used. Thus, if you are using none of
672+
these drivers, a ``None`` object is returned instead. See the
673+
`Engine API documentation
674+
<https://docs.docker.com/engine/api/v1.30/#operation/ContainerLogs/>`_
675+
for full details.
676+
670677
If ``detach`` is ``True``, a :py:class:`Container` object is
671678
returned instead.
672679
@@ -709,7 +716,14 @@ def run(self, image, command=None, stdout=True, stderr=False,
709716
if exit_status != 0:
710717
stdout = False
711718
stderr = True
712-
out = container.logs(stdout=stdout, stderr=stderr)
719+
720+
logging_driver = container.attrs['HostConfig']['LogConfig']['Type']
721+
722+
if logging_driver == 'json-file' or logging_driver == 'journald':
723+
out = container.logs(stdout=stdout, stderr=stderr)
724+
else:
725+
out = None
726+
713727
if remove:
714728
container.remove()
715729
if exit_status != 0:

tests/integration/models_containers_test.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,24 @@ def test_run_with_network(self):
8888
assert 'Networks' in attrs['NetworkSettings']
8989
assert list(attrs['NetworkSettings']['Networks'].keys()) == [net_name]
9090

91+
def test_run_with_none_driver(self):
92+
client = docker.from_env(version=TEST_API_VERSION)
93+
94+
out = client.containers.run(
95+
"alpine", "echo hello",
96+
log_config=dict(type='none')
97+
)
98+
self.assertEqual(out, None)
99+
100+
def test_run_with_json_file_driver(self):
101+
client = docker.from_env(version=TEST_API_VERSION)
102+
103+
out = client.containers.run(
104+
"alpine", "echo hello",
105+
log_config=dict(type='json-file')
106+
)
107+
self.assertEqual(out, b'hello\n')
108+
91109
def test_get(self):
92110
client = docker.from_env(version=TEST_API_VERSION)
93111
container = client.containers.run("alpine", "sleep 300", detach=True)

tests/unit/errors_test.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
import requests
44

5-
from docker.errors import (APIError, DockerException,
5+
from docker.errors import (APIError, ContainerError, DockerException,
66
create_unexpected_kwargs_error)
7+
from .fake_api import FAKE_CONTAINER_ID, FAKE_IMAGE_ID
8+
from .fake_api_client import make_fake_client
79

810

911
class APIErrorTest(unittest.TestCase):
@@ -77,6 +79,36 @@ def test_is_client_error_400(self):
7779
assert err.is_client_error() is True
7880

7981

82+
class ContainerErrorTest(unittest.TestCase):
83+
def test_container_without_stderr(self):
84+
"""The massage does not contain stderr"""
85+
client = make_fake_client()
86+
container = client.containers.get(FAKE_CONTAINER_ID)
87+
command = "echo Hello World"
88+
exit_status = 42
89+
image = FAKE_IMAGE_ID
90+
stderr = None
91+
92+
err = ContainerError(container, exit_status, command, image, stderr)
93+
msg = ("Command '{}' in image '{}' returned non-zero exit status {}"
94+
).format(command, image, exit_status, stderr)
95+
assert str(err) == msg
96+
97+
def test_container_with_stderr(self):
98+
"""The massage contains stderr"""
99+
client = make_fake_client()
100+
container = client.containers.get(FAKE_CONTAINER_ID)
101+
command = "echo Hello World"
102+
exit_status = 42
103+
image = FAKE_IMAGE_ID
104+
stderr = "Something went wrong"
105+
106+
err = ContainerError(container, exit_status, command, image, stderr)
107+
msg = ("Command '{}' in image '{}' returned non-zero exit status {}: "
108+
"{}").format(command, image, exit_status, stderr)
109+
assert str(err) == msg
110+
111+
80112
class CreateUnexpectedKwargsErrorTest(unittest.TestCase):
81113
def test_create_unexpected_kwargs_error_single(self):
82114
e = create_unexpected_kwargs_error('f', {'foo': 'bar'})

tests/unit/fake_api.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,12 @@ def get_fake_inspect_container(tty=False):
146146
"StartedAt": "2013-09-25T14:01:18.869545111+02:00",
147147
"Ghost": False
148148
},
149+
"HostConfig": {
150+
"LogConfig": {
151+
"Type": "json-file",
152+
"Config": {}
153+
},
154+
},
149155
"MacAddress": "02:42:ac:11:00:0a"
150156
}
151157
return status_code, response

0 commit comments

Comments
 (0)