github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/pkg/domain/infra/abi/parse/parse.go (about) 1 package parse 2 3 import ( 4 "strconv" 5 "strings" 6 7 "github.com/hanks177/podman/v4/libpod" 8 "github.com/hanks177/podman/v4/libpod/define" 9 units "github.com/docker/go-units" 10 "github.com/pkg/errors" 11 "github.com/sirupsen/logrus" 12 ) 13 14 // Handle volume options from CLI. 15 // Parse "o" option to find UID, GID, Size. 16 func VolumeOptions(opts map[string]string) ([]libpod.VolumeCreateOption, error) { 17 libpodOptions := []libpod.VolumeCreateOption{} 18 volumeOptions := make(map[string]string) 19 20 for key, value := range opts { 21 switch key { 22 case "o": 23 // o has special handling to parse out UID, GID. 24 // These are separate Libpod options. 25 splitVal := strings.Split(value, ",") 26 finalVal := []string{} 27 for _, o := range splitVal { 28 // Options will be formatted as either "opt" or 29 // "opt=value" 30 splitO := strings.SplitN(o, "=", 2) 31 switch strings.ToLower(splitO[0]) { 32 case "size": 33 size, err := units.FromHumanSize(splitO[1]) 34 if err != nil { 35 return nil, errors.Wrapf(err, "cannot convert size %s to integer", splitO[1]) 36 } 37 libpodOptions = append(libpodOptions, libpod.WithVolumeSize(uint64(size))) 38 finalVal = append(finalVal, o) 39 // set option "SIZE": "$size" 40 volumeOptions["SIZE"] = splitO[1] 41 case "inodes": 42 inodes, err := strconv.ParseUint(splitO[1], 10, 64) 43 if err != nil { 44 return nil, errors.Wrapf(err, "cannot convert inodes %s to integer", splitO[1]) 45 } 46 libpodOptions = append(libpodOptions, libpod.WithVolumeInodes(inodes)) 47 finalVal = append(finalVal, o) 48 // set option "INODES": "$size" 49 volumeOptions["INODES"] = splitO[1] 50 case "uid": 51 if len(splitO) != 2 { 52 return nil, errors.Wrapf(define.ErrInvalidArg, "uid option must provide a UID") 53 } 54 intUID, err := strconv.Atoi(splitO[1]) 55 if err != nil { 56 return nil, errors.Wrapf(err, "cannot convert UID %s to integer", splitO[1]) 57 } 58 logrus.Debugf("Removing uid= from options and adding WithVolumeUID for UID %d", intUID) 59 libpodOptions = append(libpodOptions, libpod.WithVolumeUID(intUID), libpod.WithVolumeNoChown()) 60 finalVal = append(finalVal, o) 61 // set option "UID": "$uid" 62 volumeOptions["UID"] = splitO[1] 63 case "gid": 64 if len(splitO) != 2 { 65 return nil, errors.Wrapf(define.ErrInvalidArg, "gid option must provide a GID") 66 } 67 intGID, err := strconv.Atoi(splitO[1]) 68 if err != nil { 69 return nil, errors.Wrapf(err, "cannot convert GID %s to integer", splitO[1]) 70 } 71 logrus.Debugf("Removing gid= from options and adding WithVolumeGID for GID %d", intGID) 72 libpodOptions = append(libpodOptions, libpod.WithVolumeGID(intGID), libpod.WithVolumeNoChown()) 73 finalVal = append(finalVal, o) 74 // set option "GID": "$gid" 75 volumeOptions["GID"] = splitO[1] 76 case "noquota": 77 logrus.Debugf("Removing noquota from options and adding WithVolumeDisableQuota") 78 libpodOptions = append(libpodOptions, libpod.WithVolumeDisableQuota()) 79 // set option "NOQUOTA": "true" 80 volumeOptions["NOQUOTA"] = "true" 81 default: 82 finalVal = append(finalVal, o) 83 } 84 } 85 if len(finalVal) > 0 { 86 volumeOptions[key] = strings.Join(finalVal, ",") 87 } 88 default: 89 volumeOptions[key] = value 90 } 91 } 92 93 if len(volumeOptions) > 0 { 94 libpodOptions = append(libpodOptions, libpod.WithVolumeOptions(volumeOptions)) 95 } 96 97 return libpodOptions, nil 98 }