package integration import ( "fmt" "os" "path/filepath" . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman volume plugins", func() { var ( tempdir string err error podmanTest *PodmanTestIntegration ) BeforeEach(func() { tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) } podmanTest = PodmanTestCreate(tempdir) podmanTest.Setup() podmanTest.SeedImages() os.Setenv("CONTAINERS_CONF", "config/containers.conf") SkipIfRemote("Volume plugins only supported as local") SkipIfRootless("Root is required for volume plugin testing") os.MkdirAll("/run/docker/plugins", 0755) }) AfterEach(func() { podmanTest.CleanupVolume() f := CurrentGinkgoTestDescription() processTestResult(f) os.Unsetenv("CONTAINERS_CONF") }) It("volume create with nonexistent plugin errors", func() { session := podmanTest.Podman([]string{"volume", "create", "--driver", "notexist", "test_volume_name"}) session.WaitWithDefaultTimeout() Expect(session).To(ExitWithError()) }) It("volume create with not-running plugin does not error", func() { session := podmanTest.Podman([]string{"volume", "create", "--driver", "testvol0", "test_volume_name"}) session.WaitWithDefaultTimeout() Expect(session).To(ExitWithError()) }) It("volume create and remove with running plugin succeeds", func() { podmanTest.AddImageToRWStore(volumeTest) pluginStatePath := filepath.Join(podmanTest.TempDir, "volumes") os.Mkdir(pluginStatePath, 0755) // Keep this distinct within tests to avoid multiple tests using the same plugin. pluginName := "testvol1" plugin := podmanTest.Podman([]string{"run", "--security-opt", "label=disable", "-v", "/run/docker/plugins:/run/docker/plugins", "-v", fmt.Sprintf("%v:%v", pluginStatePath, pluginStatePath), "-d", volumeTest, "--sock-name", pluginName, "--path", pluginStatePath}) plugin.WaitWithDefaultTimeout() Expect(plugin).Should(Exit(0)) volName := "testVolume1" create := podmanTest.Podman([]string{"volume", "create", "--driver", pluginName, volName}) create.WaitWithDefaultTimeout() Expect(create).Should(Exit(0)) ls1 := podmanTest.Podman([]string{"volume", "ls", "-q"}) ls1.WaitWithDefaultTimeout() Expect(ls1).Should(Exit(0)) arrOutput := ls1.OutputToStringArray() Expect(arrOutput).To(HaveLen(1)) Expect(arrOutput[0]).To(ContainSubstring(volName)) remove := podmanTest.Podman([]string{"volume", "rm", volName}) remove.WaitWithDefaultTimeout() Expect(remove).Should(Exit(0)) ls2 := podmanTest.Podman([]string{"volume", "ls", "-q"}) ls2.WaitWithDefaultTimeout() Expect(ls2).Should(Exit(0)) Expect(ls2.OutputToStringArray()).To(BeEmpty()) }) It("volume inspect with running plugin succeeds", func() { podmanTest.AddImageToRWStore(volumeTest) pluginStatePath := filepath.Join(podmanTest.TempDir, "volumes") os.Mkdir(pluginStatePath, 0755) // Keep this distinct within tests to avoid multiple tests using the same plugin. pluginName := "testvol2" plugin := podmanTest.Podman([]string{"run", "--security-opt", "label=disable", "-v", "/run/docker/plugins:/run/docker/plugins", "-v", fmt.Sprintf("%v:%v", pluginStatePath, pluginStatePath), "-d", volumeTest, "--sock-name", pluginName, "--path", pluginStatePath}) plugin.WaitWithDefaultTimeout() Expect(plugin).Should(Exit(0)) volName := "testVolume1" create := podmanTest.Podman([]string{"volume", "create", "--driver", pluginName, volName}) create.WaitWithDefaultTimeout() Expect(create).Should(Exit(0)) volInspect := podmanTest.Podman([]string{"volume", "inspect", "--format", "{{ .Driver }}", volName}) volInspect.WaitWithDefaultTimeout() Expect(volInspect).Should(Exit(0)) Expect(volInspect.OutputToString()).To(ContainSubstring(pluginName)) }) It("remove plugin with stopped plugin succeeds", func() { podmanTest.AddImageToRWStore(volumeTest) pluginStatePath := filepath.Join(podmanTest.TempDir, "volumes") os.Mkdir(pluginStatePath, 0755) // Keep this distinct within tests to avoid multiple tests using the same plugin. pluginName := "testvol3" ctrName := "pluginCtr" plugin := podmanTest.Podman([]string{"run", "--name", ctrName, "--security-opt", "label=disable", "-v", "/run/docker/plugins:/run/docker/plugins", "-v", fmt.Sprintf("%v:%v", pluginStatePath, pluginStatePath), "-d", volumeTest, "--sock-name", pluginName, "--path", pluginStatePath}) plugin.WaitWithDefaultTimeout() Expect(plugin).Should(Exit(0)) volName := "testVolume1" create := podmanTest.Podman([]string{"volume", "create", "--driver", pluginName, volName}) create.WaitWithDefaultTimeout() Expect(create).Should(Exit(0)) ls1 := podmanTest.Podman([]string{"volume", "ls", "-q"}) ls1.WaitWithDefaultTimeout() Expect(ls1).Should(Exit(0)) arrOutput := ls1.OutputToStringArray() Expect(arrOutput).To(HaveLen(1)) Expect(arrOutput[0]).To(ContainSubstring(volName)) stop := podmanTest.Podman([]string{"stop", "--timeout", "0", ctrName}) stop.WaitWithDefaultTimeout() Expect(stop).Should(Exit(0)) // Remove should exit non-zero because missing plugin remove := podmanTest.Podman([]string{"volume", "rm", volName}) remove.WaitWithDefaultTimeout() Expect(remove).To(ExitWithError()) // But the volume should still be gone ls2 := podmanTest.Podman([]string{"volume", "ls", "-q"}) ls2.WaitWithDefaultTimeout() Expect(ls2).Should(Exit(0)) Expect(ls2.OutputToStringArray()).To(BeEmpty()) }) It("use plugin in containers", func() { podmanTest.AddImageToRWStore(volumeTest) pluginStatePath := filepath.Join(podmanTest.TempDir, "volumes") os.Mkdir(pluginStatePath, 0755) // Keep this distinct within tests to avoid multiple tests using the same plugin. pluginName := "testvol4" plugin := podmanTest.Podman([]string{"run", "--security-opt", "label=disable", "-v", "/run/docker/plugins:/run/docker/plugins", "-v", fmt.Sprintf("%v:%v", pluginStatePath, pluginStatePath), "-d", volumeTest, "--sock-name", pluginName, "--path", pluginStatePath}) plugin.WaitWithDefaultTimeout() Expect(plugin).Should(Exit(0)) volName := "testVolume1" create := podmanTest.Podman([]string{"volume", "create", "--driver", pluginName, volName}) create.WaitWithDefaultTimeout() Expect(create).Should(Exit(0)) ctr1 := podmanTest.Podman([]string{"run", "--security-opt", "label=disable", "-v", fmt.Sprintf("%v:/test", volName), ALPINE, "sh", "-c", "touch /test/testfile && echo helloworld > /test/testfile"}) ctr1.WaitWithDefaultTimeout() Expect(ctr1).Should(Exit(0)) ctr2 := podmanTest.Podman([]string{"run", "--security-opt", "label=disable", "-v", fmt.Sprintf("%v:/test", volName), ALPINE, "cat", "/test/testfile"}) ctr2.WaitWithDefaultTimeout() Expect(ctr2).Should(Exit(0)) Expect(ctr2.OutputToString()).To(ContainSubstring("helloworld")) // HACK: `volume rm -f` is timing out trying to remove containers using the volume. // Solution: remove them manually... // TODO: fix this when I get back rmAll := podmanTest.Podman([]string{"rm", "-af"}) rmAll.WaitWithDefaultTimeout() Expect(rmAll).Should(Exit(0)) }) })