Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check the image is outdated and pop warning to pull the latest #193

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

unkcpz
Copy link
Member

@unkcpz unkcpz commented Oct 3, 2023

fixes #188

@unkcpz
Copy link
Member Author

unkcpz commented Oct 3, 2023

It is quite hard to test the feature added here since 1) don't know how to test the image_is_latest function which rely on the real image 2) don't know how to test the warning is properly raised in the start stage which are currently in the life cycle test.

I test it manually and works as I expected.

EDIT: the added util function is tested by checking with a light weight image.
EDIT: see the last commit where I tried to test this feature. But has to import the util as a module otherwise the function can not be overridden. Not sure this is proper.

@unkcpz unkcpz requested a review from danielhollas October 3, 2023 21:20
@codecov
Copy link

codecov bot commented Oct 3, 2023

Codecov Report

Attention: 4 lines in your changes are missing coverage. Please review.

Comparison is base (1eedb9d) 86.32% compared to head (5d3cf30) 86.11%.

❗ Current head 5d3cf30 differs from pull request most recent head 42f0867. Consider uploading reports for the commit 42f0867 to get more accurate results

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #193      +/-   ##
==========================================
- Coverage   86.32%   86.11%   -0.21%     
==========================================
  Files           9        9              
  Lines         914      929      +15     
==========================================
+ Hits          789      800      +11     
- Misses        125      129       +4     
Flag Coverage Δ
py-3.10 86.00% <73.33%> (-0.21%) ⬇️
py-3.11 86.00% <73.33%> (-0.21%) ⬇️
py-3.8 85.96% <73.33%> (-0.21%) ⬇️
py-3.9 86.06% <73.33%> (-0.21%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
aiidalab_launch/__main__.py 79.81% <100.00%> (+0.18%) ⬆️
aiidalab_launch/util.py 82.85% <66.66%> (-1.52%) ⬇️

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@unkcpz unkcpz force-pushed the fix/188/warn-when-new-image-avail branch from b884cd9 to e658d11 Compare October 3, 2023 21:34
Copy link
Contributor

@danielhollas danielhollas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, thanks for improving this and adding a test!

Just a couple of small suggestions.

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"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use something more lightweight, perhaps the hello-world image from Docker?

Also, it is not clear to me, is this image then automatically deleted in enable_docker_pull fixture?

Copy link
Member Author

@unkcpz unkcpz Oct 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

more lightweight, perhaps the hello-world image from Docker?

👍

is this image then automatically deleted in enable_docker_pull fixture?

No, I don't think so. This fixture is to guarantee the test will be skipped if it contains docker pull.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What a surprise, the hello-world is bigger than alpine. 😄

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh. But that seems to be only true for for windows (which does not exist for Alpine), for linux it is only a couple of kB, i.e. an order of magnitute smaller. So I would still prefer to switch to hello-world image, and mark this test as skipped if ran on windows (I don't think we support windows anyway, but just to ensure we do not end up downloading 100Mb in case anybody tried it).

Also since these tests rely on the network, I would prefer if they were marked as "slow".

image_name = "alpine:latest"
docker_client.images.pull(image_name)

# check that the image is identified as latest
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to also test the converse, i.e. pull some outdated version of the same image and check that it is identified as not latest. That should be possible right? (should be a separate test to keep it clean)

Copy link
Member Author

@unkcpz unkcpz Oct 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it can, by pulling the old image and retag it. See the new commit.

"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}'. "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please delete the line below. We now automatically try to download the image when we do not find it locally, so this advice is not helpful.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, I wasn't aware of it in #184, this conditional never be hit.

@unkcpz unkcpz force-pushed the fix/188/warn-when-new-image-avail branch from 1fabd9f to 42f0867 Compare October 6, 2023 08:27
@unkcpz unkcpz requested a review from danielhollas October 6, 2023 08:29
Copy link
Contributor

@danielhollas danielhollas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @unkcpz, I have a couple more comments. My biggest concern here is to not accidentaly delete all images on the machine. 😰

# 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")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the remote_digest ends up being None here? We should probably return true in that case, since that is likely a problem with the Dockerhub and we should not pull. (or it could indicate that the API changed)

# 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]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a little unhappy about the split()[-1] here since that does not seem very robust. But if there is not a better way of getting the digest than I guess it is fine.

@@ -57,6 +57,19 @@ def docker_client():
pytest.skip("docker not available")


@pytest.fixture(scope="function")
def remove_created_images(docker_client):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a little nervous here, how does this ensure that we do not wipe out all the images on the machine? Is that ensured by the docker_client fixture?

Even if it supposedly is, I would be much more comfortable if we filtered the image names somehow (e.g. the image name needs to contain test or some other unique string.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about this more, this approach is definitely not safe since, since other processes can create docker images in the meantime while the test is running. The logic here would delete these images.

Instead we could perhaps hard-code the name of the test image (`hello-world"), which should always be safe to delete.

result: Result = runner.invoke(
cli.cli, ["start", "--no-browser", "--no-pull", "--wait=300"]
)
assert "Warning!" in result.output.strip()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you get this assert be a more specific than just "Warning"? That is too generic.
Also please also check the exit code and that the container is up and has already been running, as done above?

@@ -260,6 +260,20 @@ def assert_status_down():
assert result.exit_code == 0
assert_status_up()

# test the warning message of image not the latest is not raised
assert "Warning!" not in result.output.strip()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, you could maybe have this assert earlier after the container is first started. Then you could move the monkeypatch above as well and avoid starting up the container for the third time.

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"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh. But that seems to be only true for for windows (which does not exist for Alpine), for linux it is only a couple of kB, i.e. an order of magnitute smaller. So I would still prefer to switch to hello-world image, and mark this test as skipped if ran on windows (I don't think we support windows anyway, but just to ensure we do not end up downloading 100Mb in case anybody tried it).

Also since these tests rely on the network, I would prefer if they were marked as "slow".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Notify user when new image is available
2 participants