summaryrefslogtreecommitdiff
path: root/pkg/api/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/api/handlers')
-rw-r--r--pkg/api/handlers/compat/images.go54
-rw-r--r--pkg/api/handlers/libpod/images.go43
-rw-r--r--pkg/api/handlers/libpod/manifests.go265
-rw-r--r--pkg/api/handlers/types.go40
-rw-r--r--pkg/api/handlers/utils/handler.go4
-rw-r--r--pkg/api/handlers/utils/images.go40
6 files changed, 285 insertions, 161 deletions
diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go
index c1cc99da4..f08a7ee41 100644
--- a/pkg/api/handlers/compat/images.go
+++ b/pkg/api/handlers/compat/images.go
@@ -11,6 +11,7 @@ import (
"github.com/containers/buildah"
"github.com/containers/common/libimage"
"github.com/containers/common/pkg/config"
+ "github.com/containers/common/pkg/filters"
"github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/types"
"github.com/containers/podman/v3/libpod"
@@ -404,25 +405,52 @@ func GetImage(w http.ResponseWriter, r *http.Request) {
}
func GetImages(w http.ResponseWriter, r *http.Request) {
- images, err := utils.GetImages(w, r)
- if err != nil {
- utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Failed get images"))
+ decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
+ runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
+ query := struct {
+ All bool
+ Digests bool
+ Filter string // Docker 1.24 compatibility
+ }{
+ // 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, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
+ errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
+ return
+ }
+ if _, found := r.URL.Query()["digests"]; found && query.Digests {
+ utils.UnSupportedParameter("digests")
return
}
- summaries := make([]*entities.ImageSummary, 0, len(images))
- for _, img := range images {
- // If the image is a manifest list, extract as much as we can.
- if isML, _ := img.IsManifestList(r.Context()); isML {
- continue
+ filterList, err := filters.FiltersFromRequest(r)
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
+ return
+ }
+ if !utils.IsLibpodRequest(r) {
+ if len(query.Filter) > 0 { // Docker 1.24 compatibility
+ filterList = append(filterList, "reference="+query.Filter)
}
+ filterList = append(filterList, "manifest=false")
+ }
- is, err := handlers.ImageToImageSummary(img)
- if err != nil {
- utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Failed transform image summaries"))
- return
+ imageEngine := abi.ImageEngine{Libpod: runtime}
+
+ listOptions := entities.ImageListOptions{All: query.All, Filter: filterList}
+ summaries, err := imageEngine.List(r.Context(), listOptions)
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
+ return
+ }
+
+ if !utils.IsLibpodRequest(r) {
+ // docker adds sha256: in front of the ID
+ for _, s := range summaries {
+ s.ID = "sha256:" + s.ID
}
- summaries = append(summaries, is)
}
utils.WriteResponse(w, http.StatusOK, summaries)
}
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index 6e23845f0..d3dbf3023 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -12,7 +12,6 @@ import (
"github.com/containers/buildah"
"github.com/containers/common/libimage"
- "github.com/containers/common/pkg/filters"
"github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/types"
"github.com/containers/podman/v3/libpod"
@@ -103,48 +102,6 @@ func GetImage(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, inspect)
}
-func GetImages(w http.ResponseWriter, r *http.Request) {
- decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
- runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
- query := struct {
- All bool
- Digests bool
- Filter string // Docker 1.24 compatibility
- }{
- // 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, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
- errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
- return
- }
- if _, found := r.URL.Query()["digests"]; found && query.Digests {
- utils.UnSupportedParameter("digests")
- return
- }
-
- filterList, err := filters.FiltersFromRequest(r)
- if err != nil {
- utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
- return
- }
- if !utils.IsLibpodRequest(r) && len(query.Filter) > 0 { // Docker 1.24 compatibility
- filterList = append(filterList, "reference="+query.Filter)
- }
-
- imageEngine := abi.ImageEngine{Libpod: runtime}
-
- listOptions := entities.ImageListOptions{All: query.All, Filter: filterList}
- summaries, err := imageEngine.List(r.Context(), listOptions)
- if err != nil {
- utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
- return
- }
-
- utils.WriteResponse(w, http.StatusOK, summaries)
-}
-
func PruneImages(w http.ResponseWriter, r *http.Request) {
var (
err error
diff --git a/pkg/api/handlers/libpod/manifests.go b/pkg/api/handlers/libpod/manifests.go
index eb0b6827f..ef0839d1f 100644
--- a/pkg/api/handlers/libpod/manifests.go
+++ b/pkg/api/handlers/libpod/manifests.go
@@ -3,7 +3,11 @@ package libpod
import (
"context"
"encoding/json"
+ "fmt"
+ "io/ioutil"
"net/http"
+ "net/url"
+ "strings"
"github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/manifest"
@@ -15,6 +19,8 @@ import (
"github.com/containers/podman/v3/pkg/auth"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/domain/infra/abi"
+ "github.com/containers/podman/v3/pkg/errorhandling"
+ "github.com/gorilla/mux"
"github.com/gorilla/schema"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
@@ -24,40 +30,93 @@ func ManifestCreate(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
query := struct {
- Name []string `schema:"name"`
- Image []string `schema:"image"`
- All bool `schema:"all"`
+ Name string `schema:"name"`
+ Images []string `schema:"images"`
+ All bool `schema:"all"`
}{
// Add defaults here once needed.
}
+
+ // Support 3.x API calls, alias image to images
+ if image, ok := r.URL.Query()["image"]; ok {
+ query.Images = image
+ }
+
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
}
- // TODO: (jhonce) When c/image is refactored the roadmap calls for this check to be pushed into that library.
- for _, n := range query.Name {
- if _, err := reference.ParseNormalizedNamed(n); err != nil {
+ // Support 4.x API calls, map query parameter to path
+ if name, ok := mux.Vars(r)["name"]; ok {
+ n, err := url.QueryUnescape(name)
+ if err != nil {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
- errors.Wrapf(err, "invalid image name %s", n))
+ errors.Wrapf(err, "failed to parse name parameter %q", name))
return
}
+ query.Name = n
+ }
+
+ if _, err := reference.ParseNormalizedNamed(query.Name); err != nil {
+ utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
+ errors.Wrapf(err, "invalid image name %s", query.Name))
+ return
}
imageEngine := abi.ImageEngine{Libpod: runtime}
createOptions := entities.ManifestCreateOptions{All: query.All}
- manID, err := imageEngine.ManifestCreate(r.Context(), query.Name, query.Image, createOptions)
+ manID, err := imageEngine.ManifestCreate(r.Context(), query.Name, query.Images, createOptions)
+ if err != nil {
+ utils.InternalServerError(w, err)
+ return
+ }
+
+ status := http.StatusOK
+ if _, err := utils.SupportedVersion(r, "< 4.0.0"); err == utils.ErrVersionNotSupported {
+ status = http.StatusCreated
+ }
+
+ buffer, err := ioutil.ReadAll(r.Body)
+ if err != nil {
+ utils.InternalServerError(w, err)
+ return
+ }
+
+ // Treat \r\n as empty body
+ if len(buffer) < 3 {
+ utils.WriteResponse(w, status, handlers.IDResponse{ID: manID})
+ return
+ }
+
+ body := new(entities.ManifestModifyOptions)
+ if err := json.Unmarshal(buffer, body); err != nil {
+ utils.InternalServerError(w, errors.Wrap(err, "Decode()"))
+ return
+ }
+
+ // gather all images for manifest list
+ var images []string
+ if len(query.Images) > 0 {
+ images = append(query.Images)
+ }
+ if len(body.Images) > 0 {
+ images = append(body.Images)
+ }
+
+ id, err := imageEngine.ManifestAdd(r.Context(), query.Name, images, body.ManifestAddOptions)
if err != nil {
utils.InternalServerError(w, err)
return
}
- utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: manID})
+
+ utils.WriteResponse(w, status, handlers.IDResponse{ID: id})
}
-// ExistsManifest check if a manifest list exists
-func ExistsManifest(w http.ResponseWriter, r *http.Request) {
+// ManifestExists return true if manifest list exists.
+func ManifestExists(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
name := utils.GetName(r)
@@ -94,10 +153,18 @@ func ManifestInspect(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, schema2List)
}
+// ManifestAdd remove digest from manifest list
+//
+// Deprecated: As of 4.0.0 use ManifestModify instead
func ManifestAdd(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
- var addOptions entities.ManifestAddOptions
- if err := json.NewDecoder(r.Body).Decode(&addOptions); err != nil {
+
+ // Wrapper to support 3.x with 4.x libpod
+ query := struct {
+ entities.ManifestAddOptions
+ Images []string
+ }{}
+ if err := json.NewDecoder(r.Body).Decode(&query); err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()"))
return
}
@@ -108,15 +175,8 @@ func ManifestAdd(w http.ResponseWriter, r *http.Request) {
return
}
- // FIXME: we really need to clean up the manifest API. Swagger states
- // the arguments were strings not string slices. The use of string
- // slices, mixing lists and images is incredibly confusing.
- if len(addOptions.Images) == 1 {
- addOptions.Images = append(addOptions.Images, name)
- }
-
imageEngine := abi.ImageEngine{Libpod: runtime}
- newID, err := imageEngine.ManifestAdd(r.Context(), addOptions)
+ newID, err := imageEngine.ManifestAdd(r.Context(), name, query.Images, query.ManifestAddOptions)
if err != nil {
utils.InternalServerError(w, err)
return
@@ -124,7 +184,10 @@ func ManifestAdd(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: newID})
}
-func ManifestRemove(w http.ResponseWriter, r *http.Request) {
+// ManifestRemoveDigest remove digest from manifest list
+//
+// Deprecated: As of 4.0.0 use ManifestModify instead
+func ManifestRemoveDigest(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
query := struct {
@@ -155,7 +218,10 @@ func ManifestRemove(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: manifestList.ID()})
}
-func ManifestPush(w http.ResponseWriter, r *http.Request) {
+// ManifestPushV3 push image to registry
+//
+// Deprecated: As of 4.0.0 use ManifestPush instead
+func ManifestPushV3(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
query := struct {
@@ -207,3 +273,156 @@ func ManifestPush(w http.ResponseWriter, r *http.Request) {
}
utils.WriteResponse(w, http.StatusOK, digest)
}
+
+// ManifestPush push image to registry
+//
+// As of 4.0.0
+func ManifestPush(w http.ResponseWriter, r *http.Request) {
+ runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
+ decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
+
+ query := struct {
+ All bool `schema:"all"`
+ TLSVerify bool `schema:"tlsVerify"`
+ }{
+ // Add defaults here once needed.
+ }
+ 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
+ }
+
+ destination := utils.GetVar(r, "destination")
+ if err := utils.IsRegistryReference(destination); err != nil {
+ utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, err)
+ return
+ }
+
+ authconf, authfile, err := auth.GetCredentials(r)
+ if err != nil {
+ utils.Error(w, "failed to retrieve repository credentials", http.StatusBadRequest, errors.Wrapf(err, "failed to parse registry header for %s", r.URL.String()))
+ return
+ }
+ defer auth.RemoveAuthfile(authfile)
+ var username, password string
+ if authconf != nil {
+ username = authconf.Username
+ password = authconf.Password
+ }
+ options := entities.ImagePushOptions{
+ Authfile: authfile,
+ Username: username,
+ Password: password,
+ All: query.All,
+ }
+ if sys := runtime.SystemContext(); sys != nil {
+ options.CertDir = sys.DockerCertPath
+ }
+ if _, found := r.URL.Query()["tlsVerify"]; found {
+ options.SkipTLSVerify = types.NewOptionalBool(!query.TLSVerify)
+ }
+
+ imageEngine := abi.ImageEngine{Libpod: runtime}
+ source := utils.GetName(r)
+ digest, err := imageEngine.ManifestPush(context.Background(), source, destination, options)
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "error pushing image %q", destination))
+ return
+ }
+ utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: digest})
+}
+
+// ManifestModify efficiently updates the named manifest list
+func ManifestModify(w http.ResponseWriter, r *http.Request) {
+ runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
+ imageEngine := abi.ImageEngine{Libpod: runtime}
+
+ body := new(entities.ManifestModifyOptions)
+ if err := json.NewDecoder(r.Body).Decode(body); err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()"))
+ return
+ }
+
+ name := utils.GetName(r)
+ if _, err := runtime.LibimageRuntime().LookupManifestList(name); err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusNotFound, err)
+ return
+ }
+
+ var report entities.ManifestModifyReport
+ switch {
+ case strings.EqualFold("update", body.Operation):
+ id, err := imageEngine.ManifestAdd(r.Context(), name, body.Images, body.ManifestAddOptions)
+ if err != nil {
+ report.Errors = append(report.Errors, err)
+ break
+ }
+ report = entities.ManifestModifyReport{
+ ID: id,
+ Images: body.Images,
+ }
+ case strings.EqualFold("remove", body.Operation):
+ for _, image := range body.Images {
+ id, err := imageEngine.ManifestRemoveDigest(r.Context(), name, image)
+ if err != nil {
+ report.Errors = append(report.Errors, err)
+ continue
+ }
+ report.ID = id
+ report.Images = append(report.Images, image)
+ }
+ case strings.EqualFold("annotate", body.Operation):
+ options := entities.ManifestAnnotateOptions{
+ Annotation: body.Annotation,
+ Arch: body.Arch,
+ Features: body.Features,
+ OS: body.OS,
+ OSFeatures: body.OSFeatures,
+ OSVersion: body.OSVersion,
+ Variant: body.Variant,
+ }
+ for _, image := range body.Images {
+ id, err := imageEngine.ManifestAnnotate(r.Context(), name, image, options)
+ if err != nil {
+ report.Errors = append(report.Errors, err)
+ continue
+ }
+ report.ID = id
+ report.Images = append(report.Images, image)
+ }
+ default:
+ utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
+ fmt.Errorf("illegal operation %q for %q", body.Operation, r.URL.String()))
+ return
+ }
+
+ statusCode := http.StatusOK
+ switch {
+ case len(report.Errors) > 0 && len(report.Images) > 0:
+ statusCode = http.StatusConflict
+ case len(report.Errors) > 0:
+ statusCode = http.StatusInternalServerError
+ }
+ utils.WriteResponse(w, statusCode, report)
+}
+
+// ManifestDelete removes a manifest list from storage
+func ManifestDelete(w http.ResponseWriter, r *http.Request) {
+ runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
+ imageEngine := abi.ImageEngine{Libpod: runtime}
+
+ name := utils.GetName(r)
+ if _, err := runtime.LibimageRuntime().LookupManifestList(name); err != nil {
+ utils.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound, err)
+ return
+ }
+
+ results, errs := imageEngine.ManifestRm(r.Context(), []string{name})
+ errsString := errorhandling.ErrorsToStrings(errs)
+ report := handlers.LibpodImagesRemoveReport{
+ ImageRemoveReport: *results,
+ Errors: errsString,
+ }
+ utils.WriteResponse(w, http.StatusOK, report)
+}
diff --git a/pkg/api/handlers/types.go b/pkg/api/handlers/types.go
index 1733476cc..d3a592bdf 100644
--- a/pkg/api/handlers/types.go
+++ b/pkg/api/handlers/types.go
@@ -184,46 +184,6 @@ type ExecStartConfig struct {
Width uint16 `json:"w"`
}
-func ImageToImageSummary(l *libimage.Image) (*entities.ImageSummary, error) {
- options := &libimage.InspectOptions{WithParent: true, WithSize: true}
- imageData, err := l.Inspect(context.TODO(), options)
- if err != nil {
- return nil, errors.Wrapf(err, "failed to obtain summary for image %s", l.ID())
- }
-
- containers, err := l.Containers()
- if err != nil {
- return nil, errors.Wrapf(err, "failed to obtain Containers for image %s", l.ID())
- }
- containerCount := len(containers)
-
- isDangling, err := l.IsDangling(context.TODO())
- if err != nil {
- return nil, errors.Wrapf(err, "failed to check if image %s is dangling", l.ID())
- }
-
- is := entities.ImageSummary{
- // docker adds sha256: in front of the ID
- ID: "sha256:" + l.ID(),
- ParentId: imageData.Parent,
- RepoTags: imageData.RepoTags,
- RepoDigests: imageData.RepoDigests,
- Created: l.Created().Unix(),
- Size: imageData.Size,
- SharedSize: 0,
- VirtualSize: imageData.VirtualSize,
- Labels: imageData.Labels,
- Containers: containerCount,
- ReadOnly: l.IsReadOnly(),
- Dangling: isDangling,
- Names: l.Names(),
- Digest: string(imageData.Digest),
- ConfigDigest: "", // TODO: libpod/image didn't set it but libimage should
- History: imageData.NamesHistory,
- }
- return &is, nil
-}
-
func ImageDataToImageInspect(ctx context.Context, l *libimage.Image) (*ImageInspect, error) {
options := &libimage.InspectOptions{WithParent: true, WithSize: true}
info, err := l.Inspect(context.Background(), options)
diff --git a/pkg/api/handlers/utils/handler.go b/pkg/api/handlers/utils/handler.go
index 96b7a957c..ee83755a1 100644
--- a/pkg/api/handlers/utils/handler.go
+++ b/pkg/api/handlers/utils/handler.go
@@ -174,7 +174,7 @@ func FilterMapToString(filters map[string][]string) (string, error) {
return string(f), nil
}
-func getVar(r *http.Request, k string) string {
+func GetVar(r *http.Request, k string) string {
val := mux.Vars(r)[k]
safeVal, err := url.PathUnescape(val)
if err != nil {
@@ -186,5 +186,5 @@ func getVar(r *http.Request, k string) string {
// GetName extracts the name from the mux
func GetName(r *http.Request) string {
- return getVar(r, "name")
+ return GetVar(r, "name")
}
diff --git a/pkg/api/handlers/utils/images.go b/pkg/api/handlers/utils/images.go
index 3f3f48193..639de9915 100644
--- a/pkg/api/handlers/utils/images.go
+++ b/pkg/api/handlers/utils/images.go
@@ -6,7 +6,6 @@ import (
"strings"
"github.com/containers/common/libimage"
- "github.com/containers/common/pkg/filters"
"github.com/containers/image/v5/docker"
storageTransport "github.com/containers/image/v5/storage"
"github.com/containers/image/v5/transports/alltransports"
@@ -16,7 +15,6 @@ import (
"github.com/containers/podman/v3/pkg/util"
"github.com/containers/storage"
"github.com/docker/distribution/reference"
- "github.com/gorilla/schema"
"github.com/pkg/errors"
)
@@ -91,44 +89,6 @@ func ParseStorageReference(name string) (types.ImageReference, error) {
return imageRef, nil
}
-// GetImages is a common function used to get images for libpod and other compatibility
-// mechanisms
-func GetImages(w http.ResponseWriter, r *http.Request) ([]*libimage.Image, error) {
- decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
- runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
- query := struct {
- All bool
- Digests bool
- Filter string // Docker 1.24 compatibility
- }{
- // This is where you can override the golang default value for one of fields
- }
-
- if err := decoder.Decode(&query, r.URL.Query()); err != nil {
- return nil, err
- }
- if _, found := r.URL.Query()["digests"]; found && query.Digests {
- UnSupportedParameter("digests")
- }
-
- filterList, err := filters.FiltersFromRequest(r)
- if err != nil {
- return nil, err
- }
- if !IsLibpodRequest(r) && len(query.Filter) > 0 { // Docker 1.24 compatibility
- filterList = append(filterList, "reference="+query.Filter)
- }
-
- if !query.All {
- // Filter intermediate images unless we want to list *all*.
- // NOTE: it's a positive filter, so `intermediate=false` means
- // to display non-intermediate images.
- filterList = append(filterList, "intermediate=false")
- }
- listOptions := &libimage.ListImagesOptions{Filters: filterList}
- return runtime.LibimageRuntime().ListImages(r.Context(), nil, listOptions)
-}
-
func GetImage(r *http.Request, name string) (*libimage.Image, error) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
image, _, err := runtime.LibimageRuntime().LookupImage(name, nil)