github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/libpod/runtime_volume.go (about) 1 package libpod 2 3 import ( 4 "context" 5 6 "github.com/containers/libpod/libpod/define" 7 "github.com/containers/libpod/libpod/events" 8 "github.com/pkg/errors" 9 ) 10 11 // Contains the public Runtime API for volumes 12 13 // A VolumeCreateOption is a functional option which alters the Volume created by 14 // NewVolume 15 type VolumeCreateOption func(*Volume) error 16 17 // VolumeFilter is a function to determine whether a volume is included in command 18 // output. Volumes to be outputted are tested using the function. a true return will 19 // include the volume, a false return will exclude it. 20 type VolumeFilter func(*Volume) bool 21 22 // RemoveVolume removes a volumes 23 func (r *Runtime) RemoveVolume(ctx context.Context, v *Volume, force bool) error { 24 r.lock.Lock() 25 defer r.lock.Unlock() 26 27 if !r.valid { 28 return define.ErrRuntimeStopped 29 } 30 31 if !v.valid { 32 if ok, _ := r.state.HasVolume(v.Name()); !ok { 33 // Volume probably already removed 34 // Or was never in the runtime to begin with 35 return nil 36 } 37 } 38 return r.removeVolume(ctx, v, force) 39 } 40 41 // GetVolume retrieves a volume given its full name. 42 func (r *Runtime) GetVolume(name string) (*Volume, error) { 43 r.lock.RLock() 44 defer r.lock.RUnlock() 45 46 if !r.valid { 47 return nil, define.ErrRuntimeStopped 48 } 49 50 vol, err := r.state.Volume(name) 51 if err != nil { 52 return nil, err 53 } 54 55 return vol, nil 56 } 57 58 // LookupVolume retrieves a volume by unambiguous partial name. 59 func (r *Runtime) LookupVolume(name string) (*Volume, error) { 60 r.lock.RLock() 61 defer r.lock.RUnlock() 62 63 if !r.valid { 64 return nil, define.ErrRuntimeStopped 65 } 66 67 vol, err := r.state.LookupVolume(name) 68 if err != nil { 69 return nil, err 70 } 71 72 return vol, nil 73 } 74 75 // HasVolume checks to see if a volume with the given name exists 76 func (r *Runtime) HasVolume(name string) (bool, error) { 77 r.lock.RLock() 78 defer r.lock.RUnlock() 79 80 if !r.valid { 81 return false, define.ErrRuntimeStopped 82 } 83 84 return r.state.HasVolume(name) 85 } 86 87 // Volumes retrieves all volumes 88 // Filters can be provided which will determine which volumes are included in the 89 // output. Multiple filters are handled by ANDing their output, so only volumes 90 // matching all filters are returned 91 func (r *Runtime) Volumes(filters ...VolumeFilter) ([]*Volume, error) { 92 r.lock.RLock() 93 defer r.lock.RUnlock() 94 95 if !r.valid { 96 return nil, define.ErrRuntimeStopped 97 } 98 99 vols, err := r.state.AllVolumes() 100 if err != nil { 101 return nil, err 102 } 103 104 volsFiltered := make([]*Volume, 0, len(vols)) 105 for _, vol := range vols { 106 include := true 107 for _, filter := range filters { 108 include = include && filter(vol) 109 } 110 111 if include { 112 volsFiltered = append(volsFiltered, vol) 113 } 114 } 115 116 return volsFiltered, nil 117 } 118 119 // GetAllVolumes retrieves all the volumes 120 func (r *Runtime) GetAllVolumes() ([]*Volume, error) { 121 r.lock.RLock() 122 defer r.lock.RUnlock() 123 124 if !r.valid { 125 return nil, define.ErrRuntimeStopped 126 } 127 128 return r.state.AllVolumes() 129 } 130 131 // PruneVolumes removes unused volumes from the system 132 func (r *Runtime) PruneVolumes(ctx context.Context) (map[string]error, error) { 133 reports := make(map[string]error) 134 vols, err := r.GetAllVolumes() 135 if err != nil { 136 return nil, err 137 } 138 139 for _, vol := range vols { 140 if err := r.RemoveVolume(ctx, vol, false); err != nil { 141 if errors.Cause(err) != define.ErrVolumeBeingUsed && errors.Cause(err) != define.ErrVolumeRemoved { 142 reports[vol.Name()] = err 143 } 144 continue 145 } 146 vol.newVolumeEvent(events.Prune) 147 reports[vol.Name()] = nil 148 } 149 return reports, nil 150 }