Skip to content

Commit 644b9f4

Browse files
authored
Merge pull request #1890 from docker/wait_return
Update wait to always return a dict
2 parents 0a86ff0 + 7fabcda commit 644b9f4

File tree

9 files changed

+74
-35
lines changed

9 files changed

+74
-35
lines changed

docker/api/container.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,8 +1207,8 @@ def wait(self, container, timeout=None, condition=None):
12071207
or ``removed``
12081208
12091209
Returns:
1210-
(int or dict): The exit code of the container. Returns the full API
1211-
response if no ``StatusCode`` field is included.
1210+
(dict): The API's response as a Python dictionary, including
1211+
the container's exit code under the ``StatusCode`` attribute.
12121212
12131213
Raises:
12141214
:py:class:`requests.exceptions.ReadTimeout`
@@ -1226,8 +1226,4 @@ def wait(self, container, timeout=None, condition=None):
12261226
params['condition'] = condition
12271227

12281228
res = self._post(url, timeout=timeout, params=params)
1229-
self._raise_for_status(res)
1230-
json_ = res.json()
1231-
if 'StatusCode' in json_:
1232-
return json_['StatusCode']
1233-
return json_
1229+
return self._result(res, True)

docker/models/containers.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,8 @@ def wait(self, **kwargs):
448448
or ``removed``
449449
450450
Returns:
451-
(int): The exit code of the container. Returns ``-1`` if the API
452-
responds without a ``StatusCode`` attribute.
451+
(dict): The API's response as a Python dictionary, including
452+
the container's exit code under the ``StatusCode`` attribute.
453453
454454
Raises:
455455
:py:class:`requests.exceptions.ReadTimeout`
@@ -758,7 +758,7 @@ def run(self, image, command=None, stdout=True, stderr=False,
758758
stdout=stdout, stderr=stderr, stream=True, follow=True
759759
)
760760

761-
exit_status = container.wait()
761+
exit_status = container.wait()['StatusCode']
762762
if exit_status != 0:
763763
out = None
764764
if not kwargs.get('auto_remove'):

docker/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
version = "2.8.0-dev"
1+
version = "3.0.0"
22
version_info = tuple([int(d) for d in version.split("-")[0].split(".")])

docs/change-log.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,47 @@
11
Change log
22
==========
33

4+
3.0.0
5+
-----
6+
7+
[List of PRs / issues for this release](https://github.com/docker/docker-py/milestone/39?closed=1)
8+
9+
### Breaking changes
10+
11+
* Support for API version < 1.21 has been removed.
12+
* The following methods have been removed:
13+
* `APIClient.copy` has been removed. Users should use `APIClient.get_archive`
14+
instead.
15+
* `APIClient.insert` has been removed. Users may use `APIClient.put_archive`
16+
combined with `APIClient.commit` to replicate the method's behavior.
17+
* `utils.ping_registry` and `utils.ping` have been removed.
18+
* The following parameters have been removed:
19+
* `stream` in `APIClient.build`
20+
* `cpu_shares`, `cpuset`, `dns`, `mem_limit`, `memswap_limit`,
21+
`volume_driver`, `volumes_from` in `APIClient.create_container`. These are
22+
all replaced by their equivalent in `create_host_config`
23+
* `insecure_registry` in `APIClient.login`, `APIClient.pull`,
24+
`APIClient.push`, `DockerClient.images.push` and `DockerClient.images.pull`
25+
* `viz` in `APIClient.images`
26+
* The following parameters have been renamed:
27+
* `endpoint_config` in `APIClient.create_service` and
28+
`APIClient.update_service` is now `endpoint_spec`
29+
* `name` in `DockerClient.images.pull` is now `repository`
30+
* The return value for the following methods has changed:
31+
* `APIClient.wait` and `Container.wait` now return a ``dict`` representing
32+
the API's response instead of returning the status code directly.
33+
* `DockerClient.images.load` now returns a list of `Image` objects that have
34+
for the images that were loaded, instead of a log stream.
35+
* `Container.exec_run` now returns a tuple of (exit_code, output) instead of
36+
just the output.
37+
* `DockerClient.images.build` now returns a tuple of (image, build_logs)
38+
instead of just the image object.
39+
* `APIClient.export`, `APIClient.get_archive` and `APIClient.get_image` now
40+
return generators streaming the raw binary data from the server's response.
41+
* When no tag is provided, `DockerClient.images.pull` now returns a list of
42+
`Image`s associated to the pulled repository instead of just the `latest`
43+
image.
44+
445
2.7.0
546
-----
647

tests/integration/api_container_test.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def test_create_with_links(self):
102102
container3_id = res2['Id']
103103
self.tmp_containers.append(container3_id)
104104
self.client.start(container3_id)
105-
assert self.client.wait(container3_id) == 0
105+
assert self.client.wait(container3_id)['StatusCode'] == 0
106106

107107
logs = self.client.logs(container3_id)
108108
if six.PY3:
@@ -169,7 +169,7 @@ def create_container_readonly_fs(self):
169169
assert 'Id' in ctnr
170170
self.tmp_containers.append(ctnr['Id'])
171171
self.client.start(ctnr)
172-
res = self.client.wait(ctnr)
172+
res = self.client.wait(ctnr)['StatusCode']
173173
assert res != 0
174174

175175
def create_container_with_name(self):
@@ -771,7 +771,7 @@ def test_run_shlex_commands(self):
771771
id = container['Id']
772772
self.client.start(id)
773773
self.tmp_containers.append(id)
774-
exitcode = self.client.wait(id)
774+
exitcode = self.client.wait(id)['StatusCode']
775775
assert exitcode == 0, cmd
776776

777777

@@ -781,7 +781,7 @@ def test_wait(self):
781781
id = res['Id']
782782
self.tmp_containers.append(id)
783783
self.client.start(id)
784-
exitcode = self.client.wait(id)
784+
exitcode = self.client.wait(id)['StatusCode']
785785
assert exitcode == 0
786786
inspect = self.client.inspect_container(id)
787787
assert 'Running' in inspect['State']
@@ -794,7 +794,7 @@ def test_wait_with_dict_instead_of_id(self):
794794
id = res['Id']
795795
self.tmp_containers.append(id)
796796
self.client.start(res)
797-
exitcode = self.client.wait(res)
797+
exitcode = self.client.wait(res)['StatusCode']
798798
assert exitcode == 0
799799
inspect = self.client.inspect_container(res)
800800
assert 'Running' in inspect['State']
@@ -815,7 +815,9 @@ def test_wait_with_condition(self):
815815
)
816816
self.tmp_containers.append(ctnr)
817817
self.client.start(ctnr)
818-
assert self.client.wait(ctnr, condition='removed', timeout=5) == 0
818+
assert self.client.wait(
819+
ctnr, condition='removed', timeout=5
820+
)['StatusCode'] == 0
819821

