diff options
-rwxr-xr-x | API.md | 15 | ||||
-rw-r--r-- | cmd/podman/commands.go | 12 | ||||
-rw-r--r-- | cmd/podman/commands_remoteclient.go | 10 | ||||
-rw-r--r-- | cmd/podman/varlink/io.podman.varlink | 9 | ||||
-rw-r--r-- | cmd/podman/volume.go | 10 | ||||
-rw-r--r-- | cmd/podman/volume_prune.go | 29 | ||||
-rw-r--r-- | libpod/adapter/runtime.go | 5 | ||||
-rw-r--r-- | libpod/adapter/runtime_remote.go | 14 | ||||
-rw-r--r-- | libpod/runtime_volume.go | 24 | ||||
-rw-r--r-- | pkg/varlinkapi/volumes.go | 16 | ||||
-rw-r--r-- | test/e2e/volume_create_test.go | 2 | ||||
-rw-r--r-- | test/e2e/volume_inspect_test.go | 2 | ||||
-rw-r--r-- | test/e2e/volume_ls_test.go | 2 | ||||
-rw-r--r-- | test/e2e/volume_rm_test.go | 3 |
14 files changed, 101 insertions, 52 deletions
@@ -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() |