diff options
author | Sascha Grunert <sgrunert@suse.com> | 2020-02-05 12:07:44 +0100 |
---|---|---|
committer | Sascha Grunert <sgrunert@suse.com> | 2020-02-17 11:12:35 +0100 |
commit | 93358ef915f639e52088b0f6aec52e77d3da0af7 (patch) | |
tree | 797e7b98b6efe2b0bdb74e93146b53c798367308 /pkg | |
parent | ff0f8388138f7b66c4312db0e984f0bedcac2558 (diff) | |
download | podman-93358ef915f639e52088b0f6aec52e77d3da0af7.tar.gz podman-93358ef915f639e52088b0f6aec52e77d3da0af7.tar.bz2 podman-93358ef915f639e52088b0f6aec52e77d3da0af7.zip |
Refactor image tree for API usage
Signed-off-by: Sascha Grunert <sgrunert@suse.com>
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/adapter/images.go | 33 | ||||
-rw-r--r-- | pkg/adapter/images_remote.go | 31 | ||||
-rw-r--r-- | pkg/adapter/runtime.go | 9 | ||||
-rw-r--r-- | pkg/adapter/runtime_remote.go | 4 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/images.go | 41 | ||||
-rw-r--r-- | pkg/api/handlers/swagger.go | 9 | ||||
-rw-r--r-- | pkg/api/server/register_images.go | 25 | ||||
-rw-r--r-- | pkg/varlinkapi/images.go | 14 |
8 files changed, 90 insertions, 76 deletions
diff --git a/pkg/adapter/images.go b/pkg/adapter/images.go deleted file mode 100644 index 762f1a656..000000000 --- a/pkg/adapter/images.go +++ /dev/null @@ -1,33 +0,0 @@ -// +build !remoteclient - -package adapter - -import ( - "github.com/containers/libpod/libpod/image" - "github.com/pkg/errors" -) - -// Tree ... -func (r *LocalRuntime) Tree(imageOrID string) (*image.InfoImage, map[string]*image.LayerInfo, *ContainerImage, error) { - img, err := r.NewImageFromLocal(imageOrID) - if err != nil { - return nil, nil, nil, err - } - - // Fetch map of image-layers, which is used for printing output. - layerInfoMap, err := image.GetLayersMapWithImageInfo(r.Runtime.ImageRuntime()) - if err != nil { - return nil, nil, nil, errors.Wrapf(err, "error while retrieving layers of image %q", img.InputName) - } - - // Create an imageInfo and fill the image and layer info - imageInfo := &image.InfoImage{ - ID: img.ID(), - Tags: img.Names(), - } - - if err := image.BuildImageHierarchyMap(imageInfo, layerInfoMap, img.TopLayer()); err != nil { - return nil, nil, nil, err - } - return imageInfo, layerInfoMap, img, nil -} diff --git a/pkg/adapter/images_remote.go b/pkg/adapter/images_remote.go index 1d4997d9a..e7b38dccc 100644 --- a/pkg/adapter/images_remote.go +++ b/pkg/adapter/images_remote.go @@ -7,9 +7,7 @@ import ( "encoding/json" iopodman "github.com/containers/libpod/cmd/podman/varlink" - "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/inspect" - "github.com/pkg/errors" ) // Inspect returns returns an ImageData struct from over a varlink connection @@ -24,32 +22,3 @@ func (i *ContainerImage) Inspect(ctx context.Context) (*inspect.ImageData, error } return &data, nil } - -// Tree ... -func (r *LocalRuntime) Tree(imageOrID string) (*image.InfoImage, map[string]*image.LayerInfo, *ContainerImage, error) { - layerInfoMap := make(map[string]*image.LayerInfo) - imageInfo := &image.InfoImage{} - - img, err := r.NewImageFromLocal(imageOrID) - if err != nil { - return nil, nil, nil, err - } - - reply, err := iopodman.GetLayersMapWithImageInfo().Call(r.Conn) - if err != nil { - return nil, nil, nil, errors.Wrap(err, "failed to obtain image layers") - } - if err := json.Unmarshal([]byte(reply), &layerInfoMap); err != nil { - return nil, nil, nil, errors.Wrap(err, "failed to unmarshal image layers") - } - - reply, err = iopodman.BuildImageHierarchyMap().Call(r.Conn, imageOrID) - if err != nil { - return nil, nil, nil, errors.Wrap(err, "failed to get build image map") - } - if err := json.Unmarshal([]byte(reply), imageInfo); err != nil { - return nil, nil, nil, errors.Wrap(err, "failed to unmarshal build image map") - } - - return imageInfo, layerInfoMap, img, nil -} diff --git a/pkg/adapter/runtime.go b/pkg/adapter/runtime.go index 40089797d..dfe6b7f07 100644 --- a/pkg/adapter/runtime.go +++ b/pkg/adapter/runtime.go @@ -133,6 +133,15 @@ func (r *LocalRuntime) NewImageFromLocal(name string) (*ContainerImage, error) { return &ContainerImage{img}, nil } +// ImageTree reutnrs an new image.Tree for the provided `imageOrID` and `whatrequires` flag +func (r *LocalRuntime) ImageTree(imageOrID string, whatRequires bool) (string, error) { + img, err := r.Runtime.ImageRuntime().NewFromLocal(imageOrID) + if err != nil { + return "", err + } + return img.GenerateTree(whatRequires) +} + // LoadFromArchiveReference calls into local storage to load an image from an archive func (r *LocalRuntime) LoadFromArchiveReference(ctx context.Context, srcRef types.ImageReference, signaturePolicyPath string, writer io.Writer) ([]*ContainerImage, error) { var containerImages []*ContainerImage diff --git a/pkg/adapter/runtime_remote.go b/pkg/adapter/runtime_remote.go index c908358ff..220d4cf75 100644 --- a/pkg/adapter/runtime_remote.go +++ b/pkg/adapter/runtime_remote.go @@ -344,6 +344,10 @@ func (r *LocalRuntime) New(ctx context.Context, name, signaturePolicyPath, authf return newImage, nil } +func (r *LocalRuntime) ImageTree(imageOrID string, whatRequires bool) (string, error) { + return iopodman.ImageTree().Call(r.Conn, imageOrID, whatRequires) +} + // IsParent goes through the layers in the store and checks if i.TopLayer is // the parent of any other layer in store. Double check that image with that // layer exists as well. diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go index bcbe4977e..eac0e4dad 100644 --- a/pkg/api/handlers/libpod/images.go +++ b/pkg/api/handlers/libpod/images.go @@ -46,17 +46,34 @@ func ImageExists(w http.ResponseWriter, r *http.Request) { } func ImageTree(w http.ResponseWriter, r *http.Request) { - // tree is a bit of a mess ... logic is in adapter and therefore not callable from here. needs rework - - // name := utils.GetName(r) - // _, layerInfoMap, _, err := s.Runtime.Tree(name) - // if err != nil { - // Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "Failed to find image information for %q", name)) - // return - // } - // it is not clear to me how to deal with this given all the processing of the image - // is in main. we need to discuss how that really should be and return something useful. - handlers.UnsupportedHandler(w, r) + runtime := r.Context().Value("runtime").(*libpod.Runtime) + name := utils.GetName(r) + + img, err := runtime.ImageRuntime().NewFromLocal(name) + if err != nil { + utils.Error(w, "Something went wrong.", http.StatusNotFound, errors.Wrapf(err, "Failed to find image %s", name)) + return + } + + decoder := r.Context().Value("decoder").(*schema.Decoder) + query := struct { + WhatRequires bool `schema:"whatrequires"` + }{ + WhatRequires: false, + } + if err := decoder.Decode(&query, r.URL.Query()); err != nil { + utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, + errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) + return + } + + tree, err := img.GenerateTree(query.WhatRequires) + if err != nil { + utils.Error(w, "Server error", http.StatusInternalServerError, errors.Wrapf(err, "failed to generate image tree for %s", name)) + return + } + + utils.WriteResponse(w, http.StatusOK, tree) } func GetImage(w http.ResponseWriter, r *http.Request) { @@ -72,8 +89,8 @@ func GetImage(w http.ResponseWriter, r *http.Request) { return } utils.WriteResponse(w, http.StatusOK, inspect) - } + func GetImages(w http.ResponseWriter, r *http.Request) { images, err := utils.GetImages(w, r) if err != nil { diff --git a/pkg/api/handlers/swagger.go b/pkg/api/handlers/swagger.go index 10525bfc7..4ba123ba9 100644 --- a/pkg/api/handlers/swagger.go +++ b/pkg/api/handlers/swagger.go @@ -136,3 +136,12 @@ type swagInspectVolumeResponse struct { libpod.InspectVolumeData } } + +// Image tree response +// swagger:response LibpodImageTreeResponse +type swagImageTreeResponse struct { + // in:body + Body struct { + ImageTreeResponse + } +} diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go index f082c5fec..4706a7c69 100644 --- a/pkg/api/server/register_images.go +++ b/pkg/api/server/register_images.go @@ -578,6 +578,31 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // 500: // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/libpod/images/{name}/exists"), APIHandler(s.Context, libpod.ImageExists)) + // swagger:operation POST /libpod/images/{name}/tree libpod libpodImageTree + // --- + // tags: + // - images + // summary: Image tree + // description: Retrieve the image tree for the provided image name or ID + // parameters: + // - in: path + // name: name + // type: string + // required: true + // description: the name or ID of the container + // - in: query + // name: whatrequires + // type: boolean + // description: show all child images and layers of the specified image + // produces: + // - application/json + // responses: + // 200: + // $ref: '#/responses/LibpodImageTreeResponse' + // 401: + // $ref: '#/responses/NoSuchImage' + // 500: + // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/libpod/images/{name}/tree"), APIHandler(s.Context, libpod.ImageTree)) // swagger:operation GET /libpod/images/{name}/history libpod libpodImageHistory // --- diff --git a/pkg/varlinkapi/images.go b/pkg/varlinkapi/images.go index b144bfa5e..c4809f16b 100644 --- a/pkg/varlinkapi/images.go +++ b/pkg/varlinkapi/images.go @@ -1016,3 +1016,17 @@ func (i *LibpodAPI) BuildImageHierarchyMap(call iopodman.VarlinkCall, name strin } return call.ReplyBuildImageHierarchyMap(string(b)) } + +// ImageTree returns the image tree string for the provided image name or ID +func (i *LibpodAPI) ImageTree(call iopodman.VarlinkCall, nameOrID string, whatRequires bool) error { + img, err := i.Runtime.ImageRuntime().NewFromLocal(nameOrID) + if err != nil { + return call.ReplyErrorOccurred(err.Error()) + } + + tree, err := img.GenerateTree(whatRequires) + if err != nil { + return call.ReplyErrorOccurred(err.Error()) + } + return call.ReplyImageTree(tree) +} |