summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
authorMatthew Heon <matthew.heon@pm.me>2019-06-18 16:21:40 -0400
committerMatthew Heon <matthew.heon@pm.me>2019-06-18 17:02:20 -0400
commit8e5b294ac3429b8c59dd014a1583d0d77ea2380a (patch)
treef1ab03f0444acc92635dedcc9ba90b2d5a49e27a /pkg
parent292a48cab4f3d61b1805fa5f947667012049cce3 (diff)
downloadpodman-8e5b294ac3429b8c59dd014a1583d0d77ea2380a.tar.gz
podman-8e5b294ac3429b8c59dd014a1583d0d77ea2380a.tar.bz2
podman-8e5b294ac3429b8c59dd014a1583d0d77ea2380a.zip
Allow (but ignore) Cached and Delegated volume options
These are only used on OS X Docker, and ignored elsewhere - but since they are ignored, they're guaranteed to be safe everywhere, and people are using them. Fixes: #3340 Signed-off-by: Matthew Heon <matthew.heon@pm.me>
Diffstat (limited to 'pkg')
-rw-r--r--pkg/spec/storage.go43
-rw-r--r--pkg/util/mountOpts.go16
2 files changed, 39 insertions, 20 deletions
diff --git a/pkg/spec/storage.go b/pkg/spec/storage.go
index 283585ef8..c960ace33 100644
--- a/pkg/spec/storage.go
+++ b/pkg/spec/storage.go
@@ -251,9 +251,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 {
@@ -447,9 +449,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
}
@@ -575,35 +579,52 @@ func ValidateVolumeCtrDir(ctrDir string) error {
}
// ValidateVolumeOpts validates a volume's options
-func ValidateVolumeOpts(options []string) error {
+func ValidateVolumeOpts(options []string) ([]string, error) {
var foundRootPropagation, foundRWRO, foundLabelChange, bindType int
+ finalOpts := make([]string, 0, len(options))
+ discardOpts := []string{"cached", "delegated"}
for _, opt := range options {
+ // 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).
+ bad := false
+ for _, discard := range discardOpts {
+ if opt == discard {
+ bad = true
+ }
+ }
+ if bad {
+ continue
+ }
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 errors.Errorf("invalid options %q, can only specify 1 '[r]bind' option", strings.Join(options, ", "))
+ return nil, errors.Errorf("invalid options %q, can only specify 1 '[r]bind' option", strings.Join(options, ", "))
}
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
@@ -633,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 {
diff --git a/pkg/util/mountOpts.go b/pkg/util/mountOpts.go
index 489e7eeef..40c99384d 100644
--- a/pkg/util/mountOpts.go
+++ b/pkg/util/mountOpts.go
@@ -20,26 +20,22 @@ func ProcessOptions(options []string) []string {
foundbind, foundrw, foundro bool
rootProp string
)
+
for _, opt := range options {
switch opt {
case "bind", "rbind":
foundbind = true
- break
- }
- }
- if !foundbind {
- options = append(options, "rbind")
- }
- for _, opt := range options {
- switch opt {
- case "rw":
- foundrw = true
case "ro":
foundro = true
+ case "rw":
+ foundrw = true
case "private", "rprivate", "slave", "rslave", "shared", "rshared":
rootProp = opt
}
}
+ if !foundbind {
+ options = append(options, "rbind")
+ }
if !foundrw && !foundro {
options = append(options, "rw")
}