diff options
Diffstat (limited to 'pkg/bindings')
-rw-r--r-- | pkg/bindings/images/images.go | 39 | ||||
-rw-r--r-- | pkg/bindings/pods/pods.go | 36 | ||||
-rw-r--r-- | pkg/bindings/test/containers_test.go | 6 | ||||
-rw-r--r-- | pkg/bindings/test/images_test.go | 21 | ||||
-rw-r--r-- | pkg/bindings/test/pods_test.go | 30 |
5 files changed, 126 insertions, 6 deletions
diff --git a/pkg/bindings/images/images.go b/pkg/bindings/images/images.go index 5e3af7a60..5f5c4443f 100644 --- a/pkg/bindings/images/images.go +++ b/pkg/bindings/images/images.go @@ -8,6 +8,7 @@ import ( "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" @@ -229,3 +230,41 @@ func Import(ctx context.Context, changes []string, message, reference, u *string } return id.ID, response.Process(&id) } + +// 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 pulledImages, nil +} diff --git a/pkg/bindings/pods/pods.go b/pkg/bindings/pods/pods.go index bb0abebc4..ae87c00e9 100644 --- a/pkg/bindings/pods/pods.go +++ b/pkg/bindings/pods/pods.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/containers/libpod/libpod" + "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/specgen" @@ -213,9 +214,38 @@ func Stop(ctx context.Context, nameOrID string, timeout *int) (*entities.PodStop return &report, response.Process(&report) } -func Top() error { - // TODO - return bindings.ErrNotImplemented // nolint:typecheck +// Top gathers statistics about the running processes in a pod. The nameOrID can be a pod name +// or a partial/full ID. The descriptors allow for specifying which data to collect from each process. +func Top(ctx context.Context, nameOrID string, descriptors []string) ([]string, error) { + conn, err := bindings.GetClient(ctx) + if err != nil { + return nil, err + } + params := url.Values{} + + if len(descriptors) > 0 { + // flatten the slice into one string + params.Set("ps_args", strings.Join(descriptors, ",")) + } + response, err := conn.DoRequest(nil, http.MethodGet, "/pods/%s/top", params, nameOrID) + if err != nil { + return nil, err + } + + body := handlers.PodTopOKBody{} + if err = response.Process(&body); err != nil { + return nil, err + } + + // handlers.PodTopOKBody{} returns a slice of slices where each cell in the top table is an item. + // In libpod land, we're just using a slice with cells being split by tabs, which allows for an idiomatic + // usage of the tabwriter. + topOutput := []string{strings.Join(body.Titles, "\t")} + for _, out := range body.Processes { + topOutput = append(topOutput, strings.Join(out, "\t")) + } + + return topOutput, err } // Unpause unpauses all paused containers in a Pod. diff --git a/pkg/bindings/test/containers_test.go b/pkg/bindings/test/containers_test.go index 9dd9cb707..a31181958 100644 --- a/pkg/bindings/test/containers_test.go +++ b/pkg/bindings/test/containers_test.go @@ -387,15 +387,15 @@ var _ = Describe("Podman containers ", func() { Expect(err).To(BeNil()) // By name - output, err := containers.Top(bt.conn, name, nil) + _, err = containers.Top(bt.conn, name, nil) Expect(err).To(BeNil()) // By id - output, err = containers.Top(bt.conn, cid, nil) + _, err = containers.Top(bt.conn, cid, nil) Expect(err).To(BeNil()) // With descriptors - output, err = containers.Top(bt.conn, cid, []string{"user,pid,hpid"}) + output, err := containers.Top(bt.conn, cid, []string{"user,pid,hpid"}) Expect(err).To(BeNil()) header := strings.Split(output[0], "\t") for _, d := range []string{"USER", "PID", "HPID"} { diff --git a/pkg/bindings/test/images_test.go b/pkg/bindings/test/images_test.go index 13b6086c3..dc01a793b 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" @@ -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())) + }) }) diff --git a/pkg/bindings/test/pods_test.go b/pkg/bindings/test/pods_test.go index 0f786e341..2599ec7ef 100644 --- a/pkg/bindings/test/pods_test.go +++ b/pkg/bindings/test/pods_test.go @@ -2,6 +2,7 @@ package test_bindings import ( "net/http" + "strings" "time" "github.com/containers/libpod/libpod/define" @@ -319,4 +320,33 @@ var _ = Describe("Podman pods", func() { Expect(err).To(BeNil()) Expect(exists).To(BeTrue()) }) + + // Test validates the pod top bindings + It("pod top", func() { + var name string = "podA" + + bt.Podcreate(&name) + _, err := pods.Start(bt.conn, name) + Expect(err).To(BeNil()) + + // By name + _, err = pods.Top(bt.conn, name, nil) + Expect(err).To(BeNil()) + + // With descriptors + output, err := pods.Top(bt.conn, name, []string{"user,pid,hpid"}) + Expect(err).To(BeNil()) + header := strings.Split(output[0], "\t") + for _, d := range []string{"USER", "PID", "HPID"} { + Expect(d).To(BeElementOf(header)) + } + + // With bogus ID + _, err = pods.Top(bt.conn, "IdoNotExist", nil) + Expect(err).ToNot(BeNil()) + + // With bogus descriptors + _, err = pods.Top(bt.conn, name, []string{"Me,Neither"}) + Expect(err).ToNot(BeNil()) + }) }) |