diff options
Diffstat (limited to 'pkg/bindings')
-rw-r--r-- | pkg/bindings/bindings.go | 2 | ||||
-rw-r--r-- | pkg/bindings/images/images.go | 45 | ||||
-rw-r--r-- | pkg/bindings/images/pull.go | 99 | ||||
-rw-r--r-- | pkg/bindings/system/system.go | 10 | ||||
-rw-r--r-- | pkg/bindings/test/images_test.go | 8 |
5 files changed, 112 insertions, 52 deletions
diff --git a/pkg/bindings/bindings.go b/pkg/bindings/bindings.go index ae5610b0f..14f306910 100644 --- a/pkg/bindings/bindings.go +++ b/pkg/bindings/bindings.go @@ -22,5 +22,5 @@ var ( PFalse = &pFalse // APIVersion - podman will fail to run if this value is wrong - APIVersion = semver.MustParse("1.0.0") + APIVersion = semver.MustParse("2.0.0") ) diff --git a/pkg/bindings/images/images.go b/pkg/bindings/images/images.go index 05ab25d5b..596491044 100644 --- a/pkg/bindings/images/images.go +++ b/pkg/bindings/images/images.go @@ -270,51 +270,6 @@ func Import(ctx context.Context, changes []string, message, reference, u *string 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("overrideArch", options.OverrideArch) - params.Set("overrideOS", options.OverrideOS) - params.Set("overrideVariant", options.OverrideVariant) - if options.SkipTLSVerify != types.OptionalBoolUndefined { - // Note: we have to verify if skipped is false. - verifyTLS := bool(options.SkipTLSVerify == types.OptionalBoolFalse) - params.Set("tlsVerify", strconv.FormatBool(verifyTLS)) - } - params.Set("allTags", strconv.FormatBool(options.AllTags)) - - // TODO: have a global system context we can pass around (1st argument) - header, err := auth.Header(nil, options.Authfile, options.Username, options.Password) - if err != nil { - return nil, err - } - - response, err := conn.DoRequest(nil, http.MethodPost, "/images/pull", params, header) - 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 -} - // Push is the binding for libpod's v2 endpoints for push images. Note that // `source` must be a referring to an image in the remote's container storage. // The destination must be a reference to a registry (i.e., of docker transport diff --git a/pkg/bindings/images/pull.go b/pkg/bindings/images/pull.go new file mode 100644 index 000000000..2bfbbb2ac --- /dev/null +++ b/pkg/bindings/images/pull.go @@ -0,0 +1,99 @@ +package images + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "os" + "strconv" + + "github.com/containers/image/v5/types" + "github.com/containers/podman/v2/pkg/auth" + "github.com/containers/podman/v2/pkg/bindings" + "github.com/containers/podman/v2/pkg/domain/entities" + "github.com/hashicorp/go-multierror" +) + +// 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. Progress reported on stderr +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("overrideArch", options.OverrideArch) + params.Set("overrideOS", options.OverrideOS) + params.Set("overrideVariant", options.OverrideVariant) + + if options.SkipTLSVerify != types.OptionalBoolUndefined { + // Note: we have to verify if skipped is false. + verifyTLS := bool(options.SkipTLSVerify == types.OptionalBoolFalse) + params.Set("tlsVerify", strconv.FormatBool(verifyTLS)) + } + params.Set("allTags", strconv.FormatBool(options.AllTags)) + + // TODO: have a global system context we can pass around (1st argument) + header, err := auth.Header(nil, options.Authfile, options.Username, options.Password) + if err != nil { + return nil, err + } + + response, err := conn.DoRequest(nil, http.MethodPost, "/images/pull", params, header) + if err != nil { + return nil, err + } + defer response.Body.Close() + + if !response.IsSuccess() { + return nil, response.Process(err) + } + + // Historically pull writes status to stderr + stderr := io.Writer(os.Stderr) + if options.Quiet { + stderr = ioutil.Discard + } + + dec := json.NewDecoder(response.Body) + var images []string + var mErr error + for { + var report entities.ImagePullReport + if err := dec.Decode(&report); err != nil { + if errors.Is(err, io.EOF) { + break + } + report.Error = err.Error() + "\n" + } + + select { + case <-response.Request.Context().Done(): + return images, mErr + default: + // non-blocking select + } + + switch { + case report.Stream != "": + fmt.Fprint(stderr, report.Stream) + case report.Error != "": + mErr = multierror.Append(mErr, errors.New(report.Error)) + case len(report.Images) > 0: + images = report.Images + case report.ID != "": + default: + return images, errors.New("failed to parse pull results stream, unexpected input") + } + + } + return images, mErr +} diff --git a/pkg/bindings/system/system.go b/pkg/bindings/system/system.go index e995770ba..1203f5c3c 100644 --- a/pkg/bindings/system/system.go +++ b/pkg/bindings/system/system.go @@ -118,10 +118,10 @@ func Version(ctx context.Context) (*entities.SystemVersionReport, error) { if err = response.Process(&component); err != nil { return nil, err } - f, _ := strconv.ParseFloat(component.APIVersion, 64) + b, _ := time.Parse(time.RFC3339, component.BuildTime) report.Server = &define.Version{ - APIVersion: int64(f), + APIVersion: component.APIVersion, Version: component.Version.Version, GoVersion: component.GoVersion, GitCommit: component.GitCommit, @@ -129,6 +129,12 @@ func Version(ctx context.Context) (*entities.SystemVersionReport, error) { Built: b.Unix(), OsArch: fmt.Sprintf("%s/%s", component.Os, component.Arch), } + + for _, c := range component.Components { + if c.Name == "Podman Engine" { + report.Server.APIVersion = c.Details["APIVersion"] + } + } return &report, err } diff --git a/pkg/bindings/test/images_test.go b/pkg/bindings/test/images_test.go index e0dd28d7a..681855293 100644 --- a/pkg/bindings/test/images_test.go +++ b/pkg/bindings/test/images_test.go @@ -360,19 +360,19 @@ var _ = Describe("Podman images", func() { rawImage := "docker.io/library/busybox:latest" pulledImages, err := images.Pull(bt.conn, rawImage, entities.ImagePullOptions{}) - Expect(err).To(BeNil()) + Expect(err).NotTo(HaveOccurred()) Expect(len(pulledImages)).To(Equal(1)) exists, err := images.Exists(bt.conn, rawImage) - Expect(err).To(BeNil()) + Expect(err).NotTo(HaveOccurred()) 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()) + Expect(err).NotTo(HaveOccurred()) // 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())) + Expect(err).To(HaveOccurred()) }) }) |