github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/pkg/domain/infra/abi/volumes.go (about)

     1  package abi
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/hanks177/podman/v4/libpod"
     7  	"github.com/hanks177/podman/v4/libpod/define"
     8  	"github.com/hanks177/podman/v4/pkg/domain/entities"
     9  	"github.com/hanks177/podman/v4/pkg/domain/entities/reports"
    10  	"github.com/hanks177/podman/v4/pkg/domain/filters"
    11  	"github.com/hanks177/podman/v4/pkg/domain/infra/abi/parse"
    12  	"github.com/pkg/errors"
    13  )
    14  
    15  func (ic *ContainerEngine) VolumeCreate(ctx context.Context, opts entities.VolumeCreateOptions) (*entities.IDOrNameResponse, error) {
    16  	var (
    17  		volumeOptions []libpod.VolumeCreateOption
    18  	)
    19  	if len(opts.Name) > 0 {
    20  		volumeOptions = append(volumeOptions, libpod.WithVolumeName(opts.Name))
    21  	}
    22  	if len(opts.Driver) > 0 {
    23  		volumeOptions = append(volumeOptions, libpod.WithVolumeDriver(opts.Driver))
    24  	}
    25  	if len(opts.Label) > 0 {
    26  		volumeOptions = append(volumeOptions, libpod.WithVolumeLabels(opts.Label))
    27  	}
    28  	if len(opts.Options) > 0 {
    29  		parsedOptions, err := parse.VolumeOptions(opts.Options)
    30  		if err != nil {
    31  			return nil, err
    32  		}
    33  		volumeOptions = append(volumeOptions, parsedOptions...)
    34  	}
    35  	vol, err := ic.Libpod.NewVolume(ctx, volumeOptions...)
    36  	if err != nil {
    37  		return nil, err
    38  	}
    39  	return &entities.IDOrNameResponse{IDOrName: vol.Name()}, nil
    40  }
    41  
    42  func (ic *ContainerEngine) VolumeRm(ctx context.Context, namesOrIds []string, opts entities.VolumeRmOptions) ([]*entities.VolumeRmReport, error) {
    43  	var (
    44  		err     error
    45  		vols    []*libpod.Volume
    46  		reports = []*entities.VolumeRmReport{}
    47  	)
    48  
    49  	if opts.All {
    50  		vols, err = ic.Libpod.Volumes()
    51  		if err != nil {
    52  			return nil, err
    53  		}
    54  	} else {
    55  		for _, id := range namesOrIds {
    56  			vol, err := ic.Libpod.LookupVolume(id)
    57  			if err != nil {
    58  				reports = append(reports, &entities.VolumeRmReport{
    59  					Err: err,
    60  					Id:  id,
    61  				})
    62  				continue
    63  			}
    64  			vols = append(vols, vol)
    65  		}
    66  	}
    67  	for _, vol := range vols {
    68  		reports = append(reports, &entities.VolumeRmReport{
    69  			Err: ic.Libpod.RemoveVolume(ctx, vol, opts.Force, opts.Timeout),
    70  			Id:  vol.Name(),
    71  		})
    72  	}
    73  	return reports, nil
    74  }
    75  
    76  func (ic *ContainerEngine) VolumeInspect(ctx context.Context, namesOrIds []string, opts entities.InspectOptions) ([]*entities.VolumeInspectReport, []error, error) {
    77  	var (
    78  		err  error
    79  		errs []error
    80  		vols []*libpod.Volume
    81  	)
    82  
    83  	// Note: as with previous implementation, a single failure here
    84  	// results a return.
    85  	if opts.All {
    86  		vols, err = ic.Libpod.GetAllVolumes()
    87  		if err != nil {
    88  			return nil, nil, err
    89  		}
    90  	} else {
    91  		for _, v := range namesOrIds {
    92  			vol, err := ic.Libpod.LookupVolume(v)
    93  			if err != nil {
    94  				if errors.Cause(err) == define.ErrNoSuchVolume {
    95  					errs = append(errs, errors.Errorf("no such volume %s", v))
    96  					continue
    97  				} else {
    98  					return nil, nil, errors.Wrapf(err, "error inspecting volume %s", v)
    99  				}
   100  			}
   101  			vols = append(vols, vol)
   102  		}
   103  	}
   104  	reports := make([]*entities.VolumeInspectReport, 0, len(vols))
   105  	for _, v := range vols {
   106  		inspectOut, err := v.Inspect()
   107  		if err != nil {
   108  			return nil, nil, err
   109  		}
   110  		config := entities.VolumeConfigResponse{
   111  			InspectVolumeData: *inspectOut,
   112  		}
   113  		reports = append(reports, &entities.VolumeInspectReport{VolumeConfigResponse: &config})
   114  	}
   115  	return reports, errs, nil
   116  }
   117  
   118  func (ic *ContainerEngine) VolumePrune(ctx context.Context, options entities.VolumePruneOptions) ([]*reports.PruneReport, error) {
   119  	filterFuncs, err := filters.GenerateVolumeFilters(options.Filters)
   120  	if err != nil {
   121  		return nil, err
   122  	}
   123  	return ic.pruneVolumesHelper(ctx, filterFuncs)
   124  }
   125  
   126  func (ic *ContainerEngine) pruneVolumesHelper(ctx context.Context, filterFuncs []libpod.VolumeFilter) ([]*reports.PruneReport, error) {
   127  	pruned, err := ic.Libpod.PruneVolumes(ctx, filterFuncs)
   128  	if err != nil {
   129  		return nil, err
   130  	}
   131  	return pruned, nil
   132  }
   133  
   134  func (ic *ContainerEngine) VolumeList(ctx context.Context, opts entities.VolumeListOptions) ([]*entities.VolumeListReport, error) {
   135  	volumeFilters, err := filters.GenerateVolumeFilters(opts.Filter)
   136  	if err != nil {
   137  		return nil, err
   138  	}
   139  	vols, err := ic.Libpod.Volumes(volumeFilters...)
   140  	if err != nil {
   141  		return nil, err
   142  	}
   143  	reports := make([]*entities.VolumeListReport, 0, len(vols))
   144  	for _, v := range vols {
   145  		inspectOut, err := v.Inspect()
   146  		if err != nil {
   147  			return nil, err
   148  		}
   149  		config := entities.VolumeConfigResponse{
   150  			InspectVolumeData: *inspectOut,
   151  		}
   152  		reports = append(reports, &entities.VolumeListReport{VolumeConfigResponse: config})
   153  	}
   154  	return reports, nil
   155  }
   156  
   157  // VolumeExists check if a given volume name exists
   158  func (ic *ContainerEngine) VolumeExists(ctx context.Context, nameOrID string) (*entities.BoolReport, error) {
   159  	exists, err := ic.Libpod.HasVolume(nameOrID)
   160  	if err != nil {
   161  		return nil, err
   162  	}
   163  	return &entities.BoolReport{Value: exists}, nil
   164  }
   165  
   166  // Volumemounted check if a given volume using plugin or filesystem is mounted or not.
   167  func (ic *ContainerEngine) VolumeMounted(ctx context.Context, nameOrID string) (*entities.BoolReport, error) {
   168  	vol, err := ic.Libpod.LookupVolume(nameOrID)
   169  	if err != nil {
   170  		return nil, err
   171  	}
   172  	mountCount, err := vol.MountCount()
   173  	if err != nil {
   174  		// FIXME: this error should probably be returned
   175  		return &entities.BoolReport{Value: false}, nil // nolint: nilerr
   176  	}
   177  	if mountCount > 0 {
   178  		return &entities.BoolReport{Value: true}, nil
   179  	}
   180  	return &entities.BoolReport{Value: false}, nil
   181  }
   182  
   183  func (ic *ContainerEngine) VolumeMount(ctx context.Context, nameOrIDs []string) ([]*entities.VolumeMountReport, error) {
   184  	reports := []*entities.VolumeMountReport{}
   185  	for _, name := range nameOrIDs {
   186  		report := entities.VolumeMountReport{Id: name}
   187  		vol, err := ic.Libpod.LookupVolume(name)
   188  		if err != nil {
   189  			report.Err = err
   190  		} else {
   191  			report.Path, report.Err = vol.Mount()
   192  		}
   193  		reports = append(reports, &report)
   194  	}
   195  
   196  	return reports, nil
   197  }
   198  
   199  func (ic *ContainerEngine) VolumeUnmount(ctx context.Context, nameOrIDs []string) ([]*entities.VolumeUnmountReport, error) {
   200  	reports := []*entities.VolumeUnmountReport{}
   201  	for _, name := range nameOrIDs {
   202  		report := entities.VolumeUnmountReport{Id: name}
   203  		vol, err := ic.Libpod.LookupVolume(name)
   204  		if err != nil {
   205  			report.Err = err
   206  		} else {
   207  			report.Err = vol.Unmount()
   208  		}
   209  		reports = append(reports, &report)
   210  	}
   211  
   212  	return reports, nil
   213  }