summaryrefslogtreecommitdiff
path: root/pkg/bindings/manifests/manifests.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/bindings/manifests/manifests.go')
-rw-r--r--pkg/bindings/manifests/manifests.go138
1 files changed, 96 insertions, 42 deletions
diff --git a/pkg/bindings/manifests/manifests.go b/pkg/bindings/manifests/manifests.go
index 458cb913a..70b3819f5 100644
--- a/pkg/bindings/manifests/manifests.go
+++ b/pkg/bindings/manifests/manifests.go
@@ -2,20 +2,24 @@ package manifests
import (
"context"
- "errors"
"fmt"
+ "io/ioutil"
"net/http"
- "net/url"
"strconv"
"strings"
"github.com/blang/semver"
"github.com/containers/image/v5/manifest"
+ imageTypes "github.com/containers/image/v5/types"
"github.com/containers/podman/v4/pkg/api/handlers"
+ "github.com/containers/podman/v4/pkg/auth"
"github.com/containers/podman/v4/pkg/bindings"
"github.com/containers/podman/v4/pkg/bindings/images"
+ "github.com/containers/podman/v4/pkg/domain/entities"
+ "github.com/containers/podman/v4/pkg/errorhandling"
"github.com/containers/podman/v4/version"
jsoniter "github.com/json-iterator/go"
+ "github.com/pkg/errors"
)
// Create creates a manifest for the given name. Optional images to be associated with
@@ -93,15 +97,19 @@ func Add(ctx context.Context, name string, options *AddOptions) (string, error)
if bindings.ServiceVersion(ctx).GTE(semver.MustParse("4.0.0")) {
optionsv4 := ModifyOptions{
- All: options.All,
- Annotations: options.Annotation,
- Arch: options.Arch,
- Features: options.Features,
- Images: options.Images,
- OS: options.OS,
- OSFeatures: nil,
- OSVersion: options.OSVersion,
- Variant: options.Variant,
+ All: options.All,
+ Annotations: options.Annotation,
+ Arch: options.Arch,
+ Features: options.Features,
+ Images: options.Images,
+ OS: options.OS,
+ OSFeatures: nil,
+ OSVersion: options.OSVersion,
+ Variant: options.Variant,
+ Username: options.Username,
+ Password: options.Password,
+ Authfile: options.Authfile,
+ SkipTLSVerify: options.SkipTLSVerify,
}
optionsv4.WithOperation("update")
return Modify(ctx, name, options.Images, &optionsv4)
@@ -118,40 +126,27 @@ func Add(ctx context.Context, name string, options *AddOptions) (string, error)
}
reader := strings.NewReader(opts)
- headers := make(http.Header)
- v := version.APIVersion[version.Libpod][version.MinimalAPI]
- headers.Add("API-Version",
- fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch))
- response, err := conn.DoRequest(ctx, reader, http.MethodPost, "/manifests/%s/add", nil, headers, name)
+ header, err := auth.MakeXRegistryAuthHeader(&imageTypes.SystemContext{AuthFilePath: options.GetAuthfile()}, options.GetUsername(), options.GetPassword())
if err != nil {
return "", err
}
- defer response.Body.Close()
-
- var idr handlers.IDResponse
- return idr.ID, response.Process(&idr)
-}
-
-// Remove deletes a manifest entry from a manifest list. Both name and the digest to be
-// removed are mandatory inputs. The ID of the new manifest list is returned as a string.
-func Remove(ctx context.Context, name, digest string, _ *RemoveOptions) (string, error) {
- if bindings.ServiceVersion(ctx).GTE(semver.MustParse("4.0.0")) {
- optionsv4 := new(ModifyOptions).WithOperation("remove")
- return Modify(ctx, name, []string{digest}, optionsv4)
- }
- // API Version < 4.0.0
- conn, err := bindings.GetClient(ctx)
+ params, err := options.ToParams()
if err != nil {
return "", err
}
+ // SkipTLSVerify is special. We need to delete the param added by
+ // ToParams() and change the key and flip the bool
+ if options.SkipTLSVerify != nil {
+ params.Del("SkipTLSVerify")
+ params.Set("tlsVerify", strconv.FormatBool(!options.GetSkipTLSVerify()))
+ }
- headers := http.Header{}
- headers.Add("API-Version", "3.4.0")
+ v := version.APIVersion[version.Libpod][version.MinimalAPI]
+ header.Add("API-Version",
+ fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch))
- params := url.Values{}
- params.Set("digest", digest)
- response, err := conn.DoRequest(ctx, nil, http.MethodDelete, "/manifests/%s", params, headers, name)
+ response, err := conn.DoRequest(ctx, reader, http.MethodPost, "/manifests/%s/add", params, header, name)
if err != nil {
return "", err
}
@@ -161,6 +156,13 @@ func Remove(ctx context.Context, name, digest string, _ *RemoveOptions) (string,
return idr.ID, response.Process(&idr)
}
+// Remove deletes a manifest entry from a manifest list. Both name and the digest to be
+// removed are mandatory inputs. The ID of the new manifest list is returned as a string.
+func Remove(ctx context.Context, name, digest string, _ *RemoveOptions) (string, error) {
+ optionsv4 := new(ModifyOptions).WithOperation("remove")
+ return Modify(ctx, name, []string{digest}, optionsv4)
+}
+
// Push takes a manifest list and pushes to a destination. If the destination is not specified,
// the name will be used instead. If the optional all boolean is specified, all images specified
// in the list will be pushed as well.
@@ -179,6 +181,14 @@ func Push(ctx context.Context, name, destination string, options *images.PushOpt
return "", err
}
+ header, err := auth.MakeXRegistryAuthHeader(&imageTypes.SystemContext{AuthFilePath: options.GetAuthfile()}, options.GetUsername(), options.GetPassword())
+ if err != nil {
+ return "", err
+ }
+ v := version.APIVersion[version.Libpod][version.MinimalAPI]
+ header.Add("API-Version",
+ fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch))
+
params, err := options.ToParams()
if err != nil {
return "", err
@@ -192,18 +202,18 @@ func Push(ctx context.Context, name, destination string, options *images.PushOpt
var response *bindings.APIResponse
if bindings.ServiceVersion(ctx).GTE(semver.MustParse("4.0.0")) {
- response, err = conn.DoRequest(ctx, nil, http.MethodPost, "/manifests/%s/registry/%s", params, nil, name, destination)
+ response, err = conn.DoRequest(ctx, nil, http.MethodPost, "/manifests/%s/registry/%s", params, header, name, destination)
} else {
params.Set("image", name)
params.Set("destination", destination)
- response, err = conn.DoRequest(ctx, nil, http.MethodPost, "/manifests/%s/push", params, nil, name)
+ response, err = conn.DoRequest(ctx, nil, http.MethodPost, "/manifests/%s/push", params, header, name)
}
if err != nil {
return "", err
}
defer response.Body.Close()
- return idr.ID, err
+ return idr.ID, response.Process(&idr)
}
// Modify modifies the given manifest list using options and the optional list of images
@@ -223,14 +233,58 @@ func Modify(ctx context.Context, name string, images []string, options *ModifyOp
}
reader := strings.NewReader(opts)
- response, err := conn.DoRequest(ctx, reader, http.MethodPut, "/manifests/%s", nil, nil, name)
+ header, err := auth.MakeXRegistryAuthHeader(&imageTypes.SystemContext{AuthFilePath: options.GetAuthfile()}, options.GetUsername(), options.GetPassword())
+ if err != nil {
+ return "", err
+ }
+
+ params, err := options.ToParams()
+ if err != nil {
+ return "", err
+ }
+ // SkipTLSVerify is special. We need to delete the param added by
+ // ToParams() and change the key and flip the bool
+ if options.SkipTLSVerify != nil {
+ params.Del("SkipTLSVerify")
+ params.Set("tlsVerify", strconv.FormatBool(!options.GetSkipTLSVerify()))
+ }
+
+ response, err := conn.DoRequest(ctx, reader, http.MethodPut, "/manifests/%s", params, header, name)
if err != nil {
return "", err
}
defer response.Body.Close()
- var idr handlers.IDResponse
- return idr.ID, response.Process(&idr)
+ data, err := ioutil.ReadAll(response.Body)
+ if err != nil {
+ return "", errors.Wrap(err, "unable to process API response")
+ }
+
+ if response.IsSuccess() || response.IsRedirection() {
+ var report entities.ManifestModifyReport
+ if err = jsoniter.Unmarshal(data, &report); err != nil {
+ return "", errors.Wrap(err, "unable to decode API response")
+ }
+
+ err = errorhandling.JoinErrors(report.Errors)
+ if err != nil {
+ errModel := errorhandling.ErrorModel{
+ Because: (errors.Cause(err)).Error(),
+ Message: err.Error(),
+ ResponseCode: response.StatusCode,
+ }
+ return report.ID, &errModel
+ }
+ return report.ID, nil
+ }
+
+ errModel := errorhandling.ErrorModel{
+ ResponseCode: response.StatusCode,
+ }
+ if err = jsoniter.Unmarshal(data, &errModel); err != nil {
+ return "", errors.Wrap(err, "unable to decode API response")
+ }
+ return "", &errModel
}
// Annotate modifies the given manifest list using options and the optional list of images