github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/cmd/podman/shared/volumes_shared.go (about) 1 package shared 2 3 import ( 4 "context" 5 "strconv" 6 "strings" 7 8 "github.com/containers/libpod/libpod" 9 "github.com/containers/libpod/libpod/define" 10 "github.com/pkg/errors" 11 "github.com/sirupsen/logrus" 12 ) 13 14 // Remove given set of volumes 15 func SharedRemoveVolumes(ctx context.Context, runtime *libpod.Runtime, vols []string, all, force bool) ([]string, map[string]error, error) { 16 var ( 17 toRemove []*libpod.Volume 18 success []string 19 failed map[string]error 20 ) 21 22 failed = make(map[string]error) 23 24 if all { 25 vols, err := runtime.Volumes() 26 if err != nil { 27 return nil, nil, err 28 } 29 toRemove = vols 30 } else { 31 for _, v := range vols { 32 vol, err := runtime.LookupVolume(v) 33 if err != nil { 34 failed[v] = err 35 continue 36 } 37 toRemove = append(toRemove, vol) 38 } 39 } 40 41 // We could parallelize this, but I haven't heard anyone complain about 42 // performance here yet, so hold off. 43 for _, vol := range toRemove { 44 if err := runtime.RemoveVolume(ctx, vol, force); err != nil { 45 failed[vol.Name()] = err 46 continue 47 } 48 success = append(success, vol.Name()) 49 } 50 51 return success, failed, nil 52 } 53 54 // Handle volume options from CLI. 55 // Parse "o" option to find UID, GID. 56 func ParseVolumeOptions(opts map[string]string) ([]libpod.VolumeCreateOption, error) { 57 libpodOptions := []libpod.VolumeCreateOption{} 58 volumeOptions := make(map[string]string) 59 60 for key, value := range opts { 61 switch key { 62 case "o": 63 // o has special handling to parse out UID, GID. 64 // These are separate Libpod options. 65 splitVal := strings.Split(value, ",") 66 finalVal := []string{} 67 for _, o := range splitVal { 68 // Options will be formatted as either "opt" or 69 // "opt=value" 70 splitO := strings.SplitN(o, "=", 2) 71 switch strings.ToLower(splitO[0]) { 72 case "uid": 73 if len(splitO) != 2 { 74 return nil, errors.Wrapf(define.ErrInvalidArg, "uid option must provide a UID") 75 } 76 intUID, err := strconv.Atoi(splitO[1]) 77 if err != nil { 78 return nil, errors.Wrapf(err, "cannot convert UID %s to integer", splitO[1]) 79 } 80 logrus.Debugf("Removing uid= from options and adding WithVolumeUID for UID %d", intUID) 81 libpodOptions = append(libpodOptions, libpod.WithVolumeUID(intUID)) 82 case "gid": 83 if len(splitO) != 2 { 84 return nil, errors.Wrapf(define.ErrInvalidArg, "gid option must provide a GID") 85 } 86 intGID, err := strconv.Atoi(splitO[1]) 87 if err != nil { 88 return nil, errors.Wrapf(err, "cannot convert GID %s to integer", splitO[1]) 89 } 90 logrus.Debugf("Removing gid= from options and adding WithVolumeGID for GID %d", intGID) 91 libpodOptions = append(libpodOptions, libpod.WithVolumeGID(intGID)) 92 default: 93 finalVal = append(finalVal, o) 94 } 95 } 96 if len(finalVal) > 0 { 97 volumeOptions[key] = strings.Join(finalVal, ",") 98 } 99 default: 100 volumeOptions[key] = value 101 } 102 } 103 104 if len(volumeOptions) > 0 { 105 libpodOptions = append(libpodOptions, libpod.WithVolumeOptions(volumeOptions)) 106 } 107 108 return libpodOptions, nil 109 }