Skip to content

Commit

Permalink
Check the image is outdated and pop warning to pull the latest
Browse files Browse the repository at this point in the history
  • Loading branch information
unkcpz committed Oct 3, 2023
1 parent 33c7a26 commit e658d11
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 2 deletions.
15 changes: 14 additions & 1 deletion aiidalab_launch/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,13 @@
from .core import LOGGER
from .instance import AiidaLabInstance
from .profile import DEFAULT_IMAGE, DEFAULT_PORT, Profile
from .util import confirm_with_value, get_latest_version, spinner, webbrowser_available
from .util import (
confirm_with_value,
get_latest_version,
image_is_latest,
spinner,
webbrowser_available,
)
from .version import __version__

MSG_MOUNT_POINT_CONFLICT = """Warning: There is at least one other running
Expand Down Expand Up @@ -350,6 +356,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}'. "
Expand Down
23 changes: 23 additions & 0 deletions aiidalab_launch/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,26 @@ def get_docker_env(container: docker.models.containers.Container, env_name: str)
except KeyError:
pass
raise KeyError(env_name)


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
14 changes: 13 additions & 1 deletion tests/test_util.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from time import time

import pytest
from packaging.version import parse

from aiidalab_launch.util import get_latest_version
from aiidalab_launch.util import get_latest_version, image_is_latest


def test_get_latest_version(mock_pypi_request):
Expand All @@ -13,3 +14,14 @@ def test_get_latest_version_timeout(mock_pypi_request_timeout):
start = time()
assert get_latest_version() is None
assert (time() - start) < 0.5


@pytest.mark.usefixtures("enable_docker_pull")
def test_image_is_latest(docker_client):
"""Test that the latest version is identified correctly."""
# download the alpine image for testing
image_name = "alpine:latest"
docker_client.images.pull(image_name)

# check that the image is identified as latest
assert image_is_latest(docker_client, image_name)

0 comments on commit e658d11

Please sign in to comment.