diff --git a/aiidalab_launch/__main__.py b/aiidalab_launch/__main__.py index a41fe6d..bebe98f 100644 --- a/aiidalab_launch/__main__.py +++ b/aiidalab_launch/__main__.py @@ -87,6 +87,29 @@ def callback(ctx, param, value): # noqa: U100 )(cmd) +def image_is_latest(docker_client, image: str): + """Check if the local image has the same digest as the image + on remote registry. + """ + try: + local_image = docker_client.images.get(image) + except docker.errors.ImageNotFound: + return False + + try: + remote_image = docker_client.images.get_registry_data(image) + except docker.errors.APIError: + return False + + # There is no need to check creation date of the image, since the once + # there is a new image with the same tag, the id will be different. + # We can not use image id, see https://windsock.io/explaining-docker-image-ids/ + local_digest = local_image.attrs.get("RepoDigests")[0].split("@")[-1] + remote_digest = remote_image.attrs.get("Descriptor", {}).get("digest") + + return local_digest == remote_digest + + @click.group(context_settings={"help_option_names": ["-h", "--help"]}) @click.option( "-v", @@ -350,6 +373,13 @@ async def _async_start( # use local image msg = f"Using local image '{profile.image}'." + # check if local image is outdated and pull latest version if so + if not image_is_latest(instance.client, profile.image): + click.secho( + "Warning! Local image is outdated, please run with --pull to update.", + fg="yellow", + ) + if instance.image is None: raise click.ClickException( f"Unable to find image '{profile.image}'. "