aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xAPI.md19
-rw-r--r--cmd/podman/pod_create.go38
-rw-r--r--cmd/podman/shared/pod.go37
-rw-r--r--cmd/podman/varlink/io.podman.varlink14
-rw-r--r--pkg/varlinkapi/images.go93
-rw-r--r--pkg/varlinkapi/pods.go20
6 files changed, 156 insertions, 65 deletions
diff --git a/API.md b/API.md
index a338f0212..7bc866d98 100755
--- a/API.md
+++ b/API.md
@@ -87,9 +87,9 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in
[func Ping() StringResponse](#Ping)
-[func PullImage(name: string) string](#PullImage)
+[func PullImage(name: string, certDir: string, creds: string, signaturePolicy: string, tlsVerify: bool) string](#PullImage)
-[func PushImage(name: string, tag: string, tlsverify: bool) string](#PushImage)
+[func PushImage(name: string, tag: string, tlsverify: bool, signaturePolicy: string, creds: string, certDir: string, compress: bool, format: string, removeSignatures: bool, signBy: string) string](#PushImage)
[func RemoveContainer(name: string, force: bool) string](#RemoveContainer)
@@ -739,7 +739,7 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.Ping
### <a name="PullImage"></a>func PullImage
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
-method PullImage(name: [string](https://godoc.org/builtin#string)) [string](https://godoc.org/builtin#string)</div>
+method PullImage(name: [string](https://godoc.org/builtin#string), certDir: [string](https://godoc.org/builtin#string), creds: [string](https://godoc.org/builtin#string), signaturePolicy: [string](https://godoc.org/builtin#string), tlsVerify: [bool](https://godoc.org/builtin#bool)) [string](https://godoc.org/builtin#string)</div>
PullImage pulls an image from a repository to local storage. After the pull is successful, the ID of the image
is returned.
#### Example
@@ -752,7 +752,7 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.PullImage '{"name": "regi
### <a name="PushImage"></a>func PushImage
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
-method PushImage(name: [string](https://godoc.org/builtin#string), tag: [string](https://godoc.org/builtin#string), tlsverify: [bool](https://godoc.org/builtin#bool)) [string](https://godoc.org/builtin#string)</div>
+method PushImage(name: [string](https://godoc.org/builtin#string), tag: [string](https://godoc.org/builtin#string), tlsverify: [bool](https://godoc.org/builtin#bool), signaturePolicy: [string](https://godoc.org/builtin#string), creds: [string](https://godoc.org/builtin#string), certDir: [string](https://godoc.org/builtin#string), compress: [bool](https://godoc.org/builtin#bool), format: [string](https://godoc.org/builtin#string), removeSignatures: [bool](https://godoc.org/builtin#bool), signBy: [string](https://godoc.org/builtin#string)) [string](https://godoc.org/builtin#string)</div>
PushImage takes three input arguments: the name or ID of an image, the fully-qualified destination name of the image,
and a boolean as to whether tls-verify should be used (with false disabling TLS, not affecting the default behavior).
It will return an [ImageNotFound](#ImageNotFound) error if
@@ -1499,9 +1499,8 @@ reason [string](https://godoc.org/builtin#string)
### <a name="PodCreate"></a>type PodCreate
PodCreate is an input structure for creating pods.
-It emulates options to podman pod create, however
-changing pause image name and pause container
-is not currently supported
+It emulates options to podman pod create. The infraCommand and
+infraImage options are currently NotSupported.
name [string](https://godoc.org/builtin#string)
@@ -1512,6 +1511,12 @@ labels [map[string]](#map[string])
share [[]string](#[]string)
infra [bool](https://godoc.org/builtin#bool)
+
+infraCommand [string](https://godoc.org/builtin#string)
+
+infraImage [string](https://godoc.org/builtin#string)
+
+publish [[]string](#[]string)
### <a name="PodmanInfo"></a>type PodmanInfo
PodmanInfo describes the Podman host and build
diff --git a/cmd/podman/pod_create.go b/cmd/podman/pod_create.go
index a3364ac4b..967ce7610 100644
--- a/cmd/podman/pod_create.go
+++ b/cmd/podman/pod_create.go
@@ -3,15 +3,12 @@ package main
import (
"fmt"
"os"
- "strconv"
"strings"
"github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/rootless"
- "github.com/cri-o/ocicni/pkg/ocicni"
- "github.com/docker/go-connections/nat"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
@@ -150,7 +147,7 @@ func podCreateCmd(c *cli.Context) error {
}
if len(c.StringSlice("publish")) > 0 {
- portBindings, err := CreatePortBindings(c.StringSlice("publish"))
+ portBindings, err := shared.CreatePortBindings(c.StringSlice("publish"))
if err != nil {
return err
}
@@ -178,36 +175,3 @@ func podCreateCmd(c *cli.Context) error {
return nil
}
-
-// CreatePortBindings iterates ports mappings and exposed ports into a format CNI understands
-func CreatePortBindings(ports []string) ([]ocicni.PortMapping, error) {
- var portBindings []ocicni.PortMapping
- // The conversion from []string to natBindings is temporary while mheon reworks the port
- // deduplication code. Eventually that step will not be required.
- _, natBindings, err := nat.ParsePortSpecs(ports)
- if err != nil {
- return nil, err
- }
- for containerPb, hostPb := range natBindings {
- var pm ocicni.PortMapping
- pm.ContainerPort = int32(containerPb.Int())
- for _, i := range hostPb {
- var hostPort int
- var err error
- pm.HostIP = i.HostIP
- if i.HostPort == "" {
- hostPort = containerPb.Int()
- } else {
- hostPort, err = strconv.Atoi(i.HostPort)
- if err != nil {
- return nil, errors.Wrapf(err, "unable to convert host port to integer")
- }
- }
-
- pm.HostPort = int32(hostPort)
- pm.Protocol = containerPb.Proto()
- portBindings = append(portBindings, pm)
- }
- }
- return portBindings, nil
-}
diff --git a/cmd/podman/shared/pod.go b/cmd/podman/shared/pod.go
index 4e8e58c4d..30dd14845 100644
--- a/cmd/podman/shared/pod.go
+++ b/cmd/podman/shared/pod.go
@@ -1,7 +1,11 @@
package shared
import (
+ "strconv"
+
"github.com/containers/libpod/libpod"
+ "github.com/cri-o/ocicni/pkg/ocicni"
+ "github.com/docker/go-connections/nat"
"github.com/pkg/errors"
)
@@ -95,3 +99,36 @@ func GetNamespaceOptions(ns []string) ([]libpod.PodCreateOption, error) {
}
return options, nil
}
+
+// CreatePortBindings iterates ports mappings and exposed ports into a format CNI understands
+func CreatePortBindings(ports []string) ([]ocicni.PortMapping, error) {
+ var portBindings []ocicni.PortMapping
+ // The conversion from []string to natBindings is temporary while mheon reworks the port
+ // deduplication code. Eventually that step will not be required.
+ _, natBindings, err := nat.ParsePortSpecs(ports)
+ if err != nil {
+ return nil, err
+ }
+ for containerPb, hostPb := range natBindings {
+ var pm ocicni.PortMapping
+ pm.ContainerPort = int32(containerPb.Int())
+ for _, i := range hostPb {
+ var hostPort int
+ var err error
+ pm.HostIP = i.HostIP
+ if i.HostPort == "" {
+ hostPort = containerPb.Int()
+ } else {
+ hostPort, err = strconv.Atoi(i.HostPort)
+ if err != nil {
+ return nil, errors.Wrapf(err, "unable to convert host port to integer")
+ }
+ }
+
+ pm.HostPort = int32(hostPort)
+ pm.Protocol = containerPb.Proto()
+ portBindings = append(portBindings, pm)
+ }
+ }
+ return portBindings, nil
+}
diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink
index e596a5c91..376bbc950 100644
--- a/cmd/podman/varlink/io.podman.varlink
+++ b/cmd/podman/varlink/io.podman.varlink
@@ -343,15 +343,17 @@ type ListPodContainerInfo (
)
# PodCreate is an input structure for creating pods.
-# It emulates options to podman pod create, however
-# changing pause image name and pause container
-# is not currently supported
+# It emulates options to podman pod create. The infraCommand and
+# infraImage options are currently NotSupported.
type PodCreate (
name: string,
cgroupParent: string,
labels: [string]string,
share: []string,
- infra: bool
+ infra: bool,
+ infraCommand: string,
+ infraImage: string,
+ publish: []string
)
# ListPodData is the returned struct for an individual pod
@@ -632,7 +634,7 @@ method HistoryImage(name: string) -> (history: []ImageHistory)
# and a boolean as to whether tls-verify should be used (with false disabling TLS, not affecting the default behavior).
# It will return an [ImageNotFound](#ImageNotFound) error if
# the image cannot be found in local storage; otherwise the ID of the image will be returned on success.
-method PushImage(name: string, tag: string, tlsverify: bool) -> (image: string)
+method PushImage(name: string, tag: string, tlsverify: bool, signaturePolicy: string, creds: string, certDir: string, compress: bool, format: string, removeSignatures: bool, signBy: string) -> (image: string)
# TagImage takes the name or ID of an image in local storage as well as the desired tag name. If the image cannot
# be found, an [ImageNotFound](#ImageNotFound) error will be returned; otherwise, the ID of the image is returned on success.
@@ -700,7 +702,7 @@ method ExportImage(name: string, destination: string, compress: bool, tags: []st
# "id": "426866d6fa419873f97e5cbd320eeb22778244c1dfffa01c944db3114f55772e"
# }
# ~~~
-method PullImage(name: string) -> (id: string)
+method PullImage(name: string, certDir: string, creds: string, signaturePolicy: string, tlsVerify: bool) -> (id: string)
# CreatePod creates a new empty pod. It uses a [PodCreate](#PodCreate) type for input.
# On success, the ID of the newly created pod will be returned.
diff --git a/pkg/varlinkapi/images.go b/pkg/varlinkapi/images.go
index a5673f636..5e4cb4ccb 100644
--- a/pkg/varlinkapi/images.go
+++ b/pkg/varlinkapi/images.go
@@ -13,7 +13,9 @@ import (
"github.com/containers/buildah"
"github.com/containers/buildah/imagebuildah"
"github.com/containers/image/docker"
+ dockerarchive "github.com/containers/image/docker/archive"
"github.com/containers/image/manifest"
+ "github.com/containers/image/transports/alltransports"
"github.com/containers/image/types"
"github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/cmd/podman/varlink"
@@ -130,7 +132,7 @@ func (i *LibpodAPI) BuildImage(call iopodman.VarlinkCall, config iopodman.BuildI
if config.Pull_always {
pullPolicy = imagebuildah.PullAlways
}
- manifestType := "oci"
+ manifestType := "oci" //nolint
if config.Image_format != "" {
manifestType = config.Image_format
}
@@ -311,8 +313,12 @@ func (i *LibpodAPI) HistoryImage(call iopodman.VarlinkCall, name string) error {
}
// PushImage pushes an local image to registry
-// TODO We need to add options for signing, credentials, tls, and multi-tag
-func (i *LibpodAPI) PushImage(call iopodman.VarlinkCall, name, tag string, tlsVerify bool) error {
+func (i *LibpodAPI) PushImage(call iopodman.VarlinkCall, name, tag string, tlsVerify bool, signaturePolicy, creds, certDir string, compress bool, format string, removeSignatures bool, signBy string) error {
+ var (
+ registryCreds *types.DockerAuthConfig
+ manifestType string
+ )
+
newImage, err := i.Runtime.ImageRuntime().NewFromLocal(name)
if err != nil {
return call.ReplyImageNotFound(err.Error())
@@ -321,15 +327,38 @@ func (i *LibpodAPI) PushImage(call iopodman.VarlinkCall, name, tag string, tlsVe
if tag != "" {
destname = tag
}
-
- dockerRegistryOptions := image.DockerRegistryOptions{}
+ if creds != "" {
+ creds, err := util.ParseRegistryCreds(creds)
+ if err != nil {
+ return err
+ }
+ registryCreds = creds
+ }
+ dockerRegistryOptions := image.DockerRegistryOptions{
+ DockerRegistryCreds: registryCreds,
+ DockerCertPath: certDir,
+ }
if !tlsVerify {
dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.OptionalBoolTrue
}
+ if format != "" {
+ switch format {
+ case "oci": //nolint
+ manifestType = v1.MediaTypeImageManifest
+ case "v2s1":
+ manifestType = manifest.DockerV2Schema1SignedMediaType
+ case "v2s2", "docker":
+ manifestType = manifest.DockerV2Schema2MediaType
+ default:
+ return call.ReplyErrorOccurred(fmt.Sprintf("unknown format %q. Choose on of the supported formats: 'oci', 'v2s1', or 'v2s2'", format))
+ }
+ }
+ so := image.SigningOptions{
+ RemoveSignatures: removeSignatures,
+ SignBy: signBy,
+ }
- so := image.SigningOptions{}
-
- if err := newImage.PushImageToHeuristicDestination(getContext(), destname, "", "", "", nil, false, so, &dockerRegistryOptions, nil); err != nil {
+ if err := newImage.PushImageToHeuristicDestination(getContext(), destname, manifestType, "", signaturePolicy, nil, compress, so, &dockerRegistryOptions, nil); err != nil {
return call.ReplyErrorOccurred(err.Error())
}
return call.ReplyPushImage(newImage.ID())
@@ -428,7 +457,7 @@ func (i *LibpodAPI) Commit(call iopodman.VarlinkCall, name, imageName string, ch
sc := image.GetSystemContext(i.Runtime.GetConfig().SignaturePolicyPath, "", false)
var mimeType string
switch manifestType {
- case "oci", "":
+ case "oci", "": //nolint
mimeType = buildah.OCIv1ImageManifest
case "docker":
mimeType = manifest.DockerV2Schema2MediaType
@@ -496,13 +525,47 @@ func (i *LibpodAPI) ExportImage(call iopodman.VarlinkCall, name, destination str
}
// PullImage pulls an image from a registry to the image store.
-// TODO This implementation is incomplete
-func (i *LibpodAPI) PullImage(call iopodman.VarlinkCall, name string) error {
- newImage, err := i.Runtime.ImageRuntime().New(getContext(), name, "", "", nil, &image.DockerRegistryOptions{}, image.SigningOptions{}, true)
- if err != nil {
- return call.ReplyErrorOccurred(fmt.Sprintf("unable to pull %s: %s", name, err.Error()))
+func (i *LibpodAPI) PullImage(call iopodman.VarlinkCall, name string, certDir, creds, signaturePolicy string, tlsVerify bool) error {
+ var (
+ registryCreds *types.DockerAuthConfig
+ imageID string
+ )
+ if creds != "" {
+ creds, err := util.ParseRegistryCreds(creds)
+ if err != nil {
+ return err
+ }
+ registryCreds = creds
+ }
+
+ dockerRegistryOptions := image.DockerRegistryOptions{
+ DockerRegistryCreds: registryCreds,
+ DockerCertPath: certDir,
+ }
+ if tlsVerify {
+ dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!tlsVerify)
+ }
+
+ so := image.SigningOptions{}
+
+ if strings.HasPrefix(name, dockerarchive.Transport.Name()+":") {
+ srcRef, err := alltransports.ParseImageName(name)
+ if err != nil {
+ return errors.Wrapf(err, "error parsing %q", name)
+ }
+ newImage, err := i.Runtime.ImageRuntime().LoadFromArchiveReference(getContext(), srcRef, signaturePolicy, nil)
+ if err != nil {
+ return errors.Wrapf(err, "error pulling image from %q", name)
+ }
+ imageID = newImage[0].ID()
+ } else {
+ newImage, err := i.Runtime.ImageRuntime().New(getContext(), name, signaturePolicy, "", nil, &dockerRegistryOptions, so, false)
+ if err != nil {
+ return call.ReplyErrorOccurred(fmt.Sprintf("unable to pull %s: %s", name, err.Error()))
+ }
+ imageID = newImage.ID()
}
- return call.ReplyPullImage(newImage.ID())
+ return call.ReplyPullImage(imageID)
}
// ImageExists returns bool as to whether the input image exists in local storage
diff --git a/pkg/varlinkapi/pods.go b/pkg/varlinkapi/pods.go
index 461371497..6e758786a 100644
--- a/pkg/varlinkapi/pods.go
+++ b/pkg/varlinkapi/pods.go
@@ -2,6 +2,7 @@ package varlinkapi
import (
"encoding/json"
+ "github.com/containers/libpod/pkg/rootless"
"syscall"
"github.com/containers/libpod/cmd/podman/shared"
@@ -12,6 +13,10 @@ import (
// CreatePod ...
func (i *LibpodAPI) CreatePod(call iopodman.VarlinkCall, create iopodman.PodCreate) error {
var options []libpod.PodCreateOption
+
+ if create.InfraCommand != "" || create.InfraImage != "" {
+ return call.ReplyErrorOccurred("the infra-command and infra-image options are not supported yet")
+ }
if create.CgroupParent != "" {
options = append(options, libpod.WithPodCgroupParent(create.CgroupParent))
}
@@ -27,6 +32,21 @@ func (i *LibpodAPI) CreatePod(call iopodman.VarlinkCall, create iopodman.PodCrea
if len(create.Share) == 0 && create.Infra {
return call.ReplyErrorOccurred("You must share kernel namespaces to run an infra container")
}
+
+ if len(create.Publish) > 0 {
+ if !create.Infra {
+ return call.ReplyErrorOccurred("you must have an infra container to publish port bindings to the host")
+ }
+ if rootless.IsRootless() {
+ return call.ReplyErrorOccurred("rootless networking does not allow port binding to the host")
+ }
+ portBindings, err := shared.CreatePortBindings(create.Publish)
+ if err != nil {
+ return err
+ }
+ options = append(options, libpod.WithInfraContainerPorts(portBindings))
+
+ }
if create.Infra {
options = append(options, libpod.WithInfraContainer())
nsOptions, err := shared.GetNamespaceOptions(create.Share)