|
3 | 3 | package integration
|
4 | 4 |
|
5 | 5 | import (
|
| 6 | + "encoding/json" |
6 | 7 | "fmt"
|
7 | 8 | "os"
|
8 | 9 | "os/exec"
|
9 | 10 | "os/user"
|
10 | 11 | "path/filepath"
|
| 12 | + "strconv" |
11 | 13 | "strings"
|
12 | 14 |
|
13 | 15 | . "github.com/containers/podman/v5/test/utils"
|
14 | 16 | . "github.com/onsi/ginkgo/v2"
|
15 | 17 | . "github.com/onsi/gomega"
|
16 | 18 | . "github.com/onsi/gomega/gexec"
|
| 19 | + "github.com/opencontainers/runtime-spec/specs-go" |
17 | 20 | )
|
18 | 21 |
|
19 | 22 | // in-container mount point: using a path that is definitely not present
|
@@ -447,9 +450,27 @@ var _ = Describe("Podman run with volumes", func() {
|
447 | 450 | Expect(separateVolumeSession).Should(ExitCleanly())
|
448 | 451 | Expect(separateVolumeSession.OutputToString()).To(Equal(baselineOutput))
|
449 | 452 |
|
450 |
| - copySession := podmanTest.Podman([]string{"run", "--rm", "-v", "testvol3:/etc/apk:copy", ALPINE, "stat", "-c", "%h", "/etc/apk/arch"}) |
451 |
| - copySession.WaitWithDefaultTimeout() |
452 |
| - Expect(copySession).Should(ExitCleanly()) |
| 453 | + podmanTest.PodmanExitCleanly("run", "--name", "testctr", "-v", "testvol3:/etc/apk:copy", ALPINE, "stat", "-c", "%h", "/etc/apk/arch") |
| 454 | + |
| 455 | + inspect := podmanTest.PodmanExitCleanly("container", "inspect", "testctr", "--format", "{{.OCIConfigPath}}") |
| 456 | + |
| 457 | + // Make extra check that the OCI config does not contain the copy opt, runc 1.3.0 fails on that while crun does not. |
| 458 | + // We only test crun upstream so make sure the spec is sane: https://github.com/containers/podman/issues/26938 |
| 459 | + f, err := os.Open(inspect.OutputToString()) |
| 460 | + Expect(err).ToNot(HaveOccurred()) |
| 461 | + defer f.Close() |
| 462 | + var spec specs.Spec |
| 463 | + err = json.NewDecoder(f).Decode(&spec) |
| 464 | + Expect(err).ToNot(HaveOccurred()) |
| 465 | + |
| 466 | + found := false |
| 467 | + for _, m := range spec.Mounts { |
| 468 | + if m.Destination == "/etc/apk" { |
| 469 | + found = true |
| 470 | + Expect(m.Options).To(Equal([]string{"rprivate", "nosuid", "nodev", "rbind"})) |
| 471 | + } |
| 472 | + } |
| 473 | + Expect(found).To(BeTrue(), "OCI spec contains /etc/apk mount") |
453 | 474 |
|
454 | 475 | noCopySession := podmanTest.Podman([]string{"run", "--rm", "-v", "testvol4:/etc/apk:nocopy", ALPINE, "stat", "-c", "%h", "/etc/apk/arch"})
|
455 | 476 | noCopySession.WaitWithDefaultTimeout()
|
@@ -859,14 +880,17 @@ VOLUME /test/`, ALPINE)
|
859 | 880 | It("podman run with --mount and named volume with driver-opts", func() {
|
860 | 881 | // anonymous volume mount with driver opts
|
861 | 882 | vol := "type=volume,source=test_vol,dst=/test,volume-opt=type=tmpfs,volume-opt=device=tmpfs,volume-opt=o=nodev"
|
862 |
| - session := podmanTest.Podman([]string{"run", "--rm", "--mount", vol, ALPINE, "echo", "hello"}) |
863 |
| - session.WaitWithDefaultTimeout() |
864 |
| - Expect(session).Should(ExitCleanly()) |
| 883 | + // Loop twice to cover both the initial code path that creates the volume and the ones which reuses it. |
| 884 | + for i := range 2 { |
| 885 | + name := "testctr" + strconv.Itoa(i) |
| 886 | + podmanTest.PodmanExitCleanly("run", "--name", name, "--mount", vol, ALPINE, "echo", "hello") |
865 | 887 |
|
866 |
| - inspectVol := podmanTest.Podman([]string{"volume", "inspect", "test_vol"}) |
867 |
| - inspectVol.WaitWithDefaultTimeout() |
868 |
| - Expect(inspectVol).Should(ExitCleanly()) |
869 |
| - Expect(inspectVol.OutputToString()).To(ContainSubstring("nodev")) |
| 888 | + inspectVol := podmanTest.PodmanExitCleanly("volume", "inspect", "test_vol") |
| 889 | + Expect(inspectVol.OutputToString()).To(ContainSubstring("nodev")) |
| 890 | + |
| 891 | + inspect := podmanTest.PodmanExitCleanly("container", "inspect", name, "--format", "{{range .Mounts}}{{.Options}}{{end}}") |
| 892 | + Expect(inspect.OutputToString()).To(ContainSubstring("[nosuid nodev rbind]")) |
| 893 | + } |
870 | 894 | })
|
871 | 895 |
|
872 | 896 | It("volume permissions after run", func() {
|
|
0 commit comments