Merge pull request from flouthoc/api-image-lookup-manifest

api,images: add support for `LookupManifest` to `Image removal` REST API
This commit is contained in:
openshift-ci[bot]
2022-06-30 13:54:02 +00:00
committed by GitHub
6 changed files with 59 additions and 8 deletions
pkg
api
handlers/libpod
server
bindings/images
domain/infra/tunnel
test/e2e

@ -615,10 +615,11 @@ func ImagesBatchRemove(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
query := struct { query := struct {
All bool `schema:"all"` All bool `schema:"all"`
Force bool `schema:"force"` Force bool `schema:"force"`
Ignore bool `schema:"ignore"` Ignore bool `schema:"ignore"`
Images []string `schema:"images"` LookupManifest bool `schema:"lookupManifest"`
Images []string `schema:"images"`
}{} }{}
if err := decoder.Decode(&query, r.URL.Query()); err != nil { if err := decoder.Decode(&query, r.URL.Query()); err != nil {
@ -626,7 +627,7 @@ func ImagesBatchRemove(w http.ResponseWriter, r *http.Request) {
return return
} }
opts := entities.ImageRemoveOptions{All: query.All, Force: query.Force, Ignore: query.Ignore} opts := entities.ImageRemoveOptions{All: query.All, Force: query.Force, Ignore: query.Ignore, LookupManifest: query.LookupManifest}
imageEngine := abi.ImageEngine{Libpod: runtime} imageEngine := abi.ImageEngine{Libpod: runtime}
rmReport, rmErrors := imageEngine.Remove(r.Context(), query.Images, opts) rmReport, rmErrors := imageEngine.Remove(r.Context(), query.Images, opts)
strErrs := errorhandling.ErrorsToStrings(rmErrors) strErrs := errorhandling.ErrorsToStrings(rmErrors)
@ -639,7 +640,8 @@ func ImagesRemove(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
query := struct { query := struct {
Force bool `schema:"force"` Force bool `schema:"force"`
LookupManifest bool `schema:"lookupManifest"`
}{ }{
Force: false, Force: false,
} }
@ -649,7 +651,7 @@ func ImagesRemove(w http.ResponseWriter, r *http.Request) {
return return
} }
opts := entities.ImageRemoveOptions{Force: query.Force} opts := entities.ImageRemoveOptions{Force: query.Force, LookupManifest: query.LookupManifest}
imageEngine := abi.ImageEngine{Libpod: runtime} imageEngine := abi.ImageEngine{Libpod: runtime}
rmReport, rmErrors := imageEngine.Remove(r.Context(), []string{utils.GetName(r)}, opts) rmReport, rmErrors := imageEngine.Remove(r.Context(), []string{utils.GetName(r)}, opts)

@ -948,6 +948,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// name: ignore // name: ignore
// description: Ignore if a specified image does not exist and do not throw an error. // description: Ignore if a specified image does not exist and do not throw an error.
// type: boolean // type: boolean
// - in: query
// name: lookupManifest
// description: Resolves to manifest list instead of image.
// type: boolean
// produces: // produces:
// - application/json // - application/json
// responses: // responses:

@ -13,6 +13,8 @@ type RemoveOptions struct {
Force *bool Force *bool
// Ignore if a specified image does not exist and do not throw an error. // Ignore if a specified image does not exist and do not throw an error.
Ignore *bool Ignore *bool
// Confirms if given name is a manifest list and removes it, otherwise returns error.
LookupManifest *bool
} }
//go:generate go run ../generator/generator.go DiffOptions //go:generate go run ../generator/generator.go DiffOptions

@ -61,3 +61,18 @@ func (o *RemoveOptions) GetIgnore() bool {
} }
return *o.Ignore return *o.Ignore
} }
// WithLookupManifest set field LookupManifest to given value
func (o *RemoveOptions) WithLookupManifest(value bool) *RemoveOptions {
o.LookupManifest = &value
return o
}
// GetLookupManifest returns value of field LookupManifest
func (o *RemoveOptions) GetLookupManifest() bool {
if o.LookupManifest == nil {
var z bool
return z
}
return *o.LookupManifest
}

@ -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) { 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) options := new(images.RemoveOptions).WithForce(opts.Force).WithIgnore(opts.Ignore).WithAll(opts.All).WithLookupManifest(opts.LookupManifest)
return images.Remove(ir.ClientCtx, imagesArg, options) return images.Remove(ir.ClientCtx, imagesArg, options)
} }

@ -405,4 +405,32 @@ var _ = Describe("Podman manifest", func() {
session.WaitWithDefaultTimeout() session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0)) Expect(session).Should(Exit(0))
}) })
It("manifest rm should not remove image and should be able to remove tagged manifest list", func() {
// manifest rm should fail with `image is not a manifest list`
session := podmanTest.Podman([]string{"manifest", "rm", ALPINE})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(125))
Expect(session.ErrorToString()).To(ContainSubstring("image is not a manifest list"))
manifestName := "testmanifest:sometag"
session = podmanTest.Podman([]string{"manifest", "create", manifestName})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
// verify if manifest exists
session = podmanTest.Podman([]string{"manifest", "exists", manifestName})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
// manifest rm should be able to remove tagged manifest list
session = podmanTest.Podman([]string{"manifest", "rm", manifestName})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
// verify that manifest should not exist
session = podmanTest.Podman([]string{"manifest", "exists", manifestName})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(1))
})
}) })