mirror of
https://github.com/containers/podman.git
synced 2025-07-15 03:02:52 +08:00
honor pull policy in play kube
When a container specification has a pull policy, we should honor it when recreating the pods/containers from yaml. furthermore, ini kube, if a tag is :latest, then the always pull policy is automatically instituted. Fixes: #4880 Signed-off-by: Brent Baude <bbaude@redhat.com>
This commit is contained in:
@ -1,5 +1,11 @@
|
|||||||
package image
|
package image
|
||||||
|
|
||||||
|
const (
|
||||||
|
// LatestTag describes the tag used to refer to the latest version
|
||||||
|
// of an image
|
||||||
|
LatestTag = "latest"
|
||||||
|
)
|
||||||
|
|
||||||
// ImageDeleteResponse is the response for removing an image from storage and containers
|
// ImageDeleteResponse is the response for removing an image from storage and containers
|
||||||
// what was untagged vs actually removed
|
// what was untagged vs actually removed
|
||||||
type ImageDeleteResponse struct { //nolint
|
type ImageDeleteResponse struct { //nolint
|
||||||
|
@ -67,7 +67,7 @@ func (ip *imageParts) suspiciousRefNameTagValuesForSearch() (string, string, str
|
|||||||
} else if _, hasDigest := ip.unnormalizedRef.(reference.Digested); hasDigest {
|
} else if _, hasDigest := ip.unnormalizedRef.(reference.Digested); hasDigest {
|
||||||
tag = "none"
|
tag = "none"
|
||||||
} else {
|
} else {
|
||||||
tag = "latest"
|
tag = LatestTag
|
||||||
}
|
}
|
||||||
return registry, imageName, tag
|
return registry, imageName, tag
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/containers/buildah/pkg/parse"
|
"github.com/containers/buildah/pkg/parse"
|
||||||
|
"github.com/containers/image/v5/docker/reference"
|
||||||
"github.com/containers/image/v5/types"
|
"github.com/containers/image/v5/types"
|
||||||
"github.com/containers/libpod/cmd/podman/cliconfig"
|
"github.com/containers/libpod/cmd/podman/cliconfig"
|
||||||
"github.com/containers/libpod/cmd/podman/shared"
|
"github.com/containers/libpod/cmd/podman/shared"
|
||||||
@ -604,7 +605,24 @@ func (r *LocalRuntime) PlayKubeYAML(ctx context.Context, c *cliconfig.KubePlayVa
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, container := range podYAML.Spec.Containers {
|
for _, container := range podYAML.Spec.Containers {
|
||||||
newImage, err := r.ImageRuntime().New(ctx, container.Image, c.SignaturePolicy, c.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, nil, util.PullImageMissing)
|
pullPolicy := util.PullImageMissing
|
||||||
|
if len(container.ImagePullPolicy) > 0 {
|
||||||
|
pullPolicy, err = util.ValidatePullType(string(container.ImagePullPolicy))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
named, err := reference.ParseNormalizedNamed(container.Image)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// In kube, if the image is tagged with latest, it should always pull
|
||||||
|
if tagged, isTagged := named.(reference.NamedTagged); isTagged {
|
||||||
|
if tagged.Tag() == image.LatestTag {
|
||||||
|
pullPolicy = util.PullImageAlways
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newImage, err := r.ImageRuntime().New(ctx, container.Image, c.SignaturePolicy, c.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, nil, pullPolicy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,7 @@ spec:
|
|||||||
value: podman
|
value: podman
|
||||||
image: {{ .Image }}
|
image: {{ .Image }}
|
||||||
name: {{ .Name }}
|
name: {{ .Name }}
|
||||||
|
imagePullPolicy: {{ .PullPolicy }}
|
||||||
resources: {}
|
resources: {}
|
||||||
{{ if .SecurityContext }}
|
{{ if .SecurityContext }}
|
||||||
securityContext:
|
securityContext:
|
||||||
@ -153,12 +154,13 @@ type Ctr struct {
|
|||||||
Caps bool
|
Caps bool
|
||||||
CapAdd []string
|
CapAdd []string
|
||||||
CapDrop []string
|
CapDrop []string
|
||||||
|
PullPolicy string
|
||||||
}
|
}
|
||||||
|
|
||||||
// getCtr takes a list of ctrOptions and returns a Ctr with sane defaults
|
// getCtr takes a list of ctrOptions and returns a Ctr with sane defaults
|
||||||
// and the configured options
|
// and the configured options
|
||||||
func getCtr(options ...ctrOption) *Ctr {
|
func getCtr(options ...ctrOption) *Ctr {
|
||||||
c := Ctr{defaultCtrName, defaultCtrImage, defaultCtrCmd, true, false, nil, nil}
|
c := Ctr{defaultCtrName, defaultCtrImage, defaultCtrCmd, true, false, nil, nil, ""}
|
||||||
for _, option := range options {
|
for _, option := range options {
|
||||||
option(&c)
|
option(&c)
|
||||||
}
|
}
|
||||||
@ -199,6 +201,12 @@ func withCapDrop(caps []string) ctrOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func withPullPolicy(policy string) ctrOption {
|
||||||
|
return func(c *Ctr) {
|
||||||
|
c.PullPolicy = policy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var _ = Describe("Podman generate kube", func() {
|
var _ = Describe("Podman generate kube", func() {
|
||||||
var (
|
var (
|
||||||
tempdir string
|
tempdir string
|
||||||
@ -396,4 +404,86 @@ var _ = Describe("Podman generate kube", func() {
|
|||||||
Expect(logs.ExitCode()).To(Equal(0))
|
Expect(logs.ExitCode()).To(Equal(0))
|
||||||
Expect(logs.OutputToString()).To(ContainSubstring("Operation not permitted"))
|
Expect(logs.OutputToString()).To(ContainSubstring("Operation not permitted"))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("podman play kube with pull policy of never should be 125", func() {
|
||||||
|
ctr := getCtr(withPullPolicy("never"), withImage(BB_GLIBC))
|
||||||
|
err := generateKubeYaml(getPod(withCtr(ctr)), kubeYaml)
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
|
||||||
|
kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
|
||||||
|
kube.WaitWithDefaultTimeout()
|
||||||
|
Expect(kube.ExitCode()).To(Equal(125))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("podman play kube with pull policy of missing", func() {
|
||||||
|
ctr := getCtr(withPullPolicy("missing"), withImage(BB))
|
||||||
|
err := generateKubeYaml(getPod(withCtr(ctr)), kubeYaml)
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
|
||||||
|
kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
|
||||||
|
kube.WaitWithDefaultTimeout()
|
||||||
|
Expect(kube.ExitCode()).To(Equal(0))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("podman play kube with pull always", func() {
|
||||||
|
oldBB := "docker.io/library/busybox:1.30.1"
|
||||||
|
pull := podmanTest.Podman([]string{"pull", oldBB})
|
||||||
|
pull.WaitWithDefaultTimeout()
|
||||||
|
|
||||||
|
tag := podmanTest.Podman([]string{"tag", oldBB, BB})
|
||||||
|
tag.WaitWithDefaultTimeout()
|
||||||
|
Expect(tag.ExitCode()).To(BeZero())
|
||||||
|
|
||||||
|
rmi := podmanTest.Podman([]string{"rmi", oldBB})
|
||||||
|
rmi.WaitWithDefaultTimeout()
|
||||||
|
Expect(rmi.ExitCode()).To(BeZero())
|
||||||
|
|
||||||
|
inspect := podmanTest.Podman([]string{"inspect", BB})
|
||||||
|
inspect.WaitWithDefaultTimeout()
|
||||||
|
oldBBinspect := inspect.InspectImageJSON()
|
||||||
|
|
||||||
|
ctr := getCtr(withPullPolicy("always"), withImage(BB))
|
||||||
|
err := generateKubeYaml(getPod(withCtr(ctr)), kubeYaml)
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
|
||||||
|
kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
|
||||||
|
kube.WaitWithDefaultTimeout()
|
||||||
|
Expect(kube.ExitCode()).To(Equal(0))
|
||||||
|
|
||||||
|
inspect = podmanTest.Podman([]string{"inspect", BB})
|
||||||
|
inspect.WaitWithDefaultTimeout()
|
||||||
|
newBBinspect := inspect.InspectImageJSON()
|
||||||
|
Expect(oldBBinspect[0].Digest).To(Not(Equal(newBBinspect[0].Digest)))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("podman play kube with latest image should always pull", func() {
|
||||||
|
oldBB := "docker.io/library/busybox:1.30.1"
|
||||||
|
pull := podmanTest.Podman([]string{"pull", oldBB})
|
||||||
|
pull.WaitWithDefaultTimeout()
|
||||||
|
|
||||||
|
tag := podmanTest.Podman([]string{"tag", oldBB, BB})
|
||||||
|
tag.WaitWithDefaultTimeout()
|
||||||
|
Expect(tag.ExitCode()).To(BeZero())
|
||||||
|
|
||||||
|
rmi := podmanTest.Podman([]string{"rmi", oldBB})
|
||||||
|
rmi.WaitWithDefaultTimeout()
|
||||||
|
Expect(rmi.ExitCode()).To(BeZero())
|
||||||
|
|
||||||
|
inspect := podmanTest.Podman([]string{"inspect", BB})
|
||||||
|
inspect.WaitWithDefaultTimeout()
|
||||||
|
oldBBinspect := inspect.InspectImageJSON()
|
||||||
|
|
||||||
|
ctr := getCtr(withImage(BB))
|
||||||
|
err := generateKubeYaml(getPod(withCtr(ctr)), kubeYaml)
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
|
||||||
|
kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
|
||||||
|
kube.WaitWithDefaultTimeout()
|
||||||
|
Expect(kube.ExitCode()).To(Equal(0))
|
||||||
|
|
||||||
|
inspect = podmanTest.Podman([]string{"inspect", BB})
|
||||||
|
inspect.WaitWithDefaultTimeout()
|
||||||
|
newBBinspect := inspect.InspectImageJSON()
|
||||||
|
Expect(oldBBinspect[0].Digest).To(Not(Equal(newBBinspect[0].Digest)))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user