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

Add --pull option to build command #3074

Merged
merged 1 commit into from
Jun 18, 2024
Merged

Conversation

sondavidb
Copy link
Contributor

@sondavidb sondavidb commented Jun 7, 2024

Fixes #3073

docker build initially had a --pull command that forced remote image lookup when building an image. This has been changed when docker switched to buildkit to be default behavior, with an option to not check for updates if the image is already cached.

Forcing nerdctl build to use local images may be desirable for a few edge cases, so I've implemented a solution via a --pull flag in nerdctl build that can be set to false to enable this behavior, and true to always pull from remote. Without it, it will use the buildkit default.

There's a caveat here, which is that buildkit must be set up to use the same namespace as the locally cached image, which the user must set up in their buildkit config file.

Tested in a similar workflow as the integration test:

  1. Have a Dockerfile with just FROM ubuntu:latest
  2. Pull an older image tag (for me, I chose ubuntu:18.04) into your buildkit namespace (default should be buildkit)
  3. Tag it to latest version
  4. nerdctl build --pull false .
  5. Check image sha in output, it should be the same as the one locally cached
  6. nerdctl build --pull true .
  7. Check image sha in output, it should be a different one and should match the same as latest tag.

@sondavidb sondavidb force-pushed the add-pull-build branch 5 times, most recently from 348bfb7 to 0613eac Compare June 7, 2024 23:48
@sondavidb
Copy link
Contributor Author

Does buildkit output to stderr? Integration tests were failing with AssertOutContains and passed with AssertErrContains, but it seems strange that buildkit is outputting to stdout instead of stderr. Makes me worried that I did something wrong.

@Zheaoli
Copy link
Member

Zheaoli commented Jun 8, 2024

FYI docker/buildx#802

func TestBuildWithPull(t *testing.T) {
testutil.RequiresBuild(t)

oldImage := "ubuntu:18.04"
Copy link
Member

Choose a reason for hiding this comment

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

Any reason to use this very old version of Ubuntu?

Copy link
Contributor Author

@sondavidb sondavidb Jun 10, 2024

Choose a reason for hiding this comment

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

Just for testing purposes. The idea is to pull an old version of ubuntu, tag it as latest, and see if --pull=false uses local image while --pull=true uses the remote image (latest vesion).

As we aren't actually running this built image, this doesn't pose any security risk should any vulnerabilities be found.

Copy link
Member

Choose a reason for hiding this comment

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

Can we just use the mirror registry, with updating the tag with another image before checking --pull behaviror?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense, I switched to using much slimmer images as well so this test will now run a little bit faster

@sondavidb sondavidb force-pushed the add-pull-build branch 3 times, most recently from 4d44b73 to e3e33bb Compare June 10, 2024 23:19
@sondavidb
Copy link
Contributor Author

Last force-push revamped the integration test, so it should work properly. IMO it's a little bit ugly, since we're using os.Exec() to write directly to the config, but it's the only way I could think of approaching this, as buildctl doesn't support anything similar to a --config or a way to force the containerd worker instead of the OCI worker.

@sondavidb sondavidb force-pushed the add-pull-build branch 2 times, most recently from c5f5be4 to 98de079 Compare June 11, 2024 00:07
@AkihiroSuda AkihiroSuda requested a review from ktock June 14, 2024 02:08
Copy link
Member

@ktock ktock left a comment

Choose a reason for hiding this comment

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

See comments

@@ -51,6 +51,7 @@ If Dockerfile is not present and -f is not specified, it will look for Container
buildCommand.Flags().StringP("output", "o", "", "Output destination (format: type=local,dest=path)")
buildCommand.Flags().String("progress", "auto", "Set type of progress output (auto, plain, tty). Use plain to show container output")
buildCommand.Flags().String("provenance", "", "Shorthand for \"--attest=type=provenance\"")
buildCommand.Flags().String("pull", "", "On true, always attempt to pull latest image version from remote. Default uses buildkit's default.")
Copy link
Member

Choose a reason for hiding this comment

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

Can we make it a bool flag and just check if it's set when parsing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is this possible? From my understanding, the bool flag can only be true or false, and if none are provided then it will just set a default value.

Once parsed from a string, though, I can store it into a *bool instead of a string.

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is perfect, thanks. Just pushed a new set of changes.

func TestBuildWithPull(t *testing.T) {
testutil.RequiresBuild(t)

oldImage := "ubuntu:18.04"
Copy link
Member

Choose a reason for hiding this comment

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

Can we just use the mirror registry, with updating the tag with another image before checking --pull behaviror?

Comment on lines 72 to 74
// Pull determines if we should attempt to pull the latest image from remote.
// "true" will pull from remote while "false" will always use locally cached image
Pull string
Copy link
Member

Choose a reason for hiding this comment

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

Can we just make it *bool if we only take true/false/default ?

@sondavidb sondavidb force-pushed the add-pull-build branch 2 times, most recently from 4741cec to 5744262 Compare June 14, 2024 18:26
@sondavidb
Copy link
Contributor Author

sondavidb commented Jun 14, 2024

Had to move the test to builder_linux_test.go to make use of testutil. It probably makes more logical sense there, anyway, since the directory modified with the test is linux-specific.

@AkihiroSuda AkihiroSuda added this to the v2.0.0 milestone Jun 16, 2024
@AkihiroSuda AkihiroSuda requested a review from ktock June 17, 2024 09:34
@@ -51,6 +51,7 @@ If Dockerfile is not present and -f is not specified, it will look for Container
buildCommand.Flags().StringP("output", "o", "", "Output destination (format: type=local,dest=path)")
buildCommand.Flags().String("progress", "auto", "Set type of progress output (auto, plain, tty). Use plain to show container output")
buildCommand.Flags().String("provenance", "", "Shorthand for \"--attest=type=provenance\"")
buildCommand.Flags().Bool("pull", true, "On true, always attempt to pull latest image version from remote. Default uses buildkit's default.")
Copy link
Member

Choose a reason for hiding this comment

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

Default value should be false.

name string
pull bool
}{
{
Copy link
Member

Choose a reason for hiding this comment

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

Can you add a test case for the default behaviour? (i.e. not specifying --pull)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Signed-off-by: David Son <davbson@amazon.com>
Copy link
Member

@ktock ktock left a comment

Choose a reason for hiding this comment

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

Thanks

@ktock ktock merged commit 5a0558c into containerd:main Jun 18, 2024
22 checks passed
@sondavidb sondavidb deleted the add-pull-build branch June 18, 2024 20:09
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.

Allow option to use locally cached images when building images
4 participants