diff --git a/docker/models/containers.py b/docker/models/containers.py index 9c9e92c90..e22c0930e 100644 --- a/docker/models/containers.py +++ b/docker/models/containers.py @@ -894,7 +894,24 @@ def run(self, image, command=None, stdout=True, stderr=False, stdout=stdout, stderr=stderr, stream=True, follow=True ) - exit_status = container.wait()['StatusCode'] + if kwargs.get('auto_remove'): + wait_condition = 'removed' + else: + # the wait condition should theoretically be 'next-exit' (as is + # used by the cli), but it may have exited already if its run time + # was very short, which would cause the wait to hang. + # 'not-running' works in both cases. + wait_condition = 'not-running' + try: + exit_status = container.wait(condition=wait_condition)['StatusCode'] + except NotFound: + if wait_condition == 'removed': + # it has been already removed, which is why it was not found, + # so everything fine here. unfortunately, there is no way to + # have its real exit status, so assume success. + exit_status = 0 + else: + raise if exit_status != 0: out = None if not kwargs.get('auto_remove'): diff --git a/tests/unit/models_containers_test.py b/tests/unit/models_containers_test.py index 0e2ae341a..c5b38ef5c 100644 --- a/tests/unit/models_containers_test.py +++ b/tests/unit/models_containers_test.py @@ -27,7 +27,9 @@ def test_run(self): ) client.api.inspect_container.assert_called_with(FAKE_CONTAINER_ID) client.api.start.assert_called_with(FAKE_CONTAINER_ID) - client.api.wait.assert_called_with(FAKE_CONTAINER_ID) + client.api.wait.assert_called_with( + FAKE_CONTAINER_ID, condition='not-running' + ) client.api.logs.assert_called_with( FAKE_CONTAINER_ID, stderr=False, stdout=True, stream=True, follow=True