diff options
author | Aditya Rajan <arajan@redhat.com> | 2021-09-20 15:38:51 +0530 |
---|---|---|
committer | Aditya Rajan <arajan@redhat.com> | 2021-09-21 13:06:23 +0530 |
commit | ae5de8b390693784fc383b4d1df85aa92104f481 (patch) | |
tree | 2f5d3705ba132ad99cd394fb7a85c1d4ac0e5353 | |
parent | b925d707fa768245b3bd50d570b91992c1814dba (diff) | |
download | podman-ae5de8b390693784fc383b4d1df85aa92104f481.tar.gz podman-ae5de8b390693784fc383b4d1df85aa92104f481.tar.bz2 podman-ae5de8b390693784fc383b4d1df85aa92104f481.zip |
volume: Add support for overlay on named volumes
Following PR allows containers to create and mount overlays on top of
named volumes instead of mounting actual volumes via already documented `:O`.
Signed-off-by: Aditya Rajan <arajan@redhat.com>
-rw-r--r-- | libpod/container_internal_linux.go | 45 | ||||
-rw-r--r-- | test/e2e/run_volume_test.go | 33 |
2 files changed, 72 insertions, 6 deletions
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index dbecea031..0a663200a 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -369,13 +369,46 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { if err != nil { return nil, err } - volMount := spec.Mount{ - Type: "bind", - Source: mountPoint, - Destination: namedVol.Dest, - Options: namedVol.Options, + + overlayFlag := false + for _, o := range namedVol.Options { + if o == "O" { + overlayFlag = true + } + } + + if overlayFlag { + contentDir, err := overlay.TempDir(c.config.StaticDir, c.RootUID(), c.RootGID()) + if err != nil { + return nil, err + } + overlayMount, err := overlay.Mount(contentDir, mountPoint, namedVol.Dest, c.RootUID(), c.RootGID(), c.runtime.store.GraphOptions()) + if err != nil { + return nil, errors.Wrapf(err, "mounting overlay failed %q", mountPoint) + } + + for _, o := range namedVol.Options { + switch o { + case "U": + if err := chown.ChangeHostPathOwnership(mountPoint, true, int(hostUID), int(hostGID)); err != nil { + return nil, err + } + + if err := chown.ChangeHostPathOwnership(contentDir, true, int(hostUID), int(hostGID)); err != nil { + return nil, err + } + } + } + g.AddMount(overlayMount) + } else { + volMount := spec.Mount{ + Type: "bind", + Source: mountPoint, + Destination: namedVol.Dest, + Options: namedVol.Options, + } + g.AddMount(volMount) } - g.AddMount(volMount) } // Check if the spec file mounts contain the options z, Z or U. diff --git a/test/e2e/run_volume_test.go b/test/e2e/run_volume_test.go index 59937b6c0..4264e1efe 100644 --- a/test/e2e/run_volume_test.go +++ b/test/e2e/run_volume_test.go @@ -242,6 +242,39 @@ var _ = Describe("Podman run with volumes", func() { Expect(session).Should(Exit(0)) }) + It("podman support overlay on named volume", func() { + SkipIfRemote("Overlay volumes only work locally") + if os.Getenv("container") != "" { + Skip("Overlay mounts not supported when running in a container") + } + if rootless.IsRootless() { + if _, err := exec.LookPath("fuse-overlayfs"); err != nil { + Skip("Fuse-Overlayfs required for rootless overlay mount test") + } + } + session := podmanTest.Podman([]string{"volume", "create", "myvolume"}) + session.WaitWithDefaultTimeout() + volName := session.OutputToString() + Expect(session).Should(Exit(0)) + + // create file on actual volume + session = podmanTest.Podman([]string{"run", "--volume", volName + ":/data", ALPINE, "sh", "-c", "echo hello >> " + "/data/test"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + // create file on overlayed volume + session = podmanTest.Podman([]string{"run", "--volume", volName + ":/data:O", ALPINE, "sh", "-c", "echo hello >> " + "/data/overlayed"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + // volume should contain only `test` not `overlayed` + session = podmanTest.Podman([]string{"run", "--volume", volName + ":/data", ALPINE, "sh", "-c", "ls /data"}) + session.WaitWithDefaultTimeout() + Expect(session.OutputToString()).To(Not(ContainSubstring("overlayed"))) + Expect(session.OutputToString()).To(ContainSubstring("test")) + + }) + It("podman run with noexec can't exec", func() { session := podmanTest.Podman([]string{"run", "--rm", "-v", "/bin:/hostbin:noexec", ALPINE, "/hostbin/ls", "/"}) session.WaitWithDefaultTimeout() |