diff options
-rw-r--r-- | cmd/podman/common/create.go | 2 | ||||
-rw-r--r-- | cmd/podman/containers/create.go | 1 | ||||
-rw-r--r-- | libpod/image/utils.go | 2 | ||||
-rw-r--r-- | pkg/api/handlers/compat/images.go | 14 | ||||
-rw-r--r-- | pkg/bindings/network/network.go | 2 | ||||
-rw-r--r-- | pkg/domain/entities/images.go | 7 | ||||
-rw-r--r-- | pkg/domain/infra/abi/images.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/abi/network.go | 15 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/network.go | 11 | ||||
-rw-r--r-- | test/e2e/network_test.go | 50 | ||||
-rw-r--r-- | test/e2e/run_apparmor_test.go | 2 | ||||
-rw-r--r-- | test/e2e/run_test.go | 42 |
12 files changed, 135 insertions, 15 deletions
diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go index 7e3dc7fb4..bb4726817 100644 --- a/cmd/podman/common/create.go +++ b/cmd/podman/common/create.go @@ -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( diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go index 96d94dc00..d75352848 100644 --- a/cmd/podman/containers/create.go +++ b/cmd/podman/containers/create.go @@ -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 diff --git a/libpod/image/utils.go b/libpod/image/utils.go index 918314476..2538f429b 100644 --- a/libpod/image/utils.go +++ b/libpod/image/utils.go @@ -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 } diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go index c1ba9ca66..0900d1793 100644 --- a/pkg/api/handlers/compat/images.go +++ b/pkg/api/handlers/compat/images.go @@ -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) { ®istryOpts, image2.SigningOptions{}, nil, // label - util.PullImageMissing, + pullPolicy, ) if err != nil { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err) diff --git a/pkg/bindings/network/network.go b/pkg/bindings/network/network.go index d8dc7e352..151d15d3e 100644 --- a/pkg/bindings/network/network.go +++ b/pkg/bindings/network/network.go @@ -60,7 +60,7 @@ func Remove(ctx context.Context, nameOrID string, force *bool) ([]*entities.Netw } params := url.Values{} if force != nil { - params.Set("size", strconv.FormatBool(*force)) + params.Set("force", strconv.FormatBool(*force)) } response, err := conn.DoRequest(nil, http.MethodDelete, "/networks/%s", params, nil, nameOrID) if err != nil { diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go index cad6693fa..ac81c282d 100644 --- a/pkg/domain/entities/images.go +++ b/pkg/domain/entities/images.go @@ -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. diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go index 25c0c184f..d56dc7d94 100644 --- a/pkg/domain/infra/abi/images.go +++ b/pkg/domain/infra/abi/images.go @@ -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 } diff --git a/pkg/domain/infra/abi/network.go b/pkg/domain/infra/abi/network.go index 807e4b272..053be6528 100644 --- a/pkg/domain/infra/abi/network.go +++ b/pkg/domain/infra/abi/network.go @@ -82,12 +82,21 @@ func (ic *ContainerEngine) NetworkRm(ctx context.Context, namesOrIds []string, o // We need to iterate containers looking to see if they belong to the given network for _, c := range containers { if util.StringInSlice(name, c.Config().Networks) { - // if user passes force, we nuke containers + // if user passes force, we nuke containers and pods if !options.Force { // Without the force option, we return an error - return reports, errors.Errorf("%q has associated containers with it. Use -f to forcibly delete containers", name) + return reports, errors.Errorf("%q has associated containers with it. Use -f to forcibly delete containers and pods", name) } - if err := ic.Libpod.RemoveContainer(ctx, c, true, true); err != nil { + if c.IsInfra() { + // if we have a infra container we need to remove the pod + pod, err := ic.Libpod.GetPod(c.PodID()) + if err != nil { + return reports, err + } + if err := ic.Libpod.RemovePod(ctx, pod, true, true); err != nil { + return reports, err + } + } else if err := ic.Libpod.RemoveContainer(ctx, c, true, true); err != nil { return reports, err } } diff --git a/pkg/domain/infra/tunnel/network.go b/pkg/domain/infra/tunnel/network.go index 074425087..d155fdd9e 100644 --- a/pkg/domain/infra/tunnel/network.go +++ b/pkg/domain/infra/tunnel/network.go @@ -26,11 +26,16 @@ func (ic *ContainerEngine) NetworkInspect(ctx context.Context, namesOrIds []stri func (ic *ContainerEngine) NetworkRm(ctx context.Context, namesOrIds []string, options entities.NetworkRmOptions) ([]*entities.NetworkRmReport, error) { reports := make([]*entities.NetworkRmReport, 0, len(namesOrIds)) for _, name := range namesOrIds { - report, err := network.Remove(ic.ClientCxt, name, &options.Force) + response, err := network.Remove(ic.ClientCxt, name, &options.Force) if err != nil { - report[0].Err = err + report := &entities.NetworkRmReport{ + Name: name, + Err: err, + } + reports = append(reports, report) + } else { + reports = append(reports, response...) } - reports = append(reports, report...) } return reports, nil } diff --git a/test/e2e/network_test.go b/test/e2e/network_test.go index d0c096895..2ea8291fc 100644 --- a/test/e2e/network_test.go +++ b/test/e2e/network_test.go @@ -264,4 +264,54 @@ var _ = Describe("Podman network", func() { rmAll.WaitWithDefaultTimeout() Expect(rmAll.ExitCode()).To(BeZero()) }) + + It("podman network remove --force with pod", func() { + netName := "testnet" + session := podmanTest.Podman([]string{"network", "create", netName}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(BeZero()) + + session = podmanTest.Podman([]string{"pod", "create", "--network", netName}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(BeZero()) + podID := session.OutputToString() + + session = podmanTest.Podman([]string{"create", "--pod", podID, ALPINE}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(BeZero()) + + session = podmanTest.Podman([]string{"network", "rm", "--force", netName}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(BeZero()) + + // check if pod is deleted + session = podmanTest.Podman([]string{"pod", "exists", podID}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(1)) + + // check if net is deleted + session = podmanTest.Podman([]string{"network", "ls"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(BeZero()) + Expect(session.OutputToString()).To(Not(ContainSubstring(netName))) + }) + + It("podman network remove with two networks", func() { + netName1 := "net1" + session := podmanTest.Podman([]string{"network", "create", netName1}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(BeZero()) + + netName2 := "net2" + session = podmanTest.Podman([]string{"network", "create", netName2}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(BeZero()) + + session = podmanTest.Podman([]string{"network", "rm", netName1, netName2}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(BeZero()) + lines := session.OutputToStringArray() + Expect(lines[0]).To(Equal(netName1)) + Expect(lines[1]).To(Equal(netName2)) + }) }) diff --git a/test/e2e/run_apparmor_test.go b/test/e2e/run_apparmor_test.go index 7d522a752..0faf0b496 100644 --- a/test/e2e/run_apparmor_test.go +++ b/test/e2e/run_apparmor_test.go @@ -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)) diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index 0bb3fe772..5c28f18f2 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -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")) + }) }) |