podman/libpod/runtime_volume.go
Daniel J Walsh a5e37ad280
Switch all references to github.com/containers/libpod -> podman
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
2020-07-28 08:23:45 -04:00

151 lines
3.4 KiB
Go

package libpod
import (
"context"
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/libpod/events"
"github.com/pkg/errors"
)
// Contains the public Runtime API for volumes
// A VolumeCreateOption is a functional option which alters the Volume created by
// NewVolume
type VolumeCreateOption func(*Volume) error
// VolumeFilter is a function to determine whether a volume is included in command
// output. Volumes to be outputted are tested using the function. a true return will
// include the volume, a false return will exclude it.
type VolumeFilter func(*Volume) bool
// RemoveVolume removes a volumes
func (r *Runtime) RemoveVolume(ctx context.Context, v *Volume, force bool) error {
r.lock.Lock()
defer r.lock.Unlock()
if !r.valid {
return define.ErrRuntimeStopped
}
if !v.valid {
if ok, _ := r.state.HasVolume(v.Name()); !ok {
// Volume probably already removed
// Or was never in the runtime to begin with
return nil
}
}
return r.removeVolume(ctx, v, force)
}
// GetVolume retrieves a volume given its full name.
func (r *Runtime) GetVolume(name string) (*Volume, error) {
r.lock.RLock()
defer r.lock.RUnlock()
if !r.valid {
return nil, define.ErrRuntimeStopped
}
vol, err := r.state.Volume(name)
if err != nil {
return nil, err
}
return vol, nil
}
// LookupVolume retrieves a volume by unambiguous partial name.
func (r *Runtime) LookupVolume(name string) (*Volume, error) {
r.lock.RLock()
defer r.lock.RUnlock()
if !r.valid {
return nil, define.ErrRuntimeStopped
}
vol, err := r.state.LookupVolume(name)
if err != nil {
return nil, err
}
return vol, nil
}
// HasVolume checks to see if a volume with the given name exists
func (r *Runtime) HasVolume(name string) (bool, error) {
r.lock.RLock()
defer r.lock.RUnlock()
if !r.valid {
return false, define.ErrRuntimeStopped
}
return r.state.HasVolume(name)
}
// Volumes retrieves all volumes
// Filters can be provided which will determine which volumes are included in the
// output. Multiple filters are handled by ANDing their output, so only volumes
// matching all filters are returned
func (r *Runtime) Volumes(filters ...VolumeFilter) ([]*Volume, error) {
r.lock.RLock()
defer r.lock.RUnlock()
if !r.valid {
return nil, define.ErrRuntimeStopped
}
vols, err := r.state.AllVolumes()
if err != nil {
return nil, err
}
volsFiltered := make([]*Volume, 0, len(vols))
for _, vol := range vols {
include := true
for _, filter := range filters {
include = include && filter(vol)
}
if include {
volsFiltered = append(volsFiltered, vol)
}
}
return volsFiltered, nil
}
// GetAllVolumes retrieves all the volumes
func (r *Runtime) GetAllVolumes() ([]*Volume, error) {
r.lock.RLock()
defer r.lock.RUnlock()
if !r.valid {
return nil, define.ErrRuntimeStopped
}
return r.state.AllVolumes()
}
// PruneVolumes removes unused volumes from the system
func (r *Runtime) PruneVolumes(ctx context.Context) (map[string]error, error) {
reports := make(map[string]error)
vols, err := r.GetAllVolumes()
if err != nil {
return nil, err
}
for _, vol := range vols {
if err := r.RemoveVolume(ctx, vol, false); err != nil {
if errors.Cause(err) != define.ErrVolumeBeingUsed && errors.Cause(err) != define.ErrVolumeRemoved {
reports[vol.Name()] = err
}
continue
}
vol.newVolumeEvent(events.Prune)
reports[vol.Name()] = nil
}
return reports, nil
}