diff options
author | umohnani8 <umohnani@redhat.com> | 2018-02-16 10:38:12 -0500 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2018-02-22 15:14:00 +0000 |
commit | 3d395767d8c3e467e784e3836c7175f6d11931a7 (patch) | |
tree | a64044df96164ad10873ad5a642e576b99b33bdd /libpod | |
parent | 7a7a6c2d79ebd831acf0321643903136dca7c2cb (diff) | |
download | podman-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.go | 7 | ||||
-rw-r--r-- | libpod/container_internal.go | 45 | ||||
-rw-r--r-- | libpod/util.go | 13 |
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 +} |