Add ignore_removed param to containers.list() to control whether to

raise or ignore NotFound

Signed-off-by: Joffrey F <joffrey@docker.com>
This commit is contained in:
Joffrey F 2018-04-25 16:55:40 -07:00 committed by Joffrey F
parent eacf9f6d08
commit 94e9108441
3 changed files with 30 additions and 7 deletions

View File

@ -844,7 +844,7 @@ class ContainerCollection(Collection):
return self.prepare_model(resp) return self.prepare_model(resp)
def list(self, all=False, before=None, filters=None, limit=-1, since=None, 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. List containers. Similar to the ``docker ps`` command.
@ -882,6 +882,10 @@ class ContainerCollection(Collection):
information, but guaranteed not to block. Use information, but guaranteed not to block. Use
:py:meth:`Container.reload` on resulting objects to retrieve :py:meth:`Container.reload` on resulting objects to retrieve
all attributes. Default: ``False`` 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: Returns:
(list of :py:class:`Container`) (list of :py:class:`Container`)
@ -902,7 +906,8 @@ class ContainerCollection(Collection):
containers.append(self.get(r['Id'])) containers.append(self.get(r['Id']))
# a container may have been removed while iterating # a container may have been removed while iterating
except NotFound: except NotFound:
pass if not ignore_removed:
raise
return containers return containers
def prune(self, filters=None): def prune(self, filters=None):

View File

@ -20,15 +20,18 @@ class CopyReturnMagicMock(mock.MagicMock):
return ret return ret
def make_fake_api_client(): def make_fake_api_client(overrides=None):
""" """
Returns non-complete fake APIClient. Returns non-complete fake APIClient.
This returns most of the default cases correctly, but most arguments that This returns most of the default cases correctly, but most arguments that
change behaviour will not work. change behaviour will not work.
""" """
if overrides is None:
overrides = {}
api_client = docker.APIClient() api_client = docker.APIClient()
mock_client = CopyReturnMagicMock(**{ mock_attrs = {
'build.return_value': fake_api.FAKE_IMAGE_ID, 'build.return_value': fake_api.FAKE_IMAGE_ID,
'commit.return_value': fake_api.post_fake_commit()[1], 'commit.return_value': fake_api.post_fake_commit()[1],
'containers.return_value': fake_api.get_fake_containers()[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], 'networks.return_value': fake_api.get_fake_network_list()[1],
'start.return_value': None, 'start.return_value': None,
'wait.return_value': {'StatusCode': 0}, 'wait.return_value': {'StatusCode': 0},
}) }
mock_attrs.update(overrides)
mock_client = CopyReturnMagicMock(**mock_attrs)
mock_client._version = docker.constants.DEFAULT_DOCKER_API_VERSION mock_client._version = docker.constants.DEFAULT_DOCKER_API_VERSION
return mock_client return mock_client
def make_fake_client(): def make_fake_client(overrides=None):
""" """
Returns a Client with a fake APIClient. Returns a Client with a fake APIClient.
""" """
client = docker.DockerClient() client = docker.DockerClient()
client.api = make_fake_api_client() client.api = make_fake_api_client(overrides)
return client return client

View File

@ -359,6 +359,18 @@ class ContainerCollectionTest(unittest.TestCase):
assert isinstance(containers[0], Container) assert isinstance(containers[0], Container)
assert containers[0].id == FAKE_CONTAINER_ID 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): class ContainerTest(unittest.TestCase):
def test_name(self): def test_name(self):