summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/adapter/runtime.go66
-rw-r--r--libpod/adapter/runtime_remote.go93
-rw-r--r--libpod/adapter/volumes_remote.go33
-rw-r--r--libpod/container.go12
-rw-r--r--libpod/image/utils.go17
-rw-r--r--libpod/kube.go6
6 files changed, 209 insertions, 18 deletions
diff --git a/libpod/adapter/runtime.go b/libpod/adapter/runtime.go
index 2b1ddb09d..7dd845616 100644
--- a/libpod/adapter/runtime.go
+++ b/libpod/adapter/runtime.go
@@ -4,18 +4,19 @@ package adapter
import (
"context"
- "github.com/pkg/errors"
"io"
"io/ioutil"
"os"
"strconv"
+ "github.com/containers/image/docker/reference"
"github.com/containers/image/types"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/rootless"
+ "github.com/pkg/errors"
)
// LocalRuntime describes a typical libpod runtime
@@ -34,6 +35,14 @@ type Container struct {
*libpod.Container
}
+// Volume ...
+type Volume struct {
+ *libpod.Volume
+}
+
+// VolumeFilter is for filtering volumes on the client
+type VolumeFilter func(*Volume) bool
+
// GetRuntime returns a LocalRuntime struct with the actual runtime embedded in it
func GetRuntime(c *cliconfig.PodmanCommand) (*LocalRuntime, error) {
runtime, err := libpodruntime.GetRuntime(c)
@@ -190,3 +199,58 @@ func (r *LocalRuntime) CreateVolume(ctx context.Context, c *cliconfig.VolumeCrea
func (r *LocalRuntime) RemoveVolumes(ctx context.Context, c *cliconfig.VolumeRmValues) ([]string, error) {
return r.Runtime.RemoveVolumes(ctx, c.InputArgs, c.All, c.Force)
}
+
+// Push is a wrapper to push an image to a registry
+func (r *LocalRuntime) Push(ctx context.Context, srcName, destination, manifestMIMEType, authfile, signaturePolicyPath string, writer io.Writer, forceCompress bool, signingOptions image.SigningOptions, dockerRegistryOptions *image.DockerRegistryOptions, additionalDockerArchiveTags []reference.NamedTagged) error {
+ newImage, err := r.ImageRuntime().NewFromLocal(srcName)
+ if err != nil {
+ return err
+ }
+ return newImage.PushImageToHeuristicDestination(ctx, destination, manifestMIMEType, authfile, signaturePolicyPath, writer, forceCompress, signingOptions, dockerRegistryOptions, nil)
+}
+
+// InspectVolumes returns a slice of volumes based on an arg list or --all
+func (r *LocalRuntime) InspectVolumes(ctx context.Context, c *cliconfig.VolumeInspectValues) ([]*Volume, error) {
+ var (
+ volumes []*libpod.Volume
+ err error
+ )
+
+ if c.All {
+ volumes, err = r.GetAllVolumes()
+ } else {
+ for _, v := range c.InputArgs {
+ vol, err := r.GetVolume(v)
+ if err != nil {
+ return nil, err
+ }
+ volumes = append(volumes, vol)
+ }
+ }
+ if err != nil {
+ return nil, err
+ }
+ return libpodVolumeToVolume(volumes), nil
+}
+
+// Volumes returns a slice of localruntime volumes
+func (r *LocalRuntime) Volumes(ctx context.Context) ([]*Volume, error) {
+ vols, err := r.GetAllVolumes()
+ if err != nil {
+ return nil, err
+ }
+ return libpodVolumeToVolume(vols), nil
+}
+
+// libpodVolumeToVolume converts a slice of libpod volumes to a slice
+// of localruntime volumes (same as libpod)
+func libpodVolumeToVolume(volumes []*libpod.Volume) []*Volume {
+ var vols []*Volume
+ for _, v := range volumes {
+ newVol := Volume{
+ v,
+ }
+ vols = append(vols, &newVol)
+ }
+ return vols
+}
diff --git a/libpod/adapter/runtime_remote.go b/libpod/adapter/runtime_remote.go
index 4dfae34e1..d0d827582 100644
--- a/libpod/adapter/runtime_remote.go
+++ b/libpod/adapter/runtime_remote.go
@@ -13,6 +13,7 @@ import (
"strings"
"time"
+ "github.com/containers/image/docker/reference"
"github.com/containers/image/types"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/varlink"
@@ -91,6 +92,18 @@ type remoteContainer struct {
state *libpod.ContainerState
}
+type VolumeFilter func(*Volume) bool
+
+// Volume is embed for libpod volumes
+type Volume struct {
+ remoteVolume
+}
+
+type remoteVolume struct {
+ Runtime *LocalRuntime
+ config *libpod.VolumeConfig
+}
+
// GetImages returns a slice of containerimages over a varlink connection
func (r *LocalRuntime) GetImages() ([]*ContainerImage, error) {
var newImages []*ContainerImage
@@ -112,8 +125,8 @@ func (r *LocalRuntime) GetImages() ([]*ContainerImage, error) {
return newImages, nil
}
-func imageInListToContainerImage(i iopodman.ImageInList, name string, runtime *LocalRuntime) (*ContainerImage, error) {
- created, err := splitStringDate(i.Created)
+func imageInListToContainerImage(i iopodman.Image, name string, runtime *LocalRuntime) (*ContainerImage, error) {
+ created, err := time.ParseInLocation(time.RFC3339, i.Created, time.UTC)
if err != nil {
return nil, err
}
@@ -182,12 +195,6 @@ func (r *LocalRuntime) New(ctx context.Context, name, signaturePolicyPath, authf
return newImage, nil
}
-func splitStringDate(d string) (time.Time, error) {
- fields := strings.Fields(d)
- t := fmt.Sprintf("%sT%sZ", fields[0], fields[1])
- return time.ParseInLocation(time.RFC3339Nano, t, time.UTC)
-}
-
// IsParent goes through the layers in the store and checks if i.TopLayer is
// the parent of any other layer in store. Double check that image with that
// layer exists as well.
@@ -251,7 +258,7 @@ func (ci *ContainerImage) History(ctx context.Context) ([]*image.History, error)
return nil, err
}
for _, h := range reply {
- created, err := splitStringDate(h.Created)
+ created, err := time.ParseInLocation(time.RFC3339, h.Created, time.UTC)
if err != nil {
return nil, err
}
@@ -459,3 +466,71 @@ func (r *LocalRuntime) RemoveVolumes(ctx context.Context, c *cliconfig.VolumeRmV
}
return iopodman.VolumeRemove().Call(r.Conn, rmOpts)
}
+
+func (r *LocalRuntime) Push(ctx context.Context, srcName, destination, manifestMIMEType, authfile, signaturePolicyPath string, writer io.Writer, forceCompress bool, signingOptions image.SigningOptions, dockerRegistryOptions *image.DockerRegistryOptions, additionalDockerArchiveTags []reference.NamedTagged) error {
+
+ tls := true
+ if dockerRegistryOptions.DockerInsecureSkipTLSVerify == types.OptionalBoolTrue {
+ tls = false
+ }
+ reply, err := iopodman.PushImage().Send(r.Conn, varlink.More, srcName, destination, tls, signaturePolicyPath, "", dockerRegistryOptions.DockerCertPath, forceCompress, manifestMIMEType, signingOptions.RemoveSignatures, signingOptions.SignBy)
+ if err != nil {
+ return err
+ }
+ for {
+ responses, flags, err := reply()
+ if err != nil {
+ return err
+ }
+ for _, line := range responses.Logs {
+ fmt.Print(line)
+ }
+ if flags&varlink.Continues == 0 {
+ break
+ }
+ }
+
+ return err
+}
+
+// InspectVolumes returns a slice of volumes based on an arg list or --all
+func (r *LocalRuntime) InspectVolumes(ctx context.Context, c *cliconfig.VolumeInspectValues) ([]*Volume, error) {
+ reply, err := iopodman.GetVolumes().Call(r.Conn, c.InputArgs, c.All)
+ if err != nil {
+ return nil, err
+ }
+ return varlinkVolumeToVolume(r, reply), nil
+}
+
+//Volumes returns a slice of adapter.volumes based on information about libpod
+// volumes over a varlink connection
+func (r *LocalRuntime) Volumes(ctx context.Context) ([]*Volume, error) {
+ reply, err := iopodman.GetVolumes().Call(r.Conn, []string{}, true)
+ if err != nil {
+ return nil, err
+ }
+ return varlinkVolumeToVolume(r, reply), nil
+}
+
+func varlinkVolumeToVolume(r *LocalRuntime, volumes []iopodman.Volume) []*Volume {
+ var vols []*Volume
+ for _, v := range volumes {
+ volumeConfig := libpod.VolumeConfig{
+ Name: v.Name,
+ Labels: v.Labels,
+ MountPoint: v.MountPoint,
+ Driver: v.Driver,
+ Options: v.Options,
+ Scope: v.Scope,
+ }
+ n := remoteVolume{
+ Runtime: r,
+ config: &volumeConfig,
+ }
+ newVol := Volume{
+ n,
+ }
+ vols = append(vols, &newVol)
+ }
+ return vols
+}
diff --git a/libpod/adapter/volumes_remote.go b/libpod/adapter/volumes_remote.go
new file mode 100644
index 000000000..beacd943a
--- /dev/null
+++ b/libpod/adapter/volumes_remote.go
@@ -0,0 +1,33 @@
+// +build remoteclient
+
+package adapter
+
+// Name returns the name of the volume
+func (v *Volume) Name() string {
+ return v.config.Name
+}
+
+//Labels returns the labels for a volume
+func (v *Volume) Labels() map[string]string {
+ return v.config.Labels
+}
+
+// Driver returns the driver for the volume
+func (v *Volume) Driver() string {
+ return v.config.Driver
+}
+
+// Options returns the options a volume was created with
+func (v *Volume) Options() map[string]string {
+ return v.config.Options
+}
+
+// MountPath returns the path the volume is mounted to
+func (v *Volume) MountPoint() string {
+ return v.config.MountPoint
+}
+
+// Scope returns the scope for an adapter.volume
+func (v *Volume) Scope() string {
+ return v.config.Scope
+}
diff --git a/libpod/container.go b/libpod/container.go
index b0589be3b..fec61533d 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -557,8 +557,16 @@ func (c *Container) NewNetNS() bool {
// PortMappings returns the ports that will be mapped into a container if
// a new network namespace is created
// If NewNetNS() is false, this value is unused
-func (c *Container) PortMappings() []ocicni.PortMapping {
- return c.config.PortMappings
+func (c *Container) PortMappings() ([]ocicni.PortMapping, error) {
+ // First check if the container belongs to a network namespace (like a pod)
+ if len(c.config.NetNsCtr) > 0 {
+ netNsCtr, err := c.runtime.LookupContainer(c.config.NetNsCtr)
+ if err != nil {
+ return nil, errors.Wrapf(err, "unable to lookup network namespace for container %s", c.ID())
+ }
+ return netNsCtr.PortMappings()
+ }
+ return c.config.PortMappings, nil
}
// DNSServers returns DNS servers that will be used in the container's
diff --git a/libpod/image/utils.go b/libpod/image/utils.go
index ad027f32a..3585428ad 100644
--- a/libpod/image/utils.go
+++ b/libpod/image/utils.go
@@ -87,22 +87,29 @@ func hasTransport(image string) bool {
// ReposToMap parses the specified repotags and returns a map with repositories
// as keys and the corresponding arrays of tags as values.
-func ReposToMap(repotags []string) map[string][]string {
+func ReposToMap(repotags []string) (map[string][]string, error) {
// map format is repo -> tag
repos := make(map[string][]string)
for _, repo := range repotags {
var repository, tag string
if len(repo) > 0 {
- li := strings.LastIndex(repo, ":")
- repository = repo[0:li]
- tag = repo[li+1:]
+ named, err := reference.ParseNormalizedNamed(repo)
+ repository = named.Name()
+ if err != nil {
+ return nil, err
+ }
+ if ref, ok := named.(reference.NamedTagged); ok {
+ tag = ref.Tag()
+ } else if ref, ok := named.(reference.Canonical); ok {
+ tag = ref.Digest().String()
+ }
}
repos[repository] = append(repos[repository], tag)
}
if len(repos) == 0 {
repos["<none>"] = []string{"<none>"}
}
- return repos
+ return repos, nil
}
// GetAdditionalTags returns a list of reference.NamedTagged for the
diff --git a/libpod/kube.go b/libpod/kube.go
index 16cebf99b..484127870 100644
--- a/libpod/kube.go
+++ b/libpod/kube.go
@@ -228,7 +228,11 @@ func containerToV1Container(c *Container) (v1.Container, error) {
return kubeContainer, nil
}
- ports, err := ocicniPortMappingToContainerPort(c.PortMappings())
+ portmappings, err := c.PortMappings()
+ if err != nil {
+ return kubeContainer, err
+ }
+ ports, err := ocicniPortMappingToContainerPort(portmappings)
if err != nil {
return kubeContainer, nil
}