diff options
author | Joffrey F <joffrey@docker.com> | 2018-04-25 16:55:40 -0700 |
---|---|---|
committer | Joffrey F <f.joffrey@gmail.com> | 2018-04-25 17:55:16 -0700 |
commit | 94e9108441936b4cd8afa66e91397baee29e6cfd (patch) | |
tree | d355b3463c33126ee23091cc2b2ec3d94d43c579 | |
parent | eacf9f6d08537be2fad6549af4b050fdd65fbef0 (diff) | |
download | docker-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.py | 9 | ||||
-rw-r--r-- | tests/unit/fake_api_client.py | 16 | ||||
-rw-r--r-- | tests/unit/models_containers_test.py | 12 |
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): |