Implement backend for 'volume inspect'

Begin to separate the internal structures and frontend for
inspect on volumes. We can't rely on keeping internal data
structures for external presentation - separating presentation
and internal data format is good practice.

Signed-off-by: Matthew Heon <matthew.heon@pm.me>
This commit is contained in:
Matthew Heon 2019-07-15 14:55:20 -04:00
parent 3cc9ab8992
commit 8b72a72ca2
9 changed files with 132 additions and 47 deletions

View File

@ -7,8 +7,7 @@ type Volume (
labels: [string]string,
mountPoint: string,
driver: string,
options: [string]string,
scope: string
options: [string]string
)
type NotImplemented (

View File

@ -38,7 +38,6 @@ func init() {
flags.StringVar(&volumeCreateCommand.Driver, "driver", "", "Specify volume driver name (default local)")
flags.StringSliceVarP(&volumeCreateCommand.Label, "label", "l", []string{}, "Set metadata for a volume (default [])")
flags.StringSliceVarP(&volumeCreateCommand.Opt, "opt", "o", []string{}, "Set driver specific options (default [])")
}
func volumeCreateCmd(c *cliconfig.VolumeCreateValues) error {

View File

@ -1362,6 +1362,17 @@ func WithNamedVolumes(volumes []*ContainerNamedVolume) CtrCreateOption {
}
}
// WithHealthCheck adds the healthcheck to the container config
func WithHealthCheck(healthCheck *manifest.Schema2HealthConfig) CtrCreateOption {
return func(ctr *Container) error {
if ctr.valid {
return define.ErrCtrFinalized
}
ctr.config.HealthCheckConfig = healthCheck
return nil
}
}
// Volume Creation Options
// WithVolumeName sets the name of the volume.
@ -1381,6 +1392,19 @@ func WithVolumeName(name string) VolumeCreateOption {
}
}
// WithVolumeDriver sets the volume's driver.
// It is presently not implemented, but will be supported in a future Podman
// release.
func WithVolumeDriver(driver string) VolumeCreateOption {
return func(volume *Volume) error {
if volume.valid {
return define.ErrVolumeFinalized
}
return define.ErrNotImplemented
}
}
// WithVolumeLabels sets the labels of the volume.
func WithVolumeLabels(labels map[string]string) VolumeCreateOption {
return func(volume *Volume) error {
@ -1397,19 +1421,6 @@ func WithVolumeLabels(labels map[string]string) VolumeCreateOption {
}
}
// WithVolumeDriver sets the driver of the volume.
func WithVolumeDriver(driver string) VolumeCreateOption {
return func(volume *Volume) error {
if volume.valid {
return define.ErrVolumeFinalized
}
volume.config.Driver = driver
return nil
}
}
// WithVolumeOptions sets the options of the volume.
func WithVolumeOptions(options map[string]string) VolumeCreateOption {
return func(volume *Volume) error {
@ -1673,14 +1684,3 @@ func WithInfraContainerPorts(bindings []ocicni.PortMapping) PodCreateOption {
return nil
}
}
// WithHealthCheck adds the healthcheck to the container config
func WithHealthCheck(healthCheck *manifest.Schema2HealthConfig) CtrCreateOption {
return func(ctr *Container) error {
if ctr.valid {
return define.ErrCtrFinalized
}
ctr.config.HealthCheckConfig = healthCheck
return nil
}
}

View File

@ -7,6 +7,7 @@ import (
"os"
"path/filepath"
"strings"
"time"
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/libpod/events"
@ -42,14 +43,10 @@ func (r *Runtime) newVolume(ctx context.Context, options ...VolumeCreateOption)
if volume.config.Name == "" {
volume.config.Name = stringid.GenerateNonCryptoID()
}
// TODO: support for other volume drivers
if volume.config.Driver == "" {
volume.config.Driver = "local"
}
// TODO: determine when the scope is global and set it to that
if volume.config.Scope == "" {
volume.config.Scope = "local"
}
volume.config.CreatedTime = time.Now()
// Create the mountpoint of this volume
volPathRoot := filepath.Join(r.config.VolumePath, volume.config.Name)

View File

@ -1,5 +1,9 @@
package libpod
import (
"time"
)
// Volume is the type used to create named volumes
// TODO: all volumes should be created using this and the Volume API
type Volume struct {
@ -15,10 +19,10 @@ type VolumeConfig struct {
Name string `json:"name"`
Labels map[string]string `json:"labels"`
MountPoint string `json:"mountPoint"`
Driver string `json:"driver"`
MountPoint string `json:"mountPoint"`
CreatedTime time.Time `json:"createdAt,omitempty"`
Options map[string]string `json:"options"`
Scope string `json:"scope"`
IsCtrSpecific bool `json:"ctrSpecific"`
UID int `json:"uid"`
GID int `json:"gid"`
@ -29,6 +33,18 @@ func (v *Volume) Name() string {
return v.config.Name
}
// Driver retrieves the volume's driver.
func (v *Volume) Driver() string {
return v.config.Driver
}
// Scope retrieves the volume's scope.
// Libpod does not implement volume scoping, and this is provided solely for
// Docker compatability. It returns only "local".
func (v *Volume) Scope() string {
return "local"
}
// Labels returns the volume's labels
func (v *Volume) Labels() map[string]string {
labels := make(map[string]string)
@ -43,11 +59,6 @@ func (v *Volume) MountPoint() string {
return v.config.MountPoint
}
// Driver returns the volume's driver
func (v *Volume) Driver() string {
return v.config.Driver
}
// Options return the volume's options
func (v *Volume) Options() map[string]string {
options := make(map[string]string)
@ -58,14 +69,25 @@ func (v *Volume) Options() map[string]string {
return options
}
// Scope returns the scope of the volume
func (v *Volume) Scope() string {
return v.config.Scope
}
// IsCtrSpecific returns whether this volume was created specifically for a
// given container. Images with this set to true will be removed when the
// container is removed with the Volumes parameter set to true.
func (v *Volume) IsCtrSpecific() bool {
return v.config.IsCtrSpecific
}
// UID returns the UID the volume will be created as.
func (v *Volume) UID() int {
return v.config.UID
}
// GID returns the GID the volume will be created as.
func (v *Volume) GID() int {
return v.config.GID
}
// CreatedTime returns the time the volume was created at. It was not tracked
// for some time, so older volumes may not contain one.
func (v *Volume) CreatedTime() time.Time {
return v.config.CreatedTime
}

70
libpod/volume_inspect.go Normal file
View File

@ -0,0 +1,70 @@
package libpod
import (
"time"
"github.com/containers/libpod/libpod/define"
)
// InspectVolumeData is the output of Inspect() on a volume. It is matched to
// the format of 'docker volume inspect'.
type InspectVolumeData struct {
// 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 compatability.
// 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 compatability. 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"`
// ContainerSpecific indicates that the volume was created as part of a
// specific container, and will be removed when that container is
// removed.
ContainerSpecific bool `json:"ContainerSpecific,omitempty"`
}
// Inspect provides detailed information about the configuration of the given
// volume.
func (v *Volume) Inspect() (*InspectVolumeData, error) {
if !v.valid {
return nil, define.ErrVolumeRemoved
}
data := new(InspectVolumeData)
data.Name = v.config.Name
data.Driver = v.config.Driver
data.Mountpoint = v.config.MountPoint
data.CreatedAt = v.config.CreatedTime
data.Labels = make(map[string]string)
for k, v := range v.config.Labels {
data.Labels[k] = v
}
data.Scope = v.Scope()
data.Options = make(map[string]string)
data.UID = v.config.UID
data.GID = v.config.GID
data.ContainerSpecific = v.config.IsCtrSpecific
return data, nil
}

View File

@ -661,7 +661,6 @@ func varlinkVolumeToVolume(r *LocalRuntime, volumes []iopodman.Volume) []*Volume
MountPoint: v.MountPoint,
Driver: v.Driver,
Options: v.Options,
Scope: v.Scope,
}
n := remoteVolume{
Runtime: r,

View File

@ -29,5 +29,5 @@ func (v *Volume) MountPoint() string {
// Scope returns the scope for an adapter.volume
func (v *Volume) Scope() string {
return v.config.Scope
return "local"
}

View File

@ -68,7 +68,6 @@ func (i *LibpodAPI) GetVolumes(call iopodman.VarlinkCall, args []string, all boo
MountPoint: v.MountPoint(),
Name: v.Name(),
Options: v.Options(),
Scope: v.Scope(),
}
volumes = append(volumes, newVol)
}