Merge pull request #13788 from flouthoc/support-volume-opts
run, mount: allow setting driver specific option using `volume-opt=`
This commit is contained in:
		
						commit
						87d129e805
					
				|  | @ -475,6 +475,26 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai | |||
| 		if isAnonymous { | ||||
| 			volOptions = append(volOptions, withSetAnon()) | ||||
| 		} | ||||
| 
 | ||||
| 		// If volume-opts are set parse and add driver opts.
 | ||||
| 		if len(vol.Options) > 0 { | ||||
| 			isDriverOpts := false | ||||
| 			driverOpts := make(map[string]string) | ||||
| 			for _, opts := range vol.Options { | ||||
| 				if strings.HasPrefix(opts, "volume-opt") { | ||||
| 					isDriverOpts = true | ||||
| 					driverOptKey, driverOptValue, err := util.ParseDriverOpts(opts) | ||||
| 					if err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
| 					driverOpts[driverOptKey] = driverOptValue | ||||
| 				} | ||||
| 			} | ||||
| 			if isDriverOpts { | ||||
| 				parsedOptions := []VolumeCreateOption{WithVolumeOptions(driverOpts)} | ||||
| 				volOptions = append(volOptions, parsedOptions...) | ||||
| 			} | ||||
| 		} | ||||
| 		newVol, err := r.newVolume(ctx, volOptions...) | ||||
| 		if err != nil { | ||||
| 			return nil, errors.Wrapf(err, "error creating named volume %q", vol.Name) | ||||
|  |  | |||
|  | @ -523,6 +523,8 @@ func getNamedVolume(args []string) (*specgen.NamedVolume, error) { | |||
| 	for _, val := range args { | ||||
| 		kv := strings.SplitN(val, "=", 2) | ||||
| 		switch kv[0] { | ||||
| 		case "volume-opt": | ||||
| 			newVolume.Options = append(newVolume.Options, val) | ||||
| 		case "ro", "rw": | ||||
| 			if setRORW { | ||||
| 				return nil, errors.Wrapf(optionArgError, "cannot pass 'ro' and 'rw' options more than once") | ||||
|  |  | |||
|  | @ -57,6 +57,9 @@ func ProcessOptions(options []string, isTmpfs bool, sourcePath string) ([]string | |||
| 		switch splitOpt[0] { | ||||
| 		case "O": | ||||
| 			foundOverlay = true | ||||
| 		case "volume-opt": | ||||
| 			// Volume-opt should be relayed and processed by driver.
 | ||||
| 			newOptions = append(newOptions, opt) | ||||
| 		case "exec", "noexec": | ||||
| 			if foundExec { | ||||
| 				return nil, errors.Wrapf(ErrDupeMntOption, "only one of 'noexec' and 'exec' can be used") | ||||
|  | @ -175,3 +178,15 @@ func ProcessOptions(options []string, isTmpfs bool, sourcePath string) ([]string | |||
| 
 | ||||
| 	return newOptions, nil | ||||
| } | ||||
| 
 | ||||
| func ParseDriverOpts(option string) (string, string, error) { | ||||
| 	token := strings.SplitN(option, "=", 2) | ||||
| 	if len(token) != 2 { | ||||
| 		return "", "", errors.Wrapf(ErrBadMntOption, "cannot parse driver opts") | ||||
| 	} | ||||
| 	opt := strings.SplitN(token[1], "=", 2) | ||||
| 	if len(opt) != 2 { | ||||
| 		return "", "", errors.Wrapf(ErrBadMntOption, "cannot parse driver opts") | ||||
| 	} | ||||
| 	return opt[0], opt[1], nil | ||||
| } | ||||
|  |  | |||
|  | @ -797,6 +797,19 @@ VOLUME /test/`, ALPINE) | |||
| 		Expect(session.OutputToString()).Should(Equal("888:888")) | ||||
| 	}) | ||||
| 
 | ||||
| 	It("podman run with --mount and named volume with driver-opts", func() { | ||||
| 		// anonymous volume mount with driver opts
 | ||||
| 		vol := "type=volume,source=test_vol,dst=/test,volume-opt=type=tmpfs,volume-opt=device=tmpfs,volume-opt=o=nodev" | ||||
| 		session := podmanTest.Podman([]string{"run", "--rm", "--mount", vol, ALPINE, "echo", "hello"}) | ||||
| 		session.WaitWithDefaultTimeout() | ||||
| 		Expect(session).Should(Exit(0)) | ||||
| 
 | ||||
| 		inspectVol := podmanTest.Podman([]string{"volume", "inspect", "test_vol"}) | ||||
| 		inspectVol.WaitWithDefaultTimeout() | ||||
| 		Expect(inspectVol).Should(Exit(0)) | ||||
| 		Expect(inspectVol.OutputToString()).To(ContainSubstring("nodev")) | ||||
| 	}) | ||||
| 
 | ||||
| 	It("volume permissions after run", func() { | ||||
| 		imgName := "testimg" | ||||
| 		dockerfile := fmt.Sprintf(`FROM %s | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue