summaryrefslogtreecommitdiff
path: root/pkg/domain
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/domain')
-rw-r--r--pkg/domain/entities/engine_container.go1
-rw-r--r--pkg/domain/entities/volumes.go41
-rw-r--r--pkg/domain/infra/abi/parse/parse.go68
-rw-r--r--pkg/domain/infra/abi/volumes.go38
-rw-r--r--pkg/domain/infra/tunnel/volumes.go16
5 files changed, 164 insertions, 0 deletions
diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go
index aa2ceb630..c79e96391 100644
--- a/pkg/domain/entities/engine_container.go
+++ b/pkg/domain/entities/engine_container.go
@@ -11,6 +11,7 @@ type ContainerEngine interface {
ContainerWait(ctx context.Context, namesOrIds []string, options WaitOptions) ([]WaitReport, error)
PodDelete(ctx context.Context, opts PodPruneOptions) (*PodDeleteReport, 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)
}
diff --git a/pkg/domain/entities/volumes.go b/pkg/domain/entities/volumes.go
new file mode 100644
index 000000000..ad12d0d01
--- /dev/null
+++ b/pkg/domain/entities/volumes.go
@@ -0,0 +1,41 @@
+package entities
+
+import "time"
+
+// swagger:model VolumeCreate
+type VolumeCreateOptions struct {
+ // New volume's name. Can be left blank
+ Name string `schema:"name"`
+ // Volume driver to use
+ Driver string `schema:"driver"`
+ // User-defined key/value metadata.
+ Label map[string]string `schema:"label"`
+ // Mapping of driver options and values.
+ Options map[string]string `schema:"opts"`
+}
+
+type IdOrNameResponse struct {
+ // The Id or Name of an object
+ IdOrName string
+}
+
+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"`
+}
diff --git a/pkg/domain/infra/abi/parse/parse.go b/pkg/domain/infra/abi/parse/parse.go
new file mode 100644
index 000000000..6c0e1ee55
--- /dev/null
+++ b/pkg/domain/infra/abi/parse/parse.go
@@ -0,0 +1,68 @@
+package parse
+
+import (
+ "strconv"
+ "strings"
+
+ "github.com/containers/libpod/libpod"
+ "github.com/containers/libpod/libpod/define"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+)
+
+// Handle volume options from CLI.
+// Parse "o" option to find UID, GID.
+func ParseVolumeOptions(opts map[string]string) ([]libpod.VolumeCreateOption, error) {
+ libpodOptions := []libpod.VolumeCreateOption{}
+ volumeOptions := make(map[string]string)
+
+ for key, value := range opts {
+ switch key {
+ case "o":
+ // o has special handling to parse out UID, GID.
+ // These are separate Libpod options.
+ splitVal := strings.Split(value, ",")
+ finalVal := []string{}
+ for _, o := range splitVal {
+ // Options will be formatted as either "opt" or
+ // "opt=value"
+ splitO := strings.SplitN(o, "=", 2)
+ switch strings.ToLower(splitO[0]) {
+ case "uid":
+ if len(splitO) != 2 {
+ return nil, errors.Wrapf(define.ErrInvalidArg, "uid option must provide a UID")
+ }
+ intUID, err := strconv.Atoi(splitO[1])
+ if err != nil {
+ return nil, errors.Wrapf(err, "cannot convert UID %s to integer", splitO[1])
+ }
+ logrus.Debugf("Removing uid= from options and adding WithVolumeUID for UID %d", intUID)
+ libpodOptions = append(libpodOptions, libpod.WithVolumeUID(intUID))
+ case "gid":
+ if len(splitO) != 2 {
+ return nil, errors.Wrapf(define.ErrInvalidArg, "gid option must provide a GID")
+ }
+ intGID, err := strconv.Atoi(splitO[1])
+ if err != nil {
+ return nil, errors.Wrapf(err, "cannot convert GID %s to integer", splitO[1])
+ }
+ logrus.Debugf("Removing gid= from options and adding WithVolumeGID for GID %d", intGID)
+ libpodOptions = append(libpodOptions, libpod.WithVolumeGID(intGID))
+ default:
+ finalVal = append(finalVal, o)
+ }
+ }
+ if len(finalVal) > 0 {
+ volumeOptions[key] = strings.Join(finalVal, ",")
+ }
+ default:
+ volumeOptions[key] = value
+ }
+ }
+
+ if len(volumeOptions) > 0 {
+ libpodOptions = append(libpodOptions, libpod.WithVolumeOptions(volumeOptions))
+ }
+
+ return libpodOptions, nil
+}
diff --git a/pkg/domain/infra/abi/volumes.go b/pkg/domain/infra/abi/volumes.go
new file mode 100644
index 000000000..0783af441
--- /dev/null
+++ b/pkg/domain/infra/abi/volumes.go
@@ -0,0 +1,38 @@
+// +build ABISupport
+
+package abi
+
+import (
+ "context"
+
+ "github.com/containers/libpod/libpod"
+ "github.com/containers/libpod/pkg/domain/entities"
+ "github.com/containers/libpod/pkg/domain/infra/abi/parse"
+)
+
+func (ic *ContainerEngine) VolumeCreate(ctx context.Context, opts entities.VolumeCreateOptions) (*entities.IdOrNameResponse, error) {
+ var (
+ volumeOptions []libpod.VolumeCreateOption
+ )
+ if len(opts.Name) > 0 {
+ volumeOptions = append(volumeOptions, libpod.WithVolumeName(opts.Name))
+ }
+ if len(opts.Driver) > 0 {
+ volumeOptions = append(volumeOptions, libpod.WithVolumeDriver(opts.Driver))
+ }
+ if len(opts.Label) > 0 {
+ volumeOptions = append(volumeOptions, libpod.WithVolumeLabels(opts.Label))
+ }
+ if len(opts.Options) > 0 {
+ parsedOptions, err := parse.ParseVolumeOptions(opts.Options)
+ if err != nil {
+ return nil, err
+ }
+ volumeOptions = append(volumeOptions, parsedOptions...)
+ }
+ vol, err := ic.Libpod.NewVolume(ctx, volumeOptions...)
+ if err != nil {
+ return nil, err
+ }
+ return &entities.IdOrNameResponse{IdOrName: vol.Name()}, nil
+}
diff --git a/pkg/domain/infra/tunnel/volumes.go b/pkg/domain/infra/tunnel/volumes.go
new file mode 100644
index 000000000..49cf6a2f6
--- /dev/null
+++ b/pkg/domain/infra/tunnel/volumes.go
@@ -0,0 +1,16 @@
+package tunnel
+
+import (
+ "context"
+
+ "github.com/containers/libpod/pkg/bindings/volumes"
+ "github.com/containers/libpod/pkg/domain/entities"
+)
+
+func (ic *ContainerEngine) VolumeCreate(ctx context.Context, opts entities.VolumeCreateOptions) (*entities.IdOrNameResponse, error) {
+ response, err := volumes.Create(ic.ClientCxt, opts)
+ if err != nil {
+ return nil, err
+ }
+ return &entities.IdOrNameResponse{IdOrName: response.Name}, nil
+}