820822

821823
class LogsTest(BaseAPIIntegrationTest):
@@ -827,7 +829,7 @@ def test_logs(self):
827829
id = container['Id']
828830
self.tmp_containers.append(id)
829831
self.client.start(id)
830-
exitcode = self.client.wait(id)
832+
exitcode = self.client.wait(id)['StatusCode']
831833
assert exitcode == 0
832834
logs = self.client.logs(id)
833835
assert logs == (snippet + '\n').encode(encoding='ascii')
@@ -841,7 +843,7 @@ def test_logs_tail_option(self):
841843
id = container['Id']
842844
self.tmp_containers.append(id)
843845
self.client.start(id)
844-
exitcode = self.client.wait(id)
846+
exitcode = self.client.wait(id)['StatusCode']
845847
assert exitcode == 0
846848
logs = self.client.logs(id, tail=1)
847849
assert logs == 'Line2\n'.encode(encoding='ascii')
@@ -858,7 +860,7 @@ def test_logs_streaming_and_follow(self):
858860
for chunk in self.client.logs(id, stream=True, follow=True):
859861
logs += chunk
860862

861-
exitcode = self.client.wait(id)
863+
exitcode = self.client.wait(id)['StatusCode']
862864
assert exitcode == 0
863865

864866
assert logs == (snippet + '\n').encode(encoding='ascii')
@@ -871,7 +873,7 @@ def test_logs_with_dict_instead_of_id(self):
871873
id = container['Id']
872874
self.tmp_containers.append(id)
873875
self.client.start(id)
874-
exitcode = self.client.wait(id)
876+
exitcode = self.client.wait(id)['StatusCode']
875877
assert exitcode == 0
876878
logs = self.client.logs(container)
877879
assert logs == (snippet + '\n').encode(encoding='ascii')
@@ -884,7 +886,7 @@ def test_logs_with_tail_0(self):
884886
id = container['Id']
885887
self.tmp_containers.append(id)
886888
self.client.start(id)
887-
exitcode = self.client.wait(id)
889+
exitcode = self.client.wait(id)['StatusCode']
888890
assert exitcode == 0
889891
logs = self.client.logs(id, tail=0)
890892
assert logs == ''.encode(encoding='ascii')
@@ -898,7 +900,7 @@ def test_logs_with_until(self):
898900

