Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions docker/api/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -1207,8 +1207,8 @@ def wait(self, container, timeout=None, condition=None):
or ``removed``

Returns:
(int or dict): The exit code of the container. Returns the full API
response if no ``StatusCode`` field is included.
(dict): The API's response as a Python dictionary, including
the container's exit code under the ``StatusCode`` attribute.

Raises:
:py:class:`requests.exceptions.ReadTimeout`
Expand All @@ -1226,8 +1226,4 @@ def wait(self, container, timeout=None, condition=None):
params['condition'] = condition

res = self._post(url, timeout=timeout, params=params)
self._raise_for_status(res)
json_ = res.json()
if 'StatusCode' in json_:
return json_['StatusCode']
return json_
return self._result(res, True)
6 changes: 3 additions & 3 deletions docker/models/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,8 +448,8 @@ def wait(self, **kwargs):
or ``removed``

Returns:
(int): The exit code of the container. Returns ``-1`` if the API
responds without a ``StatusCode`` attribute.
(dict): The API's response as a Python dictionary, including
the container's exit code under the ``StatusCode`` attribute.

Raises:
:py:class:`requests.exceptions.ReadTimeout`
Expand Down Expand Up @@ -758,7 +758,7 @@ def run(self, image, command=None, stdout=True, stderr=False,
stdout=stdout, stderr=stderr, stream=True, follow=True
)

exit_status = container.wait()
exit_status = container.wait()['StatusCode']
if exit_status != 0:
out = None
if not kwargs.get('auto_remove'):
Expand Down
2 changes: 1 addition & 1 deletion docker/version.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
version = "2.8.0-dev"
version = "3.0.0"
version_info = tuple([int(d) for d in version.split("-")[0].split(".")])
41 changes: 41 additions & 0 deletions docs/change-log.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,47 @@
Change log
==========

3.0.0
-----

[List of PRs / issues for this release](https://github.com/docker/docker-py/milestone/39?closed=1)

### Breaking changes

* Support for API version < 1.21 has been removed.
* The following methods have been removed:
* `APIClient.copy` has been removed. Users should use `APIClient.get_archive`
instead.
* `APIClient.insert` has been removed. Users may use `APIClient.put_archive`
combined with `APIClient.commit` to replicate the method's behavior.
* `utils.ping_registry` and `utils.ping` have been removed.
* The following parameters have been removed:
* `stream` in `APIClient.build`
* `cpu_shares`, `cpuset`, `dns`, `mem_limit`, `memswap_limit`,
`volume_driver`, `volumes_from` in `APIClient.create_container`. These are
all replaced by their equivalent in `create_host_config`
* `insecure_registry` in `APIClient.login`, `APIClient.pull`,
`APIClient.push`, `DockerClient.images.push` and `DockerClient.images.pull`
* `viz` in `APIClient.images`
* The following parameters have been renamed:
* `endpoint_config` in `APIClient.create_service` and
`APIClient.update_service` is now `endpoint_spec`
* `name` in `DockerClient.images.pull` is now `repository`
* The return value for the following methods has changed:
* `APIClient.wait` and `Container.wait` now return a ``dict`` representing
the API's response instead of returning the status code directly.
* `DockerClient.images.load` now returns a list of `Image` objects that have
for the images that were loaded, instead of a log stream.
* `Container.exec_run` now returns a tuple of (exit_code, output) instead of
just the output.
* `DockerClient.images.build` now returns a tuple of (image, build_logs)
instead of just the image object.
* `APIClient.export`, `APIClient.get_archive` and `APIClient.get_image` now
return generators streaming the raw binary data from the server's response.
* When no tag is provided, `DockerClient.images.pull` now returns a list of
`Image`s associated to the pulled repository instead of just the `latest`
image.

2.7.0
-----

Expand Down
36 changes: 19 additions & 17 deletions tests/integration/api_container_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def test_create_with_links(self):
container3_id = res2['Id']
self.tmp_containers.append(container3_id)
self.client.start(container3_id)
assert self.client.wait(container3_id) == 0
assert self.client.wait(container3_id)['StatusCode'] == 0

logs = self.client.logs(container3_id)
if six.PY3:
Expand Down Expand Up @@ -169,7 +169,7 @@ def create_container_readonly_fs(self):
assert 'Id' in ctnr
self.tmp_containers.append(ctnr['Id'])
self.client.start(ctnr)
res = self.client.wait(ctnr)
res = self.client.wait(ctnr)['StatusCode']
assert res != 0

def create_container_with_name(self):
Expand Down Expand Up @@ -771,7 +771,7 @@ def test_run_shlex_commands(self):
id = container['Id']
self.client.start(id)
self.tmp_containers.append(id)
exitcode = self.client.wait(id)
exitcode = self.client.wait(id)['StatusCode']
assert exitcode == 0, cmd


Expand All @@ -781,7 +781,7 @@ def test_wait(self):
id = res['Id']
self.tmp_containers.append(id)
self.client.start(id)
exitcode = self.client.wait(id)
exitcode = self.client.wait(id)['StatusCode']
assert exitcode == 0
inspect = self.client.inspect_container(id)
assert 'Running' in inspect['State']
Expand All @@ -794,7 +794,7 @@ def test_wait_with_dict_instead_of_id(self):
id = res['Id']
self.tmp_containers.append(id)
self.client.start(res)
exitcode = self.client.wait(res)
exitcode = self.client.wait(res)['StatusCode']
assert exitcode == 0
inspect = self.client.inspect_container(res)
assert 'Running' in inspect['State']
Expand All @@ -815,7 +815,9 @@ def test_wait_with_condition(self):
)
self.tmp_containers.append(ctnr)
self.client.start(ctnr)
assert self.client.wait(ctnr, condition='removed', timeout=5) == 0
assert self.client.wait(
ctnr, condition='removed', timeout=5
)['StatusCode'] == 0


