Skip to content

Commit

Permalink
Resolves containers#13629 Add RegistryAuthHeader to manifest push
Browse files Browse the repository at this point in the history
Signed-off-by: Jason Montleon <jmontleo@redhat.com>
  • Loading branch information
jason committed Jul 13, 2022
1 parent e2b64b8 commit fb676a1
Show file tree
Hide file tree
Showing 8 changed files with 297 additions and 37 deletions.
2 changes: 2 additions & 0 deletions contrib/cirrus/setup_environment.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ do
fi
done

cp hack/podman-registry /bin

# Make sure cni network plugins directory exists
mkdir -p /etc/cni/net.d

Expand Down
44 changes: 42 additions & 2 deletions pkg/api/handlers/libpod/manifests.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,35 @@ func ManifestAdd(w http.ResponseWriter, r *http.Request) {
// Wrapper to support 3.x with 4.x libpod
query := struct {
entities.ManifestAddOptions
Images []string
Images []string
TLSVerify bool `schema:"tlsVerify"`
}{}
if err := json.NewDecoder(r.Body).Decode(&query); err != nil {
utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, "Decode()"))
return
}

authconf, authfile, err := auth.GetCredentials(r)
if err != nil {
utils.Error(w, http.StatusBadRequest, err)
return
}
defer auth.RemoveAuthfile(authfile)
var username, password string
if authconf != nil {
username = authconf.Username
password = authconf.Password
}
query.ManifestAddOptions.Authfile = authfile
query.ManifestAddOptions.Username = username
query.ManifestAddOptions.Password = password
if sys := runtime.SystemContext(); sys != nil {
query.ManifestAddOptions.CertDir = sys.DockerCertPath
}
if _, found := r.URL.Query()["tlsVerify"]; found {
query.SkipTLSVerify = types.NewOptionalBool(!query.TLSVerify)
}

name := utils.GetName(r)
if _, err := runtime.LibimageRuntime().LookupManifestList(name); err != nil {
utils.Error(w, http.StatusNotFound, err)
Expand Down Expand Up @@ -271,7 +293,7 @@ func ManifestPushV3(w http.ResponseWriter, r *http.Request) {
utils.Error(w, http.StatusBadRequest, errors.Wrapf(err, "error pushing image %q", query.Destination))
return
}
utils.WriteResponse(w, http.StatusOK, digest)
utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: digest})
}

// ManifestPush push image to registry
Expand Down Expand Up @@ -350,6 +372,24 @@ func ManifestModify(w http.ResponseWriter, r *http.Request) {
return
}

authconf, authfile, err := auth.GetCredentials(r)
if err != nil {
utils.Error(w, http.StatusBadRequest, err)
return
}
defer auth.RemoveAuthfile(authfile)
var username, password string
if authconf != nil {
username = authconf.Username
password = authconf.Password
}
body.ManifestAddOptions.Authfile = authfile
body.ManifestAddOptions.Username = username
body.ManifestAddOptions.Password = password
if sys := runtime.SystemContext(); sys != nil {
body.ManifestAddOptions.CertDir = sys.DockerCertPath
}

var report entities.ManifestModifyReport
switch {
case strings.EqualFold("update", body.Operation):
Expand Down
78 changes: 62 additions & 16 deletions pkg/bindings/manifests/manifests.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import (

"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"
Expand Down Expand Up @@ -95,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)
Expand All @@ -120,11 +126,27 @@ func Add(ctx context.Context, name string, options *AddOptions) (string, error)
}
reader := strings.NewReader(opts)

headers := make(http.Header)
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()))
}

v := version.APIVersion[version.Libpod][version.MinimalAPI]
headers.Add("API-Version",
header.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)

response, err := conn.DoRequest(ctx, reader, http.MethodPost, "/manifests/%s/add", params, header, name)
if err != nil {
return "", err
}
Expand Down Expand Up @@ -159,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
Expand All @@ -172,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
Expand All @@ -203,7 +233,23 @@ 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
}
Expand Down
45 changes: 26 additions & 19 deletions pkg/bindings/manifests/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,18 @@ type ExistsOptions struct {
//go:generate go run ../generator/generator.go AddOptions
// AddOptions are optional options for adding manifest lists
type AddOptions struct {
All *bool
Annotation map[string]string
Arch *string
Features []string
Images []string
OS *string
OSVersion *string
Variant *string
All *bool
Annotation map[string]string
Arch *string
Features []string
Images []string
OS *string
OSVersion *string
Variant *string
Authfile *string
Password *string
Username *string
SkipTLSVerify *bool
}

//go:generate go run ../generator/generator.go RemoveOptions
Expand All @@ -40,15 +44,18 @@ type RemoveOptions struct {
type ModifyOptions struct {
// Operation values are "update", "remove" and "annotate". This allows the service to
// efficiently perform each update on a manifest list.
Operation *string
All *bool // All when true, operate on all images in a manifest list that may be included in Images
Annotations map[string]string // Annotations to add to manifest list
Arch *string // Arch overrides the architecture for the image
Features []string // Feature list for the image
Images []string // Images is an optional list of images to add/remove to/from manifest list depending on operation
OS *string // OS overrides the operating system for the image
OSFeatures []string // OS features for the image
OSVersion *string // OSVersion overrides the operating system for the image
Variant *string // Variant overrides the operating system variant for the image

Operation *string
All *bool // All when true, operate on all images in a manifest list that may be included in Images
Annotations map[string]string // Annotations to add to manifest list
Arch *string // Arch overrides the architecture for the image
Features []string // Feature list for the image
Images []string // Images is an optional list of images to add/remove to/from manifest list depending on operation
OS *string // OS overrides the operating system for the image
OSFeatures []string // OS features for the image
OSVersion *string // OSVersion overrides the operating system for the image
Variant *string // Variant overrides the operating system variant for the image
Authfile *string
Password *string
Username *string
SkipTLSVerify *bool
}
60 changes: 60 additions & 0 deletions pkg/bindings/manifests/types_add_options.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 60 additions & 0 deletions pkg/bindings/manifests/types_modify_options.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit fb676a1

Please sign in to comment.