mirror of
https://github.com/containers/podman.git
synced 2025-09-13 18:54:02 +08:00
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>
This commit is contained in:
@ -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])
|
return nil, nil, errors.Errorf("invalid options %q, can only specify 'ro', 'rw', and 'z", splitVol[1])
|
||||||
}
|
}
|
||||||
options = strings.Split(splitVol[1], ",")
|
options = strings.Split(splitVol[1], ",")
|
||||||
if err := ValidateVolumeOpts(options); err != nil {
|
opts, err := ValidateVolumeOpts(options)
|
||||||
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
options = opts
|
||||||
}
|
}
|
||||||
ctr, err := runtime.LookupContainer(splitVol[0])
|
ctr, err := runtime.LookupContainer(splitVol[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -447,9 +449,11 @@ func getBindMount(args []string) (spec.Mount, error) {
|
|||||||
newMount.Source = newMount.Destination
|
newMount.Source = newMount.Destination
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ValidateVolumeOpts(newMount.Options); err != nil {
|
opts, err := ValidateVolumeOpts(newMount.Options)
|
||||||
|
if err != nil {
|
||||||
return newMount, err
|
return newMount, err
|
||||||
}
|
}
|
||||||
|
newMount.Options = opts
|
||||||
|
|
||||||
return newMount, nil
|
return newMount, nil
|
||||||
}
|
}
|
||||||
@ -575,35 +579,52 @@ func ValidateVolumeCtrDir(ctrDir string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ValidateVolumeOpts validates a volume's options
|
// ValidateVolumeOpts validates a volume's options
|
||||||
func ValidateVolumeOpts(options []string) error {
|
func ValidateVolumeOpts(options []string) ([]string, error) {
|
||||||
var foundRootPropagation, foundRWRO, foundLabelChange, bindType int
|
var foundRootPropagation, foundRWRO, foundLabelChange, bindType int
|
||||||
|
finalOpts := make([]string, 0, len(options))
|
||||||
|
discardOpts := []string{"cached", "delegated"}
|
||||||
for _, opt := range options {
|
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 {
|
switch opt {
|
||||||
case "rw", "ro":
|
case "rw", "ro":
|
||||||
foundRWRO++
|
foundRWRO++
|
||||||
if foundRWRO > 1 {
|
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":
|
case "z", "Z":
|
||||||
foundLabelChange++
|
foundLabelChange++
|
||||||
if foundLabelChange > 1 {
|
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":
|
case "private", "rprivate", "shared", "rshared", "slave", "rslave":
|
||||||
foundRootPropagation++
|
foundRootPropagation++
|
||||||
if foundRootPropagation > 1 {
|
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":
|
case "bind", "rbind":
|
||||||
bindType++
|
bindType++
|
||||||
if bindType > 1 {
|
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:
|
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
|
// 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 {
|
if len(splitVol) > 2 {
|
||||||
options = strings.Split(splitVol[2], ",")
|
options = strings.Split(splitVol[2], ",")
|
||||||
if err := ValidateVolumeOpts(options); err != nil {
|
opts, err := ValidateVolumeOpts(options)
|
||||||
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
options = opts
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ValidateVolumeHostDir(src); err != nil {
|
if err := ValidateVolumeHostDir(src); err != nil {
|
||||||
|
@ -20,26 +20,22 @@ func ProcessOptions(options []string) []string {
|
|||||||
foundbind, foundrw, foundro bool
|
foundbind, foundrw, foundro bool
|
||||||
rootProp string
|
rootProp string
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, opt := range options {
|
for _, opt := range options {
|
||||||
switch opt {
|
switch opt {
|
||||||
case "bind", "rbind":
|
case "bind", "rbind":
|
||||||
foundbind = true
|
foundbind = true
|
||||||
break
|
case "ro":
|
||||||
|
foundro = true
|
||||||
|
case "rw":
|
||||||
|
foundrw = true
|
||||||
|
case "private", "rprivate", "slave", "rslave", "shared", "rshared":
|
||||||
|
rootProp = opt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !foundbind {
|
if !foundbind {
|
||||||
options = append(options, "rbind")
|
options = append(options, "rbind")
|
||||||
}
|
}
|
||||||
for _, opt := range options {
|
|
||||||
switch opt {
|
|
||||||
case "rw":
|
|
||||||
foundrw = true
|
|
||||||
case "ro":
|
|
||||||
foundro = true
|
|
||||||
case "private", "rprivate", "slave", "rslave", "shared", "rshared":
|
|
||||||
rootProp = opt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !foundrw && !foundro {
|
if !foundrw && !foundro {
|
||||||
options = append(options, "rw")
|
options = append(options, "rw")
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user