summaryrefslogtreecommitdiff
path: root/pkg/domain
diff options
context:
space:
mode:
authorBrent Baude <bbaude@redhat.com>2020-03-21 14:29:30 -0500
committerBrent Baude <bbaude@redhat.com>2020-03-24 16:03:49 -0500
commitae614920bfe2510ca6d1dd6cea02bbe17ddb245c (patch)
tree5edd6e5fd01f12154c82146ce6170aaf7d716e19 /pkg/domain
parent0c084d9719772a9b68d5eb67114cf5bf001958b2 (diff)
downloadpodman-ae614920bfe2510ca6d1dd6cea02bbe17ddb245c.tar.gz
podman-ae614920bfe2510ca6d1dd6cea02bbe17ddb245c.tar.bz2
podman-ae614920bfe2510ca6d1dd6cea02bbe17ddb245c.zip
podmanv2 volumes
add volume commands: create, inspect, ls, prune, and rm Signed-off-by: Brent Baude <bbaude@redhat.com>
Diffstat (limited to 'pkg/domain')
-rw-r--r--pkg/domain/entities/engine_container.go9
-rw-r--r--pkg/domain/entities/types.go8
-rw-r--r--pkg/domain/entities/volumes.go89
-rw-r--r--pkg/domain/filters/volumes.go70
-rw-r--r--pkg/domain/infra/abi/containers.go20
-rw-r--r--pkg/domain/infra/abi/volumes.go108
-rw-r--r--pkg/domain/infra/tunnel/containers.go7
-rw-r--r--pkg/domain/infra/tunnel/runtime.go18
-rw-r--r--pkg/domain/infra/tunnel/volumes.go54
9 files changed, 306 insertions, 77 deletions
diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go
index 2887f0b51..2efdbd602 100644
--- a/pkg/domain/entities/engine_container.go
+++ b/pkg/domain/entities/engine_container.go
@@ -5,7 +5,6 @@ import (
)
type ContainerEngine interface {
- ContainerPrune(ctx context.Context) (*ContainerPruneReport, error)
ContainerExists(ctx context.Context, nameOrId string) (*BoolReport, error)
ContainerKill(ctx context.Context, namesOrIds []string, options KillOptions) ([]*KillReport, error)
ContainerPause(ctx context.Context, namesOrIds []string, options PauseUnPauseOptions) ([]*PauseUnpauseReport, error)
@@ -14,10 +13,10 @@ type ContainerEngine interface {
ContainerUnpause(ctx context.Context, namesOrIds []string, options PauseUnPauseOptions) ([]*PauseUnpauseReport, error)
ContainerStop(ctx context.Context, namesOrIds []string, options StopOptions) ([]*StopReport, error)
ContainerWait(ctx context.Context, namesOrIds []string, options WaitOptions) ([]WaitReport, error)
- PodDelete(ctx context.Context, opts PodPruneOptions) (*PodDeleteReport, error)
PodExists(ctx context.Context, nameOrId string) (*BoolReport, error)
- PodPrune(ctx context.Context) (*PodPruneReport, error)
VolumeCreate(ctx context.Context, opts VolumeCreateOptions) (*IdOrNameResponse, error)
- VolumeDelete(ctx context.Context, opts VolumeDeleteOptions) (*VolumeDeleteReport, error)
- VolumePrune(ctx context.Context) (*VolumePruneReport, error)
+ VolumeInspect(ctx context.Context, namesOrIds []string, opts VolumeInspectOptions) ([]*VolumeInspectReport, error)
+ VolumeRm(ctx context.Context, namesOrIds []string, opts VolumeRmOptions) ([]*VolumeRmReport, error)
+ VolumePrune(ctx context.Context, opts VolumePruneOptions) ([]*VolumePruneReport, error)
+ VolumeList(ctx context.Context, opts VolumeListOptions) ([]*VolumeListReport, error)
}
diff --git a/pkg/domain/entities/types.go b/pkg/domain/entities/types.go
index 6f947dc4d..e7757a74b 100644
--- a/pkg/domain/entities/types.go
+++ b/pkg/domain/entities/types.go
@@ -13,13 +13,5 @@ type Report struct {
Err map[string]error
}
-type ContainerDeleteOptions struct{}
-type ContainerDeleteReport struct{ Report }
-type ContainerPruneReport struct{ Report }
-
type PodDeleteReport struct{ Report }
type PodPruneOptions struct{}
-type PodPruneReport struct{ Report }
-type VolumeDeleteOptions struct{}
-type VolumeDeleteReport struct{ Report }
-type VolumePruneReport struct{ Report }
diff --git a/pkg/domain/entities/volumes.go b/pkg/domain/entities/volumes.go
index ad12d0d01..23c066083 100644
--- a/pkg/domain/entities/volumes.go
+++ b/pkg/domain/entities/volumes.go
@@ -1,6 +1,8 @@
package entities
-import "time"
+import (
+ "time"
+)
// swagger:model VolumeCreate
type VolumeCreateOptions struct {
@@ -20,22 +22,71 @@ type IdOrNameResponse struct {
}
type VolumeConfigResponse struct {
- // Name of the volume.
- Name string `json:"name"`
- Labels map[string]string `json:"labels"`
- // The volume driver. Empty string or local does not activate a volume
- // driver, all other volumes will.
- Driver string `json:"volumeDriver"`
- // The location the volume is mounted at.
- MountPoint string `json:"mountPoint"`
- // Time the volume was created.
- CreatedTime time.Time `json:"createdAt,omitempty"`
- // Options to pass to the volume driver. For the local driver, this is
- // a list of mount options. For other drivers, they are passed to the
- // volume driver handling the volume.
- Options map[string]string `json:"volumeOptions,omitempty"`
- // UID the volume will be created as.
- UID int `json:"uid"`
- // GID the volume will be created as.
- GID int `json:"gid"`
+ // Name is the name of the volume.
+ Name string `json:"Name"`
+ // Driver is the driver used to create the volume.
+ // This will be properly implemented in a future version.
+ Driver string `json:"Driver"`
+ // Mountpoint is the path on the host where the volume is mounted.
+ Mountpoint string `json:"Mountpoint"`
+ // CreatedAt is the date and time the volume was created at. This is not
+ // stored for older Libpod volumes; if so, it will be omitted.
+ CreatedAt time.Time `json:"CreatedAt,omitempty"`
+ // Status is presently unused and provided only for Docker compatibility.
+ // In the future it will be used to return information on the volume's
+ // current state.
+ Status map[string]string `json:"Status,omitempty"`
+ // Labels includes the volume's configured labels, key:value pairs that
+ // can be passed during volume creation to provide information for third
+ // party tools.
+ Labels map[string]string `json:"Labels"`
+ // Scope is unused and provided solely for Docker compatibility. It is
+ // unconditionally set to "local".
+ Scope string `json:"Scope"`
+ // Options is a set of options that were used when creating the volume.
+ // It is presently not used.
+ Options map[string]string `json:"Options"`
+ // UID is the UID that the volume was created with.
+ UID int `json:"UID,omitempty"`
+ // GID is the GID that the volume was created with.
+ GID int `json:"GID,omitempty"`
+ // Anonymous indicates that the volume was created as an anonymous
+ // volume for a specific container, and will be be removed when any
+ // container using it is removed.
+ Anonymous bool `json:"Anonymous,omitempty"`
+}
+
+type VolumeRmOptions struct {
+ All bool
+ Force bool
+}
+
+type VolumeRmReport struct {
+ Err error
+ Id string
+}
+
+type VolumeInspectOptions struct {
+ All bool
+}
+
+type VolumeInspectReport struct {
+ *VolumeConfigResponse
+}
+
+type VolumePruneOptions struct {
+ Force bool
+}
+
+type VolumePruneReport struct {
+ Err error
+ Id string
+}
+
+type VolumeListOptions struct {
+ Filter map[string][]string
+}
+
+type VolumeListReport struct {
+ VolumeConfigResponse
}
diff --git a/pkg/domain/filters/volumes.go b/pkg/domain/filters/volumes.go
new file mode 100644
index 000000000..f97c3f570
--- /dev/null
+++ b/pkg/domain/filters/volumes.go
@@ -0,0 +1,70 @@
+package filters
+
+import (
+ "strings"
+
+ "github.com/containers/libpod/libpod"
+ "github.com/pkg/errors"
+)
+
+func GenerateVolumeFilters(filters map[string][]string) ([]libpod.VolumeFilter, error) {
+ var vf []libpod.VolumeFilter
+ for filter, v := range filters {
+ for _, val := range v {
+ switch filter {
+ case "name":
+ nameVal := val
+ vf = append(vf, func(v *libpod.Volume) bool {
+ return nameVal == v.Name()
+ })
+ case "driver":
+ driverVal := val
+ vf = append(vf, func(v *libpod.Volume) bool {
+ return v.Driver() == driverVal
+ })
+ case "scope":
+ scopeVal := val
+ vf = append(vf, func(v *libpod.Volume) bool {
+ return v.Scope() == scopeVal
+ })
+ case "label":
+ filterArray := strings.SplitN(val, "=", 2)
+ filterKey := filterArray[0]
+ var filterVal string
+ if len(filterArray) > 1 {
+ filterVal = filterArray[1]
+ } else {
+ filterVal = ""
+ }
+ vf = append(vf, func(v *libpod.Volume) bool {
+ for labelKey, labelValue := range v.Labels() {
+ if labelKey == filterKey && ("" == filterVal || labelValue == filterVal) {
+ return true
+ }
+ }
+ return false
+ })
+ case "opt":
+ filterArray := strings.SplitN(val, "=", 2)
+ filterKey := filterArray[0]
+ var filterVal string
+ if len(filterArray) > 1 {
+ filterVal = filterArray[1]
+ } else {
+ filterVal = ""
+ }
+ vf = append(vf, func(v *libpod.Volume) bool {
+ for labelKey, labelValue := range v.Options() {
+ if labelKey == filterKey && ("" == filterVal || labelValue == filterVal) {
+ return true
+ }
+ }
+ return false
+ })
+ default:
+ return nil, errors.Errorf("%q is in an invalid volume filter", filter)
+ }
+ }
+ }
+ return vf, nil
+}
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index 47deb010a..a3da310c2 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -239,23 +239,3 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
}
return reports, nil
}
-
-func (ic *ContainerEngine) ContainerPrune(ctx context.Context) (*entities.ContainerPruneReport, error) {
- panic("implement me")
-}
-
-func (ic *ContainerEngine) PodDelete(ctx context.Context, opts entities.PodPruneOptions) (*entities.PodDeleteReport, error) {
- panic("implement me")
-}
-
-func (ic *ContainerEngine) PodPrune(ctx context.Context) (*entities.PodPruneReport, error) {
- panic("implement me")
-}
-
-func (ic *ContainerEngine) VolumeDelete(ctx context.Context, opts entities.VolumeDeleteOptions) (*entities.VolumeDeleteReport, error) {
- panic("implement me")
-}
-
-func (ic *ContainerEngine) VolumePrune(ctx context.Context) (*entities.VolumePruneReport, error) {
- panic("implement me")
-}
diff --git a/pkg/domain/infra/abi/volumes.go b/pkg/domain/infra/abi/volumes.go
index 0783af441..0cc20474e 100644
--- a/pkg/domain/infra/abi/volumes.go
+++ b/pkg/domain/infra/abi/volumes.go
@@ -7,7 +7,9 @@ import (
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/domain/entities"
+ "github.com/containers/libpod/pkg/domain/filters"
"github.com/containers/libpod/pkg/domain/infra/abi/parse"
+ "github.com/pkg/errors"
)
func (ic *ContainerEngine) VolumeCreate(ctx context.Context, opts entities.VolumeCreateOptions) (*entities.IdOrNameResponse, error) {
@@ -36,3 +38,109 @@ func (ic *ContainerEngine) VolumeCreate(ctx context.Context, opts entities.Volum
}
return &entities.IdOrNameResponse{IdOrName: vol.Name()}, nil
}
+
+func (ic *ContainerEngine) VolumeRm(ctx context.Context, namesOrIds []string, opts entities.VolumeRmOptions) ([]*entities.VolumeRmReport, error) {
+ var (
+ err error
+ reports []*entities.VolumeRmReport
+ vols []*libpod.Volume
+ )
+ if opts.All {
+ vols, err = ic.Libpod.Volumes()
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ for _, id := range namesOrIds {
+ vol, err := ic.Libpod.LookupVolume(id)
+ if err != nil {
+ reports = append(reports, &entities.VolumeRmReport{
+ Err: err,
+ Id: id,
+ })
+ continue
+ }
+ vols = append(vols, vol)
+ }
+ }
+ for _, vol := range vols {
+ reports = append(reports, &entities.VolumeRmReport{
+ Err: ic.Libpod.RemoveVolume(ctx, vol, opts.Force),
+ Id: vol.Name(),
+ })
+ }
+ return reports, nil
+}
+
+func (ic *ContainerEngine) VolumeInspect(ctx context.Context, namesOrIds []string, opts entities.VolumeInspectOptions) ([]*entities.VolumeInspectReport, error) {
+ var (
+ err error
+ reports []*entities.VolumeInspectReport
+ vols []*libpod.Volume
+ )
+
+ // Note: as with previous implementation, a single failure here
+ // results a return.
+ if opts.All {
+ vols, err = ic.Libpod.GetAllVolumes()
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ for _, v := range namesOrIds {
+ vol, err := ic.Libpod.LookupVolume(v)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error inspecting volume %s", v)
+ }
+ vols = append(vols, vol)
+ }
+ }
+ for _, v := range vols {
+ config := entities.VolumeConfigResponse{
+ Name: v.Name(),
+ Driver: v.Driver(),
+ Mountpoint: v.MountPoint(),
+ CreatedAt: v.CreatedTime(),
+ Labels: v.Labels(),
+ Scope: v.Scope(),
+ Options: v.Options(),
+ UID: v.UID(),
+ GID: v.GID(),
+ }
+ reports = append(reports, &entities.VolumeInspectReport{&config})
+ }
+ return reports, nil
+}
+
+func (ic *ContainerEngine) VolumePrune(ctx context.Context, opts entities.VolumePruneOptions) ([]*entities.VolumePruneReport, error) {
+ return ic.Libpod.PruneVolumes(ctx)
+}
+
+func (ic *ContainerEngine) VolumeList(ctx context.Context, opts entities.VolumeListOptions) ([]*entities.VolumeListReport, error) {
+ var (
+ reports []*entities.VolumeListReport
+ )
+ volumeFilters, err := filters.GenerateVolumeFilters(opts.Filter)
+ if err != nil {
+ return nil, err
+ }
+ vols, err := ic.Libpod.Volumes(volumeFilters...)
+ if err != nil {
+ return nil, err
+ }
+ for _, v := range vols {
+ config := entities.VolumeConfigResponse{
+ Name: v.Name(),
+ Driver: v.Driver(),
+ Mountpoint: v.MountPoint(),
+ CreatedAt: v.CreatedTime(),
+ Labels: v.Labels(),
+ Scope: v.Scope(),
+ Options: v.Options(),
+ UID: v.UID(),
+ GID: v.GID(),
+ }
+ reports = append(reports, &entities.VolumeListReport{config})
+ }
+ return reports, nil
+}
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index 21f62df6b..a8ecff41b 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -33,13 +33,6 @@ func (ic *ContainerEngine) ContainerWait(ctx context.Context, namesOrIds []strin
return responses, nil
}
-func (r *ContainerEngine) ContainerDelete(ctx context.Context, opts entities.ContainerDeleteOptions) (*entities.ContainerDeleteReport, error) {
- panic("implement me")
-}
-
-func (r *ContainerEngine) ContainerPrune(ctx context.Context) (*entities.ContainerPruneReport, error) {
- panic("implement me")
-}
func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []string, options entities.PauseUnPauseOptions) ([]*entities.PauseUnpauseReport, error) {
var (
reports []*entities.PauseUnpauseReport
diff --git a/pkg/domain/infra/tunnel/runtime.go b/pkg/domain/infra/tunnel/runtime.go
index eb9b34e4a..c111f99e9 100644
--- a/pkg/domain/infra/tunnel/runtime.go
+++ b/pkg/domain/infra/tunnel/runtime.go
@@ -2,8 +2,6 @@ package tunnel
import (
"context"
-
- "github.com/containers/libpod/pkg/domain/entities"
)
// Image-related runtime using an ssh-tunnel to utilize Podman service
@@ -15,19 +13,3 @@ type ImageEngine struct {
type ContainerEngine struct {
ClientCxt context.Context
}
-
-func (r *ContainerEngine) PodDelete(ctx context.Context, opts entities.PodPruneOptions) (*entities.PodDeleteReport, error) {
- panic("implement me")
-}
-
-func (r *ContainerEngine) PodPrune(ctx context.Context) (*entities.PodPruneReport, error) {
- panic("implement me")
-}
-
-func (r *ContainerEngine) VolumeDelete(ctx context.Context, opts entities.VolumeDeleteOptions) (*entities.VolumeDeleteReport, error) {
- panic("implement me")
-}
-
-func (r *ContainerEngine) VolumePrune(ctx context.Context) (*entities.VolumePruneReport, error) {
- panic("implement me")
-}
diff --git a/pkg/domain/infra/tunnel/volumes.go b/pkg/domain/infra/tunnel/volumes.go
index 49cf6a2f6..e48a7fa7c 100644
--- a/pkg/domain/infra/tunnel/volumes.go
+++ b/pkg/domain/infra/tunnel/volumes.go
@@ -14,3 +14,57 @@ func (ic *ContainerEngine) VolumeCreate(ctx context.Context, opts entities.Volum
}
return &entities.IdOrNameResponse{IdOrName: response.Name}, nil
}
+
+func (ic *ContainerEngine) VolumeRm(ctx context.Context, namesOrIds []string, opts entities.VolumeRmOptions) ([]*entities.VolumeRmReport, error) {
+ var (
+ reports []*entities.VolumeRmReport
+ )
+
+ if opts.All {
+ vols, err := volumes.List(ic.ClientCxt, nil)
+ if err != nil {
+ return nil, err
+ }
+ for _, v := range vols {
+ namesOrIds = append(namesOrIds, v.Name)
+ }
+ }
+ for _, id := range namesOrIds {
+ reports = append(reports, &entities.VolumeRmReport{
+ Err: volumes.Remove(ic.ClientCxt, id, &opts.Force),
+ Id: id,
+ })
+ }
+ return reports, nil
+}
+
+func (ic *ContainerEngine) VolumeInspect(ctx context.Context, namesOrIds []string, opts entities.VolumeInspectOptions) ([]*entities.VolumeInspectReport, error) {
+ var (
+ reports []*entities.VolumeInspectReport
+ )
+ if opts.All {
+ vols, err := volumes.List(ic.ClientCxt, nil)
+ if err != nil {
+ return nil, err
+ }
+ for _, v := range vols {
+ namesOrIds = append(namesOrIds, v.Name)
+ }
+ }
+ for _, id := range namesOrIds {
+ data, err := volumes.Inspect(ic.ClientCxt, id)
+ if err != nil {
+ return nil, err
+ }
+ reports = append(reports, &entities.VolumeInspectReport{VolumeConfigResponse: data})
+ }
+ return reports, nil
+}
+
+func (ic *ContainerEngine) VolumePrune(ctx context.Context, opts entities.VolumePruneOptions) ([]*entities.VolumePruneReport, error) {
+ return volumes.Prune(ic.ClientCxt)
+}
+
+func (ic *ContainerEngine) VolumeList(ctx context.Context, opts entities.VolumeListOptions) ([]*entities.VolumeListReport, error) {
+ return volumes.List(ic.ClientCxt, opts.Filter)
+}