summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbaude <bbaude@redhat.com>2019-02-11 15:36:24 -0600
committerbaude <bbaude@redhat.com>2019-02-14 10:55:05 -0600
commit5be818e715d57f98e4a930632bc599e3fee3aaed (patch)
treecde8eb83111a17d6c081c4f25cae4d751b6313a5
parent0cd22435964573231ab32e545d5f319821b35b14 (diff)
downloadpodman-5be818e715d57f98e4a930632bc599e3fee3aaed.tar.gz
podman-5be818e715d57f98e4a930632bc599e3fee3aaed.tar.bz2
podman-5be818e715d57f98e4a930632bc599e3fee3aaed.zip
enable podman-remote volume prune
allow users to remotely prune volumes. this is the last volume command for remote enablement. as such, the volume commands are being folded back into main because they are supported for both local and remote clients. also, enable all volume tests that do not use containers as containers are not enabled for the remote client yet. Signed-off-by: baude <bbaude@redhat.com>
-rwxr-xr-xAPI.md15
-rw-r--r--cmd/podman/commands.go12
-rw-r--r--cmd/podman/commands_remoteclient.go10
-rw-r--r--cmd/podman/varlink/io.podman.varlink9
-rw-r--r--cmd/podman/volume.go10
-rw-r--r--cmd/podman/volume_prune.go29
-rw-r--r--libpod/adapter/runtime.go5
-rw-r--r--libpod/adapter/runtime_remote.go14
-rw-r--r--libpod/runtime_volume.go24
-rw-r--r--pkg/varlinkapi/volumes.go16
-rw-r--r--test/e2e/volume_create_test.go2
-rw-r--r--test/e2e/volume_inspect_test.go2
-rw-r--r--test/e2e/volume_ls_test.go2
-rw-r--r--test/e2e/volume_rm_test.go3
14 files changed, 101 insertions, 52 deletions
diff --git a/API.md b/API.md
index e44862c3f..dea6b7a4c 100755
--- a/API.md
+++ b/API.md
@@ -131,6 +131,8 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in
[func VolumeRemove(options: VolumeRemoveOpts) []string](#VolumeRemove)
+[func VolumesPrune() []string, []string](#VolumesPrune)
+
[func WaitContainer(name: string) int](#WaitContainer)
[type BuildInfo](#BuildInfo)
@@ -530,7 +532,7 @@ GetVersion returns version and build information of the podman service
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
method GetVolumes(args: [[]string](#[]string), all: [bool](https://godoc.org/builtin#bool)) [Volume](#Volume)</div>
-
+GetVolumes gets slice of the volumes on a remote host
### <a name="HistoryImage"></a>func HistoryImage
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
@@ -773,7 +775,7 @@ the image cannot be found in local storage; otherwise it will return a [MoreResp
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
method ReceiveFile(path: [string](https://godoc.org/builtin#string), delete: [bool](https://godoc.org/builtin#bool)) [int](https://godoc.org/builtin#int)</div>
-
+ReceiveFile allows the host to send a remote client a file
### <a name="RemoveContainer"></a>func RemoveContainer
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
@@ -856,7 +858,7 @@ search results per registry.
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
method SendFile(type: [string](https://godoc.org/builtin#string), length: [int](https://godoc.org/builtin#int)) [string](https://godoc.org/builtin#string)</div>
-
+Sendfile allows a remote client to send a file to the host
### <a name="StartContainer"></a>func StartContainer
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
@@ -956,12 +958,17 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.UnpausePod '{"name": "foo
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
method VolumeCreate(options: [VolumeCreateOpts](#VolumeCreateOpts)) [string](https://godoc.org/builtin#string)</div>
-
+VolumeCreate creates a volume on a remote host
### <a name="VolumeRemove"></a>func VolumeRemove
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
method VolumeRemove(options: [VolumeRemoveOpts](#VolumeRemoveOpts)) [[]string](#[]string)</div>
+VolumeRemove removes a volume on a remote host
+### <a name="VolumesPrune"></a>func VolumesPrune
+<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
+method VolumesPrune() [[]string](#[]string), [[]string](#[]string)</div>
+VolumesPrune removes unused volumes on the host
### <a name="WaitContainer"></a>func WaitContainer
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
diff --git a/cmd/podman/commands.go b/cmd/podman/commands.go
index 90e2ab5cf..9004a5941 100644
--- a/cmd/podman/commands.go
+++ b/cmd/podman/commands.go
@@ -114,18 +114,6 @@ func getPodSubCommands() []*cobra.Command {
}
}
-// Commands that the local client implements
-func getVolumeSubCommands() []*cobra.Command {
- return []*cobra.Command{
- _volumeCreateCommand,
- _volumeLsCommand,
- _volumeRmCommand,
- _volumeInspectCommand,
- _volumePruneCommand,
- }
-}
-
-// Commands that the local client implements
func getGenerateSubCommands() []*cobra.Command {
return []*cobra.Command{
_containerKubeCommand,
diff --git a/cmd/podman/commands_remoteclient.go b/cmd/podman/commands_remoteclient.go
index 7bdba1c19..ba0a4d47e 100644
--- a/cmd/podman/commands_remoteclient.go
+++ b/cmd/podman/commands_remoteclient.go
@@ -32,16 +32,6 @@ func getPodSubCommands() []*cobra.Command {
}
// commands that only the remoteclient implements
-func getVolumeSubCommands() []*cobra.Command {
- return []*cobra.Command{
- _volumeCreateCommand,
- _volumeRmCommand,
- _volumeLsCommand,
- _volumeInspectCommand,
- }
-}
-
-// commands that only the remoteclient implements
func getGenerateSubCommands() []*cobra.Command {
return []*cobra.Command{}
}
diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink
index dc6a25c44..94947c0e0 100644
--- a/cmd/podman/varlink/io.podman.varlink
+++ b/cmd/podman/varlink/io.podman.varlink
@@ -1070,15 +1070,24 @@ method ContainerInspectData(name: string) -> (config: string)
# development of Podman only and generally should not be used.
method ContainerStateData(name: string) -> (config: string)
+# Sendfile allows a remote client to send a file to the host
method SendFile(type: string, length: int) -> (file_handle: string)
+
+# ReceiveFile allows the host to send a remote client a file
method ReceiveFile(path: string, delete: bool) -> (len: int)
+# VolumeCreate creates a volume on a remote host
method VolumeCreate(options: VolumeCreateOpts) -> (volumeName: string)
+# VolumeRemove removes a volume on a remote host
method VolumeRemove(options: VolumeRemoveOpts) -> (volumeNames: []string)
+# GetVolumes gets slice of the volumes on a remote host
method GetVolumes(args: []string, all: bool) -> (volumes: []Volume)
+# VolumesPrune removes unused volumes on the host
+method VolumesPrune() -> (prunedNames: []string, prunedErrors: []string)
+
# ImageNotFound means the image could not be found by the provided name or ID in local storage.
error ImageNotFound (id: string)
diff --git a/cmd/podman/volume.go b/cmd/podman/volume.go
index 36798a19e..8a8664151 100644
--- a/cmd/podman/volume.go
+++ b/cmd/podman/volume.go
@@ -16,8 +16,16 @@ var volumeCommand = cliconfig.PodmanCommand{
Long: volumeDescription,
},
}
+var volumeSubcommands = []*cobra.Command{
+ _volumeCreateCommand,
+ _volumeLsCommand,
+ _volumeRmCommand,
+ _volumeInspectCommand,
+ _volumePruneCommand,
+}
func init() {
- volumeCommand.AddCommand(getVolumeSubCommands()...)
volumeCommand.SetUsageTemplate(UsageTemplate())
+ volumeCommand.AddCommand(volumeSubcommands...)
+ rootCmd.AddCommand(volumeCommand.Command)
}
diff --git a/cmd/podman/volume_prune.go b/cmd/podman/volume_prune.go
index 74228fa5b..a2205140f 100644
--- a/cmd/podman/volume_prune.go
+++ b/cmd/podman/volume_prune.go
@@ -8,7 +8,6 @@ import (
"strings"
"github.com/containers/libpod/cmd/podman/cliconfig"
- "github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/adapter"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -44,23 +43,20 @@ func init() {
}
func volumePrune(runtime *adapter.LocalRuntime, ctx context.Context) error {
- var lastError error
-
- volumes, err := runtime.GetAllVolumes()
- if err != nil {
- return err
+ prunedNames, prunedErrors := runtime.PruneVolumes(ctx)
+ for _, name := range prunedNames {
+ fmt.Println(name)
+ }
+ if len(prunedErrors) == 0 {
+ return nil
}
+ // Grab the last error
+ lastError := prunedErrors[len(prunedErrors)-1]
+ // Remove the last error from the error slice
+ prunedErrors = prunedErrors[:len(prunedErrors)-1]
- for _, vol := range volumes {
- err = runtime.RemoveVolume(ctx, vol, false, true)
- if err == nil {
- fmt.Println(vol.Name())
- } else if err != libpod.ErrVolumeBeingUsed {
- if lastError != nil {
- logrus.Errorf("%q", lastError)
- }
- lastError = errors.Wrapf(err, "failed to remove volume %q", vol.Name())
- }
+ for _, err := range prunedErrors {
+ logrus.Errorf("%q", err)
}
return lastError
}
@@ -85,6 +81,5 @@ func volumePruneCmd(c *cliconfig.VolumePruneValues) error {
return nil
}
}
-
return volumePrune(runtime, getContext())
}
diff --git a/libpod/adapter/runtime.go b/libpod/adapter/runtime.go
index 3146cf5db..02ef9af07 100644
--- a/libpod/adapter/runtime.go
+++ b/libpod/adapter/runtime.go
@@ -305,3 +305,8 @@ func (r *LocalRuntime) Build(ctx context.Context, c *cliconfig.BuildValues, opti
return r.Runtime.Build(ctx, options, dockerfiles...)
}
+
+// PruneVolumes is a wrapper function for libpod PruneVolumes
+func (r *LocalRuntime) PruneVolumes(ctx context.Context) ([]string, []error) {
+ return r.Runtime.PruneVolumes(ctx)
+}
diff --git a/libpod/adapter/runtime_remote.go b/libpod/adapter/runtime_remote.go
index 66ff5ed51..974ee63ca 100644
--- a/libpod/adapter/runtime_remote.go
+++ b/libpod/adapter/runtime_remote.go
@@ -642,3 +642,17 @@ func varlinkVolumeToVolume(r *LocalRuntime, volumes []iopodman.Volume) []*Volume
}
return vols
}
+
+// PruneVolumes removes all unused volumes from the remote system
+func (r *LocalRuntime) PruneVolumes(ctx context.Context) ([]string, []error) {
+ var errs []error
+ prunedNames, prunedErrors, err := iopodman.VolumesPrune().Call(r.Conn)
+ if err != nil {
+ return []string{}, []error{err}
+ }
+ // We need to transform the string results of the error into actual error types
+ for _, e := range prunedErrors {
+ errs = append(errs, errors.New(e))
+ }
+ return prunedNames, errs
+}
diff --git a/libpod/runtime_volume.go b/libpod/runtime_volume.go
index 485f64bf1..beae50ac9 100644
--- a/libpod/runtime_volume.go
+++ b/libpod/runtime_volume.go
@@ -154,3 +154,27 @@ func (r *Runtime) GetAllVolumes() ([]*Volume, error) {
return r.state.AllVolumes()
}
+
+// PruneVolumes removes unused volumes from the system
+func (r *Runtime) PruneVolumes(ctx context.Context) ([]string, []error) {
+ var (
+ prunedIDs []string
+ pruneErrors []error
+ )
+ vols, err := r.GetAllVolumes()
+ if err != nil {
+ pruneErrors = append(pruneErrors, err)
+ return nil, pruneErrors
+ }
+
+ for _, vol := range vols {
+ if err := r.RemoveVolume(ctx, vol, false, true); err != nil {
+ if err != ErrVolumeBeingUsed {
+ pruneErrors = append(pruneErrors, err)
+ }
+ continue
+ }
+ prunedIDs = append(prunedIDs, vol.Name())
+ }
+ return prunedIDs, pruneErrors
+}
diff --git a/pkg/varlinkapi/volumes.go b/pkg/varlinkapi/volumes.go
index d41b07065..02874d2b1 100644
--- a/pkg/varlinkapi/volumes.go
+++ b/pkg/varlinkapi/volumes.go
@@ -72,3 +72,19 @@ func (i *LibpodAPI) GetVolumes(call iopodman.VarlinkCall, args []string, all boo
}
return call.ReplyGetVolumes(volumes)
}
+
+// VolumesPrune removes unused images via a varlink call
+func (i *LibpodAPI) VolumesPrune(call iopodman.VarlinkCall) error {
+ var errs []string
+ prunedNames, prunedErrors := i.Runtime.PruneVolumes(getContext())
+ if len(prunedErrors) == 0 {
+ return call.ReplyVolumesPrune(prunedNames, []string{})
+ }
+
+ // We need to take the errors and capture their strings to go back over
+ // varlink
+ for _, e := range prunedErrors {
+ errs = append(errs, e.Error())
+ }
+ return call.ReplyVolumesPrune(prunedNames, errs)
+}
diff --git a/test/e2e/volume_create_test.go b/test/e2e/volume_create_test.go
index 9e525786e..50ee63f2a 100644
--- a/test/e2e/volume_create_test.go
+++ b/test/e2e/volume_create_test.go
@@ -1,5 +1,3 @@
-// +build !remoteclient
-
package integration
import (
diff --git a/test/e2e/volume_inspect_test.go b/test/e2e/volume_inspect_test.go
index aacdbe8be..d0d5a601e 100644
--- a/test/e2e/volume_inspect_test.go
+++ b/test/e2e/volume_inspect_test.go
@@ -1,5 +1,3 @@
-// +build !remoteclient
-
package integration
import (
diff --git a/test/e2e/volume_ls_test.go b/test/e2e/volume_ls_test.go
index d2ee558c1..119d29d9b 100644
--- a/test/e2e/volume_ls_test.go
+++ b/test/e2e/volume_ls_test.go
@@ -1,5 +1,3 @@
-// +build !remoteclient
-
package integration
import (
diff --git a/test/e2e/volume_rm_test.go b/test/e2e/volume_rm_test.go
index 295b290e4..6a1e7d0e8 100644
--- a/test/e2e/volume_rm_test.go
+++ b/test/e2e/volume_rm_test.go
@@ -1,5 +1,3 @@
-// +build !remoteclient
-
package integration
import (
@@ -50,6 +48,7 @@ var _ = Describe("Podman volume rm", func() {
})
It("podman rm with --force flag", func() {
+ SkipIfRemote()
session := podmanTest.Podman([]string{"create", "-v", "myvol:/myvol", ALPINE, "ls"})
cid := session.OutputToString()
session.WaitWithDefaultTimeout()