diff options
Diffstat (limited to 'pkg/spec/storage.go')
-rw-r--r-- | pkg/spec/storage.go | 56 |
1 files changed, 43 insertions, 13 deletions
diff --git a/pkg/spec/storage.go b/pkg/spec/storage.go index dcc149b55..88f1f6dc1 100644 --- a/pkg/spec/storage.go +++ b/pkg/spec/storage.go @@ -211,6 +211,13 @@ func (config *CreateConfig) parseVolumes(runtime *libpod.Runtime) ([]spec.Mount, } mount.Options = opts } + if mount.Type == TypeBind { + absSrc, err := filepath.Abs(mount.Source) + if err != nil { + return nil, nil, errors.Wrapf(err, "error getting absolute path of %s", mount.Source) + } + mount.Source = absSrc + } finalMounts = append(finalMounts, mount) } finalVolumes := make([]*libpod.ContainerNamedVolume, 0, len(baseVolumes)) @@ -251,9 +258,11 @@ func (config *CreateConfig) getVolumesFrom(runtime *libpod.Runtime) (map[string] return nil, nil, errors.Errorf("invalid options %q, can only specify 'ro', 'rw', and 'z", splitVol[1]) } options = strings.Split(splitVol[1], ",") - if err := ValidateVolumeOpts(options); err != nil { + opts, err := ValidateVolumeOpts(options) + if err != nil { return nil, nil, err } + options = opts } ctr, err := runtime.LookupContainer(splitVol[0]) if err != nil { @@ -384,7 +393,7 @@ func (config *CreateConfig) getMounts() (map[string]spec.Mount, map[string]*libp } finalNamedVolumes[volume.Dest] = volume default: - return nil, nil, errors.Errorf("invalid fylesystem type %q", kv[1]) + return nil, nil, errors.Errorf("invalid filesystem type %q", kv[1]) } } @@ -403,6 +412,8 @@ func getBindMount(args []string) (spec.Mount, error) { for _, val := range args { kv := strings.Split(val, "=") switch kv[0] { + case "bind-nonrecursive": + newMount.Options = append(newMount.Options, "bind") case "ro", "nosuid", "nodev", "noexec": // TODO: detect duplication of these options. // (Is this necessary?) @@ -445,9 +456,11 @@ func getBindMount(args []string) (spec.Mount, error) { newMount.Source = newMount.Destination } - if err := ValidateVolumeOpts(newMount.Options); err != nil { + opts, err := ValidateVolumeOpts(newMount.Options) + if err != nil { return newMount, err } + newMount.Options = opts return newMount, nil } @@ -573,30 +586,45 @@ func ValidateVolumeCtrDir(ctrDir string) error { } // ValidateVolumeOpts validates a volume's options -func ValidateVolumeOpts(options []string) error { - var foundRootPropagation, foundRWRO, foundLabelChange int +func ValidateVolumeOpts(options []string) ([]string, error) { + var foundRootPropagation, foundRWRO, foundLabelChange, bindType int + finalOpts := make([]string, 0, len(options)) for _, opt := range options { switch opt { case "rw", "ro": foundRWRO++ if foundRWRO > 1 { - return errors.Errorf("invalid options %q, can only specify 1 'rw' or 'ro' option", strings.Join(options, ", ")) + return nil, errors.Errorf("invalid options %q, can only specify 1 'rw' or 'ro' option", strings.Join(options, ", ")) } case "z", "Z": foundLabelChange++ if foundLabelChange > 1 { - return errors.Errorf("invalid options %q, can only specify 1 'z' or 'Z' option", strings.Join(options, ", ")) + return nil, errors.Errorf("invalid options %q, can only specify 1 'z' or 'Z' option", strings.Join(options, ", ")) } case "private", "rprivate", "shared", "rshared", "slave", "rslave": foundRootPropagation++ if foundRootPropagation > 1 { - return errors.Errorf("invalid options %q, can only specify 1 '[r]shared', '[r]private' or '[r]slave' option", strings.Join(options, ", ")) - } + return nil, errors.Errorf("invalid options %q, can only specify 1 '[r]shared', '[r]private' or '[r]slave' option", strings.Join(options, ", ")) + } + case "bind", "rbind": + bindType++ + if bindType > 1 { + return nil, errors.Errorf("invalid options %q, can only specify 1 '[r]bind' option", strings.Join(options, ", ")) + } + case "cached", "delegated": + // The discarded ops are OS X specific volume options + // introduced in a recent Docker version. + // They have no meaning on Linux, so here we silently + // drop them. This matches Docker's behavior (the options + // are intended to be always safe to use, even not on OS + // X). + continue default: - return errors.Errorf("invalid option type %q", opt) + return nil, errors.Errorf("invalid mount option %q", opt) } + finalOpts = append(finalOpts, opt) } - return nil + return finalOpts, nil } // GetVolumeMounts takes user provided input for bind mounts and creates Mount structs @@ -626,9 +654,11 @@ func (config *CreateConfig) getVolumeMounts() (map[string]spec.Mount, map[string } if len(splitVol) > 2 { options = strings.Split(splitVol[2], ",") - if err := ValidateVolumeOpts(options); err != nil { + opts, err := ValidateVolumeOpts(options) + if err != nil { return nil, nil, err } + options = opts } if err := ValidateVolumeHostDir(src); err != nil { @@ -797,7 +827,7 @@ func initFSMounts(inputMounts []spec.Mount) []spec.Mount { if m.Type == TypeBind { m.Options = util.ProcessOptions(m.Options) } - if m.Type == TypeTmpfs { + if m.Type == TypeTmpfs && filepath.Clean(m.Destination) != "/dev" { m.Options = append(m.Options, "tmpcopyup") } mounts = append(mounts, m) |