Skip to content

Commit 94e9108

Browse files
committed
Add ignore_removed param to containers.list() to control whether to
raise or ignore NotFound Signed-off-by: Joffrey F <[email protected]>
1 parent eacf9f6 commit 94e9108

File tree

3 files changed

+30
-7
lines changed

3 files changed

+30
-7
lines changed

docker/models/containers.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -844,7 +844,7 @@ def get(self, container_id):
844844
return self.prepare_model(resp)
845845

846846
def list(self, all=False, before=None, filters=None, limit=-1, since=None,
847-
sparse=False):
847+
sparse=False, ignore_removed=False):
848848
"""
849849
List containers. Similar to the ``docker ps`` command.
850850
@@ -882,6 +882,10 @@ def list(self, all=False, before=None, filters=None, limit=-1, since=None,
882882
information, but guaranteed not to block. Use
883883
:py:meth:`Container.reload` on resulting objects to retrieve
884884
all attributes. Default: ``False``
885+
ignore_removed (bool): Ignore failures due to missing containers
886+
when attempting to inspect containers from the original list.
887+
Set to ``True`` if race conditions are likely. Has no effect
888+
if ``sparse=True``. Default: ``False``
885889
886890
Returns:
887891
(list of :py:class:`Container`)
@@ -902,7 +906,8 @@ def list(self, all=False, before=None, filters=None, limit=-1, since=None,
902906
containers.append(self.get(r['Id']))
903907
# a container may have been removed while iterating
904908
except NotFound:
905-
pass
909+
if not ignore_removed:
910+
raise
906911
return containers
907912

908913
def prune(self, filters=None):

tests/unit/fake_api_client.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,18 @@ def _mock_call(self, *args, **kwargs):
2020
return ret
2121

2222

23-
def make_fake_api_client():
23+
def make_fake_api_client(overrides=None):
2424
"""
2525
Returns non-complete fake APIClient.
2626
2727
This returns most of the default cases correctly, but most arguments that
2828
change behaviour will not work.
2929
"""
30+
31+
if overrides is None:
32+
overrides = {}
3033
api_client = docker.APIClient()
31-
mock_client = CopyReturnMagicMock(**{
34+
mock_attrs = {
3235
'build.return_value': fake_api.FAKE_IMAGE_ID,
3336
'commit.return_value': fake_api.post_fake_commit()[1],
3437
'containers.return_value': fake_api.get_fake_containers()[1],
@@ -47,15 +50,18 @@ def make_fake_api_client():
4750
'networks.return_value': fake_api.get_fake_network_list()[1],
4851
'start.return_value': None,
4952
'wait.return_value': {'StatusCode': 0},
50-
})
53+
}
54+
mock_attrs.update(overrides)
55+
mock_client = CopyReturnMagicMock(**mock_attrs)
56+
5157
mock_client._version = docker.constants.DEFAULT_DOCKER_API_VERSION
5258
return mock_client
5359

5460

55-
def make_fake_client():
61+
def make_fake_client(overrides=None):
5662
"""
5763
Returns a Client with a fake APIClient.
5864
"""
5965
client = docker.DockerClient()
60-
client.api = make_fake_api_client()
66+
client.api = make_fake_api_client(overrides)
6167
return client

tests/unit/models_containers_test.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,18 @@ def test_list(self):
359359
assert isinstance(containers[0], Container)
360360
assert containers[0].id == FAKE_CONTAINER_ID
361361

362+
def test_list_ignore_removed(self):
363+
def side_effect(*args, **kwargs):
364+
raise docker.errors.NotFound('Container not found')
365+
client = make_fake_client({
366+
'inspect_container.side_effect': side_effect
367+
})
368+
369+
with pytest.raises(docker.errors.NotFound):
370+
client.containers.list(all=True, ignore_removed=False)
371+
372+
assert client.containers.list(all=True, ignore_removed=True) == []
373+
362374

363375
class ContainerTest(unittest.TestCase):
364376
def test_name(self):

0 commit comments

Comments
 (0)