-
Notifications
You must be signed in to change notification settings - Fork 5.3k
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
introduce pull --policy flag to only pull images not present in cache #10981
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,6 +38,7 @@ | |
includeDeps bool | ||
ignorePullFailures bool | ||
noBuildable bool | ||
policy string | ||
} | ||
|
||
func pullCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command { | ||
|
@@ -67,20 +68,39 @@ | |
flags.MarkHidden("no-parallel") //nolint:errcheck | ||
cmd.Flags().BoolVar(&opts.ignorePullFailures, "ignore-pull-failures", false, "Pull what it can and ignores images with pull failures.") | ||
cmd.Flags().BoolVar(&opts.noBuildable, "ignore-buildable", false, "Ignore images that can be built.") | ||
cmd.Flags().StringVar(&opts.policy, "policy", "", `Apply pull policy ("missing"|"always").`) | ||
return cmd | ||
} | ||
|
||
func (opts pullOptions) apply(project *types.Project, services []string) error { | ||
if !opts.includeDeps { | ||
err := project.ForServices(services, types.IgnoreDependencies) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
if opts.policy != "" { | ||
for i, service := range project.Services { | ||
if service.Image == "" { | ||
continue | ||
} | ||
service.PullPolicy = opts.policy | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should ignore services that either have e.g. imagine this project services:
explicit-build:
image: registry.example.com/myservice
pull_policy: build
build: .
no-image:
build: .
nginx:
image: nginx Without args:
With
So it is properly skipping the one without There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree about service without an |
||
project.Services[i] = service | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func runPull(ctx context.Context, dockerCli command.Cli, backend api.Service, opts pullOptions, services []string) error { | ||
project, err := opts.ToProject(dockerCli, services) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if !opts.includeDeps { | ||
err := project.ForServices(services, types.IgnoreDependencies) | ||
if err != nil { | ||
return err | ||
} | ||
err = opts.apply(project, services) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return backend.Pull(ctx, project, api.PullOptions{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
Copyright 2023 Docker Compose CLI authors | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package compose | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/compose-spec/compose-go/types" | ||
"gotest.tools/v3/assert" | ||
) | ||
|
||
func TestApplyPullOptions(t *testing.T) { | ||
project := &types.Project{ | ||
Services: []types.ServiceConfig{ | ||
{ | ||
Name: "must-build", | ||
// No image, local build only | ||
Build: &types.BuildConfig{ | ||
Context: ".", | ||
}, | ||
}, | ||
{ | ||
Name: "has-build", | ||
Image: "registry.example.com/myservice", | ||
Build: &types.BuildConfig{ | ||
Context: ".", | ||
}, | ||
}, | ||
{ | ||
Name: "must-pull", | ||
Image: "registry.example.com/another-service", | ||
}, | ||
}, | ||
} | ||
err := pullOptions{ | ||
policy: types.PullPolicyMissing, | ||
}.apply(project, nil) | ||
assert.NilError(t, err) | ||
|
||
assert.Equal(t, project.Services[0].PullPolicy, "") // still default | ||
assert.Equal(t, project.Services[1].PullPolicy, types.PullPolicyMissing) | ||
assert.Equal(t, project.Services[2].PullPolicy, types.PullPolicyMissing) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -101,8 +101,8 @@ func upCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *c | |
flags := upCmd.Flags() | ||
flags.BoolVarP(&up.Detach, "detach", "d", false, "Detached mode: Run containers in the background") | ||
flags.BoolVar(&create.Build, "build", false, "Build images before starting containers.") | ||
flags.BoolVar(&create.noBuild, "no-build", false, "Don't build an image, even if it's missing.") | ||
flags.StringVar(&create.Pull, "pull", "missing", `Pull image before running ("always"|"missing"|"never")`) | ||
flags.BoolVar(&create.noBuild, "no-build", false, "Don't build an image, even if it's policy.") | ||
flags.StringVar(&create.Pull, "pull", "policy", `Pull image before running ("always"|"policy"|"never")`) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm...this (also) interferes with e.g. for my same example from before, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that's not the expected behavior. When compose file has both There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should look at that by the way, because if
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
flags.BoolVar(&create.removeOrphans, "remove-orphans", false, "Remove containers for services not defined in the Compose file.") | ||
flags.StringArrayVar(&create.scale, "scale", []string{}, "Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if present.") | ||
flags.BoolVar(&up.noColor, "no-color", false, "Produce monochrome output.") | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have these args/descriptions across several commands, and I think we need to improve the copy here, especially since we're making changes, as they're pretty vague and unclear as-is.
cc @aevesdocker
My understanding of desired behaviors:
--build
: Re-build images for all services being launched that have abuild
section. Images withpull_policy: build
are always re-built unless--no-build
is specified.--no-build
: Don't build ANY images, which might mean the project can't start if local versions are not already available in the engine.--policy
always
build
section, fetch the latest base image (FROM
), similar todocker build --pull .
build
section, fetch theimage
even if it's already present locally (e.g. useful for:latest
)never
build
section, no-op (AFAIK there's no builder option to say "don't automatically pull missing base images" nor would it make much sense)build
section, don't pull theimage
even if it doesn't exist in the engine, which might mean the project can't launch.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, fetch the configured tagged image, which is the result of the build. We don't parse the Dockerfile to know about the base image. No relation with
docker build --pull