diff options
author | Aditya R <arajan@redhat.com> | 2022-02-22 22:10:34 +0530 |
---|---|---|
committer | Aditya R <arajan@redhat.com> | 2022-02-23 17:38:28 +0530 |
commit | fbbcb957c710ab817c969a8dc3ff3c46619604e2 (patch) | |
tree | 33971ff9377ee3cbf455ebe4c915722d3c3438bc | |
parent | 0cfb5d7e75507783e463e0df645e873e5a77bbfa (diff) | |
download | podman-fbbcb957c710ab817c969a8dc3ff3c46619604e2.tar.gz podman-fbbcb957c710ab817c969a8dc3ff3c46619604e2.tar.bz2 podman-fbbcb957c710ab817c969a8dc3ff3c46619604e2.zip |
container-commit: support --squash to squash layers into one
Allow users to commit containers into a single layer.
Usage
```bash
podman container commit --squash <name>
```
Signed-off-by: Aditya R <arajan@redhat.com>
-rw-r--r-- | cmd/podman/containers/commit.go | 1 | ||||
-rw-r--r-- | docs/source/markdown/podman-commit.1.md | 5 | ||||
-rw-r--r-- | libpod/container_commit.go | 2 | ||||
-rw-r--r-- | pkg/api/handlers/compat/images.go | 2 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/images.go | 2 | ||||
-rw-r--r-- | pkg/api/server/register_images.go | 4 | ||||
-rw-r--r-- | pkg/bindings/containers/types.go | 1 | ||||
-rw-r--r-- | pkg/bindings/containers/types_commit_options.go | 15 | ||||
-rw-r--r-- | pkg/domain/entities/containers.go | 1 | ||||
-rw-r--r-- | pkg/domain/infra/abi/containers.go | 1 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/containers.go | 2 | ||||
-rw-r--r-- | test/e2e/commit_test.go | 18 |
12 files changed, 53 insertions, 1 deletions
diff --git a/cmd/podman/containers/commit.go b/cmd/podman/containers/commit.go index f74fd4ab1..e0cadd5b0 100644 --- a/cmd/podman/containers/commit.go +++ b/cmd/podman/containers/commit.go @@ -77,6 +77,7 @@ func commitFlags(cmd *cobra.Command) { flags.BoolVarP(&commitOptions.Pause, "pause", "p", false, "Pause container during commit") flags.BoolVarP(&commitOptions.Quiet, "quiet", "q", false, "Suppress output") + flags.BoolVarP(&commitOptions.Squash, "squash", "s", false, "squash newly built layers into a single new layer") flags.BoolVar(&commitOptions.IncludeVolumes, "include-volumes", false, "Include container volumes as image volumes") } diff --git a/docs/source/markdown/podman-commit.1.md b/docs/source/markdown/podman-commit.1.md index 87b7e8aea..df3c38711 100644 --- a/docs/source/markdown/podman-commit.1.md +++ b/docs/source/markdown/podman-commit.1.md @@ -60,6 +60,11 @@ Set commit message for committed image.\ Pause the container when creating an image.\ The default is **false**. +#### **--squash**, **-s** + +Squash newly built layers into a single new layer.\ +The default is **false**. + #### **--quiet**, **-q** Suppresses output.\ diff --git a/libpod/container_commit.go b/libpod/container_commit.go index 99d08ccf1..7018ee7d8 100644 --- a/libpod/container_commit.go +++ b/libpod/container_commit.go @@ -27,6 +27,7 @@ type ContainerCommitOptions struct { Author string Message string Changes []string + Squash bool } // Commit commits the changes between a container and its image, creating a new @@ -63,6 +64,7 @@ func (c *Container) Commit(ctx context.Context, destImage string, options Contai commitOptions := buildah.CommitOptions{ SignaturePolicyPath: options.SignaturePolicyPath, ReportWriter: options.ReportWriter, + Squash: options.Squash, SystemContext: c.runtime.imageContext, PreferredManifestType: options.PreferredManifestType, } diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go index 3546f88a0..edefce010 100644 --- a/pkg/api/handlers/compat/images.go +++ b/pkg/api/handlers/compat/images.go @@ -102,6 +102,7 @@ func CommitContainer(w http.ResponseWriter, r *http.Request) { Comment string `schema:"comment"` Container string `schema:"container"` Pause bool `schema:"pause"` + Squash bool `schema:"squash"` Repo string `schema:"repo"` Tag string `schema:"tag"` // fromSrc string # fromSrc is currently unused @@ -138,6 +139,7 @@ func CommitContainer(w http.ResponseWriter, r *http.Request) { options.Message = query.Comment options.Author = query.Author options.Pause = query.Pause + options.Squash = query.Squash for _, change := range query.Changes { options.Changes = append(options.Changes, strings.Split(change, "\n")...) } diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go index f078c13cc..eb9fb12a6 100644 --- a/pkg/api/handlers/libpod/images.go +++ b/pkg/api/handlers/libpod/images.go @@ -497,6 +497,7 @@ func CommitContainer(w http.ResponseWriter, r *http.Request) { Container string `schema:"container"` Format string `schema:"format"` Pause bool `schema:"pause"` + Squash bool `schema:"squash"` Repo string `schema:"repo"` Tag string `schema:"tag"` }{ @@ -543,6 +544,7 @@ func CommitContainer(w http.ResponseWriter, r *http.Request) { options.Message = query.Comment options.Author = query.Author options.Pause = query.Pause + options.Squash = query.Squash options.Changes = query.Changes ctr, err := runtime.LookupContainer(query.Container) if err != nil { diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go index d7bc17093..017310f12 100644 --- a/pkg/api/server/register_images.go +++ b/pkg/api/server/register_images.go @@ -460,6 +460,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // name: changes // type: string // description: instructions to apply while committing in Dockerfile format + // - in: query + // name: squash + // type: boolean + // description: squash newly built layers into a single new layer // produces: // - application/json // responses: diff --git a/pkg/bindings/containers/types.go b/pkg/bindings/containers/types.go index 4915e3e23..66b90af9b 100644 --- a/pkg/bindings/containers/types.go +++ b/pkg/bindings/containers/types.go @@ -30,6 +30,7 @@ type CommitOptions struct { Comment *string Format *string Pause *bool + Squash *bool Repo *string Tag *string } diff --git a/pkg/bindings/containers/types_commit_options.go b/pkg/bindings/containers/types_commit_options.go index 7eb04198f..7b4745eb8 100644 --- a/pkg/bindings/containers/types_commit_options.go +++ b/pkg/bindings/containers/types_commit_options.go @@ -92,6 +92,21 @@ func (o *CommitOptions) GetPause() bool { return *o.Pause } +// WithSquash set field Squash to given value +func (o *CommitOptions) WithSquash(value bool) *CommitOptions { + o.Squash = &value + return o +} + +// GetSquash returns value of field Squash +func (o *CommitOptions) GetSquash() bool { + if o.Squash == nil { + var z bool + return z + } + return *o.Squash +} + // WithRepo set field Repo to given value func (o *CommitOptions) WithRepo(value string) *CommitOptions { o.Repo = &value diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go index d39a70732..9f37c24c5 100644 --- a/pkg/domain/entities/containers.go +++ b/pkg/domain/entities/containers.go @@ -154,6 +154,7 @@ type CommitOptions struct { Message string Pause bool Quiet bool + Squash bool Writer io.Writer } diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index a5c4647d7..f79e1a5e0 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -528,6 +528,7 @@ func (ic *ContainerEngine) ContainerCommit(ctx context.Context, nameOrID string, Message: options.Message, Changes: options.Changes, Author: options.Author, + Squash: options.Squash, } newImage, err := ctr.Commit(ctx, options.ImageName, opts) if err != nil { diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index 67e709486..6348a5281 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -302,7 +302,7 @@ func (ic *ContainerEngine) ContainerCommit(ctx context.Context, nameOrID string, return nil, errors.Errorf("invalid image name %q", opts.ImageName) } } - options := new(containers.CommitOptions).WithAuthor(opts.Author).WithChanges(opts.Changes).WithComment(opts.Message) + options := new(containers.CommitOptions).WithAuthor(opts.Author).WithChanges(opts.Changes).WithComment(opts.Message).WithSquash(opts.Squash) options.WithFormat(opts.Format).WithPause(opts.Pause).WithRepo(repo).WithTag(tag) response, err := containers.Commit(ic.ClientCtx, nameOrID, options) if err != nil { diff --git a/test/e2e/commit_test.go b/test/e2e/commit_test.go index 495e31520..6bcf17bfe 100644 --- a/test/e2e/commit_test.go +++ b/test/e2e/commit_test.go @@ -4,6 +4,7 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" . "github.com/containers/podman/v4/test/utils" . "github.com/onsi/ginkgo" @@ -133,6 +134,23 @@ var _ = Describe("Podman commit", func() { Expect(foundBlue).To(Equal(true)) }) + It("podman commit container with --squash", func() { + test := podmanTest.Podman([]string{"run", "--name", "test1", "-d", ALPINE, "ls"}) + test.WaitWithDefaultTimeout() + Expect(test).Should(Exit(0)) + Expect(podmanTest.NumberOfContainers()).To(Equal(1)) + + session := podmanTest.Podman([]string{"commit", "--squash", "test1", "foobar.com/test1-image:latest"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"inspect", "--format", "{{.RootFS.Layers}}", "foobar.com/test1-image:latest"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + // Check for one layers + Expect(strings.Fields(session.OutputToString())).To(HaveLen(1)) + }) + It("podman commit container with change flag and JSON entrypoint with =", func() { test := podmanTest.Podman([]string{"run", "--name", "test1", "-d", ALPINE, "ls"}) test.WaitWithDefaultTimeout() |