From 74a63df0539ce1488353f03c7cb100ee4bbc7e73 Mon Sep 17 00:00:00 2001 From: Daniel J Walsh Date: Fri, 22 Jan 2021 10:52:18 -0500 Subject: Fixup search podman-remote search had some FIXMEs in tests that were failing. So I reworked the search handler to use the local abi. This means the podman search and podman-remote search will use the same functions. While doing this, I noticed we were just outputing errors via logrus.Error rather then returning them, which works ok for podman but the messages get lost on podman-remote. Changed the code to actually return the error messages to the caller. This allows us to turn on the remaining podman-remote FIXME tests. Signed-off-by: Daniel J Walsh --- pkg/api/handlers/compat/images_search.go | 84 ++++++++++++------------------- pkg/api/handlers/libpod/images.go | 86 -------------------------------- 2 files changed, 31 insertions(+), 139 deletions(-) (limited to 'pkg/api/handlers') diff --git a/pkg/api/handlers/compat/images_search.go b/pkg/api/handlers/compat/images_search.go index 6808cdad5..885112b31 100644 --- a/pkg/api/handlers/compat/images_search.go +++ b/pkg/api/handlers/compat/images_search.go @@ -1,25 +1,30 @@ package compat import ( + "fmt" "net/http" - "strconv" "github.com/containers/image/v5/types" - "github.com/containers/podman/v2/libpod/image" + "github.com/containers/podman/v2/libpod" + "github.com/containers/podman/v2/libpod/define" "github.com/containers/podman/v2/pkg/api/handlers/utils" "github.com/containers/podman/v2/pkg/auth" - "github.com/docker/docker/api/types/registry" + "github.com/containers/podman/v2/pkg/domain/entities" + "github.com/containers/podman/v2/pkg/domain/infra/abi" "github.com/gorilla/schema" "github.com/pkg/errors" ) func SearchImages(w http.ResponseWriter, r *http.Request) { + runtime := r.Context().Value("runtime").(*libpod.Runtime) decoder := r.Context().Value("decoder").(*schema.Decoder) query := struct { Term string `json:"term"` Limit int `json:"limit"` + NoTrunc bool `json:"noTrunc"` Filters map[string][]string `json:"filters"` TLSVerify bool `json:"tlsVerify"` + ListTags bool `json:"listTags"` }{ // This is where you can override the golang default value for one of fields } @@ -29,67 +34,40 @@ func SearchImages(w http.ResponseWriter, r *http.Request) { return } - filter := image.SearchFilter{} - if len(query.Filters) > 0 { - if len(query.Filters["stars"]) > 0 { - stars, err := strconv.Atoi(query.Filters["stars"][0]) - if err != nil { - utils.InternalServerError(w, err) - return - } - filter.Stars = stars - } - if len(query.Filters["is-official"]) > 0 { - isOfficial, err := strconv.ParseBool(query.Filters["is-official"][0]) - if err != nil { - utils.InternalServerError(w, err) - return - } - filter.IsOfficial = types.NewOptionalBool(isOfficial) - } - if len(query.Filters["is-automated"]) > 0 { - isAutomated, err := strconv.ParseBool(query.Filters["is-automated"][0]) - if err != nil { - utils.InternalServerError(w, err) - return - } - filter.IsAutomated = types.NewOptionalBool(isAutomated) - } - } - options := image.SearchOptions{ - Filter: filter, - Limit: query.Limit, - } - - if _, found := r.URL.Query()["tlsVerify"]; found { - options.InsecureSkipTLSVerify = types.NewOptionalBool(!query.TLSVerify) - } - _, authfile, key, err := auth.GetCredentials(r) if err != nil { utils.Error(w, "failed to retrieve repository credentials", http.StatusBadRequest, errors.Wrapf(err, "failed to parse %q header for %s", key, r.URL.String())) return } defer auth.RemoveAuthfile(authfile) - options.Authfile = authfile - results, err := image.SearchImages(query.Term, options) + filters := []string{} + for key, val := range query.Filters { + filters = append(filters, fmt.Sprintf("%s=%s", key, val[0])) + } + + options := entities.ImageSearchOptions{ + Authfile: authfile, + Limit: query.Limit, + NoTrunc: query.NoTrunc, + ListTags: query.ListTags, + Filters: filters, + } + if _, found := r.URL.Query()["tlsVerify"]; found { + options.SkipTLSVerify = types.NewOptionalBool(!query.TLSVerify) + } + ir := abi.ImageEngine{Libpod: runtime} + reports, err := ir.Search(r.Context(), query.Term, options) if err != nil { - utils.BadRequest(w, "term", query.Term, err) + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err) return } - - compatResults := make([]registry.SearchResult, 0, len(results)) - for _, result := range results { - compatResult := registry.SearchResult{ - Name: result.Name, - Description: result.Description, - StarCount: result.Stars, - IsAutomated: result.Automated == "[OK]", - IsOfficial: result.Official == "[OK]", + if !utils.IsLibpodRequest(r) { + if len(reports) == 0 { + utils.ImageNotFound(w, query.Term, define.ErrNoSuchImage) + return } - compatResults = append(compatResults, compatResult) } - utils.WriteResponse(w, http.StatusOK, compatResults) + utils.WriteResponse(w, http.StatusOK, reports) } diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go index 97cd5a65e..3b531652f 100644 --- a/pkg/api/handlers/libpod/images.go +++ b/pkg/api/handlers/libpod/images.go @@ -589,92 +589,6 @@ func UntagImage(w http.ResponseWriter, r *http.Request) { utils.WriteResponse(w, http.StatusCreated, "") } -func SearchImages(w http.ResponseWriter, r *http.Request) { - decoder := r.Context().Value("decoder").(*schema.Decoder) - query := struct { - Term string `json:"term"` - Limit int `json:"limit"` - NoTrunc bool `json:"noTrunc"` - Filters map[string][]string `json:"filters"` - TLSVerify bool `json:"tlsVerify"` - ListTags bool `json:"listTags"` - }{ - // This is where you can override the golang default value for one of fields - } - - if err := decoder.Decode(&query, r.URL.Query()); err != nil { - utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) - return - } - - filter := image.SearchFilter{} - if len(query.Filters) > 0 { - if len(query.Filters["stars"]) > 0 { - stars, err := strconv.Atoi(query.Filters["stars"][0]) - if err != nil { - utils.InternalServerError(w, err) - return - } - filter.Stars = stars - } - if len(query.Filters["is-official"]) > 0 { - isOfficial, err := strconv.ParseBool(query.Filters["is-official"][0]) - if err != nil { - utils.InternalServerError(w, err) - return - } - filter.IsOfficial = types.NewOptionalBool(isOfficial) - } - if len(query.Filters["is-automated"]) > 0 { - isAutomated, err := strconv.ParseBool(query.Filters["is-automated"][0]) - if err != nil { - utils.InternalServerError(w, err) - return - } - filter.IsAutomated = types.NewOptionalBool(isAutomated) - } - } - options := image.SearchOptions{ - Limit: query.Limit, - NoTrunc: query.NoTrunc, - ListTags: query.ListTags, - Filter: filter, - } - - if _, found := r.URL.Query()["tlsVerify"]; found { - options.InsecureSkipTLSVerify = types.NewOptionalBool(!query.TLSVerify) - } - - _, authfile, key, err := auth.GetCredentials(r) - if err != nil { - utils.Error(w, "failed to retrieve repository credentials", http.StatusBadRequest, errors.Wrapf(err, "failed to parse %q header for %s", key, r.URL.String())) - return - } - defer auth.RemoveAuthfile(authfile) - options.Authfile = authfile - - searchResults, err := image.SearchImages(query.Term, options) - if err != nil { - utils.BadRequest(w, "term", query.Term, err) - return - } - // Convert from image.SearchResults to entities.ImageSearchReport. We don't - // want to leak any low-level packages into the remote client, which - // requires converting. - reports := make([]entities.ImageSearchReport, len(searchResults)) - for i := range searchResults { - reports[i].Index = searchResults[i].Index - reports[i].Name = searchResults[i].Name - reports[i].Description = searchResults[i].Description - reports[i].Stars = searchResults[i].Stars - reports[i].Official = searchResults[i].Official - reports[i].Automated = searchResults[i].Automated - reports[i].Tag = searchResults[i].Tag - } - - utils.WriteResponse(w, http.StatusOK, reports) -} - // ImagesBatchRemove is the endpoint for batch image removal. func ImagesBatchRemove(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value("runtime").(*libpod.Runtime) -- cgit v1.2.3-54-g00ecf