From d81a487b993e0f5ef3e09d8d2a3fc5bc0508d268 Mon Sep 17 00:00:00 2001 From: Ralf Grubenmann Date: Tue, 17 Jan 2023 09:27:32 +0100 Subject: [PATCH] fix(cli): check for image in registry before pulling and improve error messages (#3265) Co-authored-by: Ralf Grubenmann --- renku/core/session/docker.py | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/renku/core/session/docker.py b/renku/core/session/docker.py index 93fcc1d589..70380c7d0d 100644 --- a/renku/core/session/docker.py +++ b/renku/core/session/docker.py @@ -22,6 +22,7 @@ from uuid import uuid4 import docker +from requests.exceptions import ReadTimeout from renku.core import errors from renku.core.config import get_value @@ -77,16 +78,22 @@ def build_image(self, image_descriptor: Path, image_name: str, config: Optional[ def find_image(self, image_name: str, config: Optional[Dict[str, Any]]) -> bool: """Find the given container image.""" - try: - self.docker_client().images.get(image_name) - except docker.errors.ImageNotFound: + with communication.busy(msg=f"Checking for image {image_name}"): try: - with communication.busy(msg=f"Pulling image from remote {image_name}"): - self.docker_client().images.pull(image_name) - except docker.errors.NotFound: - return False + self.docker_client().images.get(image_name) + except docker.errors.ImageNotFound: + try: + self.docker_client().images.get_registry_data(image_name) + except docker.errors.NotFound: + return False else: return True + + try: + with communication.busy(msg=f"Pulling image from remote {image_name}"): + self.docker_client().images.pull(image_name) + except docker.errors.NotFound: + return False else: return True @@ -208,8 +215,14 @@ def session_start( message = f"The session for '{image_name}' has been successfully started. It is available at:\n\t" message += "\n\t".join(jupyter_urls) return message - except (docker.errors.APIError, docker.errors.BuildError) as error: - raise errors.DockerError(str(error)) + except docker.errors.BuildError as error: + raise errors.DockerError("Couldn't build the image. See inner exception for details.") from error + except docker.errors.APIError as error: + raise errors.DockerError("Docker API returned an error. See inner exception for details.") from error + except ReadTimeout as error: + raise errors.DockerError( + "Couldn't reach the Docker API. Is the docker service running and up to date?" + ) from error def session_stop(self, project_name: str, session_name: Optional[str], stop_all: bool) -> bool: """Stops all or a given interactive session."""