summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
authorQi Wang <qiwan@redhat.com>2020-07-09 15:46:14 -0400
committerQi Wang <qiwan@redhat.com>2020-07-20 09:48:55 -0400
commit020d81f113ea1e11398ea77495cc4b8e05a91d38 (patch)
treef3347aa5b378e215a76e37b2356035e544197da0 /libpod
parent17f9b80600bc008e7c0a4060ff3a6bb5eb56d0cc (diff)
downloadpodman-020d81f113ea1e11398ea77495cc4b8e05a91d38.tar.gz
podman-020d81f113ea1e11398ea77495cc4b8e05a91d38.tar.bz2
podman-020d81f113ea1e11398ea77495cc4b8e05a91d38.zip
Add support for overlay volume mounts in podman.
Add support -v for overlay volume mounts in podman. Signed-off-by: Daniel J Walsh <dwalsh@redhat.com> Signed-off-by: Qi Wang <qiwan@redhat.com>
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container.go11
-rw-r--r--libpod/container_internal.go6
-rw-r--r--libpod/container_internal_linux.go18
-rw-r--r--libpod/container_internal_unsupported.go4
-rw-r--r--libpod/container_validate.go19
-rw-r--r--libpod/options.go29
-rw-r--r--libpod/runtime.go2
7 files changed, 78 insertions, 11 deletions
diff --git a/libpod/container.go b/libpod/container.go
index 1ca38ae7e..fda018640 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -262,6 +262,8 @@ type ContainerConfig struct {
Mounts []string `json:"mounts,omitempty"`
// NamedVolumes lists the named volumes to mount into the container.
NamedVolumes []*ContainerNamedVolume `json:"namedVolumes,omitempty"`
+ // OverlayVolumes lists the overlay volumes to mount into the container.
+ OverlayVolumes []*ContainerOverlayVolume `json:"overlayVolumes,omitempty"`
// Security Config
@@ -449,6 +451,15 @@ type ContainerNamedVolume struct {
Options []string `json:"options,omitempty"`
}
+// ContainerOverlayVolume is a overlay volume that will be mounted into the
+// container. Each volume is a libpod Volume present in the state.
+type ContainerOverlayVolume struct {
+ // Destination is the absolute path where the mount will be placed in the container.
+ Dest string `json:"dest"`
+ // Source specifies the source path of the mount.
+ Source string `json:"source,omitempty"`
+}
+
// Config accessors
// Unlocked
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index a79b9e5a8..b2e23b3a8 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -1588,6 +1588,12 @@ func (c *Container) cleanupStorage() error {
}
}
+ if err := c.cleanupOverlayMounts(); err != nil {
+ // If the container can't remove content report the error
+ logrus.Errorf("Failed to cleanup overlay mounts for %s: %v", c.ID(), err)
+ cleanupErr = err
+ }
+
if c.config.Rootfs != "" {
return cleanupErr
}
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 255505416..1c21f2ff9 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -20,6 +20,7 @@ import (
cnitypes "github.com/containernetworking/cni/pkg/types/current"
"github.com/containernetworking/plugins/pkg/ns"
+ "github.com/containers/buildah/pkg/overlay"
"github.com/containers/buildah/pkg/secrets"
"github.com/containers/common/pkg/apparmor"
"github.com/containers/common/pkg/config"
@@ -319,6 +320,19 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
}
}
+ // Add overlay volumes
+ for _, overlayVol := range c.config.OverlayVolumes {
+ contentDir, err := overlay.TempDir(c.config.StaticDir, c.RootUID(), c.RootGID())
+ if err != nil {
+ return nil, errors.Wrapf(err, "failed to create TempDir in the %s directory", c.config.StaticDir)
+ }
+ overlayMount, err := overlay.Mount(contentDir, overlayVol.Source, overlayVol.Dest, c.RootUID(), c.RootGID(), c.runtime.store.GraphOptions())
+ if err != nil {
+ return nil, errors.Wrapf(err, "creating overlay failed %q", overlayVol.Source)
+ }
+ g.AddMount(overlayMount)
+ }
+
hasHomeSet := false
for _, s := range c.config.Spec.Process.Env {
if strings.HasPrefix(s, "HOME=") {
@@ -1642,3 +1656,7 @@ func (c *Container) copyTimezoneFile(zonePath string) (string, error) {
}
return localtimeCopy, err
}
+
+func (c *Container) cleanupOverlayMounts() error {
+ return overlay.CleanupContent(c.config.StaticDir)
+}
diff --git a/libpod/container_internal_unsupported.go b/libpod/container_internal_unsupported.go
index e6d94104c..b58a5116b 100644
--- a/libpod/container_internal_unsupported.go
+++ b/libpod/container_internal_unsupported.go
@@ -46,6 +46,10 @@ func (c *Container) getOCICgroupPath() (string, error) {
return "", define.ErrNotImplemented
}
+func (c *Container) cleanupOverlayMounts() error {
+ return nil
+}
+
func (c *Container) getUserOverrides() *lookup.Overrides {
return nil
}
diff --git a/libpod/container_validate.go b/libpod/container_validate.go
index c02833359..666ad0aca 100644
--- a/libpod/container_validate.go
+++ b/libpod/container_validate.go
@@ -99,5 +99,24 @@ func (c *Container) validate() error {
return errors.Wrapf(define.ErrInvalidArg, "cannot add to /etc/hosts if using image's /etc/hosts")
}
+ // Check named volume and overlay volumes destination conflits
+ destinations := make(map[string]bool)
+ for _, vol := range c.config.NamedVolumes {
+ // Don't check if they already exist.
+ // If they don't we will automatically create them.
+ if _, ok := destinations[vol.Dest]; ok {
+ return errors.Wrapf(define.ErrInvalidArg, "two volumes found with destination %s", vol.Dest)
+ }
+ destinations[vol.Dest] = true
+ }
+ for _, vol := range c.config.OverlayVolumes {
+ // Don't check if they already exist.
+ // If they don't we will automatically create them.
+ if _, ok := destinations[vol.Dest]; ok {
+ return errors.Wrapf(define.ErrInvalidArg, "two volumes found with destination %s", vol.Dest)
+ }
+ destinations[vol.Dest] = true
+ }
+
return nil
}
diff --git a/libpod/options.go b/libpod/options.go
index 32748a3c1..40cf452db 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -1380,17 +1380,7 @@ func WithNamedVolumes(volumes []*ContainerNamedVolume) CtrCreateOption {
return define.ErrCtrFinalized
}
- destinations := make(map[string]bool)
-
for _, vol := range volumes {
- // Don't check if they already exist.
- // If they don't we will automatically create them.
-
- if _, ok := destinations[vol.Dest]; ok {
- return errors.Wrapf(define.ErrInvalidArg, "two volumes found with destination %s", vol.Dest)
- }
- destinations[vol.Dest] = true
-
mountOpts, err := util.ProcessOptions(vol.Options, false, "")
if err != nil {
return errors.Wrapf(err, "error processing options for named volume %q mounted at %q", vol.Name, vol.Dest)
@@ -1407,6 +1397,25 @@ func WithNamedVolumes(volumes []*ContainerNamedVolume) CtrCreateOption {
}
}
+// WithOverlayVolumes adds the given overlay volumes to the container.
+func WithOverlayVolumes(volumes []*ContainerOverlayVolume) CtrCreateOption {
+ return func(ctr *Container) error {
+ if ctr.valid {
+ return define.ErrCtrFinalized
+ }
+
+ for _, vol := range volumes {
+
+ ctr.config.OverlayVolumes = append(ctr.config.OverlayVolumes, &ContainerOverlayVolume{
+ Dest: vol.Dest,
+ Source: vol.Source,
+ })
+ }
+
+ return nil
+ }
+}
+
// WithHealthCheck adds the healthcheck to the container config
func WithHealthCheck(healthCheck *manifest.Schema2HealthConfig) CtrCreateOption {
return func(ctr *Container) error {
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 0075c0e13..b30933b0c 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -577,7 +577,7 @@ func (r *Runtime) Shutdown(force bool) error {
}
var lastError error
- // If no store was requested, it can bew nil and there is no need to
+ // If no store was requested, it can be nil and there is no need to
// attempt to shut it down
if r.store != nil {
if _, err := r.store.Shutdown(force); err != nil {