diff options
| -rw-r--r-- | pkg/spec/storage.go | 31 | ||||
| -rw-r--r-- | test/e2e/run_volume_test.go | 18 | 
2 files changed, 48 insertions, 1 deletions
diff --git a/pkg/spec/storage.go b/pkg/spec/storage.go index ac7a2c30f..e0bb48a9c 100644 --- a/pkg/spec/storage.go +++ b/pkg/spec/storage.go @@ -410,13 +410,42 @@ func getBindMount(args []string) (spec.Mount, error) {  	setSource := false  	setDest := false +	setRORW := false  	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": +		case "ro", "rw": +			if setRORW { +				return newMount, errors.Wrapf(optionArgError, "cannot pass 'ro' or 'rw' options more than once") +			} +			setRORW = true +			// Can be formatted as one of: +			// ro +			// ro=[true|false] +			// rw +			// rw=[true|false] +			if len(kv) == 1 { +				newMount.Options = append(newMount.Options, kv[0]) +			} else if len(kv) == 2 { +				switch strings.ToLower(kv[1]) { +				case "true": +					newMount.Options = append(newMount.Options, kv[0]) +				case "false": +					// Set the opposite only for rw +					// ro's opposite is the default +					if kv[0] == "rw" { +						newMount.Options = append(newMount.Options, "ro") +					} +				default: +					return newMount, errors.Wrapf(optionArgError, "%s must be set to true or false, instead received %q", kv[0], kv[1]) +				} +			} else { +				return newMount, errors.Wrapf(optionArgError, "badly formatted option %q", val) +			} +		case "nosuid", "nodev", "noexec":  			// TODO: detect duplication of these options.  			// (Is this necessary?)  			newMount.Options = append(newMount.Options, kv[0]) diff --git a/test/e2e/run_volume_test.go b/test/e2e/run_volume_test.go index 9e160e73c..1e0b84310 100644 --- a/test/e2e/run_volume_test.go +++ b/test/e2e/run_volume_test.go @@ -136,4 +136,22 @@ var _ = Describe("Podman run with volumes", func() {  		session.WaitWithDefaultTimeout()  		Expect(session.ExitCode()).To(Equal(0))  	}) + +	It("podman run with mount flag and boolean options", func() { +		mountPath := filepath.Join(podmanTest.TempDir, "secrets") +		os.Mkdir(mountPath, 0755) +		session := podmanTest.Podman([]string{"run", "--rm", "--mount", fmt.Sprintf("type=bind,src=%s,target=/run/test,ro=false", mountPath), ALPINE, "grep", "/run/test", "/proc/self/mountinfo"}) +		session.WaitWithDefaultTimeout() +		Expect(session.ExitCode()).To(Equal(0)) +		Expect(session.OutputToString()).To(ContainSubstring("/run/test rw")) + +		session = podmanTest.Podman([]string{"run", "--rm", "--mount", fmt.Sprintf("type=bind,src=%s,target=/run/test,ro=true", mountPath), ALPINE, "grep", "/run/test", "/proc/self/mountinfo"}) +		session.WaitWithDefaultTimeout() +		Expect(session.ExitCode()).To(Equal(0)) +		Expect(session.OutputToString()).To(ContainSubstring("/run/test ro")) + +		session = podmanTest.Podman([]string{"run", "--rm", "--mount", fmt.Sprintf("type=bind,src=%s,target=/run/test,ro=true,rw=false", mountPath), ALPINE, "grep", "/run/test", "/proc/self/mountinfo"}) +		session.WaitWithDefaultTimeout() +		Expect(session.ExitCode()).To(Not(Equal(0))) +	})  })  | 
