mirror of https://github.com/containers/podman.git
Resolves #13629 Add RegistryAuthHeader to manifest push
Signed-off-by: Jason Montleon <jmontleo@redhat.com>
This commit is contained in:
parent
a416fd6de4
commit
3cc1739373
|
@ -36,6 +36,8 @@ do
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
cp hack/podman-registry /bin
|
||||||
|
|
||||||
# Make sure cni network plugins directory exists
|
# Make sure cni network plugins directory exists
|
||||||
mkdir -p /etc/cni/net.d
|
mkdir -p /etc/cni/net.d
|
||||||
|
|
||||||
|
|
|
@ -162,13 +162,35 @@ func ManifestAdd(w http.ResponseWriter, r *http.Request) {
|
||||||
// Wrapper to support 3.x with 4.x libpod
|
// Wrapper to support 3.x with 4.x libpod
|
||||||
query := struct {
|
query := struct {
|
||||||
entities.ManifestAddOptions
|
entities.ManifestAddOptions
|
||||||
Images []string
|
Images []string
|
||||||
|
TLSVerify bool `schema:"tlsVerify"`
|
||||||
}{}
|
}{}
|
||||||
if err := json.NewDecoder(r.Body).Decode(&query); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&query); err != nil {
|
||||||
utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, "Decode()"))
|
utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, "Decode()"))
|
||||||
return
|
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)
|
name := utils.GetName(r)
|
||||||
if _, err := runtime.LibimageRuntime().LookupManifestList(name); err != nil {
|
if _, err := runtime.LibimageRuntime().LookupManifestList(name); err != nil {
|
||||||
utils.Error(w, http.StatusNotFound, err)
|
utils.Error(w, http.StatusNotFound, err)
|
||||||
|
@ -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))
|
utils.Error(w, http.StatusBadRequest, errors.Wrapf(err, "error pushing image %q", query.Destination))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
utils.WriteResponse(w, http.StatusOK, digest)
|
utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: digest})
|
||||||
}
|
}
|
||||||
|
|
||||||
// ManifestPush push image to registry
|
// ManifestPush push image to registry
|
||||||
|
@ -350,6 +372,24 @@ func ManifestModify(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
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
|
var report entities.ManifestModifyReport
|
||||||
switch {
|
switch {
|
||||||
case strings.EqualFold("update", body.Operation):
|
case strings.EqualFold("update", body.Operation):
|
||||||
|
|
|
@ -11,7 +11,9 @@ import (
|
||||||
|
|
||||||
"github.com/blang/semver"
|
"github.com/blang/semver"
|
||||||
"github.com/containers/image/v5/manifest"
|
"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/api/handlers"
|
||||||
|
"github.com/containers/podman/v4/pkg/auth"
|
||||||
"github.com/containers/podman/v4/pkg/bindings"
|
"github.com/containers/podman/v4/pkg/bindings"
|
||||||
"github.com/containers/podman/v4/pkg/bindings/images"
|
"github.com/containers/podman/v4/pkg/bindings/images"
|
||||||
"github.com/containers/podman/v4/version"
|
"github.com/containers/podman/v4/version"
|
||||||
|
@ -93,15 +95,19 @@ func Add(ctx context.Context, name string, options *AddOptions) (string, error)
|
||||||
|
|
||||||
if bindings.ServiceVersion(ctx).GTE(semver.MustParse("4.0.0")) {
|
if bindings.ServiceVersion(ctx).GTE(semver.MustParse("4.0.0")) {
|
||||||
optionsv4 := ModifyOptions{
|
optionsv4 := ModifyOptions{
|
||||||
All: options.All,
|
All: options.All,
|
||||||
Annotations: options.Annotation,
|
Annotations: options.Annotation,
|
||||||
Arch: options.Arch,
|
Arch: options.Arch,
|
||||||
Features: options.Features,
|
Features: options.Features,
|
||||||
Images: options.Images,
|
Images: options.Images,
|
||||||
OS: options.OS,
|
OS: options.OS,
|
||||||
OSFeatures: nil,
|
OSFeatures: nil,
|
||||||
OSVersion: options.OSVersion,
|
OSVersion: options.OSVersion,
|
||||||
Variant: options.Variant,
|
Variant: options.Variant,
|
||||||
|
Username: options.Username,
|
||||||
|
Password: options.Password,
|
||||||
|
Authfile: options.Authfile,
|
||||||
|
SkipTLSVerify: options.SkipTLSVerify,
|
||||||
}
|
}
|
||||||
optionsv4.WithOperation("update")
|
optionsv4.WithOperation("update")
|
||||||
return Modify(ctx, name, options.Images, &optionsv4)
|
return Modify(ctx, name, options.Images, &optionsv4)
|
||||||
|
@ -118,11 +124,27 @@ func Add(ctx context.Context, name string, options *AddOptions) (string, error)
|
||||||
}
|
}
|
||||||
reader := strings.NewReader(opts)
|
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]
|
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))
|
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 {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -179,6 +201,14 @@ func Push(ctx context.Context, name, destination string, options *images.PushOpt
|
||||||
return "", err
|
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()
|
params, err := options.ToParams()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -192,18 +222,18 @@ func Push(ctx context.Context, name, destination string, options *images.PushOpt
|
||||||
|
|
||||||
var response *bindings.APIResponse
|
var response *bindings.APIResponse
|
||||||
if bindings.ServiceVersion(ctx).GTE(semver.MustParse("4.0.0")) {
|
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 {
|
} else {
|
||||||
params.Set("image", name)
|
params.Set("image", name)
|
||||||
params.Set("destination", destination)
|
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 {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
defer response.Body.Close()
|
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
|
// Modify modifies the given manifest list using options and the optional list of images
|
||||||
|
@ -223,7 +253,23 @@ func Modify(ctx context.Context, name string, images []string, options *ModifyOp
|
||||||
}
|
}
|
||||||
reader := strings.NewReader(opts)
|
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 {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,14 +20,18 @@ type ExistsOptions struct {
|
||||||
//go:generate go run ../generator/generator.go AddOptions
|
//go:generate go run ../generator/generator.go AddOptions
|
||||||
// AddOptions are optional options for adding manifest lists
|
// AddOptions are optional options for adding manifest lists
|
||||||
type AddOptions struct {
|
type AddOptions struct {
|
||||||
All *bool
|
All *bool
|
||||||
Annotation map[string]string
|
Annotation map[string]string
|
||||||
Arch *string
|
Arch *string
|
||||||
Features []string
|
Features []string
|
||||||
Images []string
|
Images []string
|
||||||
OS *string
|
OS *string
|
||||||
OSVersion *string
|
OSVersion *string
|
||||||
Variant *string
|
Variant *string
|
||||||
|
Authfile *string
|
||||||
|
Password *string
|
||||||
|
Username *string
|
||||||
|
SkipTLSVerify *bool
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:generate go run ../generator/generator.go RemoveOptions
|
//go:generate go run ../generator/generator.go RemoveOptions
|
||||||
|
@ -40,15 +44,18 @@ type RemoveOptions struct {
|
||||||
type ModifyOptions struct {
|
type ModifyOptions struct {
|
||||||
// Operation values are "update", "remove" and "annotate". This allows the service to
|
// Operation values are "update", "remove" and "annotate". This allows the service to
|
||||||
// efficiently perform each update on a manifest list.
|
// efficiently perform each update on a manifest list.
|
||||||
Operation *string
|
Operation *string
|
||||||
All *bool // All when true, operate on all images in a manifest list that may be included in Images
|
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
|
Annotations map[string]string // Annotations to add to manifest list
|
||||||
Arch *string // Arch overrides the architecture for the image
|
Arch *string // Arch overrides the architecture for the image
|
||||||
Features []string // Feature list 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
|
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
|
OS *string // OS overrides the operating system for the image
|
||||||
OSFeatures []string // OS features for the image
|
OSFeatures []string // OS features for the image
|
||||||
OSVersion *string // OSVersion overrides the operating system for the image
|
OSVersion *string // OSVersion overrides the operating system for the image
|
||||||
Variant *string // Variant overrides the operating system variant for the image
|
Variant *string // Variant overrides the operating system variant for the image
|
||||||
|
Authfile *string
|
||||||
|
Password *string
|
||||||
|
Username *string
|
||||||
|
SkipTLSVerify *bool
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,3 +136,63 @@ func (o *AddOptions) GetVariant() string {
|
||||||
}
|
}
|
||||||
return *o.Variant
|
return *o.Variant
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithAuthfile set field Authfile to given value
|
||||||
|
func (o *AddOptions) WithAuthfile(value string) *AddOptions {
|
||||||
|
o.Authfile = &value
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAuthfile returns value of field Authfile
|
||||||
|
func (o *AddOptions) GetAuthfile() string {
|
||||||
|
if o.Authfile == nil {
|
||||||
|
var z string
|
||||||
|
return z
|
||||||
|
}
|
||||||
|
return *o.Authfile
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPassword set field Password to given value
|
||||||
|
func (o *AddOptions) WithPassword(value string) *AddOptions {
|
||||||
|
o.Password = &value
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPassword returns value of field Password
|
||||||
|
func (o *AddOptions) GetPassword() string {
|
||||||
|
if o.Password == nil {
|
||||||
|
var z string
|
||||||
|
return z
|
||||||
|
}
|
||||||
|
return *o.Password
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithUsername set field Username to given value
|
||||||
|
func (o *AddOptions) WithUsername(value string) *AddOptions {
|
||||||
|
o.Username = &value
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUsername returns value of field Username
|
||||||
|
func (o *AddOptions) GetUsername() string {
|
||||||
|
if o.Username == nil {
|
||||||
|
var z string
|
||||||
|
return z
|
||||||
|
}
|
||||||
|
return *o.Username
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithSkipTLSVerify set field SkipTLSVerify to given value
|
||||||
|
func (o *AddOptions) WithSkipTLSVerify(value bool) *AddOptions {
|
||||||
|
o.SkipTLSVerify = &value
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSkipTLSVerify returns value of field SkipTLSVerify
|
||||||
|
func (o *AddOptions) GetSkipTLSVerify() bool {
|
||||||
|
if o.SkipTLSVerify == nil {
|
||||||
|
var z bool
|
||||||
|
return z
|
||||||
|
}
|
||||||
|
return *o.SkipTLSVerify
|
||||||
|
}
|
||||||
|
|
|
@ -166,3 +166,63 @@ func (o *ModifyOptions) GetVariant() string {
|
||||||
}
|
}
|
||||||
return *o.Variant
|
return *o.Variant
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithAuthfile set field Authfile to given value
|
||||||
|
func (o *ModifyOptions) WithAuthfile(value string) *ModifyOptions {
|
||||||
|
o.Authfile = &value
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAuthfile returns value of field Authfile
|
||||||
|
func (o *ModifyOptions) GetAuthfile() string {
|
||||||
|
if o.Authfile == nil {
|
||||||
|
var z string
|
||||||
|
return z
|
||||||
|
}
|
||||||
|
return *o.Authfile
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPassword set field Password to given value
|
||||||
|
func (o *ModifyOptions) WithPassword(value string) *ModifyOptions {
|
||||||
|
o.Password = &value
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPassword returns value of field Password
|
||||||
|
func (o *ModifyOptions) GetPassword() string {
|
||||||
|
if o.Password == nil {
|
||||||
|
var z string
|
||||||
|
return z
|
||||||
|
}
|
||||||
|
return *o.Password
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithUsername set field Username to given value
|
||||||
|
func (o *ModifyOptions) WithUsername(value string) *ModifyOptions {
|
||||||
|
o.Username = &value
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUsername returns value of field Username
|
||||||
|
func (o *ModifyOptions) GetUsername() string {
|
||||||
|
if o.Username == nil {
|
||||||
|
var z string
|
||||||
|
return z
|
||||||
|
}
|
||||||
|
return *o.Username
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithSkipTLSVerify set field SkipTLSVerify to given value
|
||||||
|
func (o *ModifyOptions) WithSkipTLSVerify(value bool) *ModifyOptions {
|
||||||
|
o.SkipTLSVerify = &value
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSkipTLSVerify returns value of field SkipTLSVerify
|
||||||
|
func (o *ModifyOptions) GetSkipTLSVerify() bool {
|
||||||
|
if o.SkipTLSVerify == nil {
|
||||||
|
var z bool
|
||||||
|
return z
|
||||||
|
}
|
||||||
|
return *o.SkipTLSVerify
|
||||||
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ func (ir *ImageEngine) ManifestInspect(_ context.Context, name string) ([]byte,
|
||||||
func (ir *ImageEngine) ManifestAdd(_ context.Context, name string, imageNames []string, opts entities.ManifestAddOptions) (string, error) {
|
func (ir *ImageEngine) ManifestAdd(_ context.Context, name string, imageNames []string, opts entities.ManifestAddOptions) (string, error) {
|
||||||
options := new(manifests.AddOptions).WithAll(opts.All).WithArch(opts.Arch).WithVariant(opts.Variant)
|
options := new(manifests.AddOptions).WithAll(opts.All).WithArch(opts.Arch).WithVariant(opts.Variant)
|
||||||
options.WithFeatures(opts.Features).WithImages(imageNames).WithOS(opts.OS).WithOSVersion(opts.OSVersion)
|
options.WithFeatures(opts.Features).WithImages(imageNames).WithOS(opts.OS).WithOSVersion(opts.OSVersion)
|
||||||
|
options.WithUsername(opts.Username).WithPassword(opts.Password).WithAuthfile(opts.Authfile)
|
||||||
if len(opts.Annotation) != 0 {
|
if len(opts.Annotation) != 0 {
|
||||||
annotations := make(map[string]string)
|
annotations := make(map[string]string)
|
||||||
for _, annotationSpec := range opts.Annotation {
|
for _, annotationSpec := range opts.Annotation {
|
||||||
|
@ -61,6 +62,13 @@ func (ir *ImageEngine) ManifestAdd(_ context.Context, name string, imageNames []
|
||||||
}
|
}
|
||||||
options.WithAnnotation(annotations)
|
options.WithAnnotation(annotations)
|
||||||
}
|
}
|
||||||
|
if s := opts.SkipTLSVerify; s != types.OptionalBoolUndefined {
|
||||||
|
if s == types.OptionalBoolTrue {
|
||||||
|
options.WithSkipTLSVerify(true)
|
||||||
|
} else {
|
||||||
|
options.WithSkipTLSVerify(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
id, err := manifests.Add(ir.ClientCtx, name, options)
|
id, err := manifests.Add(ir.ClientCtx, name, options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
podmanRegistry "github.com/containers/podman/v4/hack/podman-registry-go"
|
||||||
. "github.com/containers/podman/v4/test/utils"
|
. "github.com/containers/podman/v4/test/utils"
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
@ -272,6 +273,42 @@ var _ = Describe("Podman manifest", func() {
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("authenticated push", func() {
|
||||||
|
registry, err := podmanRegistry.Start()
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
|
||||||
|
session := podmanTest.Podman([]string{"manifest", "create", "foo"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session).Should(Exit(0))
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"pull", ALPINE})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session).Should(Exit(0))
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"tag", ALPINE, "localhost:" + registry.Port + "/alpine:latest"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session).Should(Exit(0))
|
||||||
|
|
||||||
|
push := podmanTest.Podman([]string{"push", "--tls-verify=false", "--creds=" + registry.User + ":" + registry.Password, "--format=v2s2", "localhost:" + registry.Port + "/alpine:latest"})
|
||||||
|
push.WaitWithDefaultTimeout()
|
||||||
|
Expect(push).Should(Exit(0))
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"manifest", "add", "--tls-verify=false", "--creds=" + registry.User + ":" + registry.Password, "foo", "localhost:" + registry.Port + "/alpine:latest"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session).Should(Exit(0))
|
||||||
|
|
||||||
|
push = podmanTest.Podman([]string{"manifest", "push", "--tls-verify=false", "--creds=" + registry.User + ":" + registry.Password, "foo", "localhost:" + registry.Port + "/credstest"})
|
||||||
|
push.WaitWithDefaultTimeout()
|
||||||
|
Expect(push).Should(Exit(0))
|
||||||
|
|
||||||
|
push = podmanTest.Podman([]string{"manifest", "push", "--tls-verify=false", "--creds=podmantest:wrongpasswd", "foo", "localhost:" + registry.Port + "/credstest"})
|
||||||
|
push.WaitWithDefaultTimeout()
|
||||||
|
Expect(push).To(ExitWithError())
|
||||||
|
|
||||||
|
err = registry.Stop()
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
})
|
||||||
|
|
||||||
It("push --rm", func() {
|
It("push --rm", func() {
|
||||||
SkipIfRemote("remote does not support --rm")
|
SkipIfRemote("remote does not support --rm")
|
||||||
session := podmanTest.Podman([]string{"manifest", "create", "foo"})
|
session := podmanTest.Podman([]string{"manifest", "create", "foo"})
|
||||||
|
|
Loading…
Reference in New Issue