From 24a599fe1d8f7f9da23cf3056c4eda8bcc89e563 Mon Sep 17 00:00:00 2001
From: Romain Geissler <romain.geissler@amadeus.com>
Date: Sat, 30 Jul 2022 12:50:57 +0000
Subject: Add flag "--compression-format" to "podman manifest push" both in
 local/remote mode.

Also Fix usage of flag "--compression-format" for remote "podman image push". Fix usage of flags "--format", "--remove-signatures" in remote "podman manifest push".
Closes #15109.

Signed-off-by: Romain Geissler <romain.geissler@amadeus.com>
---
 pkg/api/handlers/libpod/images_push.go    | 28 +++++++++++++++-------------
 pkg/api/handlers/libpod/manifests.go      | 18 ++++++++++++------
 pkg/bindings/images/types.go              |  2 ++
 pkg/bindings/images/types_push_options.go | 15 +++++++++++++++
 pkg/domain/infra/abi/manifest.go          | 17 +++++++++++++++++
 pkg/domain/infra/tunnel/images.go         |  2 +-
 pkg/domain/infra/tunnel/manifest.go       |  3 +--
 7 files changed, 63 insertions(+), 22 deletions(-)

(limited to 'pkg')

diff --git a/pkg/api/handlers/libpod/images_push.go b/pkg/api/handlers/libpod/images_push.go
index 9ee651f5b..e931fd2f9 100644
--- a/pkg/api/handlers/libpod/images_push.go
+++ b/pkg/api/handlers/libpod/images_push.go
@@ -25,12 +25,13 @@ func PushImage(w http.ResponseWriter, r *http.Request) {
 	runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
 
 	query := struct {
-		All              bool   `schema:"all"`
-		Destination      string `schema:"destination"`
-		Format           string `schema:"format"`
-		RemoveSignatures bool   `schema:"removeSignatures"`
-		TLSVerify        bool   `schema:"tlsVerify"`
-		Quiet            bool   `schema:"quiet"`
+		All               bool   `schema:"all"`
+		CompressionFormat string `schema:"compressionFormat"`
+		Destination       string `schema:"destination"`
+		Format            string `schema:"format"`
+		RemoveSignatures  bool   `schema:"removeSignatures"`
+		TLSVerify         bool   `schema:"tlsVerify"`
+		Quiet             bool   `schema:"quiet"`
 	}{
 		TLSVerify: true,
 		// #14971: older versions did not sent *any* data, so we need
@@ -71,13 +72,14 @@ func PushImage(w http.ResponseWriter, r *http.Request) {
 		password = authconf.Password
 	}
 	options := entities.ImagePushOptions{
-		All:              query.All,
-		Authfile:         authfile,
-		Format:           query.Format,
-		Password:         password,
-		Quiet:            true,
-		RemoveSignatures: query.RemoveSignatures,
-		Username:         username,
+		All:               query.All,
+		Authfile:          authfile,
+		CompressionFormat: query.CompressionFormat,
+		Format:            query.Format,
+		Password:          password,
+		Quiet:             true,
+		RemoveSignatures:  query.RemoveSignatures,
+		Username:          username,
 	}
 
 	if _, found := r.URL.Query()["tlsVerify"]; found {
diff --git a/pkg/api/handlers/libpod/manifests.go b/pkg/api/handlers/libpod/manifests.go
index 43c7139d3..2d6223e4e 100644
--- a/pkg/api/handlers/libpod/manifests.go
+++ b/pkg/api/handlers/libpod/manifests.go
@@ -306,8 +306,11 @@ func ManifestPush(w http.ResponseWriter, r *http.Request) {
 	decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
 
 	query := struct {
-		All       bool `schema:"all"`
-		TLSVerify bool `schema:"tlsVerify"`
+		All               bool   `schema:"all"`
+		CompressionFormat string `schema:"compressionFormat"`
+		Format            string `schema:"format"`
+		RemoveSignatures  bool   `schema:"removeSignatures"`
+		TLSVerify         bool   `schema:"tlsVerify"`
 	}{
 		// Add defaults here once needed.
 		TLSVerify: true,
@@ -336,10 +339,13 @@ func ManifestPush(w http.ResponseWriter, r *http.Request) {
 		password = authconf.Password
 	}
 	options := entities.ImagePushOptions{
-		Authfile: authfile,
-		Username: username,
-		Password: password,
-		All:      query.All,
+		All:               query.All,
+		Authfile:          authfile,
+		CompressionFormat: query.CompressionFormat,
+		Format:            query.Format,
+		Password:          password,
+		RemoveSignatures:  query.RemoveSignatures,
+		Username:          username,
 	}
 	if sys := runtime.SystemContext(); sys != nil {
 		options.CertDir = sys.DockerCertPath
diff --git a/pkg/bindings/images/types.go b/pkg/bindings/images/types.go
index 0e672cdea..0664afc1b 100644
--- a/pkg/bindings/images/types.go
+++ b/pkg/bindings/images/types.go
@@ -123,6 +123,8 @@ type PushOptions struct {
 	Authfile *string
 	// Compress tarball image layers when pushing to a directory using the 'dir' transport.
 	Compress *bool
+	// CompressionFormat is the format to use for the compression of the blobs
+	CompressionFormat *string
 	// Manifest type of the pushed image
 	Format *string
 	// Password for authenticating against the registry.
diff --git a/pkg/bindings/images/types_push_options.go b/pkg/bindings/images/types_push_options.go
index 63a19fb81..1ae031824 100644
--- a/pkg/bindings/images/types_push_options.go
+++ b/pkg/bindings/images/types_push_options.go
@@ -62,6 +62,21 @@ func (o *PushOptions) GetCompress() bool {
 	return *o.Compress
 }
 
+// WithCompressionFormat set field CompressionFormat to given value
+func (o *PushOptions) WithCompressionFormat(value string) *PushOptions {
+	o.CompressionFormat = &value
+	return o
+}
+
+// GetCompressionFormat returns value of field CompressionFormat
+func (o *PushOptions) GetCompressionFormat() string {
+	if o.CompressionFormat == nil {
+		var z string
+		return z
+	}
+	return *o.CompressionFormat
+}
+
 // WithFormat set field Format to given value
 func (o *PushOptions) WithFormat(value string) *PushOptions {
 	o.Format = &value
diff --git a/pkg/domain/infra/abi/manifest.go b/pkg/domain/infra/abi/manifest.go
index bdc3d9513..b135b05ba 100644
--- a/pkg/domain/infra/abi/manifest.go
+++ b/pkg/domain/infra/abi/manifest.go
@@ -13,6 +13,7 @@ import (
 	"github.com/containers/common/libimage"
 	cp "github.com/containers/image/v5/copy"
 	"github.com/containers/image/v5/manifest"
+	"github.com/containers/image/v5/pkg/compression"
 	"github.com/containers/image/v5/pkg/shortnames"
 	"github.com/containers/image/v5/transports"
 	"github.com/containers/image/v5/transports/alltransports"
@@ -318,6 +319,22 @@ func (ir *ImageEngine) ManifestPush(ctx context.Context, name, destination strin
 	pushOptions.SignBy = opts.SignBy
 	pushOptions.InsecureSkipTLSVerify = opts.SkipTLSVerify
 
+	compressionFormat := opts.CompressionFormat
+	if compressionFormat == "" {
+		config, err := ir.Libpod.GetConfigNoCopy()
+		if err != nil {
+			return "", err
+		}
+		compressionFormat = config.Engine.CompressionFormat
+	}
+	if compressionFormat != "" {
+		algo, err := compression.AlgorithmByName(compressionFormat)
+		if err != nil {
+			return "", err
+		}
+		pushOptions.CompressionFormat = &algo
+	}
+
 	if opts.All {
 		pushOptions.ImageListSelection = cp.CopyAllImages
 	}
diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go
index 9ad408850..4f79325fd 100644
--- a/pkg/domain/infra/tunnel/images.go
+++ b/pkg/domain/infra/tunnel/images.go
@@ -240,7 +240,7 @@ func (ir *ImageEngine) Import(ctx context.Context, opts entities.ImageImportOpti
 
 func (ir *ImageEngine) Push(ctx context.Context, source string, destination string, opts entities.ImagePushOptions) error {
 	options := new(images.PushOptions)
-	options.WithAll(opts.All).WithCompress(opts.Compress).WithUsername(opts.Username).WithPassword(opts.Password).WithAuthfile(opts.Authfile).WithFormat(opts.Format).WithRemoveSignatures(opts.RemoveSignatures).WithQuiet(opts.Quiet)
+	options.WithAll(opts.All).WithCompress(opts.Compress).WithUsername(opts.Username).WithPassword(opts.Password).WithAuthfile(opts.Authfile).WithFormat(opts.Format).WithRemoveSignatures(opts.RemoveSignatures).WithQuiet(opts.Quiet).WithCompressionFormat(opts.CompressionFormat)
 
 	if s := opts.SkipTLSVerify; s != types.OptionalBoolUndefined {
 		if s == types.OptionalBoolTrue {
diff --git a/pkg/domain/infra/tunnel/manifest.go b/pkg/domain/infra/tunnel/manifest.go
index 4a3148fac..00ecb3b59 100644
--- a/pkg/domain/infra/tunnel/manifest.go
+++ b/pkg/domain/infra/tunnel/manifest.go
@@ -99,8 +99,7 @@ func (ir *ImageEngine) ManifestRm(ctx context.Context, names []string) (*entitie
 // ManifestPush pushes a manifest list or image index to the destination
 func (ir *ImageEngine) ManifestPush(ctx context.Context, name, destination string, opts entities.ImagePushOptions) (string, error) {
 	options := new(images.PushOptions)
-	options.WithUsername(opts.Username).WithPassword(opts.Password).WithAuthfile(opts.Authfile).WithRemoveSignatures(opts.RemoveSignatures)
-	options.WithAll(opts.All)
+	options.WithUsername(opts.Username).WithPassword(opts.Password).WithAuthfile(opts.Authfile).WithRemoveSignatures(opts.RemoveSignatures).WithAll(opts.All).WithFormat(opts.Format).WithCompressionFormat(opts.CompressionFormat)
 
 	if s := opts.SkipTLSVerify; s != types.OptionalBoolUndefined {
 		if s == types.OptionalBoolTrue {
-- 
cgit v1.2.3-54-g00ecf