class LogsTest(BaseAPIIntegrationTest):
Expand All @@ -827,7 +829,7 @@ def test_logs(self):
id = container['Id']
self.tmp_containers.append(id)
self.client.start(id)
exitcode = self.client.wait(id)
exitcode = self.client.wait(id)['StatusCode']
assert exitcode == 0
logs = self.client.logs(id)
assert logs == (snippet + '\n').encode(encoding='ascii')
Expand All @@ -841,7 +843,7 @@ def test_logs_tail_option(self):
id = container['Id']
self.tmp_containers.append(id)
self.client.start(id)
exitcode = self.client.wait(id)
exitcode = self.client.wait(id)['StatusCode']
assert exitcode == 0
logs = self.client.logs(id, tail=1)
assert logs == 'Line2\n'.encode(encoding='ascii')
Expand All @@ -858,7 +860,7 @@ def test_logs_streaming_and_follow(self):
for chunk in self.client.logs(id, stream=True, follow=True):
logs += chunk

exitcode = self.client.wait(id)
exitcode = self.client.wait(id)['StatusCode']
assert exitcode == 0

assert logs == (snippet + '\n').encode(encoding='ascii')
Expand All @@ -871,7 +873,7 @@ def test_logs_with_dict_instead_of_id(self):
id = container['Id']
self.tmp_containers.append(id)
self.client.start(id)
exitcode = self.client.wait(id)
exitcode = self.client.wait(id)['StatusCode']
assert exitcode == 0
logs = self.client.logs(container)
assert logs == (snippet + '\n').encode(encoding='ascii')
Expand All @@ -884,7 +886,7 @@ def test_logs_with_tail_0(self):
id = container['Id']
self.tmp_containers.append(id)
self.client.start(id)
exitcode = self.client.wait(id)
exitcode = self.client.wait(id)['StatusCode']
assert exitcode == 0
logs = self.client.logs(id, tail=0)
assert logs == ''.encode(encoding='ascii')
Expand All @@ -898,7 +900,7 @@ def test_logs_with_until(self):

