summaryrefslogtreecommitdiff
path: root/pkg/bindings
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/bindings')
-rw-r--r--pkg/bindings/containers/containers.go20
-rw-r--r--pkg/bindings/images/images.go106
-rw-r--r--pkg/bindings/test/images_test.go25
3 files changed, 135 insertions, 16 deletions
diff --git a/pkg/bindings/containers/containers.go b/pkg/bindings/containers/containers.go
index bad1294f4..49a2dfd58 100644
--- a/pkg/bindings/containers/containers.go
+++ b/pkg/bindings/containers/containers.go
@@ -2,6 +2,7 @@ package containers
import (
"context"
+ "io"
"net/http"
"net/url"
"strconv"
@@ -296,3 +297,22 @@ func Stop(ctx context.Context, nameOrID string, timeout *uint) error {
}
return response.Process(nil)
}
+
+// Export creates a tarball of the given name or ID of a container. It
+// requires an io.Writer be provided to write the tarball.
+func Export(ctx context.Context, nameOrID string, w io.Writer) error {
+ params := url.Values{}
+ conn, err := bindings.GetClient(ctx)
+ if err != nil {
+ return err
+ }
+ response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/export", params, nameOrID)
+ if err != nil {
+ return err
+ }
+ if response.StatusCode/100 == 2 {
+ _, err = io.Copy(w, response.Body)
+ return err
+ }
+ return response.Process(nil)
+}
diff --git a/pkg/bindings/images/images.go b/pkg/bindings/images/images.go
index 5e3af7a60..dcb568d6b 100644
--- a/pkg/bindings/images/images.go
+++ b/pkg/bindings/images/images.go
@@ -3,15 +3,16 @@ package images
import (
"context"
"errors"
+ "fmt"
"io"
"net/http"
"net/url"
"strconv"
+ "github.com/containers/image/v5/types"
"github.com/containers/libpod/pkg/api/handlers"
"github.com/containers/libpod/pkg/bindings"
"github.com/containers/libpod/pkg/domain/entities"
- "github.com/containers/libpod/pkg/inspect"
)
// Exists a lightweight way to determine if an image exists in local storage. It returns a
@@ -56,7 +57,7 @@ func List(ctx context.Context, all *bool, filters map[string][]string) ([]*entit
// Get performs an image inspect. To have the on-disk size of the image calculated, you can
// use the optional size parameter.
-func GetImage(ctx context.Context, nameOrID string, size *bool) (*inspect.ImageData, error) {
+func GetImage(ctx context.Context, nameOrID string, size *bool) (*entities.ImageData, error) {
conn, err := bindings.GetClient(ctx)
if err != nil {
return nil, err
@@ -65,7 +66,7 @@ func GetImage(ctx context.Context, nameOrID string, size *bool) (*inspect.ImageD
if size != nil {
params.Set("size", strconv.FormatBool(*size))
}
- inspectedData := inspect.ImageData{}
+ inspectedData := entities.ImageData{}
response, err := conn.DoRequest(nil, http.MethodGet, "/images/%s/json", params, nameOrID)
if err != nil {
return &inspectedData, err
@@ -91,11 +92,11 @@ func History(ctx context.Context, nameOrID string) ([]*handlers.HistoryResponse,
return history, response.Process(&history)
}
-func Load(ctx context.Context, r io.Reader, name *string) (string, error) {
- var id handlers.IDResponse
+func Load(ctx context.Context, r io.Reader, name *string) (*entities.ImageLoadReport, error) {
+ var report entities.ImageLoadReport
conn, err := bindings.GetClient(ctx)
if err != nil {
- return "", err
+ return nil, err
}
params := url.Values{}
if name != nil {
@@ -103,9 +104,9 @@ func Load(ctx context.Context, r io.Reader, name *string) (string, error) {
}
response, err := conn.DoRequest(r, http.MethodPost, "/images/load", params)
if err != nil {
- return "", err
+ return nil, err
}
- return id.ID, response.Process(&id)
+ return &report, response.Process(&report)
}
// Remove deletes an image from local storage. The optional force parameter will forcibly remove
@@ -196,19 +197,35 @@ func Tag(ctx context.Context, nameOrID, tag, repo string) error {
return response.Process(nil)
}
+// Untag removes a name from locally-stored image. Both the tag and repo parameters are required.
+func Untag(ctx context.Context, nameOrID, tag, repo string) error {
+ conn, err := bindings.GetClient(ctx)
+ if err != nil {
+ return err
+ }
+ params := url.Values{}
+ params.Set("tag", tag)
+ params.Set("repo", repo)
+ response, err := conn.DoRequest(nil, http.MethodPost, "/images/%s/untag", params, nameOrID)
+ if err != nil {
+ return err
+ }
+ return response.Process(nil)
+}
+
func Build(nameOrId string) {}
// Imports adds the given image to the local image store. This can be done by file and the given reader
// or via the url parameter. Additional metadata can be associated with the image by using the changes and
// message parameters. The image can also be tagged given a reference. One of url OR r must be provided.
-func Import(ctx context.Context, changes []string, message, reference, u *string, r io.Reader) (string, error) {
- var id handlers.IDResponse
+func Import(ctx context.Context, changes []string, message, reference, u *string, r io.Reader) (*entities.ImageImportReport, error) {
+ var report entities.ImageImportReport
if r != nil && u != nil {
- return "", errors.New("url and r parameters cannot be used together")
+ return nil, errors.New("url and r parameters cannot be used together")
}
conn, err := bindings.GetClient(ctx)
if err != nil {
- return "", err
+ return nil, err
}
params := url.Values{}
for _, change := range changes {
@@ -225,7 +242,68 @@ func Import(ctx context.Context, changes []string, message, reference, u *string
}
response, err := conn.DoRequest(r, http.MethodPost, "/images/import", params)
if err != nil {
- return "", err
+ return nil, err
+ }
+ return &report, response.Process(&report)
+}
+
+// Pull is the binding for libpod's v2 endpoints for pulling images. Note that
+// `rawImage` must be a reference to a registry (i.e., of docker transport or be
+// normalized to one). Other transports are rejected as they do not make sense
+// in a remote context.
+func Pull(ctx context.Context, rawImage string, options entities.ImagePullOptions) ([]string, error) {
+ conn, err := bindings.GetClient(ctx)
+ if err != nil {
+ return nil, err
+ }
+ params := url.Values{}
+ params.Set("reference", rawImage)
+ params.Set("credentials", options.Credentials)
+ params.Set("overrideArch", options.OverrideArch)
+ params.Set("overrideOS", options.OverrideOS)
+ if options.TLSVerify != types.OptionalBoolUndefined {
+ val := bool(options.TLSVerify == types.OptionalBoolTrue)
+ params.Set("tlsVerify", strconv.FormatBool(val))
+ }
+ params.Set("allTags", strconv.FormatBool(options.AllTags))
+
+ response, err := conn.DoRequest(nil, http.MethodPost, "/images/pull", params)
+ if err != nil {
+ return nil, err
+ }
+
+ reports := []handlers.LibpodImagesPullReport{}
+ if err := response.Process(&reports); err != nil {
+ return nil, err
+ }
+
+ pulledImages := []string{}
+ for _, r := range reports {
+ pulledImages = append(pulledImages, r.ID)
}
- return id.ID, response.Process(&id)
+
+ return pulledImages, nil
+}
+
+// Push is the binding for libpod's v2 endpoints for push images. Note that
+// `source` must be a refering to an image in the remote's container storage.
+// The destination must be a reference to a registry (i.e., of docker transport
+// or be normalized to one). Other transports are rejected as they do not make
+// sense in a remote context.
+func Push(ctx context.Context, source string, destination string, options entities.ImagePushOptions) error {
+ conn, err := bindings.GetClient(ctx)
+ if err != nil {
+ return err
+ }
+ params := url.Values{}
+ params.Set("credentials", options.Credentials)
+ params.Set("destination", destination)
+ if options.TLSVerify != types.OptionalBoolUndefined {
+ val := bool(options.TLSVerify == types.OptionalBoolTrue)
+ params.Set("tlsVerify", strconv.FormatBool(val))
+ }
+
+ path := fmt.Sprintf("/images/%s/push", source)
+ _, err = conn.DoRequest(nil, http.MethodPost, path, params)
+ return err
}
diff --git a/pkg/bindings/test/images_test.go b/pkg/bindings/test/images_test.go
index 13b6086c3..992720196 100644
--- a/pkg/bindings/test/images_test.go
+++ b/pkg/bindings/test/images_test.go
@@ -9,6 +9,7 @@ import (
"github.com/containers/libpod/pkg/bindings"
"github.com/containers/libpod/pkg/bindings/containers"
"github.com/containers/libpod/pkg/bindings/images"
+ "github.com/containers/libpod/pkg/domain/entities"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gexec"
@@ -218,7 +219,7 @@ var _ = Describe("Podman images", func() {
Expect(err).To(BeNil())
names, err := images.Load(bt.conn, f, nil)
Expect(err).To(BeNil())
- Expect(names).To(Equal(alpine.name))
+ Expect(names.Name).To(Equal(alpine.name))
exists, err = images.Exists(bt.conn, alpine.name)
Expect(err).To(BeNil())
Expect(exists).To(BeTrue())
@@ -234,7 +235,7 @@ var _ = Describe("Podman images", func() {
newName := "quay.io/newname:fizzle"
names, err = images.Load(bt.conn, f, &newName)
Expect(err).To(BeNil())
- Expect(names).To(Equal(alpine.name))
+ Expect(names.Name).To(Equal(alpine.name))
exists, err = images.Exists(bt.conn, newName)
Expect(err).To(BeNil())
Expect(exists).To(BeTrue())
@@ -353,4 +354,24 @@ var _ = Describe("Podman images", func() {
Expect(results).To(ContainElement("docker.io/library/alpine:latest"))
})
+ // TODO: we really need to extent to pull tests once we have a more sophisticated CI.
+ It("Image Pull", func() {
+ rawImage := "docker.io/library/busybox:latest"
+
+ pulledImages, err := images.Pull(bt.conn, rawImage, entities.ImagePullOptions{})
+ Expect(err).To(BeNil())
+ Expect(len(pulledImages)).To(Equal(1))
+
+ exists, err := images.Exists(bt.conn, rawImage)
+ Expect(err).To(BeNil())
+ Expect(exists).To(BeTrue())
+
+ // Make sure the normalization AND the full-transport reference works.
+ _, err = images.Pull(bt.conn, "docker://"+rawImage, entities.ImagePullOptions{})
+ Expect(err).To(BeNil())
+
+ // The v2 endpoint only supports the docker transport. Let's see if that's really true.
+ _, err = images.Pull(bt.conn, "bogus-transport:bogus.com/image:reference", entities.ImagePullOptions{})
+ Expect(err).To(Not(BeNil()))
+ })
})