Properly handle podman run --pull command

Currently the --pull missing|always|never is ignored

This PR implements this for local API.  For remote we
need to default to pullpolicy specified in the containers.conf
file.

Also fixed an issue when images were matching other images names
based on prefix, causing images to always be pulled.

I had named an image myfedora and when ever I pulled fedora, the system
thought that it there were two images named fedora since it was checking
for the name fedora as well as the prefix fedora.  I changed it to check
for fedora and the prefix /fedora, to prefent failures like I had.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
Daniel J Walsh
2020-09-24 18:38:52 -04:00
parent 03d01abec6
commit 1b5853e647
8 changed files with 64 additions and 8 deletions

View File

@ -363,7 +363,7 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet {
)
createFlags.StringVar(
&cf.Pull,
"pull", "missing",
"pull", containerConfig.Engine.PullPolicy,
`Pull image before creating ("always"|"missing"|"never")`,
)
createFlags.BoolVarP(

View File

@ -261,6 +261,7 @@ func pullImage(imageName string) (string, error) {
OverrideOS: cliVals.OverrideOS,
OverrideVariant: cliVals.OverrideVariant,
SignaturePolicy: cliVals.SignaturePolicy,
PullPolicy: pullPolicy,
})
if pullErr != nil {
return "", pullErr

View File

@ -33,7 +33,7 @@ func findImageInRepotags(search imageParts, images []*Image) (*storage.Image, er
continue
}
// account for registry:/somedir/image
if strings.HasSuffix(dName, searchName) && dSuspiciousTagValueForSearch == searchSuspiciousTagValueForSearch {
if strings.HasSuffix(dName, "/"+searchName) && dSuspiciousTagValueForSearch == searchSuspiciousTagValueForSearch {
results = append(results, image.image)
continue
}

View File

@ -10,6 +10,7 @@ import (
"strings"
"github.com/containers/buildah"
"github.com/containers/common/pkg/config"
"github.com/containers/image/v5/manifest"
"github.com/containers/podman/v2/libpod"
image2 "github.com/containers/podman/v2/libpod/image"
@ -17,7 +18,6 @@ import (
"github.com/containers/podman/v2/pkg/api/handlers/utils"
"github.com/containers/podman/v2/pkg/auth"
"github.com/containers/podman/v2/pkg/domain/entities"
"github.com/containers/podman/v2/pkg/util"
"github.com/docker/docker/api/types"
"github.com/gorilla/schema"
"github.com/pkg/errors"
@ -268,6 +268,16 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) {
if sys := runtime.SystemContext(); sys != nil {
registryOpts.DockerCertPath = sys.DockerCertPath
}
rtc, err := runtime.GetConfig()
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()"))
return
}
pullPolicy, err := config.ValidatePullPolicy(rtc.Engine.PullPolicy)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()"))
return
}
img, err := runtime.ImageRuntime().New(r.Context(),
fromImage,
"", // signature policy
@ -276,7 +286,7 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) {
&registryOpts,
image2.SigningOptions{},
nil, // label
util.PullImageMissing,
pullPolicy,
)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)

View File

@ -3,6 +3,7 @@ package entities
import (
"time"
"github.com/containers/common/pkg/config"
"github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/types"
"github.com/containers/podman/v2/pkg/inspect"
@ -119,8 +120,8 @@ type ImageHistoryReport struct {
// ImagePullOptions are the arguments for pulling images.
type ImagePullOptions struct {
// AllTags can be specified to pull all tags of the spiecifed image. Note
// that this only works if the specified image does not include a tag.
// AllTags can be specified to pull all tags of an image. Note
// that this only works if the image does not include a tag.
AllTags bool
// Authfile is the path to the authentication file. Ignored for remote
// calls.
@ -146,6 +147,8 @@ type ImagePullOptions struct {
SignaturePolicy string
// SkipTLSVerify to skip HTTPS and certificate verification.
SkipTLSVerify types.OptionalBool
// PullPolicy whether to pull new image
PullPolicy config.PullPolicy
}
// ImagePullReport is the response from pulling one or more images.

View File

@ -255,7 +255,7 @@ func pull(ctx context.Context, runtime *image.Runtime, rawImage string, options
}
if !options.AllTags {
newImage, err := runtime.New(ctx, rawImage, options.SignaturePolicy, options.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, label, util.PullImageAlways)
newImage, err := runtime.New(ctx, rawImage, options.SignaturePolicy, options.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, label, options.PullPolicy)
if err != nil {
return nil, err
}

View File

@ -106,7 +106,7 @@ profile aa-test-profile flags=(attach_disconnected,mediate_deleted) {
parse := SystemExec("apparmor_parser", []string{"-Kr", aaFile})
Expect(parse.ExitCode()).To(Equal(0))
session := podmanTest.Podman([]string{"create", "--security-opt", "apparmor=aa-test-profile", "ls"})
session := podmanTest.Podman([]string{"create", "--security-opt", "apparmor=aa-test-profile", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))

View File

@ -1273,4 +1273,46 @@ WORKDIR /madethis`
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
It("podman run a container with --pull never should fail if no local store", func() {
// Make sure ALPINE image does not exist. Ignore errors
session := podmanTest.PodmanNoCache([]string{"rmi", "--force", "never", ALPINE})
session.WaitWithDefaultTimeout()
session = podmanTest.PodmanNoCache([]string{"run", "--pull", "never", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(125))
})
It("podman run container with --pull missing and only pull once", func() {
// Make sure ALPINE image does not exist. Ignore errors
session := podmanTest.PodmanNoCache([]string{"rmi", "--force", "never", ALPINE})
session.WaitWithDefaultTimeout()
session = podmanTest.PodmanNoCache([]string{"run", "--pull", "missing", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull"))
session = podmanTest.PodmanNoCache([]string{"run", "--pull", "missing", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull"))
})
It("podman run container with --pull missing should pull image multiple times", func() {
// Make sure ALPINE image does not exist. Ignore errors
session := podmanTest.PodmanNoCache([]string{"rmi", "--force", "never", ALPINE})
session.WaitWithDefaultTimeout()
session = podmanTest.PodmanNoCache([]string{"run", "--pull", "always", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull"))
session = podmanTest.PodmanNoCache([]string{"run", "--pull", "always", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull"))
})
})