aboutsummaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
authorumohnani8 <umohnani@redhat.com>2018-02-16 10:38:12 -0500
committerAtomic Bot <atomic-devel@projectatomic.io>2018-02-22 15:14:00 +0000
commit3d395767d8c3e467e784e3836c7175f6d11931a7 (patch)
treea64044df96164ad10873ad5a642e576b99b33bdd /libpod
parent7a7a6c2d79ebd831acf0321643903136dca7c2cb (diff)
downloadpodman-3d395767d8c3e467e784e3836c7175f6d11931a7.tar.gz
podman-3d395767d8c3e467e784e3836c7175f6d11931a7.tar.bz2
podman-3d395767d8c3e467e784e3836c7175f6d11931a7.zip
Implement --image-volumes for create and run
--image-volumes tells podman what to do with the image volumes in the image config There are 3 options: bind, tmpfs, and ignore bind puts the volume contents in /var/lib/containers/storage/container-id/volumes/vol-dir and bind mounts it into the container at /vol-dir tmpfs mounts /vol-dir as a tmps into the container ignore doesn't mount the image volumes onto the container Signed-off-by: umohnani8 <umohnani@redhat.com> Closes: #377 Approved by: rhatdan
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container_api.go7
-rw-r--r--libpod/container_internal.go45
-rw-r--r--libpod/util.go13
3 files changed, 64 insertions, 1 deletions
diff --git a/libpod/container_api.go b/libpod/container_api.go
index 6fdc45589..149197470 100644
--- a/libpod/container_api.go
+++ b/libpod/container_api.go
@@ -144,6 +144,13 @@ func (c *Container) Init() (err error) {
}
g.AddMount(hostnameMnt)
+ // Bind builtin image volumes
+ if c.config.ImageVolumes {
+ if err = c.addImageVolumes(&g); err != nil {
+ return errors.Wrapf(err, "error mounting image volumes")
+ }
+ }
+
if c.config.User != "" {
if !c.state.Mounted {
return errors.Wrapf(ErrCtrStateInvalid, "container %s must be mounted in order to translate User field", c.ID())
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index 6e9852d1e..e22d36f99 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -12,10 +12,12 @@ import (
"github.com/containers/storage"
"github.com/containers/storage/pkg/archive"
+ "github.com/containers/storage/pkg/chrootarchive"
"github.com/docker/docker/pkg/mount"
"github.com/docker/docker/pkg/namesgenerator"
"github.com/docker/docker/pkg/stringid"
spec "github.com/opencontainers/runtime-spec/specs-go"
+ "github.com/opencontainers/runtime-tools/generate"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -271,6 +273,49 @@ func (c *Container) export(path string) error {
return err
}
+func (c *Container) addImageVolumes(g *generate.Generator) error {
+ mountPoint := c.state.Mountpoint
+ if !c.state.Mounted {
+ return errors.Wrapf(ErrInternal, "container is not mounted")
+ }
+
+ imageStorage, err := c.runtime.getImage(c.config.RootfsImageID)
+ if err != nil {
+ return err
+ }
+ imageData, err := c.runtime.getImageInspectInfo(*imageStorage)
+ if err != nil {
+ return err
+ }
+
+ for k := range imageData.ContainerConfig.Volumes {
+ mount := spec.Mount{
+ Destination: k,
+ Type: "bind",
+ Options: []string{"rbind", "rw"},
+ }
+ if MountExists(g.Mounts(), k) {
+ continue
+ }
+ volumePath := filepath.Join(c.config.StaticDir, "volumes", k)
+ if _, err := os.Stat(volumePath); os.IsNotExist(err) {
+ if err = os.MkdirAll(volumePath, 0755); err != nil {
+ return errors.Wrapf(err, "error creating directory %q for volume %q in container %q", volumePath, k, c.ID)
+ }
+ if err = label.Relabel(volumePath, c.config.MountLabel, false); err != nil {
+ return errors.Wrapf(err, "error relabeling directory %q for volume %q in container %q", volumePath, k, c.ID)
+ }
+ srcPath := filepath.Join(mountPoint, k)
+ if err = chrootarchive.NewArchiver(nil).CopyWithTar(srcPath, volumePath); err != nil && !os.IsNotExist(err) {
+ return errors.Wrapf(err, "error populating directory %q for volume %q in container %q using contents of %q", volumePath, k, c.ID, srcPath)
+ }
+ mount.Source = volumePath
+ }
+ g.AddMount(mount)
+ }
+ return nil
+}
+
// Get path of artifact with a given name for this container
func (c *Container) getArtifactPath(name string) string {
return filepath.Join(c.config.StaticDir, artifactsDir, name)
diff --git a/libpod/util.go b/libpod/util.go
index 1a033a940..0c6700fbf 100644
--- a/libpod/util.go
+++ b/libpod/util.go
@@ -4,13 +4,14 @@ import (
"fmt"
"os"
"path/filepath"
+ "strconv"
"strings"
"time"
"github.com/containers/image/signature"
"github.com/containers/image/types"
+ spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
- "strconv"
)
// Runtime API constants
@@ -96,3 +97,13 @@ func RemoveScientificNotationFromFloat(x float64) (float64, error) {
}
return result, nil
}
+
+// MountExists returns true if dest exists in the list of mounts
+func MountExists(specMounts []spec.Mount, dest string) bool {
+ for _, m := range specMounts {
+ if m.Destination == dest {
+ return true
+ }
+ }
+ return false
+}