Skip to content

Commit

Permalink
Merge pull request #15093 from karthikelango137/rmiNoPrune1
Browse files Browse the repository at this point in the history
remove image podman no prune
  • Loading branch information
openshift-ci[bot] authored Aug 5, 2022
2 parents ff144e0 + cc8e4d5 commit 66c246d
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 3 deletions.
1 change: 1 addition & 0 deletions cmd/podman/images/rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ func imageRemoveFlagSet(flags *pflag.FlagSet) {
flags.BoolVarP(&imageOpts.All, "all", "a", false, "Remove all images")
flags.BoolVarP(&imageOpts.Ignore, "ignore", "i", false, "Ignore errors if a specified image does not exist")
flags.BoolVarP(&imageOpts.Force, "force", "f", false, "Force Removal of the image")
flags.BoolVar(&imageOpts.NoPrune, "no-prune", false, "Do not remove dangling images")
}

func rm(cmd *cobra.Command, args []string) error {
Expand Down
3 changes: 3 additions & 0 deletions docs/source/markdown/podman-rmi.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ This option will cause podman to remove all containers that are using the image

If a specified image does not exist in the local storage, ignore it and do not throw an error.

#### **--no-prune**

This options will not remove dangling parents of specified image

Remove an image by its short ID
```
Expand Down
3 changes: 2 additions & 1 deletion pkg/api/handlers/libpod/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -547,14 +547,15 @@ func ImagesBatchRemove(w http.ResponseWriter, r *http.Request) {
Ignore bool `schema:"ignore"`
LookupManifest bool `schema:"lookupManifest"`
Images []string `schema:"images"`
NoPrune bool `schema:"noprune"`
}{}

if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusBadRequest, fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err))
return
}

opts := entities.ImageRemoveOptions{All: query.All, Force: query.Force, Ignore: query.Ignore, LookupManifest: query.LookupManifest}
opts := entities.ImageRemoveOptions{All: query.All, Force: query.Force, Ignore: query.Ignore, LookupManifest: query.LookupManifest, NoPrune: query.NoPrune}
imageEngine := abi.ImageEngine{Libpod: runtime}
rmReport, rmErrors := imageEngine.Remove(r.Context(), query.Images, opts)
strErrs := errorhandling.ErrorsToStrings(rmErrors)
Expand Down
2 changes: 2 additions & 0 deletions pkg/bindings/images/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ type RemoveOptions struct {
Ignore *bool
// Confirms if given name is a manifest list and removes it, otherwise returns error.
LookupManifest *bool
// Does not remove dangling parent images
NoPrune *bool
}

//go:generate go run ../generator/generator.go DiffOptions
Expand Down
15 changes: 15 additions & 0 deletions pkg/bindings/images/types_remove_options.go

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

2 changes: 2 additions & 0 deletions pkg/domain/entities/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ type ImageRemoveOptions struct {
Ignore bool
// Confirms if given name is a manifest list and removes it, otherwise returns error.
LookupManifest bool
// NoPrune will not remove dangling images
NoPrune bool
}

// ImageRemoveReport is the response for removing one or more image(s) from storage
Expand Down
3 changes: 2 additions & 1 deletion pkg/domain/infra/abi/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,7 @@ func (ir *ImageEngine) Remove(ctx context.Context, images []string, opts entitie
libimageOptions.Force = opts.Force
libimageOptions.Ignore = opts.Ignore
libimageOptions.LookupManifest = opts.LookupManifest
libimageOptions.NoPrune = opts.NoPrune
if !opts.All {
libimageOptions.Filters = append(libimageOptions.Filters, "intermediate=false")
}
Expand All @@ -581,7 +582,7 @@ func (ir *ImageEngine) Remove(ctx context.Context, images []string, opts entitie

rmErrors = libimageErrors

return
return report, rmErrors
}

// Shutdown Libpod engine
Expand Down
2 changes: 1 addition & 1 deletion pkg/domain/infra/tunnel/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func (ir *ImageEngine) Exists(_ context.Context, nameOrID string) (*entities.Boo
}

func (ir *ImageEngine) Remove(ctx context.Context, imagesArg []string, opts entities.ImageRemoveOptions) (*entities.ImageRemoveReport, []error) {
options := new(images.RemoveOptions).WithForce(opts.Force).WithIgnore(opts.Ignore).WithAll(opts.All).WithLookupManifest(opts.LookupManifest)
options := new(images.RemoveOptions).WithForce(opts.Force).WithIgnore(opts.Ignore).WithAll(opts.All).WithLookupManifest(opts.LookupManifest).WithNoPrune(opts.NoPrune)
return images.Remove(ir.ClientCtx, imagesArg, options)
}

Expand Down
78 changes: 78 additions & 0 deletions test/e2e/rmi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,4 +307,82 @@ RUN touch %s`, CIRROS_IMAGE, imageName)
}
wg.Wait()
})

It("podman rmi --no-prune with dangling parents", func() {
podmanTest.AddImageToRWStore(ALPINE)
session := podmanTest.Podman([]string{"create", "--name", "c_test1", ALPINE, "true"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))

session = podmanTest.Podman([]string{"commit", "-q", "c_test1", "test1"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))

session = podmanTest.Podman([]string{"create", "--name", "c_test2", "test1", "true"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))

session = podmanTest.Podman([]string{"commit", "-q", "c_test2", "test2"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
imageID2 := session.OutputToString()

session = podmanTest.Podman([]string{"create", "--name", "c_test3", "test2", "true"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))

session = podmanTest.Podman([]string{"commit", "-q", "c_test3", "test3"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
imageID3 := session.OutputToString()

session = podmanTest.Podman([]string{"untag", "test2"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))

session = podmanTest.Podman([]string{"untag", "test1"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))

session = podmanTest.Podman([]string{"rmi", "-f", "--no-prune", "test3"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
Expect(session.OutputToString()).To(ContainSubstring(imageID3))
Expect(session.OutputToString()).NotTo(ContainSubstring(imageID2))
})

It("podman rmi --no-prune with undangling parents", func() {
podmanTest.AddImageToRWStore(ALPINE)
session := podmanTest.Podman([]string{"create", "--name", "c_test1", ALPINE, "true"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))

session = podmanTest.Podman([]string{"commit", "-q", "c_test1", "test1"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))

session = podmanTest.Podman([]string{"create", "--name", "c_test2", "test1", "true"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))

session = podmanTest.Podman([]string{"commit", "-q", "c_test2", "test2"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
imageID2 := session.OutputToString()

session = podmanTest.Podman([]string{"create", "--name", "c_test3", "test2", "true"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))

session = podmanTest.Podman([]string{"commit", "-q", "c_test3", "test3"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
imageID3 := session.OutputToString()

session = podmanTest.Podman([]string{"rmi", "-f", "--no-prune", "test3"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
Expect(session.OutputToString()).To(ContainSubstring(imageID3))
Expect(session.OutputToString()).NotTo(ContainSubstring(imageID2))
})
})

0 comments on commit 66c246d

Please sign in to comment.