Add handling for new named volumes code in pkg/spec

Now that named volumes must be explicitly enumerated rather than
passed in with all other volumes, we need to split normal and
named volumes up before passing them into libpod. This PR does
this.

Signed-off-by: Matthew Heon <matthew.heon@pm.me>
This commit is contained in:
Matthew Heon
2019-03-26 15:29:20 -04:00
parent ee770ad5b5
commit 7309e38ddd
3 changed files with 49 additions and 17 deletions

View File

@ -545,14 +545,6 @@ func (r *Runtime) GetLatestContainer() (*Container, error) {
return ctrs[lastCreatedIndex], nil
}
// Check if volName is a named volume and not one of the default mounts we add to containers
func isNamedVolume(volName string) bool {
if volName != "proc" && volName != "tmpfs" && volName != "devpts" && volName != "shm" && volName != "mqueue" && volName != "sysfs" && volName != "cgroup" {
return true
}
return false
}
// Export is the libpod portion of exporting a container to a tar file
func (r *Runtime) Export(name string, path string) error {
ctr, err := r.LookupContainer(name)

View File

@ -130,11 +130,12 @@ type CreateConfig struct {
Mounts []spec.Mount //mounts
Volumes []string //volume
VolumesFrom []string
WorkDir string //workdir
LabelOpts []string //SecurityOpts
NoNewPrivs bool //SecurityOpts
ApparmorProfile string //SecurityOpts
SeccompProfilePath string //SecurityOpts
NamedVolumes []*libpod.ContainerNamedVolume // Filled in by CreateConfigToOCISpec
WorkDir string //workdir
LabelOpts []string //SecurityOpts
NoNewPrivs bool //SecurityOpts
ApparmorProfile string //SecurityOpts
SeccompProfilePath string //SecurityOpts
SecurityOpts []string
Rootfs string
LocalVolumes []spec.Mount //Keeps track of the built-in volumes of container used in the --volumes-from flag
@ -217,7 +218,7 @@ func (c *CreateConfig) initFSMounts() []spec.Mount {
return mounts
}
//GetVolumeMounts takes user provided input for bind mounts and creates Mount structs
// GetVolumeMounts takes user provided input for bind mounts and creates Mount structs
func (c *CreateConfig) GetVolumeMounts(specMounts []spec.Mount) ([]spec.Mount, error) {
m := c.LocalVolumes
for _, i := range c.Volumes {
@ -423,6 +424,10 @@ func (c *CreateConfig) GetContainerCreateOptions(runtime *libpod.Runtime, pod *l
options = append(options, libpod.WithUserVolumes(volumes))
}
if len(c.NamedVolumes) != 0 {
options = append(options, libpod.WithNamedVolumes(c.NamedVolumes))
}
if len(c.LocalVolumes) != 0 {
options = append(options, libpod.WithLocalVolumes(c.LocalVolumes))
}

View File

@ -6,6 +6,7 @@ import (
"path/filepath"
"strings"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/rootless"
"github.com/containers/storage/pkg/mount"
pmount "github.com/containers/storage/pkg/mount"
@ -19,6 +20,7 @@ import (
)
const cpuPeriod = 100000
const bindMount = "bind"
func supercedeUserMounts(mounts []spec.Mount, configMount []spec.Mount) []spec.Mount {
if len(mounts) > 0 {
@ -48,6 +50,33 @@ func supercedeUserMounts(mounts []spec.Mount, configMount []spec.Mount) []spec.M
return configMount
}
// Split named volumes from normal volumes
func splitNamedVolumes(mounts []spec.Mount) ([]spec.Mount, []*libpod.ContainerNamedVolume) {
newMounts := make([]spec.Mount, 0)
namedVolumes := make([]*libpod.ContainerNamedVolume, 0)
for _, mount := range mounts {
// If it's not a named volume, append unconditionally
if mount.Type != bindMount {
newMounts = append(newMounts, mount)
continue
}
// Volumes that are not named volumes must be an absolute or
// relative path.
// Volume names may not begin with a non-alphanumeric character
// so the HasPrefix() check is safe here.
if strings.HasPrefix(mount.Source, "/") || strings.HasPrefix(mount.Source, ".") {
newMounts = append(newMounts, mount)
} else {
namedVolume := new(libpod.ContainerNamedVolume)
namedVolume.Name = mount.Source
namedVolume.Dest = mount.Destination
namedVolume.Options = mount.Options
namedVolumes = append(namedVolumes, namedVolume)
}
}
return newMounts, namedVolumes
}
func getAvailableGids() (int64, error) {
idMap, err := user.ParseIDMapFile("/proc/self/gid_map")
if err != nil {
@ -99,7 +128,7 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
}
sysMnt := spec.Mount{
Destination: "/sys",
Type: "bind",
Type: bindMount,
Source: "/sys",
Options: []string{"rprivate", "nosuid", "noexec", "nodev", r, "rbind"},
}
@ -126,7 +155,7 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
g.RemoveMount("/dev/mqueue")
devMqueue := spec.Mount{
Destination: "/dev/mqueue",
Type: "bind",
Type: bindMount,
Source: "/dev/mqueue",
Options: []string{"bind", "nosuid", "noexec", "nodev"},
}
@ -136,7 +165,7 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
g.RemoveMount("/proc")
procMount := spec.Mount{
Destination: "/proc",
Type: "bind",
Type: bindMount,
Source: "/proc",
Options: []string{"rbind", "nosuid", "noexec", "nodev"},
}
@ -377,6 +406,12 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
configSpec.Mounts = supercedeUserMounts(volumeMounts, configSpec.Mounts)
//--mount
configSpec.Mounts = supercedeUserMounts(config.initFSMounts(), configSpec.Mounts)
// Split normal mounts and named volumes
newMounts, namedVolumes := splitNamedVolumes(configSpec.Mounts)
configSpec.Mounts = newMounts
config.NamedVolumes = namedVolumes
// BLOCK IO
blkio, err := config.CreateBlockIO()
if err != nil {