899901
self.tmp_containers.append(container)
900902
self.client.start(container)
901-
exitcode = self.client.wait(container)
903+
exitcode = self.client.wait(container)['StatusCode']
902904
assert exitcode == 0
903905
logs_until_1 = self.client.logs(container, until=1)
904906
assert logs_until_1 == b''
@@ -912,7 +914,7 @@ def test_diff(self):
912914
id = container['Id']
913915
self.client.start(id)
914916
self.tmp_containers.append(id)
915-
exitcode = self.client.wait(id)
917+
exitcode = self.client.wait(id)['StatusCode']
916918
assert exitcode == 0
917919
diff = self.client.diff(id)
918920
test_diff = [x for x in diff if x.get('Path', None) == '/test']
@@ -925,7 +927,7 @@ def test_diff_with_dict_instead_of_id(self):
925927
id = container['Id']
926928
self.client.start(id)
927929
self.tmp_containers.append(id)
928-
exitcode = self.client.wait(id)
930+
exitcode = self.client.wait(id)['StatusCode']
929931
assert exitcode == 0
930932
diff = self.client.diff(container)
931933
test_diff = [x for x in diff if x.get('Path', None) == '/test']
@@ -997,7 +999,7 @@ def test_kill_with_signal(self):
997999
self.client.kill(
9981000
id, signal=signal.SIGKILL if not IS_WINDOWS_PLATFORM else 9
9991001
)
1000-
exitcode = self.client.wait(id)
1002+
exitcode = self.client.wait(id)['StatusCode']
10011003
assert exitcode != 0
10021004
container_info = self.client.inspect_container(id)
10031005
assert 'State' in container_info
@@ -1012,7 +1014,7 @@ def test_kill_with_signal_name(self):
10121014
self.client.start(id)
10131015
self.tmp_containers.append(id)
10141016
self.client.kill(id, signal='SIGKILL')
1015-
exitcode = self.client.wait(id)
1017+
exitcode = self.client.wait(id)['StatusCode']
10161018
assert exitcode != 0
10171019
container_info = self.client.inspect_container(id)
10181020
assert 'State' in container_info
@@ -1027,7 +1029,7 @@ def test_kill_with_signal_integer(self):
10271029
self.client.start(id)
10281030
self.tmp_containers.append(id)
10291031
self.client.kill(id, signal=9)
1030-
exitcode = self.client.wait(id)
1032+
exitcode = self.client.wait(id)['StatusCode']
10311033
assert exitcode != 0
10321034
container_info = self.client.inspect_container(id)
10331035
assert 'State' in container_info

tests/integration/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def run_container(self, *args, **kwargs):
9696
container = self.client.create_container(*args, **kwargs)
9797
self.tmp_containers.append(container)
9898
self.client.start(container)
99-
exitcode = self.client.wait(container)
99+
exitcode = self.client.wait(container)['StatusCode']
100100

101101
if exitcode != 0:
102102
output = self.client.logs(container)

tests/integration/models_containers_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,8 +309,8 @@ def test_wait(self):
309309
container = client.containers.run("alpine", "sh -c 'exit 0'",
310310
detach=True)
311311
self.tmp_containers.append(container.id)
312-
assert container.wait() == 0
312+
assert container.wait()['StatusCode'] == 0
313313
container = client.containers.run("alpine", "sh -c 'exit 1'",
314314
detach=True)
315315
self.tmp_containers.append(container.id)
316-
assert container.wait() == 1
316+
assert container.wait()['StatusCode'] == 1

tests/unit/fake_api_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def make_fake_api_client():
4646
'logs.return_value': [b'hello world\n'],
4747
'networks.return_value': fake_api.get_fake_network_list()[1],
4848
'start.return_value': None,
49-
'wait.return_value': 0,
49+
'wait.return_value': {'StatusCode': 0},
5050
})
5151
mock_client._version = docker.constants.DEFAULT_DOCKER_API_VERSION
5252
return mock_client

tests/unit/models_containers_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ def test_run_pull(self):
234234
def test_run_with_error(self):
235235
client = make_fake_client()
236236
client.api.logs.return_value = "some error"
237-
client.api.wait.return_value = 1
237+
client.api.wait.return_value = {'StatusCode': 1}
238238

239239
with pytest.raises(docker.errors.ContainerError) as cm:
240240
client.containers.run('alpine', 'echo hello world')
@@ -260,7 +260,7 @@ def test_run_remove(self):
260260
client.api.remove_container.assert_not_called()
261261

262262
client = make_fake_client()
263-
client.api.wait.return_value = 1
263+
client.api.wait.return_value = {'StatusCode': 1}
264264
with pytest.raises(docker.errors.ContainerError):
265265
client.containers.run("alpine")
266266
client.api.remove_container.assert_not_called()
@@ -270,7 +270,7 @@ def test_run_remove(self):
270270
client.api.remove_container.assert_called_with(FAKE_CONTAINER_ID)
271271

272272
client = make_fake_client()
273-
client.api.wait.return_value = 1
273+
client.api.wait.return_value = {'StatusCode': 1}
274274
with pytest.raises(docker.errors.ContainerError):
275275
client.containers.run("alpine", remove=True)
276276
client.api.remove_container.assert_called_with(FAKE_CONTAINER_ID)

0 commit comments

Comments
 (0)