diff options
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 +} |