summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrent Baude <bbaude@redhat.com>2020-01-27 11:53:39 -0600
committerBrent Baude <bbaude@redhat.com>2020-01-28 13:36:10 -0600
commit31a1f44fe6934c6247f7bf2f5774805b263da660 (patch)
treea818496c7612b310d0b651fcc954d23df802a6c4
parentd07c26310697d8874219731c6c42f6d0d0330e87 (diff)
downloadpodman-31a1f44fe6934c6247f7bf2f5774805b263da660.tar.gz
podman-31a1f44fe6934c6247f7bf2f5774805b263da660.tar.bz2
podman-31a1f44fe6934c6247f7bf2f5774805b263da660.zip
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>
-rw-r--r--libpod/image/config.go6
-rw-r--r--libpod/image/parts.go2
-rw-r--r--pkg/adapter/pods.go20
-rw-r--r--test/e2e/play_kube_test.go92
4 files changed, 117 insertions, 3 deletions
diff --git a/libpod/image/config.go b/libpod/image/config.go
index bb84175a3..efd83d343 100644
--- a/libpod/image/config.go
+++ b/libpod/image/config.go
@@ -1,5 +1,11 @@
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
// what was untagged vs actually removed
type ImageDeleteResponse struct { //nolint
diff --git a/libpod/image/parts.go b/libpod/image/parts.go
index d4677f935..d6c98783b 100644
--- a/libpod/image/parts.go
+++ b/libpod/image/parts.go
@@ -67,7 +67,7 @@ func (ip *imageParts) suspiciousRefNameTagValuesForSearch() (string, string, str
} else if _, hasDigest := ip.unnormalizedRef.(reference.Digested); hasDigest {
tag = "none"
} else {
- tag = "latest"
+ tag = LatestTag
}
return registry, imageName, tag
}
diff --git a/pkg/adapter/pods.go b/pkg/adapter/pods.go
index f89fc7011..b0e63f770 100644
--- a/pkg/adapter/pods.go
+++ b/pkg/adapter/pods.go
@@ -12,6 +12,7 @@ import (
"strings"
"github.com/containers/buildah/pkg/parse"
+ "github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/types"
"github.com/containers/libpod/cmd/podman/cliconfig"
"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 {
- 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 {
return nil, err
}
diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go
index 89a5eddf4..8411e632a 100644
--- a/test/e2e/play_kube_test.go
+++ b/test/e2e/play_kube_test.go
@@ -47,6 +47,7 @@ spec:
value: podman
image: {{ .Image }}
name: {{ .Name }}
+ imagePullPolicy: {{ .PullPolicy }}
resources: {}
{{ if .SecurityContext }}
securityContext:
@@ -153,12 +154,13 @@ type Ctr struct {
Caps bool
CapAdd []string
CapDrop []string
+ PullPolicy string
}
// getCtr takes a list of ctrOptions and returns a Ctr with sane defaults
// and the configured options
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 {
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 (
tempdir string
@@ -396,4 +404,86 @@ var _ = Describe("Podman generate kube", func() {
Expect(logs.ExitCode()).To(Equal(0))
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)))
+ })
})