summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/commands_remoteclient.go1
-rw-r--r--cmd/podman/varlink/io.podman.varlink8
-rw-r--r--cmd/podman/volume_rm.go36
-rw-r--r--libpod/adapter/runtime.go5
-rw-r--r--libpod/adapter/runtime_remote.go10
-rw-r--r--libpod/runtime_volume.go51
-rw-r--r--pkg/varlinkapi/volumes.go9
7 files changed, 101 insertions, 19 deletions
diff --git a/cmd/podman/commands_remoteclient.go b/cmd/podman/commands_remoteclient.go
index e1f68405e..a656d5a29 100644
--- a/cmd/podman/commands_remoteclient.go
+++ b/cmd/podman/commands_remoteclient.go
@@ -35,6 +35,7 @@ func getPodSubCommands() []*cobra.Command {
func getVolumeSubCommands() []*cobra.Command {
return []*cobra.Command{
_volumeCreateCommand,
+ _volumeRmCommand,
}
}
diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink
index 7263cfea3..b03fde0df 100644
--- a/cmd/podman/varlink/io.podman.varlink
+++ b/cmd/podman/varlink/io.podman.varlink
@@ -34,7 +34,11 @@ type VolumeCreateOpts (
options: [string]string
)
-
+type VolumeRemoveOpts (
+ volumes: []string,
+ all: bool,
+ force: bool
+)
# ImageInList describes the structure that is returned in
# ListImages.
@@ -1064,6 +1068,8 @@ method ReceiveFile(path: string, delete: bool) -> (len: int)
method VolumeCreate(options: VolumeCreateOpts) -> (volumeName: string)
+method VolumeRemove(options: VolumeRemoveOpts) -> (volumeNames: []string)
+
# ImageNotFound means the image could not be found by the provided name or ID in local storage.
error ImageNotFound (name: string)
diff --git a/cmd/podman/volume_rm.go b/cmd/podman/volume_rm.go
index b02a06ed9..af05957e8 100644
--- a/cmd/podman/volume_rm.go
+++ b/cmd/podman/volume_rm.go
@@ -4,9 +4,8 @@ import (
"fmt"
"github.com/containers/libpod/cmd/podman/cliconfig"
- "github.com/containers/libpod/cmd/podman/libpodruntime"
+ "github.com/containers/libpod/libpod/adapter"
"github.com/pkg/errors"
- "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
@@ -43,25 +42,28 @@ func init() {
func volumeRmCmd(c *cliconfig.VolumeRmValues) error {
var err error
- runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+ if (len(c.InputArgs) > 0 && c.All) || (len(c.InputArgs) < 1 && !c.All) {
+ return errors.New("choose either one or more volumes or all")
+ }
+
+ runtime, err := adapter.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
defer runtime.Shutdown(false)
-
- ctx := getContext()
-
- vols, lastError := getVolumesFromContext(&c.PodmanCommand, runtime)
- for _, vol := range vols {
- err = runtime.RemoveVolume(ctx, vol, c.Force, false)
- if err != nil {
- if lastError != nil {
- logrus.Errorf("%q", lastError)
- }
- lastError = errors.Wrapf(err, "failed to remove volume %q", vol.Name())
- } else {
- fmt.Println(vol.Name())
+ deletedVolumeNames, err := runtime.RemoveVolumes(getContext(), c)
+ if err != nil {
+ if len(deletedVolumeNames) > 0 {
+ printDeleteVolumes(deletedVolumeNames)
+ return err
}
}
- return lastError
+ printDeleteVolumes(deletedVolumeNames)
+ return err
+}
+
+func printDeleteVolumes(volumes []string) {
+ for _, v := range volumes {
+ fmt.Println(v)
+ }
}
diff --git a/libpod/adapter/runtime.go b/libpod/adapter/runtime.go
index 050ea6ed4..2b1ddb09d 100644
--- a/libpod/adapter/runtime.go
+++ b/libpod/adapter/runtime.go
@@ -185,3 +185,8 @@ func (r *LocalRuntime) CreateVolume(ctx context.Context, c *cliconfig.VolumeCrea
}
return newVolume.Name(), nil
}
+
+// RemoveVolumes is a wrapper to remove volumes
+func (r *LocalRuntime) RemoveVolumes(ctx context.Context, c *cliconfig.VolumeRmValues) ([]string, error) {
+ return r.Runtime.RemoveVolumes(ctx, c.InputArgs, c.All, c.Force)
+}
diff --git a/libpod/adapter/runtime_remote.go b/libpod/adapter/runtime_remote.go
index 3df8afc6e..4dfae34e1 100644
--- a/libpod/adapter/runtime_remote.go
+++ b/libpod/adapter/runtime_remote.go
@@ -449,3 +449,13 @@ func (r *LocalRuntime) CreateVolume(ctx context.Context, c *cliconfig.VolumeCrea
return iopodman.VolumeCreate().Call(r.Conn, cvOpts)
}
+
+// RemoveVolumes removes volumes over a varlink connection for the remote client
+func (r *LocalRuntime) RemoveVolumes(ctx context.Context, c *cliconfig.VolumeRmValues) ([]string, error) {
+ rmOpts := iopodman.VolumeRemoveOpts{
+ All: c.All,
+ Force: c.Force,
+ Volumes: c.InputArgs,
+ }
+ return iopodman.VolumeRemove().Call(r.Conn, rmOpts)
+}
diff --git a/libpod/runtime_volume.go b/libpod/runtime_volume.go
index 3921758ee..485f64bf1 100644
--- a/libpod/runtime_volume.go
+++ b/libpod/runtime_volume.go
@@ -2,6 +2,9 @@ package libpod
import (
"context"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+ "strings"
)
// Contains the public Runtime API for volumes
@@ -38,6 +41,38 @@ func (r *Runtime) RemoveVolume(ctx context.Context, v *Volume, force, prune bool
return r.removeVolume(ctx, v, force, prune)
}
+// RemoveVolumes removes a slice of volumes or all with a force bool
+func (r *Runtime) RemoveVolumes(ctx context.Context, volumes []string, all, force bool) ([]string, error) {
+ var (
+ vols []*Volume
+ err error
+ deletedVols []string
+ )
+ if all {
+ vols, err = r.Volumes()
+ if err != nil {
+ return nil, errors.Wrapf(err, "unable to get all volumes")
+ }
+ } else {
+ for _, i := range volumes {
+ vol, err := r.GetVolume(i)
+ if err != nil {
+ return nil, err
+ }
+ vols = append(vols, vol)
+ }
+ }
+
+ for _, vol := range vols {
+ if err := r.RemoveVolume(ctx, vol, force, false); err != nil {
+ return deletedVols, err
+ }
+ logrus.Debugf("removed volume %s", vol.Name())
+ deletedVols = append(deletedVols, vol.Name())
+ }
+ return deletedVols, nil
+}
+
// GetVolume retrieves a volume by its name
func (r *Runtime) GetVolume(name string) (*Volume, error) {
r.lock.RLock()
@@ -47,7 +82,21 @@ func (r *Runtime) GetVolume(name string) (*Volume, error) {
return nil, ErrRuntimeStopped
}
- return r.state.Volume(name)
+ vol, err := r.state.Volume(name)
+ if err == nil {
+ return vol, err
+ }
+
+ vols, err := r.GetAllVolumes()
+ if err != nil {
+ return nil, err
+ }
+ for _, v := range vols {
+ if strings.HasPrefix(v.Name(), name) {
+ return v, nil
+ }
+ }
+ return nil, errors.Errorf("unable to find volume %s", name)
}
// HasVolume checks to see if a volume with the given name exists
diff --git a/pkg/varlinkapi/volumes.go b/pkg/varlinkapi/volumes.go
index d1e4ae3c6..ced394e90 100644
--- a/pkg/varlinkapi/volumes.go
+++ b/pkg/varlinkapi/volumes.go
@@ -27,3 +27,12 @@ func (i *LibpodAPI) VolumeCreate(call iopodman.VarlinkCall, options iopodman.Vol
}
return call.ReplyVolumeCreate(newVolume.Name())
}
+
+// VolumeRemove removes volumes by options.All or options.Volumes
+func (i *LibpodAPI) VolumeRemove(call iopodman.VarlinkCall, options iopodman.VolumeRemoveOpts) error {
+ deletedVolumes, err := i.Runtime.RemoveVolumes(getContext(), options.Volumes, options.All, options.Force)
+ if err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+ return call.ReplyVolumeRemove(deletedVolumes)
+}