summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
authorAditya Rajan <arajan@redhat.com>2021-12-28 16:02:25 +0530
committerAditya R <arajan@redhat.com>2022-01-28 13:10:15 +0530
commite64e6500d3a3bdbb2d3c9faa5e2d9d845f120b17 (patch)
tree21f9548d8b1c880359a44a2c2357d31a0452f442 /libpod
parent5b01dab618fc287df4e6c41fa88c4a64d31fa3f3 (diff)
downloadpodman-e64e6500d3a3bdbb2d3c9faa5e2d9d845f120b17.tar.gz
podman-e64e6500d3a3bdbb2d3c9faa5e2d9d845f120b17.tar.bz2
podman-e64e6500d3a3bdbb2d3c9faa5e2d9d845f120b17.zip
volume: add support for non-volatile upperdir,workdir for overlay volumes
Often users want their overlayed volumes to be `non-volatile` in nature that means that same `upper` dir can be re-used by one or more containers but overall of nature of volumes still have to be `overlay` so work done is still on a overlay not on the actual volume. Following PR adds support for more advanced options i.e custom `workdir` and `upperdir` for overlayed volumes. So that users can re-use `workdir` and `upperdir` across new containers as well. Usage ```console $ podman run -it -v myvol:/data:O,upperdir=/path/persistant/upper,workdir=/path/persistant/work alpine sh ``` Signed-off-by: Aditya R <arajan@redhat.com>
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container_internal_linux.go36
1 files changed, 35 insertions, 1 deletions
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 84293ccb2..5cc2a78fc 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -391,18 +391,52 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
}
overlayFlag := false
+ upperDir := ""
+ workDir := ""
for _, o := range namedVol.Options {
if o == "O" {
overlayFlag = true
}
+ if overlayFlag && strings.Contains(o, "upperdir") {
+ splitOpt := strings.SplitN(o, "=", 2)
+ if len(splitOpt) > 1 {
+ upperDir = splitOpt[1]
+ if upperDir == "" {
+ return nil, errors.New("cannot accept empty value for upperdir")
+ }
+ }
+ }
+ if overlayFlag && strings.Contains(o, "workdir") {
+ splitOpt := strings.SplitN(o, "=", 2)
+ if len(splitOpt) > 1 {
+ workDir = splitOpt[1]
+ if workDir == "" {
+ return nil, errors.New("cannot accept empty value for workdir")
+ }
+ }
+ }
}
if overlayFlag {
+ var overlayMount spec.Mount
+ var overlayOpts *overlay.Options
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 (upperDir != "" && workDir == "") || (upperDir == "" && workDir != "") {
+ return nil, errors.Wrapf(err, "must specify both upperdir and workdir")
+ }
+
+ overlayOpts = &overlay.Options{RootUID: c.RootUID(),
+ RootGID: c.RootGID(),
+ UpperDirOptionFragment: upperDir,
+ WorkDirOptionFragment: workDir,
+ GraphOpts: c.runtime.store.GraphOptions(),
+ }
+
+ overlayMount, err = overlay.MountWithOptions(contentDir, mountPoint, namedVol.Dest, overlayOpts)
if err != nil {
return nil, errors.Wrapf(err, "mounting overlay failed %q", mountPoint)
}