summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoffrey F <joffrey@docker.com>2018-04-25 16:55:40 -0700
committerJoffrey F <f.joffrey@gmail.com>2018-04-25 17:55:16 -0700
commit94e9108441936b4cd8afa66e91397baee29e6cfd (patch)
treed355b3463c33126ee23091cc2b2ec3d94d43c579
parenteacf9f6d08537be2fad6549af4b050fdd65fbef0 (diff)
downloaddocker-py-94e9108441936b4cd8afa66e91397baee29e6cfd.tar.gz
Add ignore_removed param to containers.list() to control whether to
raise or ignore NotFound Signed-off-by: Joffrey F <joffrey@docker.com>
-rw-r--r--docker/models/containers.py9
-rw-r--r--tests/unit/fake_api_client.py16
-rw-r--r--tests/unit/models_containers_test.py12
3 files changed, 30 insertions, 7 deletions
diff --git a/docker/models/containers.py b/docker/models/containers.py
index 789fa93..b33a718 100644
--- a/docker/models/containers.py
+++ b/docker/models/containers.py
@@ -844,7 +844,7 @@ class ContainerCollection(Collection):
return self.prepare_model(resp)
def list(self, all=False, before=None, filters=None, limit=-1, since=None,
- sparse=False):
+ sparse=False, ignore_removed=False):
"""
List containers. Similar to the ``docker ps`` command.
@@ -882,6 +882,10 @@ class ContainerCollection(Collection):
information, but guaranteed not to block. Use
:py:meth:`Container.reload` on resulting objects to retrieve
all attributes. Default: ``False``
+ ignore_removed (bool): Ignore failures due to missing containers
+ when attempting to inspect containers from the original list.
+ Set to ``True`` if race conditions are likely. Has no effect
+ if ``sparse=True``. Default: ``False``
Returns:
(list of :py:class:`Container`)
@@ -902,7 +906,8 @@ class ContainerCollection(Collection):
containers.append(self.get(r['Id']))
# a container may have been removed while iterating
except NotFound:
- pass
+ if not ignore_removed:
+ raise
return containers
def prune(self, filters=None):
diff --git a/tests/unit/fake_api_client.py b/tests/unit/fake_api_client.py
index 15b60ea..2147bfd 100644
--- a/tests/unit/fake_api_client.py
+++ b/tests/unit/fake_api_client.py
@@ -20,15 +20,18 @@ class CopyReturnMagicMock(mock.MagicMock):
return ret
-def make_fake_api_client():
+def make_fake_api_client(overrides=None):
"""
Returns non-complete fake APIClient.
This returns most of the default cases correctly, but most arguments that
change behaviour will not work.
"""
+
+ if overrides is None:
+ overrides = {}
api_client = docker.APIClient()
- mock_client = CopyReturnMagicMock(**{
+ mock_attrs = {
'build.return_value': fake_api.FAKE_IMAGE_ID,
'commit.return_value': fake_api.post_fake_commit()[1],
'containers.return_value': fake_api.get_fake_containers()[1],
@@ -47,15 +50,18 @@ def make_fake_api_client():
'networks.return_value': fake_api.get_fake_network_list()[1],
'start.return_value': None,
'wait.return_value': {'StatusCode': 0},
- })
+ }
+ mock_attrs.update(overrides)
+ mock_client = CopyReturnMagicMock(**mock_attrs)
+
mock_client._version = docker.constants.DEFAULT_DOCKER_API_VERSION
return mock_client
-def make_fake_client():
+def make_fake_client(overrides=None):
"""
Returns a Client with a fake APIClient.
"""
client = docker.DockerClient()
- client.api = make_fake_api_client()
+ client.api = make_fake_api_client(overrides)
return client
diff --git a/tests/unit/models_containers_test.py b/tests/unit/models_containers_test.py
index 2b0b499..48a5288 100644
--- a/tests/unit/models_containers_test.py
+++ b/tests/unit/models_containers_test.py
@@ -359,6 +359,18 @@ class ContainerCollectionTest(unittest.TestCase):
assert isinstance(containers[0], Container)
assert containers[0].id == FAKE_CONTAINER_ID
+ def test_list_ignore_removed(self):
+ def side_effect(*args, **kwargs):
+ raise docker.errors.NotFound('Container not found')
+ client = make_fake_client({
+ 'inspect_container.side_effect': side_effect
+ })
+
+ with pytest.raises(docker.errors.NotFound):
+ client.containers.list(all=True, ignore_removed=False)
+
+ assert client.containers.list(all=True, ignore_removed=True) == []
+
class ContainerTest(unittest.TestCase):
def test_name(self):