Skip to content

Commit

Permalink
honor pull policy in play kube
Browse files Browse the repository at this point in the history
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: containers#4880

Signed-off-by: Brent Baude <bbaude@redhat.com>
  • Loading branch information
baude committed Jan 28, 2020
1 parent d07c263 commit db650d4
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 2 deletions.
20 changes: 19 additions & 1 deletion pkg/adapter/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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() == "latest" {
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
}
Expand Down
92 changes: 91 additions & 1 deletion test/e2e/play_kube_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ spec:
value: podman
image: {{ .Image }}
name: {{ .Name }}
imagePullPolicy: {{ .PullPolicy }}
resources: {}
{{ if .SecurityContext }}
securityContext:
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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("never"), 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)))
})
})

0 comments on commit db650d4

Please sign in to comment.