self.tmp_containers.append(container)
self.client.start(container)
exitcode = self.client.wait(container)
exitcode = self.client.wait(container)['StatusCode']
assert exitcode == 0
logs_until_1 = self.client.logs(container, until=1)
assert logs_until_1 == b''
Expand All @@ -912,7 +914,7 @@ def test_diff(self):
id = container['Id']
self.client.start(id)
self.tmp_containers.append(id)
exitcode = self.client.wait(id)
exitcode = self.client.wait(id)['StatusCode']
assert exitcode == 0
diff = self.client.diff(id)
test_diff = [x for x in diff if x.get('Path', None) == '/test']
Expand All @@ -925,7 +927,7 @@ def test_diff_with_dict_instead_of_id(self):
id = container['Id']
self.client.start(id)
self.tmp_containers.append(id)
exitcode = self.client.wait(id)
exitcode = self.client.wait(id)['StatusCode']
assert exitcode == 0
diff = self.client.diff(container)
test_diff = [x for x in diff if x.get('Path', None) == '/test']
Expand Down Expand Up @@ -997,7 +999,7 @@ def test_kill_with_signal(self):
self.client.kill(
id, signal=signal.SIGKILL if not IS_WINDOWS_PLATFORM else 9
)
exitcode = self.client.wait(id)
exitcode = self.client.wait(id)['StatusCode']
assert exitcode != 0
container_info = self.client.inspect_container(id)
assert 'State' in container_info
Expand All @@ -1012,7 +1014,7 @@ def test_kill_with_signal_name(self):
self.client.start(id)
self.tmp_containers.append(id)
self.client.kill(id, signal='SIGKILL')
exitcode = self.client.wait(id)
exitcode = self.client.wait(id)['StatusCode']
assert exitcode != 0
container_info = self.client.inspect_container(id)
assert 'State' in container_info
Expand All @@ -1027,7 +1029,7 @@ def test_kill_with_signal_integer(self):
self.client.start(id)
self.tmp_containers.append(id)
self.client.kill(id, signal=9)
exitcode = self.client.wait(id)
exitcode = self.client.wait(id)['StatusCode']
assert exitcode != 0
container_info = self.client.inspect_container(id)
assert 'State' in container_info
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def run_container(self, *args, **kwargs):
container = self.client.create_container(*args, **kwargs)
self.tmp_containers.append(container)
self.client.start(container)
exitcode = self.client.wait(container)
exitcode = self.client.wait(container)['StatusCode']

if exitcode != 0:
output = self.client.logs(container)
Expand Down
4 changes: 2 additions & 2 deletions tests/integration/models_containers_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,8 +309,8 @@ def test_wait(self):
container = client.containers.run("alpine", "sh -c 'exit 0'",
detach=True)
self.tmp_containers.append(container.id)
assert container.wait() == 0
assert container.wait()['StatusCode'] == 0
container = client.containers.run("alpine", "sh -c 'exit 1'",
detach=True)
self.tmp_containers.append(container.id)
assert container.wait() == 1
assert container.wait()['StatusCode'] == 1
2 changes: 1 addition & 1 deletion tests/unit/fake_api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def make_fake_api_client():
'logs.return_value': [b'hello world\n'],
'networks.return_value': fake_api.get_fake_network_list()[1],
'start.return_value': None,
'wait.return_value': 0,
'wait.return_value': {'StatusCode': 0},
})
mock_client._version = docker.constants.DEFAULT_DOCKER_API_VERSION
return mock_client
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/models_containers_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ def test_run_pull(self):
def test_run_with_error(self):
client = make_fake_client()
client.api.logs.return_value = "some error"
client.api.wait.return_value = 1
client.api.wait.return_value = {'StatusCode': 1}

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

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

client = make_fake_client()
client.api.wait.return_value = 1
client.api.wait.return_value = {'StatusCode': 1}
with pytest.raises(docker.errors.ContainerError):
client.containers.run("alpine", remove=True)
client.api.remove_container.assert_called_with(FAKE_CONTAINER_ID)
Expand Down