summaryrefslogtreecommitdiff
path: root/pkg/spec/storage.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/spec/storage.go')
-rw-r--r--pkg/spec/storage.go56
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)