diff options
30 files changed, 437 insertions, 122 deletions
diff --git a/cmd/podman/images/build.go b/cmd/podman/images/build.go index f757b764f..da6d556b1 100644 --- a/cmd/podman/images/build.go +++ b/cmd/podman/images/build.go @@ -303,6 +303,21 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil return nil, err } + pullFlagsCount := 0 + if c.Flag("pull").Changed { + pullFlagsCount++ + } + if c.Flag("pull-always").Changed { + pullFlagsCount++ + } + if c.Flag("pull-never").Changed { + pullFlagsCount++ + } + + if pullFlagsCount > 1 { + return nil, errors.Errorf("can only set one of 'pull' or 'pull-always' or 'pull-never'") + } + pullPolicy := define.PullIfMissing if c.Flags().Changed("pull") && flags.Pull { pullPolicy = define.PullAlways @@ -312,7 +327,7 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil } if flags.PullNever { - pullPolicy = define.PullIfMissing + pullPolicy = define.PullNever } args := make(map[string]string) diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go index 15ba5c685..36785a362 100644 --- a/pkg/api/handlers/compat/images_build.go +++ b/pkg/api/handlers/compat/images_build.go @@ -13,6 +13,7 @@ import ( "time" "github.com/containers/buildah" + "github.com/containers/buildah/define" "github.com/containers/buildah/imagebuildah" "github.com/containers/buildah/util" "github.com/containers/image/v5/types" @@ -98,6 +99,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { OutputFormat string `schema:"outputformat"` Platform string `schema:"platform"` Pull bool `schema:"pull"` + PullPolicy string `schema:"pullpolicy"` Quiet bool `schema:"q"` Registry string `schema:"registry"` Rm bool `schema:"rm"` @@ -275,10 +277,14 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { jobs = query.Jobs } - pullPolicy := buildah.PullIfMissing - if _, found := r.URL.Query()["pull"]; found { - if query.Pull { - pullPolicy = buildah.PullAlways + pullPolicy := define.PullIfMissing + if utils.IsLibpodRequest(r) { + pullPolicy = define.PolicyMap[query.PullPolicy] + } else { + if _, found := r.URL.Query()["pull"]; found { + if query.Pull { + pullPolicy = define.PullAlways + } } } diff --git a/pkg/bindings/images/build.go b/pkg/bindings/images/build.go index 9d77883f9..17095b84b 100644 --- a/pkg/bindings/images/build.go +++ b/pkg/bindings/images/build.go @@ -15,7 +15,6 @@ import ( "strconv" "strings" - "github.com/containers/buildah" "github.com/containers/podman/v3/pkg/auth" "github.com/containers/podman/v3/pkg/bindings" "github.com/containers/podman/v3/pkg/domain/entities" @@ -175,9 +174,9 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO if len(platform) > 0 { params.Set("platform", platform) } - if options.PullPolicy == buildah.PullAlways { - params.Set("pull", "1") - } + + params.Set("pullpolicy", options.PullPolicy.String()) + if options.Quiet { params.Set("q", "1") } diff --git a/pkg/machine/qemu/options_linux_amd64.go b/pkg/machine/qemu/options_linux_amd64.go index cc0a4bab2..3edd97ea1 100644 --- a/pkg/machine/qemu/options_linux_amd64.go +++ b/pkg/machine/qemu/options_linux_amd64.go @@ -1,11 +1,14 @@ package qemu var ( - QemuCommand = "qemu-kvm" + QemuCommand = "qemu-system-x86_64" ) func (v *MachineVM) addArchOptions() []string { - opts := []string{"-cpu", "host"} + opts := []string{ + "-accel", "kvm", + "-cpu", "host", + } return opts } diff --git a/pkg/systemd/generate/common.go b/pkg/systemd/generate/common.go index 19d468403..eafd45528 100644 --- a/pkg/systemd/generate/common.go +++ b/pkg/systemd/generate/common.go @@ -39,20 +39,46 @@ After=network-online.target RequiresMountsFor={{{{.GraphRoot}}}} {{{{.RunRoot}}}} ` -// filterPodFlags removes --pod and --pod-id-file from the specified command. -func filterPodFlags(command []string) []string { +// filterPodFlags removes --pod, --pod-id-file and --infra-conmon-pidfile from the specified command. +// argCount is the number of last arguments which should not be filtered, e.g. the container entrypoint. +func filterPodFlags(command []string, argCount int) []string { processed := []string{} - for i := 0; i < len(command); i++ { + for i := 0; i < len(command)-argCount; i++ { s := command[i] - if s == "--pod" || s == "--pod-id-file" { + if s == "--pod" || s == "--pod-id-file" || s == "--infra-conmon-pidfile" { i++ continue } - if strings.HasPrefix(s, "--pod=") || strings.HasPrefix(s, "--pod-id-file=") { + if strings.HasPrefix(s, "--pod=") || + strings.HasPrefix(s, "--pod-id-file=") || + strings.HasPrefix(s, "--infra-conmon-pidfile=") { continue } processed = append(processed, s) } + processed = append(processed, command[len(command)-argCount:]...) + return processed +} + +// filterCommonContainerFlags removes --conmon-pidfile, --cidfile and --cgroups from the specified command. +// argCount is the number of last arguments which should not be filtered, e.g. the container entrypoint. +func filterCommonContainerFlags(command []string, argCount int) []string { + processed := []string{} + for i := 0; i < len(command)-argCount; i++ { + s := command[i] + + switch { + case s == "--conmon-pidfile", s == "--cidfile", s == "--cgroups": + i++ + continue + case strings.HasPrefix(s, "--conmon-pidfile="), + strings.HasPrefix(s, "--cidfile="), + strings.HasPrefix(s, "--cgroups="): + continue + } + processed = append(processed, s) + } + processed = append(processed, command[len(command)-argCount:]...) return processed } diff --git a/pkg/systemd/generate/common_test.go b/pkg/systemd/generate/common_test.go index 3787e461e..30e758127 100644 --- a/pkg/systemd/generate/common_test.go +++ b/pkg/systemd/generate/common_test.go @@ -1,7 +1,6 @@ package generate import ( - "strings" "testing" "github.com/stretchr/testify/assert" @@ -9,22 +8,144 @@ import ( func TestFilterPodFlags(t *testing.T) { tests := []struct { - input []string + input []string + output []string + argCount int }{ - {[]string{"podman", "pod", "create"}}, - {[]string{"podman", "pod", "create", "--name", "foo"}}, - {[]string{"podman", "pod", "create", "--pod-id-file", "foo"}}, - {[]string{"podman", "pod", "create", "--pod-id-file=foo"}}, - {[]string{"podman", "run", "--pod", "foo"}}, - {[]string{"podman", "run", "--pod=foo"}}, + { + []string{"podman", "pod", "create"}, + []string{"podman", "pod", "create"}, + 0, + }, + { + []string{"podman", "pod", "create", "--name", "foo"}, + []string{"podman", "pod", "create", "--name", "foo"}, + 0, + }, + { + []string{"podman", "pod", "create", "--pod-id-file", "foo"}, + []string{"podman", "pod", "create"}, + 0, + }, + { + []string{"podman", "pod", "create", "--pod-id-file=foo"}, + []string{"podman", "pod", "create"}, + 0, + }, + { + []string{"podman", "pod", "create", "--pod-id-file", "foo", "--infra-conmon-pidfile", "foo"}, + []string{"podman", "pod", "create"}, + 0, + }, + { + []string{"podman", "pod", "create", "--pod-id-file", "foo", "--infra-conmon-pidfile=foo"}, + []string{"podman", "pod", "create"}, + 0, + }, + { + []string{"podman", "run", "--pod", "foo"}, + []string{"podman", "run"}, + 0, + }, + { + []string{"podman", "run", "--pod=foo"}, + []string{"podman", "run"}, + 0, + }, + { + []string{"podman", "run", "--pod=foo", "fedora", "podman", "run", "--pod=test", "alpine"}, + []string{"podman", "run", "fedora", "podman", "run", "--pod=test", "alpine"}, + 5, + }, + { + []string{"podman", "run", "--pod", "foo", "fedora", "podman", "run", "--pod", "test", "alpine"}, + []string{"podman", "run", "fedora", "podman", "run", "--pod", "test", "alpine"}, + 6, + }, + { + []string{"podman", "run", "--pod-id-file=foo", "fedora", "podman", "run", "--pod-id-file=test", "alpine"}, + []string{"podman", "run", "fedora", "podman", "run", "--pod-id-file=test", "alpine"}, + 5, + }, + { + []string{"podman", "run", "--pod-id-file", "foo", "fedora", "podman", "run", "--pod-id-file", "test", "alpine"}, + []string{"podman", "run", "fedora", "podman", "run", "--pod-id-file", "test", "alpine"}, + 6, + }, + } + + for _, test := range tests { + processed := filterPodFlags(test.input, test.argCount) + assert.Equal(t, test.output, processed) + } +} + +func TestFilterCommonContainerFlags(t *testing.T) { + tests := []struct { + input []string + output []string + argCount int + }{ + { + []string{"podman", "run", "alpine"}, + []string{"podman", "run", "alpine"}, + 1, + }, + { + []string{"podman", "run", "--conmon-pidfile", "foo", "alpine"}, + []string{"podman", "run", "alpine"}, + 1, + }, + { + []string{"podman", "run", "--conmon-pidfile=foo", "alpine"}, + []string{"podman", "run", "alpine"}, + 1, + }, + { + []string{"podman", "run", "--cidfile", "foo", "alpine"}, + []string{"podman", "run", "alpine"}, + 1, + }, + { + []string{"podman", "run", "--cidfile=foo", "alpine"}, + []string{"podman", "run", "alpine"}, + 1, + }, + { + []string{"podman", "run", "--cgroups", "foo", "alpine"}, + []string{"podman", "run", "alpine"}, + 1, + }, + { + []string{"podman", "run", "--cgroups=foo", "alpine"}, + []string{"podman", "run", "alpine"}, + 1, + }, + { + []string{"podman", "run", "--cgroups", "foo", "--conmon-pidfile", "foo", "--cidfile", "foo", "alpine"}, + []string{"podman", "run", "alpine"}, + 1, + }, + { + []string{"podman", "run", "--cgroups=foo", "--conmon-pidfile=foo", "--cidfile=foo", "alpine"}, + []string{"podman", "run", "alpine"}, + 1, + }, + { + []string{"podman", "run", "--cgroups", "foo", "--conmon-pidfile", "foo", "--cidfile", "foo", "alpine", "--cgroups", "foo", "--conmon-pidfile", "foo", "--cidfile", "foo"}, + []string{"podman", "run", "alpine", "--cgroups", "foo", "--conmon-pidfile", "foo", "--cidfile", "foo"}, + 7, + }, + { + []string{"podman", "run", "--cgroups=foo", "--conmon-pidfile=foo", "--cidfile=foo", "alpine", "--cgroups=foo", "--conmon-pidfile=foo", "--cidfile=foo"}, + []string{"podman", "run", "alpine", "--cgroups=foo", "--conmon-pidfile=foo", "--cidfile=foo"}, + 4, + }, } for _, test := range tests { - processed := filterPodFlags(test.input) - for _, s := range processed { - assert.False(t, strings.HasPrefix(s, "--pod-id-file")) - assert.False(t, strings.HasPrefix(s, "--pod")) - } + processed := filterCommonContainerFlags(test.input, test.argCount) + assert.Equal(t, test.output, processed) } } diff --git a/pkg/systemd/generate/containers.go b/pkg/systemd/generate/containers.go index bc13a6116..e06655a8d 100644 --- a/pkg/systemd/generate/containers.go +++ b/pkg/systemd/generate/containers.go @@ -238,13 +238,7 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst "--cidfile", "{{{{.ContainerIDFile}}}}", "--cgroups=no-conmon", ) - // If the container is in a pod, make sure that the - // --pod-id-file is set correctly. - if info.Pod != nil { - podFlags := []string{"--pod-id-file", "{{{{.Pod.PodIDFile}}}}"} - startCommand = append(startCommand, podFlags...) - info.CreateCommand = filterPodFlags(info.CreateCommand) - } + remainingCmd := info.CreateCommand[index:] // Presence check for certain flags/options. fs := pflag.NewFlagSet("args", pflag.ContinueOnError) @@ -254,7 +248,16 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst fs.BoolP("detach", "d", false, "") fs.String("name", "", "") fs.Bool("replace", false, "") - fs.Parse(info.CreateCommand[index:]) + fs.Parse(remainingCmd) + + remainingCmd = filterCommonContainerFlags(remainingCmd, fs.NArg()) + // If the container is in a pod, make sure that the + // --pod-id-file is set correctly. + if info.Pod != nil { + podFlags := []string{"--pod-id-file", "{{{{.Pod.PodIDFile}}}}"} + startCommand = append(startCommand, podFlags...) + remainingCmd = filterPodFlags(remainingCmd, fs.NArg()) + } hasDetachParam, err := fs.GetBool("detach") if err != nil { @@ -266,8 +269,6 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst return "", err } - remainingCmd := info.CreateCommand[index:] - if !hasDetachParam { // Enforce detaching // diff --git a/pkg/systemd/generate/containers_test.go b/pkg/systemd/generate/containers_test.go index 1359c1a37..899ba6bfa 100644 --- a/pkg/systemd/generate/containers_test.go +++ b/pkg/systemd/generate/containers_test.go @@ -395,6 +395,56 @@ Type=forking [Install] WantedBy=multi-user.target default.target ` + + goodNewWithIDFiles := `# jadda-jadda.service +# autogenerated by Podman CI + +[Unit] +Description=Podman jadda-jadda.service +Documentation=man:podman-generate-systemd(1) +Wants=network.target +After=network-online.target +RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage + +[Service] +Environment=PODMAN_SYSTEMD_UNIT=%n +Restart=always +TimeoutStopSec=70 +ExecStartPre=/bin/rm -f %t/jadda-jadda.pid %t/jadda-jadda.ctr-id +ExecStart=/usr/bin/podman run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon -d awesome-image:latest podman run --cgroups=foo --conmon-pidfile=foo --cidfile=foo alpine +ExecStop=/usr/bin/podman stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 10 +ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/jadda-jadda.ctr-id +PIDFile=%t/jadda-jadda.pid +Type=forking + +[Install] +WantedBy=multi-user.target default.target +` + + goodNewWithPodIDFiles := `# jadda-jadda.service +# autogenerated by Podman CI + +[Unit] +Description=Podman jadda-jadda.service +Documentation=man:podman-generate-systemd(1) +Wants=network.target +After=network-online.target +RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage + +[Service] +Environment=PODMAN_SYSTEMD_UNIT=%n +Restart=always +TimeoutStopSec=70 +ExecStartPre=/bin/rm -f %t/jadda-jadda.pid %t/jadda-jadda.ctr-id +ExecStart=/usr/bin/podman run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon --pod-id-file %t/pod-foobar.pod-id-file -d awesome-image:latest podman run --cgroups=foo --conmon-pidfile=foo --cidfile=foo --pod-id-file /tmp/pod-foobar.pod-id-file alpine +ExecStop=/usr/bin/podman stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 10 +ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/jadda-jadda.ctr-id +PIDFile=%t/jadda-jadda.pid +Type=forking + +[Install] +WantedBy=multi-user.target default.target +` tests := []struct { name string info containerInfo @@ -782,6 +832,47 @@ WantedBy=multi-user.target default.target false, false, }, + {"good with ID files", + containerInfo{ + Executable: "/usr/bin/podman", + ServiceName: "jadda-jadda", + ContainerNameOrID: "jadda-jadda", + RestartPolicy: "always", + PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", + StopTimeout: 10, + PodmanVersion: "CI", + GraphRoot: "/var/lib/containers/storage", + RunRoot: "/var/run/containers/storage", + CreateCommand: []string{"I'll get stripped", "create", "--cgroups=foo", "--conmon-pidfile=foo", "--cidfile=foo", "awesome-image:latest", "podman", "run", "--cgroups=foo", "--conmon-pidfile=foo", "--cidfile=foo", "alpine"}, + EnvVariable: define.EnvVariable, + }, + goodNewWithIDFiles, + true, + false, + false, + }, + {"good with pod ID files", + containerInfo{ + Executable: "/usr/bin/podman", + ServiceName: "jadda-jadda", + ContainerNameOrID: "jadda-jadda", + RestartPolicy: "always", + PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", + StopTimeout: 10, + PodmanVersion: "CI", + GraphRoot: "/var/lib/containers/storage", + RunRoot: "/var/run/containers/storage", + CreateCommand: []string{"I'll get stripped", "create", "--cgroups=foo", "--conmon-pidfile=foo", "--cidfile=foo", "--pod", "test", "awesome-image:latest", "podman", "run", "--cgroups=foo", "--conmon-pidfile=foo", "--cidfile=foo", "--pod-id-file", "/tmp/pod-foobar.pod-id-file", "alpine"}, + EnvVariable: define.EnvVariable, + Pod: &podInfo{ + PodIDFile: "%t/pod-foobar.pod-id-file", + }, + }, + goodNewWithPodIDFiles, + true, + false, + false, + }, } for _, tt := range tests { test := tt diff --git a/pkg/systemd/generate/pods.go b/pkg/systemd/generate/pods.go index a76979ecf..1b92649e8 100644 --- a/pkg/systemd/generate/pods.go +++ b/pkg/systemd/generate/pods.go @@ -279,16 +279,16 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions) } podRootArgs = info.CreateCommand[1 : podCreateIndex-1] info.RootFlags = strings.Join(escapeSystemdArguments(podRootArgs), " ") - podCreateArgs = filterPodFlags(info.CreateCommand[podCreateIndex+1:]) + podCreateArgs = filterPodFlags(info.CreateCommand[podCreateIndex+1:], 0) } // We're hard-coding the first five arguments and append the // CreateCommand with a stripped command and subcommand. startCommand := []string{info.Executable} startCommand = append(startCommand, podRootArgs...) startCommand = append(startCommand, - []string{"pod", "create", - "--infra-conmon-pidfile", "{{{{.PIDFile}}}}", - "--pod-id-file", "{{{{.PodIDFile}}}}"}...) + "pod", "create", + "--infra-conmon-pidfile", "{{{{.PIDFile}}}}", + "--pod-id-file", "{{{{.PodIDFile}}}}") // Presence check for certain flags/options. fs := pflag.NewFlagSet("args", pflag.ContinueOnError) diff --git a/pkg/systemd/generate/pods_test.go b/pkg/systemd/generate/pods_test.go index 559f7365f..0e4d92c50 100644 --- a/pkg/systemd/generate/pods_test.go +++ b/pkg/systemd/generate/pods_test.go @@ -320,6 +320,25 @@ WantedBy=multi-user.target default.target false, false, }, + {"pod --new with ID files", + podInfo{ + Executable: "/usr/bin/podman", + ServiceName: "pod-123abc", + InfraNameOrID: "jadda-jadda-infra", + RestartPolicy: "on-failure", + PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", + StopTimeout: 10, + PodmanVersion: "CI", + GraphRoot: "/var/lib/containers/storage", + RunRoot: "/var/run/containers/storage", + RequiredServices: []string{"container-1", "container-2"}, + CreateCommand: []string{"podman", "pod", "create", "--infra-conmon-pidfile", "/tmp/pod-123abc.pid", "--pod-id-file", "/tmp/pod-123abc.pod-id", "--name", "foo", "bar=arg with space"}, + }, + podGoodNamedNew, + true, + false, + false, + }, } for _, tt := range tests { diff --git a/test/e2e/build/basicalpine/Containerfile b/test/e2e/build/basicalpine/Containerfile index 67fd37901..f6e07066c 100644 --- a/test/e2e/build/basicalpine/Containerfile +++ b/test/e2e/build/basicalpine/Containerfile @@ -1 +1 @@ -FROM alpine +FROM quay.io/libpod/alpine:latest diff --git a/test/e2e/build/basicalpine/Containerfile.path b/test/e2e/build/basicalpine/Containerfile.path index d2b03a6b8..a1349eb05 100644 --- a/test/e2e/build/basicalpine/Containerfile.path +++ b/test/e2e/build/basicalpine/Containerfile.path @@ -1,2 +1,2 @@ -FROM alpine +FROM quay.io/libpod/alpine:latest ENV PATH=/tmp:/bin:/usr/bin:/usr/sbin diff --git a/test/e2e/build/basicalpine/Containerfile.volume b/test/e2e/build/basicalpine/Containerfile.volume index 6a4fc8242..283d6376e 100644 --- a/test/e2e/build/basicalpine/Containerfile.volume +++ b/test/e2e/build/basicalpine/Containerfile.volume @@ -1,2 +1,2 @@ -FROM alpine +FROM quay.io/libpod/alpine:latest VOLUME "/volume0" diff --git a/test/e2e/build/squash/Dockerfile.squash-a b/test/e2e/build/squash/Dockerfile.squash-a index f084e093d..ade3eafce 100644 --- a/test/e2e/build/squash/Dockerfile.squash-a +++ b/test/e2e/build/squash/Dockerfile.squash-a @@ -1,2 +1,2 @@ -FROM busybox:latest +FROM quay.io/libpod/busybox:latest ADD alpinetest.tgz /data diff --git a/test/e2e/build/squash/Dockerfile.squash-c b/test/e2e/build/squash/Dockerfile.squash-c index df9c90388..63bf84e69 100644 --- a/test/e2e/build/squash/Dockerfile.squash-c +++ b/test/e2e/build/squash/Dockerfile.squash-c @@ -1,3 +1,3 @@ -FROM busybox:latest +FROM quay.io/libpod/busybox:latest ADD alpinetest.tgz /data RUN rm -rf /data diff --git a/test/e2e/build_test.go b/test/e2e/build_test.go index e061a2154..95ed23313 100644 --- a/test/e2e/build_test.go +++ b/test/e2e/build_test.go @@ -1,6 +1,7 @@ package integration import ( + "fmt" "io/ioutil" "os" "path/filepath" @@ -150,7 +151,7 @@ var _ = Describe("Podman build", func() { } fakeFile := filepath.Join(os.TempDir(), "Containerfile") - Expect(ioutil.WriteFile(fakeFile, []byte("FROM alpine"), 0755)).To(BeNil()) + Expect(ioutil.WriteFile(fakeFile, []byte(fmt.Sprintf("FROM %s", ALPINE)), 0755)).To(BeNil()) targetFile := filepath.Join(targetPath, "Containerfile") Expect(ioutil.WriteFile(targetFile, []byte("FROM scratch"), 0755)).To(BeNil()) @@ -219,8 +220,8 @@ var _ = Describe("Podman build", func() { podmanTest.StartRemoteService() } podmanTest.AddImageToRWStore(ALPINE) - dockerfile := `FROM quay.io/libpod/alpine:latest -RUN printenv http_proxy` + dockerfile := fmt.Sprintf(`FROM %s +RUN printenv http_proxy`, ALPINE) dockerfilePath := filepath.Join(podmanTest.TempDir, "Dockerfile") err := ioutil.WriteFile(dockerfilePath, []byte(dockerfile), 0755) @@ -263,9 +264,9 @@ RUN printenv http_proxy` err = ioutil.WriteFile(dummyFile, []byte("dummy"), 0644) Expect(err).To(BeNil()) - containerfile := `FROM quay.io/libpod/alpine:latest + containerfile := fmt.Sprintf(`FROM %s ADD . /test -RUN find /test` +RUN find /test`, ALPINE) containerfilePath := filepath.Join(targetPath, "Containerfile") err = ioutil.WriteFile(containerfilePath, []byte(containerfile), 0644) @@ -307,7 +308,7 @@ RUN find /test` err = os.Mkdir(targetSubPath, 0755) Expect(err).To(BeNil()) - containerfile := `FROM quay.io/libpod/alpine:latest` + containerfile := fmt.Sprintf("FROM %s", ALPINE) containerfilePath := filepath.Join(targetSubPath, "Containerfile") err = ioutil.WriteFile(containerfilePath, []byte(containerfile), 0644) @@ -344,9 +345,9 @@ RUN find /test` targetPath, err := CreateTempDirInTempDir() Expect(err).To(BeNil()) - containerfile := `FROM quay.io/libpod/alpine:latest + containerfile := fmt.Sprintf(`FROM %s ADD . /testfilter/ -RUN find /testfilter/` +RUN find /testfilter/`, ALPINE) containerfilePath := filepath.Join(targetPath, "Containerfile") err = ioutil.WriteFile(containerfilePath, []byte(containerfile), 0644) @@ -428,10 +429,10 @@ subdir**` Expect(os.Chdir(targetSubPath)).To(BeNil()) Expect(os.Symlink("dummy", "dummy-symlink")).To(BeNil()) - containerfile := `FROM quay.io/libpod/alpine:latest + containerfile := fmt.Sprintf(`FROM %s ADD . /test RUN find /test -RUN [[ -L /test/dummy-symlink ]] && echo SYMLNKOK || echo SYMLNKERR` +RUN [[ -L /test/dummy-symlink ]] && echo SYMLNKOK || echo SYMLNKERR`, ALPINE) containerfilePath := filepath.Join(targetSubPath, "Containerfile") err = ioutil.WriteFile(containerfilePath, []byte(containerfile), 0644) @@ -475,14 +476,14 @@ RUN grep CapEff /proc/self/status` // When session := podmanTest.Podman([]string{ - "build", "--pull-never", "--cap-drop=all", "--cap-add=net_bind_service", "--add-host", "testhost:1.2.3.4", "--from", "alpine", targetPath, + "build", "--pull-never", "--cap-drop=all", "--cap-add=net_bind_service", "--add-host", "testhost:1.2.3.4", "--from", ALPINE, targetPath, }) session.WaitWithDefaultTimeout() // Then Expect(session.ExitCode()).To(Equal(0)) Expect(strings.Fields(session.OutputToString())). - To(ContainElement("alpine")) + To(ContainElement(ALPINE)) Expect(strings.Fields(session.OutputToString())). To(ContainElement("testhost")) Expect(strings.Fields(session.OutputToString())). @@ -494,7 +495,7 @@ RUN grep CapEff /proc/self/status` Expect(err).To(BeNil()) containerFile := filepath.Join(targetPath, "Containerfile") - Expect(ioutil.WriteFile(containerFile, []byte("FROM alpine"), 0755)).To(BeNil()) + Expect(ioutil.WriteFile(containerFile, []byte(fmt.Sprintf("FROM %s", ALPINE)), 0755)).To(BeNil()) defer func() { Expect(os.RemoveAll(containerFile)).To(BeNil()) @@ -502,7 +503,7 @@ RUN grep CapEff /proc/self/status` // When session := podmanTest.Podman([]string{ - "build", "--pull-never", "--isolation", "oci", "--arch", "arm64", targetPath, + "build", "--isolation", "oci", "--arch", "arm64", targetPath, }) session.WaitWithDefaultTimeout() // Then @@ -510,7 +511,7 @@ RUN grep CapEff /proc/self/status` // When session = podmanTest.Podman([]string{ - "build", "--pull-never", "--isolation", "chroot", "--arch", "arm64", targetPath, + "build", "--isolation", "chroot", "--arch", "arm64", targetPath, }) session.WaitWithDefaultTimeout() // Then @@ -534,8 +535,8 @@ RUN grep CapEff /proc/self/status` }) It("podman build --timestamp flag", func() { - containerfile := `FROM quay.io/libpod/alpine:latest -RUN echo hello` + containerfile := fmt.Sprintf(`FROM %s +RUN echo hello`, ALPINE) containerfilePath := filepath.Join(podmanTest.TempDir, "Containerfile") err := ioutil.WriteFile(containerfilePath, []byte(containerfile), 0755) diff --git a/test/e2e/containers_conf_test.go b/test/e2e/containers_conf_test.go index aa2380c51..803124de1 100644 --- a/test/e2e/containers_conf_test.go +++ b/test/e2e/containers_conf_test.go @@ -91,7 +91,7 @@ var _ = Describe("Podman run", func() { if IsRemote() { podmanTest.RestartRemoteService() } - session := podmanTest.Podman([]string{"run", "busybox", "grep", "CapEff", "/proc/self/status"}) + session := podmanTest.Podman([]string{"run", BB, "grep", "CapEff", "/proc/self/status"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).ToNot(Equal(cap.OutputToString())) diff --git a/test/e2e/exec_test.go b/test/e2e/exec_test.go index 2ffb5cd2e..df86eab15 100644 --- a/test/e2e/exec_test.go +++ b/test/e2e/exec_test.go @@ -475,10 +475,10 @@ var _ = Describe("Podman exec", func() { }) It("podman exec preserves container groups with --user and --group-add", func() { - dockerfile := `FROM registry.fedoraproject.org/fedora-minimal + dockerfile := fmt.Sprintf(`FROM %s RUN groupadd -g 4000 first RUN groupadd -g 4001 second -RUN useradd -u 1000 auser` +RUN useradd -u 1000 auser`, fedoraMinimal) imgName := "testimg" podmanTest.BuildImage(dockerfile, imgName, "false") diff --git a/test/e2e/prune_test.go b/test/e2e/prune_test.go index 73da77417..cbe38fc76 100644 --- a/test/e2e/prune_test.go +++ b/test/e2e/prune_test.go @@ -1,6 +1,7 @@ package integration import ( + "fmt" "os" . "github.com/containers/podman/v3/test/utils" @@ -8,11 +9,11 @@ import ( . "github.com/onsi/gomega" ) -var pruneImage = ` -FROM alpine:latest +var pruneImage = fmt.Sprintf(` +FROM %s LABEL RUN podman --version RUN apk update -RUN apk add bash` +RUN apk add bash`, ALPINE) var _ = Describe("Podman prune", func() { var ( diff --git a/test/e2e/ps_test.go b/test/e2e/ps_test.go index ac0910a83..37b6516c1 100644 --- a/test/e2e/ps_test.go +++ b/test/e2e/ps_test.go @@ -351,7 +351,7 @@ var _ = Describe("Podman ps", func() { }) It("podman --format by size", func() { - session := podmanTest.Podman([]string{"create", "busybox", "ls"}) + session := podmanTest.Podman([]string{"create", BB, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -366,7 +366,7 @@ var _ = Describe("Podman ps", func() { }) It("podman --sort by size", func() { - session := podmanTest.Podman([]string{"create", "busybox", "ls"}) + session := podmanTest.Podman([]string{"create", BB, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) diff --git a/test/e2e/rmi_test.go b/test/e2e/rmi_test.go index d8367d636..5e6d66d53 100644 --- a/test/e2e/rmi_test.go +++ b/test/e2e/rmi_test.go @@ -184,19 +184,20 @@ var _ = Describe("Podman rmi", func() { It("podman rmi with cached images", func() { podmanTest.AddImageToRWStore(cirros) - dockerfile := `FROM quay.io/libpod/cirros:latest + dockerfile := fmt.Sprintf(`FROM %s RUN mkdir hello RUN touch test.txt ENV foo=bar - ` + `, cirros) podmanTest.BuildImage(dockerfile, "test", "true") - dockerfile = `FROM quay.io/libpod/cirros:latest + dockerfile = fmt.Sprintf(`FROM %s RUN mkdir hello RUN touch test.txt RUN mkdir blah ENV foo=bar - ` + `, cirros) + podmanTest.BuildImage(dockerfile, "test2", "true") session := podmanTest.Podman([]string{"images", "-q", "-a"}) @@ -249,14 +250,15 @@ var _ = Describe("Podman rmi", func() { }) It("podman rmi -a with parent|child images", func() { - dockerfile := `FROM quay.io/libpod/cirros:latest AS base + podmanTest.AddImageToRWStore(cirros) + dockerfile := fmt.Sprintf(`FROM %s AS base RUN touch /1 ENV LOCAL=/1 RUN find $LOCAL FROM base RUN find $LOCAL -` +`, cirros) podmanTest.BuildImage(dockerfile, "test", "true") session := podmanTest.Podman([]string{"rmi", "-a"}) session.WaitWithDefaultTimeout() @@ -284,14 +286,15 @@ RUN find $LOCAL // a race, we may not hit the condition a 100 percent of times // but ocal reproducers hit it all the time. + podmanTest.AddImageToRWStore(cirros) var wg sync.WaitGroup buildAndRemove := func(i int) { defer GinkgoRecover() defer wg.Done() imageName := fmt.Sprintf("rmtest:%d", i) - containerfile := `FROM quay.io/libpod/cirros:latest -RUN ` + fmt.Sprintf("touch %s", imageName) + containerfile := fmt.Sprintf(`FROM %s +RUN touch %s`, cirros, imageName) podmanTest.BuildImage(containerfile, imageName, "false") session := podmanTest.Podman([]string{"rmi", "-f", imageName}) diff --git a/test/e2e/run_passwd_test.go b/test/e2e/run_passwd_test.go index 12b6c64df..0d5dd5f3b 100644 --- a/test/e2e/run_passwd_test.go +++ b/test/e2e/run_passwd_test.go @@ -1,6 +1,7 @@ package integration import ( + "fmt" "os" . "github.com/containers/podman/v3/test/utils" @@ -60,9 +61,9 @@ var _ = Describe("Podman run passwd", func() { }) It("podman can run container without /etc/passwd", func() { - dockerfile := `FROM alpine + dockerfile := fmt.Sprintf(`FROM %s RUN rm -f /etc/passwd /etc/shadow /etc/group -USER 1000` +USER 1000`, ALPINE) imgName := "testimg" podmanTest.BuildImage(dockerfile, imgName, "false") session := podmanTest.Podman([]string{"run", "--rm", imgName, "ls", "/etc/"}) @@ -113,9 +114,9 @@ USER 1000` }) It("podman run numeric group from image and no group file", func() { - dockerfile := `FROM alpine + dockerfile := fmt.Sprintf(`FROM %s RUN rm -f /etc/passwd /etc/shadow /etc/group -USER 1000` +USER 1000`, ALPINE) imgName := "testimg" podmanTest.BuildImage(dockerfile, imgName, "false") session := podmanTest.Podman([]string{"run", "--rm", imgName, "ls", "/etc/"}) diff --git a/test/e2e/run_privileged_test.go b/test/e2e/run_privileged_test.go index 33b3b85c5..0bf68e20b 100644 --- a/test/e2e/run_privileged_test.go +++ b/test/e2e/run_privileged_test.go @@ -59,7 +59,7 @@ var _ = Describe("Podman privileged container tests", func() { }) It("podman privileged make sure sys is mounted rw", func() { - session := podmanTest.Podman([]string{"run", "--privileged", "busybox", "mount"}) + session := podmanTest.Podman([]string{"run", "--privileged", BB, "mount"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) ok, lines := session.GrepString("sysfs") @@ -71,7 +71,7 @@ var _ = Describe("Podman privileged container tests", func() { hostCap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"}) Expect(hostCap.ExitCode()).To(Equal(0)) - session := podmanTest.Podman([]string{"run", "--privileged", "busybox", "awk", "/^CapEff/ { print $2 }", "/proc/self/status"}) + session := podmanTest.Podman([]string{"run", "--privileged", BB, "awk", "/^CapEff/ { print $2 }", "/proc/self/status"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -83,7 +83,7 @@ var _ = Describe("Podman privileged container tests", func() { hostCap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"}) Expect(hostCap.ExitCode()).To(Equal(0)) - session := podmanTest.Podman([]string{"run", "--cap-add", "all", "busybox", "awk", "/^CapEff/ { print $2 }", "/proc/self/status"}) + session := podmanTest.Podman([]string{"run", "--cap-add", "all", BB, "awk", "/^CapEff/ { print $2 }", "/proc/self/status"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -95,7 +95,7 @@ var _ = Describe("Podman privileged container tests", func() { hostCap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"}) Expect(hostCap.ExitCode()).To(Equal(0)) - session := podmanTest.Podman([]string{"run", "--user=bin", "--cap-add", "all", "busybox", "awk", "/^CapEff/ { print $2 }", "/proc/self/status"}) + session := podmanTest.Podman([]string{"run", "--user=bin", "--cap-add", "all", BB, "awk", "/^CapEff/ { print $2 }", "/proc/self/status"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -103,7 +103,7 @@ var _ = Describe("Podman privileged container tests", func() { }) It("podman cap-drop CapEff", func() { - session := podmanTest.Podman([]string{"run", "--cap-drop", "all", "busybox", "grep", "CapEff", "/proc/self/status"}) + session := podmanTest.Podman([]string{"run", "--cap-drop", "all", BB, "grep", "CapEff", "/proc/self/status"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) capEff := strings.Split(session.OutputToString(), " ") @@ -120,7 +120,7 @@ var _ = Describe("Podman privileged container tests", func() { }) It("podman non-privileged should have very few devices", func() { - session := podmanTest.Podman([]string{"run", "-t", "busybox", "ls", "-l", "/dev"}) + session := podmanTest.Podman([]string{"run", "-t", BB, "ls", "-l", "/dev"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(len(session.OutputToStringArray())).To(Equal(17)) @@ -147,12 +147,12 @@ var _ = Describe("Podman privileged container tests", func() { Skip("Can't determine NoNewPrivs") } - session := podmanTest.Podman([]string{"run", "busybox", "grep", "NoNewPrivs", "/proc/self/status"}) + session := podmanTest.Podman([]string{"run", BB, "grep", "NoNewPrivs", "/proc/self/status"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) privs := strings.Split(session.OutputToString(), ":") - session = podmanTest.Podman([]string{"run", "--security-opt", "no-new-privileges", "busybox", "grep", "NoNewPrivs", "/proc/self/status"}) + session = podmanTest.Podman([]string{"run", "--security-opt", "no-new-privileges", BB, "grep", "NoNewPrivs", "/proc/self/status"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) diff --git a/test/e2e/run_security_labels_test.go b/test/e2e/run_security_labels_test.go index a2e0b2aab..b714df323 100644 --- a/test/e2e/run_security_labels_test.go +++ b/test/e2e/run_security_labels_test.go @@ -1,6 +1,7 @@ package integration import ( + "fmt" "os" "strings" @@ -128,9 +129,9 @@ var _ = Describe("Podman generate kube", func() { It("podman container runlabel (podman --version)", func() { SkipIfRemote("runlabel not supported on podman-remote") - PodmanDockerfile := ` -FROM alpine:latest -LABEL io.containers.capabilities=chown,kill` + PodmanDockerfile := fmt.Sprintf(` +FROM %s +LABEL io.containers.capabilities=chown,kill`, ALPINE) image := "podman-caps:podman" podmanTest.BuildImage(PodmanDockerfile, image, "false") diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index bb1f9590d..23930b4f7 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -489,8 +489,8 @@ var _ = Describe("Podman run", func() { if IsRemote() { podmanTest.RestartRemoteService() } - dockerfile := `FROM busybox -USER bin` + dockerfile := fmt.Sprintf(`FROM %s +USER bin`, BB) podmanTest.BuildImage(dockerfile, "test", "false") session := podmanTest.Podman([]string{"run", "--rm", "--user", "bin", "test", "grep", "CapBnd", "/proc/self/status"}) session.WaitWithDefaultTimeout() @@ -898,10 +898,10 @@ USER bin` session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - dockerfile := `FROM busybox + dockerfile := fmt.Sprintf(`FROM %s RUN mkdir -p /myvol/data && chown -R mail.0 /myvol VOLUME ["/myvol/data"] -USER mail` +USER mail`, BB) podmanTest.BuildImage(dockerfile, "test", "false") session = podmanTest.Podman([]string{"run", "--rm", "test", "ls", "-al", "/myvol/data"}) @@ -1499,8 +1499,8 @@ USER mail` It("podman run makes workdir from image", func() { // BuildImage does not seem to work remote - dockerfile := `FROM busybox -WORKDIR /madethis` + dockerfile := fmt.Sprintf(`FROM %s +WORKDIR /madethis`, BB) podmanTest.BuildImage(dockerfile, "test", "false") session := podmanTest.Podman([]string{"run", "--rm", "test", "pwd"}) session.WaitWithDefaultTimeout() diff --git a/test/e2e/run_volume_test.go b/test/e2e/run_volume_test.go index 85a4d6d52..9b77aaef8 100644 --- a/test/e2e/run_volume_test.go +++ b/test/e2e/run_volume_test.go @@ -308,9 +308,9 @@ var _ = Describe("Podman run with volumes", func() { It("podman named volume copyup symlink", func() { imgName := "testimg" - dockerfile := `FROM alpine + dockerfile := fmt.Sprintf(`FROM %s RUN touch /testfile -RUN sh -c "cd /etc/apk && ln -s ../../testfile"` +RUN sh -c "cd /etc/apk && ln -s ../../testfile"`, ALPINE) podmanTest.BuildImage(dockerfile, imgName, "false") baselineSession := podmanTest.Podman([]string{"run", "--rm", "-t", "-i", imgName, "ls", "/etc/apk/"}) @@ -479,9 +479,8 @@ RUN sh -c "cd /etc/apk && ln -s ../../testfile"` It("Podman mount over image volume with trailing /", func() { image := "podman-volume-test:trailing" - dockerfile := ` -FROM alpine:latest -VOLUME /test/` + dockerfile := fmt.Sprintf(`FROM %s +VOLUME /test/`, ALPINE) podmanTest.BuildImage(dockerfile, image, "false") ctrName := "testCtr" @@ -646,9 +645,9 @@ VOLUME /test/` It("volume permissions after run", func() { imgName := "testimg" - dockerfile := `FROM fedora-minimal + dockerfile := fmt.Sprintf(`FROM %s RUN useradd -m testuser -u 1005 -USER testuser` +USER testuser`, fedoraMinimal) podmanTest.BuildImage(dockerfile, imgName, "false") testString := "testuser testuser" diff --git a/test/e2e/run_working_dir_test.go b/test/e2e/run_working_dir_test.go index 2d16cdc18..de0f55134 100644 --- a/test/e2e/run_working_dir_test.go +++ b/test/e2e/run_working_dir_test.go @@ -1,6 +1,7 @@ package integration import ( + "fmt" "os" . "github.com/containers/podman/v3/test/utils" @@ -46,9 +47,9 @@ var _ = Describe("Podman run", func() { }) It("podman run a container on an image with a workdir", func() { - dockerfile := `FROM alpine + dockerfile := fmt.Sprintf(`FROM %s RUN mkdir -p /home/foobar /etc/foobar; chown bin:bin /etc/foobar -WORKDIR /etc/foobar` +WORKDIR /etc/foobar`, ALPINE) podmanTest.BuildImage(dockerfile, "test", "false") session := podmanTest.Podman([]string{"run", "test", "pwd"}) diff --git a/test/e2e/runlabel_test.go b/test/e2e/runlabel_test.go index 2eec15c62..54fa7e2f6 100644 --- a/test/e2e/runlabel_test.go +++ b/test/e2e/runlabel_test.go @@ -1,6 +1,7 @@ package integration import ( + "fmt" "os" . "github.com/containers/podman/v3/test/utils" @@ -8,18 +9,17 @@ import ( . "github.com/onsi/gomega" ) -var PodmanDockerfile = ` -FROM alpine:latest -LABEL RUN podman --version` +var PodmanDockerfile = fmt.Sprintf(` +FROM %s +LABEL RUN podman --version`, ALPINE) -var LsDockerfile = ` -FROM alpine:latest -LABEL RUN ls -la` +var LsDockerfile = fmt.Sprintf(` +FROM %s +LABEL RUN ls -la`, ALPINE) -var GlobalDockerfile = ` -FROM alpine:latest -LABEL RUN echo \$GLOBAL_OPTS -` +var GlobalDockerfile = fmt.Sprintf(` +FROM %s +LABEL RUN echo \$GLOBAL_OPTS`, ALPINE) var _ = Describe("podman container runlabel", func() { var ( diff --git a/test/e2e/system_df_test.go b/test/e2e/system_df_test.go index 9daf3f8f9..9aee85ca3 100644 --- a/test/e2e/system_df_test.go +++ b/test/e2e/system_df_test.go @@ -44,7 +44,7 @@ var _ = Describe("podman system df", func() { session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"create", "-v", "data:/data", "--name", "container1", "busybox"}) + session = podmanTest.Podman([]string{"create", "-v", "data:/data", "--name", "container1", BB}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) diff --git a/test/system/070-build.bats b/test/system/070-build.bats index 8f6cdb46b..e5b68a0d8 100644 --- a/test/system/070-build.bats +++ b/test/system/070-build.bats @@ -668,6 +668,33 @@ EOF run_podman image prune -f } +@test "podman build --pull-never" { + local tmpdir=$PODMAN_TMPDIR/build-test + mkdir -p $tmpdir + + # First, confirm that --pull-never is a NOP if image exists locally + local random_string=$(random_string 15) + + cat >$tmpdir/Containerfile <<EOF +FROM $IMAGE +RUN echo $random_string +EOF + + run_podman build -t build_test --pull-never $tmpdir + is "$output" ".*$random_string" "pull-never is OK if image already exists" + run_podman rmi build_test + + # Now try an image that does not exist locally nor remotely + cat >$tmpdir/Containerfile <<EOF +FROM quay.io/libpod/nosuchimage:nosuchtag +RUN echo $random_string +EOF + + run_podman 125 build -t build_test --pull-never $tmpdir + is "$output" ".* pull policy is .never. but .* could not be found locally" \ + "--pull-never fails with expected error message" +} + @test "podman build --logfile test" { tmpdir=$PODMAN_TMPDIR/build-test mkdir -p $tmpdir |