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  }