From 6673ff78d3c5bba1078d9862fccadf0b7fe556fa Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Tue, 30 Nov 2021 14:00:10 +0100 Subject: podman, push: expose --compression-format support overriding the compression format at push time. Signed-off-by: Giuseppe Scrivano --- cmd/podman/common/completion.go | 6 ++++++ cmd/podman/images/push.go | 4 ++++ docs/source/markdown/podman-push.1.md | 4 ++++ pkg/domain/entities/images.go | 2 ++ pkg/domain/infra/abi/images.go | 9 +++++++++ test/e2e/push_test.go | 32 ++++++++++++++++++++++++++++++++ 6 files changed, 57 insertions(+) diff --git a/cmd/podman/common/completion.go b/cmd/podman/common/completion.go index 4cb29383a..cb3efe592 100644 --- a/cmd/podman/common/completion.go +++ b/cmd/podman/common/completion.go @@ -1289,3 +1289,9 @@ func AutocompleteCheckpointCompressType(cmd *cobra.Command, args []string, toCom types := []string{"gzip", "none", "zstd"} return types, cobra.ShellCompDirectiveNoFileComp } + +// AutocompleteCompressionFormat - Autocomplete compression-format type options. +func AutocompleteCompressionFormat(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + types := []string{"gzip", "zstd", "zstd:chunked"} + return types, cobra.ShellCompDirectiveNoFileComp +} diff --git a/cmd/podman/images/push.go b/cmd/podman/images/push.go index cf787a71f..37ace3ffe 100644 --- a/cmd/podman/images/push.go +++ b/cmd/podman/images/push.go @@ -108,6 +108,10 @@ func pushFlags(cmd *cobra.Command) { flags.BoolVar(&pushOptions.TLSVerifyCLI, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries") + compressionFormat := "compression-format" + flags.StringVar(&pushOptions.CompressionFormat, compressionFormat, "", "compression format to use") + _ = cmd.RegisterFlagCompletionFunc(compressionFormat, common.AutocompleteCompressionFormat) + if registry.IsRemote() { _ = flags.MarkHidden("cert-dir") _ = flags.MarkHidden("compress") diff --git a/docs/source/markdown/podman-push.1.md b/docs/source/markdown/podman-push.1.md index 55f294158..19c64a7e3 100644 --- a/docs/source/markdown/podman-push.1.md +++ b/docs/source/markdown/podman-push.1.md @@ -71,6 +71,10 @@ Please refer to containers-certs.d(5) for details. (This option is not available Compress tarball image layers when pushing to a directory using the 'dir' transport. (default is same compression type, compressed or uncompressed, as source) Note: This flag can only be set when using the **dir** transport +#### **--compression-format** *COMPRESSION* + +Specifies the compression format to use. Supported values are: `gzip`, `zstd` and `zstd:chunked`. The default is `gzip`. + #### **--digestfile** *Digestfile* After copying the image, write the digest of the resulting image to the file. (This option is not available with the remote Podman client) diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go index 54f7b5d45..8b0fd2b85 100644 --- a/pkg/domain/entities/images.go +++ b/pkg/domain/entities/images.go @@ -208,6 +208,8 @@ type ImagePushOptions struct { SkipTLSVerify types.OptionalBool // Progress to get progress notifications Progress chan types.ProgressProperties + // CompressionFormat is the format to use for the compression of the blobs + CompressionFormat string } // ImageSearchOptions are the arguments for searching images. diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go index 8b44b869a..7a3451a7d 100644 --- a/pkg/domain/infra/abi/images.go +++ b/pkg/domain/infra/abi/images.go @@ -18,6 +18,7 @@ import ( "github.com/containers/image/v5/docker" "github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/manifest" + "github.com/containers/image/v5/pkg/compression" "github.com/containers/image/v5/signature" "github.com/containers/image/v5/transports" "github.com/containers/image/v5/transports/alltransports" @@ -305,6 +306,14 @@ func (ir *ImageEngine) Push(ctx context.Context, source string, destination stri pushOptions.SignBy = options.SignBy pushOptions.InsecureSkipTLSVerify = options.SkipTLSVerify + if options.CompressionFormat != "" { + algo, err := compression.AlgorithmByName(options.CompressionFormat) + if err != nil { + return err + } + pushOptions.CompressionFormat = &algo + } + if !options.Quiet { pushOptions.Writer = os.Stderr } diff --git a/test/e2e/push_test.go b/test/e2e/push_test.go index 7038a09e8..a3b5e31bb 100644 --- a/test/e2e/push_test.go +++ b/test/e2e/push_test.go @@ -2,12 +2,14 @@ package integration import ( "fmt" + "io/ioutil" "os" "path/filepath" "strings" "github.com/containers/podman/v3/pkg/rootless" . "github.com/containers/podman/v3/test/utils" + "github.com/containers/storage/pkg/archive" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" . "github.com/onsi/gomega/gexec" @@ -63,6 +65,36 @@ var _ = Describe("Podman push", func() { Expect(session).Should(Exit(0)) }) + It("podman push to oci with compression-format", func() { + SkipIfRemote("Remote push does not support dir transport") + bbdir := filepath.Join(podmanTest.TempDir, "busybox-oci") + session := podmanTest.Podman([]string{"push", "--compression-format=zstd", "--remove-signatures", ALPINE, + fmt.Sprintf("oci:%s", bbdir)}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + foundZstdFile := false + + blobsDir := filepath.Join(bbdir, "blobs/sha256") + + blobs, err := ioutil.ReadDir(blobsDir) + Expect(err).To(BeNil()) + + for _, f := range blobs { + blobPath := filepath.Join(blobsDir, f.Name()) + + sourceFile, err := ioutil.ReadFile(blobPath) + Expect(err).To(BeNil()) + + compressionType := archive.DetectCompression(sourceFile) + if compressionType == archive.Zstd { + foundZstdFile = true + break + } + } + Expect(foundZstdFile).To(BeTrue()) + }) + It("podman push to local registry", func() { SkipIfRemote("Remote does not support --digestfile or --remove-signatures") if podmanTest.Host.Arch == "ppc64le" { -- cgit v1.2.3-54-g00ecf