add --pull flag for podman create&run

Requirement from https://github.com/containers/libpod/issues/3575#issuecomment-512238393

Added --pull for podman create and pull to match the newly added flag in docker CLI.
`missing`: default value, podman will pull the image if it does not exist in the local.
`always`: podman will always pull the image.
`never`: podman will never pull the image.

Signed-off-by: Qi Wang <qiwan@redhat.com>
This commit is contained in:
Qi Wang
2019-07-22 09:47:42 -04:00
parent d05798e5e8
commit decfea65be
23 changed files with 103 additions and 20 deletions

2
API.md
View File

@ -1501,6 +1501,8 @@ publish [?[]string](#?[]string)
publishAll [?bool](#?bool) publishAll [?bool](#?bool)
pull [?string](#?string)
quiet [?bool](#?bool) quiet [?bool](#?bool)
readonly [?bool](#?bool) readonly [?bool](#?bool)

View File

@ -388,6 +388,10 @@ func getCreateFlags(c *cliconfig.PodmanCommand) {
"publish-all", "P", false, "publish-all", "P", false,
"Publish all exposed ports to random ports on the host interface", "Publish all exposed ports to random ports on the host interface",
) )
createFlags.String(
"pull", "missing",
`Pull image before creating ("always"|"missing"|"never") (default "missing")`,
)
createFlags.BoolP( createFlags.BoolP(
"quiet", "q", false, "quiet", "q", false,
"Suppress output information when pulling images", "Suppress output information when pulling images",

View File

@ -150,7 +150,7 @@ func pullCmd(c *cliconfig.PullValues) (retError error) {
// See https://bugzilla.redhat.com/show_bug.cgi?id=1701922 for background // See https://bugzilla.redhat.com/show_bug.cgi?id=1701922 for background
// information. // information.
if !c.Bool("all-tags") { if !c.Bool("all-tags") {
newImage, err := runtime.New(getContext(), imgArg, c.SignaturePolicy, c.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, true, nil) newImage, err := runtime.New(getContext(), imgArg, c.SignaturePolicy, c.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, nil, util.PullImageAlways)
if err != nil { if err != nil {
return errors.Wrapf(err, "error pulling image %q", imgArg) return errors.Wrapf(err, "error pulling image %q", imgArg)
} }
@ -188,7 +188,7 @@ func pullCmd(c *cliconfig.PullValues) (retError error) {
var foundIDs []string var foundIDs []string
foundImage := true foundImage := true
for _, name := range names { for _, name := range names {
newImage, err := runtime.New(getContext(), name, c.SignaturePolicy, c.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, true, nil) newImage, err := runtime.New(getContext(), name, c.SignaturePolicy, c.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, nil, util.PullImageAlways)
if err != nil { if err != nil {
logrus.Errorf("error pulling image %q", name) logrus.Errorf("error pulling image %q", name)
foundImage = false foundImage = false

View File

@ -732,7 +732,7 @@ func GetRunlabel(label string, runlabelImage string, ctx context.Context, runtim
registryCreds = creds registryCreds = creds
} }
dockerRegistryOptions.DockerRegistryCreds = registryCreds dockerRegistryOptions.DockerRegistryCreds = registryCreds
newImage, err = runtime.ImageRuntime().New(ctx, runlabelImage, signaturePolicyPath, authfile, output, &dockerRegistryOptions, image.SigningOptions{}, false, &label) newImage, err = runtime.ImageRuntime().New(ctx, runlabelImage, signaturePolicyPath, authfile, output, &dockerRegistryOptions, image.SigningOptions{}, &label, util.PullImageMissing)
} else { } else {
newImage, err = runtime.ImageRuntime().NewFromLocal(runlabelImage) newImage, err = runtime.ImageRuntime().NewFromLocal(runlabelImage)
} }

View File

@ -83,7 +83,13 @@ func CreateContainer(ctx context.Context, c *GenericCLIResults, runtime *libpod.
} else { } else {
return nil, nil, errors.Errorf("error, no input arguments were provided") return nil, nil, errors.Errorf("error, no input arguments were provided")
} }
newImage, err := runtime.ImageRuntime().New(ctx, name, rtc.SignaturePolicyPath, GetAuthFile(c.String("authfile")), writer, nil, image.SigningOptions{}, false, nil)
pullType, err := util.ValidatePullType(c.String("pull"))
if err != nil {
return nil, nil, err
}
newImage, err := runtime.ImageRuntime().New(ctx, name, rtc.SignaturePolicyPath, GetAuthFile(c.String("authfile")), writer, nil, image.SigningOptions{}, nil, pullType)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }

View File

@ -436,6 +436,7 @@ func NewIntermediateLayer(c *cliconfig.PodmanCommand, remote bool) GenericCLIRes
m["privileged"] = newCRBool(c, "privileged") m["privileged"] = newCRBool(c, "privileged")
m["publish"] = newCRStringSlice(c, "publish") m["publish"] = newCRStringSlice(c, "publish")
m["publish-all"] = newCRBool(c, "publish-all") m["publish-all"] = newCRBool(c, "publish-all")
m["pull"] = newCRString(c, "pull")
m["quiet"] = newCRBool(c, "quiet") m["quiet"] = newCRBool(c, "quiet")
m["read-only"] = newCRBool(c, "read-only") m["read-only"] = newCRBool(c, "read-only")
m["read-only-tmpfs"] = newCRBool(c, "read-only-tmpfs") m["read-only-tmpfs"] = newCRBool(c, "read-only-tmpfs")

View File

@ -137,6 +137,7 @@ func (g GenericCLIResults) MakeVarlink() iopodman.Create {
Privileged: BoolToPtr(g.Find("privileged")), Privileged: BoolToPtr(g.Find("privileged")),
Publish: StringSliceToPtr(g.Find("publish")), Publish: StringSliceToPtr(g.Find("publish")),
PublishAll: BoolToPtr(g.Find("publish-all")), PublishAll: BoolToPtr(g.Find("publish-all")),
Pull: StringToPtr(g.Find("pull")),
Quiet: BoolToPtr(g.Find("quiet")), Quiet: BoolToPtr(g.Find("quiet")),
Readonly: BoolToPtr(g.Find("read-only")), Readonly: BoolToPtr(g.Find("read-only")),
Readonlytmpfs: BoolToPtr(g.Find("read-only-tmpfs")), Readonlytmpfs: BoolToPtr(g.Find("read-only-tmpfs")),
@ -393,6 +394,7 @@ func VarlinkCreateToGeneric(opts iopodman.Create) GenericCLIResults {
m["privileged"] = boolFromVarlink(opts.Privileged, "privileged", false) m["privileged"] = boolFromVarlink(opts.Privileged, "privileged", false)
m["publish"] = stringSliceFromVarlink(opts.Publish, "publish", nil) m["publish"] = stringSliceFromVarlink(opts.Publish, "publish", nil)
m["publish-all"] = boolFromVarlink(opts.PublishAll, "publish-all", false) m["publish-all"] = boolFromVarlink(opts.PublishAll, "publish-all", false)
m["pull"] = stringFromVarlink(opts.Pull, "missing", nil)
m["quiet"] = boolFromVarlink(opts.Quiet, "quiet", false) m["quiet"] = boolFromVarlink(opts.Quiet, "quiet", false)
m["read-only"] = boolFromVarlink(opts.Readonly, "read-only", false) m["read-only"] = boolFromVarlink(opts.Readonly, "read-only", false)
m["read-only-tmpfs"] = boolFromVarlink(opts.Readonlytmpfs, "read-only-tmpfs", true) m["read-only-tmpfs"] = boolFromVarlink(opts.Readonlytmpfs, "read-only-tmpfs", true)

View File

@ -15,6 +15,7 @@ import (
"github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/libpod/image" "github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/trust" "github.com/containers/libpod/pkg/trust"
"github.com/containers/libpod/pkg/util"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -113,7 +114,7 @@ func signCmd(c *cliconfig.SignValues) error {
if err != nil { if err != nil {
return err return err
} }
newImage, err := runtime.ImageRuntime().New(getContext(), signimage, rtc.SignaturePolicyPath, "", os.Stderr, nil, image.SigningOptions{SignBy: signby}, false, nil) newImage, err := runtime.ImageRuntime().New(getContext(), signimage, rtc.SignaturePolicyPath, "", os.Stderr, nil, image.SigningOptions{SignBy: signby}, nil, util.PullImageMissing)
if err != nil { if err != nil {
return errors.Wrapf(err, "error pulling image %s", signimage) return errors.Wrapf(err, "error pulling image %s", signimage)
} }

View File

@ -347,6 +347,7 @@ type Create (
privileged: ?bool, privileged: ?bool,
publish: ?[]string, publish: ?[]string,
publishAll: ?bool, publishAll: ?bool,
pull: ?string,
quiet: ?bool, quiet: ?bool,
readonly: ?bool, readonly: ?bool,
readonlytmpfs: ?bool, readonlytmpfs: ?bool,

View File

@ -1773,6 +1773,7 @@ _podman_container_run() {
--pids-limit --pids-limit
--pod --pod
--publish -p --publish -p
--pull
--runtime --runtime
--rootfs --rootfs
--security-opt --security-opt

View File

@ -103,7 +103,7 @@ func main() {
} }
fmt.Printf("image %s not found locally, fetching from remote registry..\n", *testImageName) fmt.Printf("image %s not found locally, fetching from remote registry..\n", *testImageName)
testImage, err = client.ImageRuntime().New(ctx, *testImageName, "", "", writer, &dockerRegistryOptions, image2.SigningOptions{}, false, nil) testImage, err = client.ImageRuntime().New(ctx, *testImageName, "", "", writer, &dockerRegistryOptions, image2.SigningOptions{}, nil, util.PullImageMissing)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -582,6 +582,15 @@ port to a random port on the host within an *ephemeral port range* defined by
`/proc/sys/net/ipv4/ip_local_port_range`. To find the mapping between the host `/proc/sys/net/ipv4/ip_local_port_range`. To find the mapping between the host
ports and the exposed ports, use `podman port`. ports and the exposed ports, use `podman port`.
**--pull**=*missing*
Pull image before creating ("always"|"missing"|"never") (default "missing").
'missing': default value, attempt to pull the latest image from the registries listed in registries.conf if a local image does not exist.Raise an error if the image is not in any listed registry and is not present locally.
'always': Pull the image from the first registry it is found in as listed in registries.conf. Raise an error if not found in the registries, even if the image is present locally.
'never': do not pull the image from the registry, use only the local version. Raise an error if the image is not present locally.
Defaults to *missing*.
**--quiet**, **-q** **--quiet**, **-q**
Suppress output information when pulling images Suppress output information when pulling images

View File

@ -601,6 +601,15 @@ When using -P, podman will bind any exposed port to a random port on the host
within an *ephemeral port range* defined by `/proc/sys/net/ipv4/ip_local_port_range`. within an *ephemeral port range* defined by `/proc/sys/net/ipv4/ip_local_port_range`.
To find the mapping between the host ports and the exposed ports, use `podman port`. To find the mapping between the host ports and the exposed ports, use `podman port`.
**--pull**=*missing*
Pull image before running ("always"|"missing"|"never") (default "missing").
'missing': default value, attempt to pull the latest image from the registries listed in registries.conf if a local image does not exist.Raise an error if the image is not in any listed registry and is not present locally.
'always': Pull the image from the first registry it is found in as listed in registries.conf. Raise an error if not found in the registries, even if the image is present locally.
'never': do not pull the image from the registry, use only the local version. Raise an error if the image is not present locally.
Defaults to *missing*.
**--quiet**, **-q** **--quiet**, **-q**
Suppress output information when pulling images Suppress output information when pulling images

View File

@ -135,7 +135,7 @@ func (ir *Runtime) NewFromLocal(name string) (*Image, error) {
// New creates a new image object where the image could be local // New creates a new image object where the image could be local
// or remote // or remote
func (ir *Runtime) New(ctx context.Context, name, signaturePolicyPath, authfile string, writer io.Writer, dockeroptions *DockerRegistryOptions, signingoptions SigningOptions, forcePull bool, label *string) (*Image, error) { func (ir *Runtime) New(ctx context.Context, name, signaturePolicyPath, authfile string, writer io.Writer, dockeroptions *DockerRegistryOptions, signingoptions SigningOptions, label *string, pullType util.PullType) (*Image, error) {
span, _ := opentracing.StartSpanFromContext(ctx, "newImage") span, _ := opentracing.StartSpanFromContext(ctx, "newImage")
span.SetTag("type", "runtime") span.SetTag("type", "runtime")
defer span.Finish() defer span.Finish()
@ -145,11 +145,13 @@ func (ir *Runtime) New(ctx context.Context, name, signaturePolicyPath, authfile
InputName: name, InputName: name,
imageruntime: ir, imageruntime: ir,
} }
if !forcePull { if pullType != util.PullImageAlways {
localImage, err := newImage.getLocalImage() localImage, err := newImage.getLocalImage()
if err == nil { if err == nil {
newImage.image = localImage newImage.image = localImage
return &newImage, nil return &newImage, nil
} else if pullType == util.PullImageNever {
return nil, err
} }
} }

View File

@ -3,12 +3,13 @@ package image
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/containers/libpod/libpod/events"
"io" "io"
"io/ioutil" "io/ioutil"
"os" "os"
"testing" "testing"
"github.com/containers/libpod/libpod/events"
"github.com/containers/libpod/pkg/util"
"github.com/containers/storage" "github.com/containers/storage"
"github.com/opencontainers/go-digest" "github.com/opencontainers/go-digest"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -89,9 +90,9 @@ func TestImage_NewFromLocal(t *testing.T) {
ir, err := NewImageRuntimeFromOptions(so) ir, err := NewImageRuntimeFromOptions(so)
assert.NoError(t, err) assert.NoError(t, err)
ir.Eventer = events.NewNullEventer() ir.Eventer = events.NewNullEventer()
bb, err := ir.New(context.Background(), "docker.io/library/busybox:latest", "", "", writer, nil, SigningOptions{}, false, nil) bb, err := ir.New(context.Background(), "docker.io/library/busybox:latest", "", "", writer, nil, SigningOptions{}, nil, util.PullImageMissing)
assert.NoError(t, err) assert.NoError(t, err)
bbglibc, err := ir.New(context.Background(), "docker.io/library/busybox:glibc", "", "", writer, nil, SigningOptions{}, false, nil) bbglibc, err := ir.New(context.Background(), "docker.io/library/busybox:glibc", "", "", writer, nil, SigningOptions{}, nil, util.PullImageMissing)
assert.NoError(t, err) assert.NoError(t, err)
tm, err := makeLocalMatrix(bb, bbglibc) tm, err := makeLocalMatrix(bb, bbglibc)
@ -139,7 +140,7 @@ func TestImage_New(t *testing.T) {
// Iterate over the names and delete the image // Iterate over the names and delete the image
// after the pull // after the pull
for _, img := range names { for _, img := range names {
newImage, err := ir.New(context.Background(), img, "", "", writer, nil, SigningOptions{}, false, nil) newImage, err := ir.New(context.Background(), img, "", "", writer, nil, SigningOptions{}, nil, util.PullImageMissing)
assert.NoError(t, err) assert.NoError(t, err)
assert.NotEqual(t, newImage.ID(), "") assert.NotEqual(t, newImage.ID(), "")
err = newImage.Remove(context.Background(), false) err = newImage.Remove(context.Background(), false)
@ -168,7 +169,7 @@ func TestImage_MatchRepoTag(t *testing.T) {
ir, err := NewImageRuntimeFromOptions(so) ir, err := NewImageRuntimeFromOptions(so)
assert.NoError(t, err) assert.NoError(t, err)
ir.Eventer = events.NewNullEventer() ir.Eventer = events.NewNullEventer()
newImage, err := ir.New(context.Background(), "busybox", "", "", os.Stdout, nil, SigningOptions{}, false, nil) newImage, err := ir.New(context.Background(), "busybox", "", "", os.Stdout, nil, SigningOptions{}, nil, util.PullImageMissing)
assert.NoError(t, err) assert.NoError(t, err)
err = newImage.TagImage("foo:latest") err = newImage.TagImage("foo:latest")
assert.NoError(t, err) assert.NoError(t, err)

View File

@ -9,6 +9,7 @@ import (
"github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/libpod/image" "github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/rootless" "github.com/containers/libpod/pkg/rootless"
"github.com/containers/libpod/pkg/util"
"github.com/opencontainers/image-spec/specs-go/v1" "github.com/opencontainers/image-spec/specs-go/v1"
spec "github.com/opencontainers/runtime-spec/specs-go" spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate" "github.com/opencontainers/runtime-tools/generate"
@ -108,7 +109,7 @@ func (r *Runtime) createInfraContainer(ctx context.Context, p *Pod) (*Container,
return nil, define.ErrRuntimeStopped return nil, define.ErrRuntimeStopped
} }
newImage, err := r.ImageRuntime().New(ctx, r.config.InfraImage, "", "", nil, nil, image.SigningOptions{}, false, nil) newImage, err := r.ImageRuntime().New(ctx, r.config.InfraImage, "", "", nil, nil, image.SigningOptions{}, nil, util.PullImageMissing)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -11,6 +11,7 @@ import (
"github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/image" "github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/errorhandling" "github.com/containers/libpod/pkg/errorhandling"
"github.com/containers/libpod/pkg/util"
"github.com/containers/storage/pkg/archive" "github.com/containers/storage/pkg/archive"
jsoniter "github.com/json-iterator/go" jsoniter "github.com/json-iterator/go"
spec "github.com/opencontainers/runtime-spec/specs-go" spec "github.com/opencontainers/runtime-spec/specs-go"
@ -112,7 +113,7 @@ func crImportCheckpoint(ctx context.Context, runtime *libpod.Runtime, input stri
return nil, err return nil, err
} }
_, err = runtime.ImageRuntime().New(ctx, config.RootfsImageName, rtc.SignaturePolicyPath, "", writer, nil, image.SigningOptions{}, false, nil) _, err = runtime.ImageRuntime().New(ctx, config.RootfsImageName, rtc.SignaturePolicyPath, "", writer, nil, image.SigningOptions{}, nil, util.PullImageMissing)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -19,6 +19,7 @@ import (
"github.com/containers/libpod/pkg/adapter/shortcuts" "github.com/containers/libpod/pkg/adapter/shortcuts"
ns "github.com/containers/libpod/pkg/namespaces" ns "github.com/containers/libpod/pkg/namespaces"
createconfig "github.com/containers/libpod/pkg/spec" createconfig "github.com/containers/libpod/pkg/spec"
"github.com/containers/libpod/pkg/util"
"github.com/containers/storage" "github.com/containers/storage"
"github.com/cri-o/ocicni/pkg/ocicni" "github.com/cri-o/ocicni/pkg/ocicni"
"github.com/ghodss/yaml" "github.com/ghodss/yaml"
@ -578,7 +579,7 @@ 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{}, false, nil) newImage, err := r.ImageRuntime().New(ctx, container.Image, c.SignaturePolicy, c.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, nil, util.PullImageMissing)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -24,6 +24,7 @@ import (
"github.com/containers/libpod/libpod/events" "github.com/containers/libpod/libpod/events"
"github.com/containers/libpod/libpod/image" "github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/rootless" "github.com/containers/libpod/pkg/rootless"
"github.com/containers/libpod/pkg/util"
"github.com/containers/storage/pkg/archive" "github.com/containers/storage/pkg/archive"
"github.com/pkg/errors" "github.com/pkg/errors"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
@ -132,8 +133,8 @@ func (r *LocalRuntime) LoadFromArchiveReference(ctx context.Context, srcRef type
} }
// New calls into local storage to look for an image in local storage or to pull it // New calls into local storage to look for an image in local storage or to pull it
func (r *LocalRuntime) New(ctx context.Context, name, signaturePolicyPath, authfile string, writer io.Writer, dockeroptions *image.DockerRegistryOptions, signingoptions image.SigningOptions, forcePull bool, label *string) (*ContainerImage, error) { func (r *LocalRuntime) New(ctx context.Context, name, signaturePolicyPath, authfile string, writer io.Writer, dockeroptions *image.DockerRegistryOptions, signingoptions image.SigningOptions, label *string, pullType util.PullType) (*ContainerImage, error) {
img, err := r.Runtime.ImageRuntime().New(ctx, name, signaturePolicyPath, authfile, writer, dockeroptions, signingoptions, forcePull, label) img, err := r.Runtime.ImageRuntime().New(ctx, name, signaturePolicyPath, authfile, writer, dockeroptions, signingoptions, label, pullType)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -25,6 +25,7 @@ import (
"github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/libpod/events" "github.com/containers/libpod/libpod/events"
"github.com/containers/libpod/libpod/image" "github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/util"
"github.com/containers/libpod/utils" "github.com/containers/libpod/utils"
"github.com/containers/storage/pkg/archive" "github.com/containers/storage/pkg/archive"
"github.com/opencontainers/go-digest" "github.com/opencontainers/go-digest"
@ -265,7 +266,7 @@ func (r *LocalRuntime) LoadFromArchiveReference(ctx context.Context, srcRef type
} }
// New calls into local storage to look for an image in local storage or to pull it // New calls into local storage to look for an image in local storage or to pull it
func (r *LocalRuntime) New(ctx context.Context, name, signaturePolicyPath, authfile string, writer io.Writer, dockeroptions *image.DockerRegistryOptions, signingoptions image.SigningOptions, forcePull bool, label *string) (*ContainerImage, error) { func (r *LocalRuntime) New(ctx context.Context, name, signaturePolicyPath, authfile string, writer io.Writer, dockeroptions *image.DockerRegistryOptions, signingoptions image.SigningOptions, label *string, pullType util.PullType) (*ContainerImage, error) {
var iid string var iid string
if label != nil { if label != nil {
return nil, errors.New("the remote client function does not support checking a remote image for a label") return nil, errors.New("the remote client function does not support checking a remote image for a label")

View File

@ -356,3 +356,32 @@ func OpenExclusiveFile(path string) (*os.File, error) {
} }
return os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666) return os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
} }
// PullType whether to pull new image
type PullType int
const (
// PullImageAlways always try to pull new image when create or run
PullImageAlways PullType = iota
// PullImageMissing pulls image if it is not locally
PullImageMissing
// PullImageNever will never pull new image
PullImageNever
)
// ValidatePullType check if the pullType from CLI is valid and returns the valid enum type
// if the value from CLI is invalid returns the error
func ValidatePullType(pullType string) (PullType, error) {
switch pullType {
case "always":
return PullImageAlways, nil
case "missing":
return PullImageMissing, nil
case "never":
return PullImageNever, nil
case "":
return PullImageMissing, nil
default:
return PullImageMissing, errors.Errorf("invalid pull type %q", pullType)
}
}

View File

@ -658,7 +658,7 @@ func (i *LibpodAPI) PullImage(call iopodman.VarlinkCall, name string) error {
imageID = newImage[0].ID() imageID = newImage[0].ID()
} }
} else { } else {
newImage, err := i.Runtime.ImageRuntime().New(getContext(), name, "", "", output, &dockerRegistryOptions, so, false, nil) newImage, err := i.Runtime.ImageRuntime().New(getContext(), name, "", "", output, &dockerRegistryOptions, so, nil, util.PullImageMissing)
if err != nil { if err != nil {
foundError = true foundError = true
c <- errors.Wrapf(err, "unable to pull %s", name) c <- errors.Wrapf(err, "unable to pull %s", name)

View File

@ -231,4 +231,14 @@ var _ = Describe("Podman create", func() {
Expect(ctrJSON[0].Config.Cmd[0]).To(Equal("redis-server")) Expect(ctrJSON[0].Config.Cmd[0]).To(Equal("redis-server"))
Expect(ctrJSON[0].Config.Entrypoint).To(Equal("docker-entrypoint.sh")) Expect(ctrJSON[0].Config.Entrypoint).To(Equal("docker-entrypoint.sh"))
}) })
It("podman create --pull", func() {
session := podmanTest.PodmanNoCache([]string{"create", "--pull", "never", "--name=foo", "nginx"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Not(Equal(0)))
session = podmanTest.PodmanNoCache([]string{"create", "--pull", "always", "--name=foo", "nginx"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To((Equal(0)))
})
}) })