summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/api/handlers/libpod/images_pull.go24
-rw-r--r--pkg/api/server/register_images.go4
-rw-r--r--pkg/bindings/images/pull.go10
-rw-r--r--pkg/bindings/images/types.go3
-rw-r--r--pkg/bindings/images/types_pull_options.go16
-rw-r--r--pkg/domain/infra/tunnel/images.go2
-rw-r--r--pkg/errorhandling/errorhandling.go9
-rw-r--r--pkg/specgen/generate/container.go3
-rw-r--r--pkg/specgen/generate/container_create.go3
9 files changed, 55 insertions, 19 deletions
diff --git a/pkg/api/handlers/libpod/images_pull.go b/pkg/api/handlers/libpod/images_pull.go
index e88b53a4b..04b415638 100644
--- a/pkg/api/handlers/libpod/images_pull.go
+++ b/pkg/api/handlers/libpod/images_pull.go
@@ -26,14 +26,16 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
- Reference string `schema:"reference"`
- OS string `schema:"OS"`
- Arch string `schema:"Arch"`
- Variant string `schema:"Variant"`
- TLSVerify bool `schema:"tlsVerify"`
- AllTags bool `schema:"allTags"`
+ Reference string `schema:"reference"`
+ OS string `schema:"OS"`
+ Arch string `schema:"Arch"`
+ Variant string `schema:"Variant"`
+ TLSVerify bool `schema:"tlsVerify"`
+ AllTags bool `schema:"allTags"`
+ PullPolicy string `schema:"policy"`
}{
- TLSVerify: true,
+ TLSVerify: true,
+ PullPolicy: "always",
}
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
@@ -83,12 +85,18 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
pullOptions.Writer = writer
+ pullPolicy, err := config.ParsePullPolicy(query.PullPolicy)
+ if err != nil {
+ utils.Error(w, "failed to parse pull policy", http.StatusBadRequest, err)
+ return
+ }
+
var pulledImages []*libimage.Image
var pullError error
runCtx, cancel := context.WithCancel(r.Context())
go func() {
defer cancel()
- pulledImages, pullError = runtime.LibimageRuntime().Pull(runCtx, query.Reference, config.PullPolicyAlways, pullOptions)
+ pulledImages, pullError = runtime.LibimageRuntime().Pull(runCtx, query.Reference, pullPolicy, pullOptions)
}()
flush := func() {
diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go
index d075cd098..3410c53cd 100644
--- a/pkg/api/server/register_images.go
+++ b/pkg/api/server/register_images.go
@@ -974,6 +974,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// description: Pull image for the specified variant.
// type: string
// - in: query
+ // name: policy
+ // description: Pull policy, "always" (default), "missing", "newer", "never".
+ // type: string
+ // - in: query
// name: tlsVerify
// description: Require TLS verification.
// type: boolean
diff --git a/pkg/bindings/images/pull.go b/pkg/bindings/images/pull.go
index 9780c3bff..7dfe9560c 100644
--- a/pkg/bindings/images/pull.go
+++ b/pkg/bindings/images/pull.go
@@ -13,7 +13,7 @@ import (
"github.com/containers/podman/v3/pkg/auth"
"github.com/containers/podman/v3/pkg/bindings"
"github.com/containers/podman/v3/pkg/domain/entities"
- "github.com/hashicorp/go-multierror"
+ "github.com/containers/podman/v3/pkg/errorhandling"
"github.com/pkg/errors"
)
@@ -65,7 +65,7 @@ func Pull(ctx context.Context, rawImage string, options *PullOptions) ([]string,
dec := json.NewDecoder(response.Body)
var images []string
- var mErr error
+ var pullErrors []error
for {
var report entities.ImagePullReport
if err := dec.Decode(&report); err != nil {
@@ -77,7 +77,7 @@ func Pull(ctx context.Context, rawImage string, options *PullOptions) ([]string,
select {
case <-response.Request.Context().Done():
- return images, mErr
+ break
default:
// non-blocking select
}
@@ -86,7 +86,7 @@ func Pull(ctx context.Context, rawImage string, options *PullOptions) ([]string,
case report.Stream != "":
fmt.Fprint(stderr, report.Stream)
case report.Error != "":
- mErr = multierror.Append(mErr, errors.New(report.Error))
+ pullErrors = append(pullErrors, errors.New(report.Error))
case len(report.Images) > 0:
images = report.Images
case report.ID != "":
@@ -94,5 +94,5 @@ func Pull(ctx context.Context, rawImage string, options *PullOptions) ([]string,
return images, errors.Errorf("failed to parse pull results stream, unexpected input: %v", report)
}
}
- return images, mErr
+ return images, errorhandling.JoinErrors(pullErrors)
}
diff --git a/pkg/bindings/images/types.go b/pkg/bindings/images/types.go
index 1f3e46729..0aa75a81e 100644
--- a/pkg/bindings/images/types.go
+++ b/pkg/bindings/images/types.go
@@ -147,6 +147,9 @@ type PullOptions struct {
// OS will overwrite the local operating system (OS) for image
// pulls.
OS *string
+ // Policy is the pull policy. Supported values are "missing", "never",
+ // "newer", "always". An empty string defaults to "always".
+ Policy *string
// Password for authenticating against the registry.
Password *string
// Quiet can be specified to suppress pull progress when pulling. Ignored
diff --git a/pkg/bindings/images/types_pull_options.go b/pkg/bindings/images/types_pull_options.go
index 0611c4447..8fcf499eb 100644
--- a/pkg/bindings/images/types_pull_options.go
+++ b/pkg/bindings/images/types_pull_options.go
@@ -84,6 +84,22 @@ func (o *PullOptions) GetOS() string {
return *o.OS
}
+// WithPolicy
+func (o *PullOptions) WithPolicy(value string) *PullOptions {
+ v := &value
+ o.Policy = v
+ return o
+}
+
+// GetPolicy
+func (o *PullOptions) GetPolicy() string {
+ var policy string
+ if o.Policy == nil {
+ return policy
+ }
+ return *o.Policy
+}
+
// WithPassword
func (o *PullOptions) WithPassword(value string) *PullOptions {
v := &value
diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go
index 3fd9a755d..42027a2dc 100644
--- a/pkg/domain/infra/tunnel/images.go
+++ b/pkg/domain/infra/tunnel/images.go
@@ -107,7 +107,7 @@ func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, opts entities.
options := new(images.PullOptions)
options.WithAllTags(opts.AllTags).WithAuthfile(opts.Authfile).WithArch(opts.Arch).WithOS(opts.OS)
options.WithVariant(opts.Variant).WithPassword(opts.Password)
- options.WithQuiet(opts.Quiet).WithUsername(opts.Username)
+ options.WithQuiet(opts.Quiet).WithUsername(opts.Username).WithPolicy(opts.PullPolicy.String())
if s := opts.SkipTLSVerify; s != types.OptionalBoolUndefined {
if s == types.OptionalBoolTrue {
options.WithSkipTLSVerify(true)
diff --git a/pkg/errorhandling/errorhandling.go b/pkg/errorhandling/errorhandling.go
index 9b1740006..6adbc9f34 100644
--- a/pkg/errorhandling/errorhandling.go
+++ b/pkg/errorhandling/errorhandling.go
@@ -15,6 +15,12 @@ func JoinErrors(errs []error) error {
return nil
}
+ // If there's just one error, return it. This prevents the "%d errors
+ // occurred:" header plus list from the multierror package.
+ if len(errs) == 1 {
+ return errs[0]
+ }
+
// `multierror` appends new lines which we need to remove to prevent
// blank lines when printing the error.
var multiE *multierror.Error
@@ -24,9 +30,6 @@ func JoinErrors(errs []error) error {
if finalErr == nil {
return finalErr
}
- if len(multiE.WrappedErrors()) == 1 && logrus.IsLevelEnabled(logrus.TraceLevel) {
- return multiE.WrappedErrors()[0]
- }
return errors.New(strings.TrimSpace(finalErr.Error()))
}
diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go
index d00e51e82..e7276892d 100644
--- a/pkg/specgen/generate/container.go
+++ b/pkg/specgen/generate/container.go
@@ -24,7 +24,8 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat
var inspectData *libimage.ImageData
var err error
if s.Image != "" {
- newImage, _, err = r.LibimageRuntime().LookupImage(s.Image, nil)
+ lookupOptions := &libimage.LookupImageOptions{IgnorePlatform: true}
+ newImage, _, err = r.LibimageRuntime().LookupImage(s.Image, lookupOptions)
if err != nil {
return nil, err
}
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index a0f5cc7e6..087ff59df 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -92,7 +92,8 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
options = append(options, libpod.WithRootFS(s.Rootfs))
} else {
var resolvedImageName string
- newImage, resolvedImageName, err = rt.LibimageRuntime().LookupImage(s.Image, nil)
+ lookupOptions := &libimage.LookupImageOptions{IgnorePlatform: true}
+ newImage, resolvedImageName, err = rt.LibimageRuntime().LookupImage(s.Image, lookupOptions)
if err != nil {
return nil, err
}