summaryrefslogtreecommitdiff
path: root/pkg/api/handlers/libpod
diff options
context:
space:
mode:
authorValentin Rothberg <rothberg@redhat.com>2021-04-22 08:01:12 +0200
committerValentin Rothberg <rothberg@redhat.com>2021-05-05 11:30:12 +0200
commit0f7d54b0260c1be992ee3b9cee359ef3a9e8bd21 (patch)
tree192e52054de2abf0c92d83ecdbc71d498c2ec947 /pkg/api/handlers/libpod
parent8eefca5a257121b177562742c972e39e1686140d (diff)
downloadpodman-0f7d54b0260c1be992ee3b9cee359ef3a9e8bd21.tar.gz
podman-0f7d54b0260c1be992ee3b9cee359ef3a9e8bd21.tar.bz2
podman-0f7d54b0260c1be992ee3b9cee359ef3a9e8bd21.zip
migrate Podman to containers/common/libimage
Migrate the Podman code base over to `common/libimage` which replaces `libpod/image` and a lot of glue code entirely. Note that I tried to leave bread crumbs for changed tests. Miscellaneous changes: * Some errors yield different messages which required to alter some tests. * I fixed some pre-existing issues in the code. Others were marked as `//TODO`s to prevent the PR from exploding. * The `NamesHistory` of an image is returned as is from the storage. Previously, we did some filtering which I think is undesirable. Instead we should return the data as stored in the storage. * Touched handlers use the ABI interfaces where possible. * Local image resolution: previously Podman would match "foo" on "myfoo". This behaviour has been changed and Podman will now only match on repository boundaries such that "foo" would match "my/foo" but not "myfoo". I consider the old behaviour to be a bug, at the very least an exotic corner case. * Futhermore, "foo:none" does *not* resolve to a local image "foo" without tag anymore. It's a hill I am (almost) willing to die on. * `image prune` prints the IDs of pruned images. Previously, in some cases, the names were printed instead. The API clearly states ID, so we should stick to it. * Compat endpoint image removal with _force_ deletes the entire not only the specified tag. Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
Diffstat (limited to 'pkg/api/handlers/libpod')
-rw-r--r--pkg/api/handlers/libpod/images.go106
-rw-r--r--pkg/api/handlers/libpod/images_pull.go144
-rw-r--r--pkg/api/handlers/libpod/manifests.go69
-rw-r--r--pkg/api/handlers/libpod/system.go44
4 files changed, 165 insertions, 198 deletions
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index 92882cc40..a90408bfd 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -11,11 +11,12 @@ import (
"strings"
"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"
"github.com/containers/podman/v3/libpod/define"
- "github.com/containers/podman/v3/libpod/image"
"github.com/containers/podman/v3/pkg/api/handlers"
"github.com/containers/podman/v3/pkg/api/handlers/utils"
"github.com/containers/podman/v3/pkg/auth"
@@ -24,6 +25,7 @@ import (
"github.com/containers/podman/v3/pkg/errorhandling"
"github.com/containers/podman/v3/pkg/util"
utils2 "github.com/containers/podman/v3/utils"
+ "github.com/containers/storage"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
@@ -74,7 +76,7 @@ func ImageTree(w http.ResponseWriter, r *http.Request) {
options := entities.ImageTreeOptions{WhatRequires: query.WhatRequires}
report, err := ir.Tree(r.Context(), name, options)
if err != nil {
- if errors.Cause(err) == define.ErrNoSuchImage {
+ if errors.Cause(err) == storage.ErrImageUnknown {
utils.Error(w, "Something went wrong.", http.StatusNotFound, errors.Wrapf(err, "failed to find image %s", name))
return
}
@@ -91,7 +93,7 @@ func GetImage(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusNotFound, errors.Wrapf(err, "failed to find image %s", name))
return
}
- inspect, err := newImage.Inspect(r.Context())
+ inspect, err := newImage.Inspect(r.Context(), true)
if err != nil {
utils.Error(w, "Server error", http.StatusInternalServerError, errors.Wrapf(err, "failed in inspect image %s", inspect.ID))
return
@@ -100,22 +102,44 @@ func GetImage(w http.ResponseWriter, r *http.Request) {
}
func GetImages(w http.ResponseWriter, r *http.Request) {
- images, err := utils.GetImages(w, r)
+ decoder := r.Context().Value("decoder").(*schema.Decoder)
+ runtime := r.Context().Value("runtime").(*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, errors.Wrap(err, "Failed get images"))
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
return
}
- var summaries = make([]*entities.ImageSummary, len(images))
- for j, img := range images {
- is, err := handlers.ImageToImageSummary(img)
- if err != nil {
- utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Failed transform image summaries"))
- return
- }
- // libpod has additional fields that we need to populate.
- is.ReadOnly = img.IsReadOnly()
- summaries[j] = is
+ 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)
}
@@ -135,7 +159,8 @@ func PruneImages(w http.ResponseWriter, r *http.Request) {
if dErr := decoder.Decode(&query, r.URL.Query()); dErr != nil || err != nil {
utils.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError,
- errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
+ errors.
+ Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
}
@@ -156,7 +181,13 @@ func PruneImages(w http.ResponseWriter, r *http.Request) {
}
}
- imagePruneReports, err := runtime.ImageRuntime().PruneImages(r.Context(), query.All, libpodFilters)
+ imageEngine := abi.ImageEngine{Libpod: runtime}
+
+ pruneOptions := entities.ImagePruneOptions{
+ All: query.All,
+ Filter: libpodFilters,
+ }
+ imagePruneReports, err := imageEngine.Prune(r.Context(), pruneOptions)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
return
@@ -183,11 +214,13 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
return
}
name := utils.GetName(r)
- newImage, err := runtime.ImageRuntime().NewFromLocal(name)
- if err != nil {
+
+ lookupOptions := &libimage.LookupImageOptions{IgnorePlatform: true}
+ if _, _, err := runtime.LibimageRuntime().LookupImage(name, lookupOptions); err != nil {
utils.ImageNotFound(w, name, err)
return
}
+
switch query.Format {
case define.OCIArchive, define.V2s2Archive:
tmpfile, err := ioutil.TempFile("", "api.tar")
@@ -211,7 +244,15 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "unknown format", http.StatusInternalServerError, errors.Errorf("unknown format %q", query.Format))
return
}
- if err := newImage.Save(r.Context(), name, query.Format, output, []string{}, false, query.Compress, true); err != nil {
+
+ imageEngine := abi.ImageEngine{Libpod: runtime}
+
+ saveOptions := entities.ImageSaveOptions{
+ Compress: query.Compress,
+ Format: query.Format,
+ Output: output,
+ }
+ if err := imageEngine.Save(r.Context(), name, nil, saveOptions); err != nil {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, err)
return
}
@@ -347,12 +388,15 @@ func ImagesLoad(w http.ResponseWriter, r *http.Request) {
return
}
- loadedImage, err := runtime.LoadImage(context.Background(), tmpfile.Name(), os.Stderr, "")
+ imageEngine := abi.ImageEngine{Libpod: runtime}
+
+ loadOptions := entities.ImageLoadOptions{Input: tmpfile.Name()}
+ loadReport, err := imageEngine.Load(r.Context(), loadOptions)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to load image"))
return
}
- utils.WriteResponse(w, http.StatusOK, entities.ImageLoadReport{Names: strings.Split(loadedImage, ",")})
+ utils.WriteResponse(w, http.StatusOK, loadReport)
}
func ImagesImport(w http.ResponseWriter, r *http.Request) {
@@ -392,13 +436,21 @@ func ImagesImport(w http.ResponseWriter, r *http.Request) {
tmpfile.Close()
source = tmpfile.Name()
}
- importedImage, err := runtime.Import(context.Background(), source, query.Reference, "", query.Changes, query.Message, true)
+
+ imageEngine := abi.ImageEngine{Libpod: runtime}
+ importOptions := entities.ImageImportOptions{
+ Changes: query.Changes,
+ Message: query.Message,
+ Reference: query.Reference,
+ Source: source,
+ }
+ report, err := imageEngine.Import(r.Context(), importOptions)
if err != nil {
- utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to import image"))
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to import tarball"))
return
}
- utils.WriteResponse(w, http.StatusOK, entities.ImageImportReport{Id: importedImage})
+ utils.WriteResponse(w, http.StatusOK, report)
}
// PushImage is the handler for the compat http endpoint for pushing images.
@@ -497,7 +549,7 @@ func CommitContainer(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "failed to get runtime config", http.StatusInternalServerError, errors.Wrap(err, "failed to get runtime config"))
return
}
- sc := image.GetSystemContext(rtc.Engine.SignaturePolicyPath, "", false)
+ sc := runtime.SystemContext()
tag := "latest"
options := libpod.ContainerCommitOptions{
Pause: true,
@@ -579,7 +631,7 @@ func UntagImage(w http.ResponseWriter, r *http.Request) {
name := utils.GetName(r)
if err := imageEngine.Untag(r.Context(), name, tags, opts); err != nil {
- if errors.Cause(err) == define.ErrNoSuchImage {
+ if errors.Cause(err) == storage.ErrImageUnknown {
utils.ImageNotFound(w, name, errors.Wrapf(err, "failed to find image %s", name))
} else {
utils.Error(w, "failed to untag", http.StatusInternalServerError, err)
diff --git a/pkg/api/handlers/libpod/images_pull.go b/pkg/api/handlers/libpod/images_pull.go
index e2e4b53b4..7545ba235 100644
--- a/pkg/api/handlers/libpod/images_pull.go
+++ b/pkg/api/handlers/libpod/images_pull.go
@@ -3,20 +3,16 @@ package libpod
import (
"context"
"encoding/json"
- "fmt"
"net/http"
- "strings"
- "github.com/containers/image/v5/docker"
- "github.com/containers/image/v5/docker/reference"
+ "github.com/containers/common/libimage"
+ "github.com/containers/common/pkg/config"
"github.com/containers/image/v5/types"
"github.com/containers/podman/v3/libpod"
- "github.com/containers/podman/v3/libpod/image"
"github.com/containers/podman/v3/pkg/api/handlers/utils"
"github.com/containers/podman/v3/pkg/auth"
"github.com/containers/podman/v3/pkg/channel"
"github.com/containers/podman/v3/pkg/domain/entities"
- "github.com/containers/podman/v3/pkg/util"
"github.com/gorilla/schema"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -51,28 +47,23 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
return
}
- imageRef, err := utils.ParseDockerReference(query.Reference)
- if err != nil {
+ // Make sure that the reference has no transport or the docker one.
+ if _, err := utils.ParseDockerReference(query.Reference); err != nil {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, err)
return
}
- // Trim the docker-transport prefix.
- rawImage := strings.TrimPrefix(query.Reference, fmt.Sprintf("%s://", docker.Transport.Name()))
+ pullOptions := &libimage.PullOptions{}
+ pullOptions.AllTags = query.AllTags
+ pullOptions.Architecture = query.Arch
+ pullOptions.OS = query.OS
+ pullOptions.Variant = query.Variant
- // all-tags doesn't work with a tagged reference, so let's check early
- namedRef, err := reference.Parse(rawImage)
- if err != nil {
- utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
- errors.Wrapf(err, "error parsing reference %q", rawImage))
- return
- }
- if _, isTagged := namedRef.(reference.Tagged); isTagged && query.AllTags {
- utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
- errors.Errorf("reference %q must not have a tag for all-tags", rawImage))
- return
+ if _, found := r.URL.Query()["tlsVerify"]; found {
+ pullOptions.InsecureSkipTLSVerify = types.NewOptionalBool(!query.TLSVerify)
}
+ // Do the auth dance.
authConf, 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()))
@@ -80,71 +71,25 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
}
defer auth.RemoveAuthfile(authfile)
- // Setup the registry options
- dockerRegistryOptions := image.DockerRegistryOptions{
- DockerRegistryCreds: authConf,
- OSChoice: query.OS,
- ArchitectureChoice: query.Arch,
- VariantChoice: query.Variant,
- }
- if _, found := r.URL.Query()["tlsVerify"]; found {
- dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!query.TLSVerify)
- }
-
- sys := runtime.SystemContext()
- if sys == nil {
- sys = image.GetSystemContext("", authfile, false)
- }
- dockerRegistryOptions.DockerCertPath = sys.DockerCertPath
- sys.DockerAuthConfig = authConf
-
- // Prepare the images we want to pull
- imagesToPull := []string{}
- imageName := namedRef.String()
-
- if !query.AllTags {
- imagesToPull = append(imagesToPull, imageName)
- } else {
- tags, err := docker.GetRepositoryTags(context.Background(), sys, imageRef)
- if err != nil {
- utils.InternalServerError(w, errors.Wrap(err, "error getting repository tags"))
- return
- }
- for _, tag := range tags {
- imagesToPull = append(imagesToPull, fmt.Sprintf("%s:%s", imageName, tag))
- }
+ pullOptions.AuthFilePath = authfile
+ if authConf != nil {
+ pullOptions.Username = authConf.Username
+ pullOptions.Password = authConf.Password
+ pullOptions.IdentityToken = authConf.IdentityToken
}
writer := channel.NewWriter(make(chan []byte))
defer writer.Close()
- stderr := channel.NewWriter(make(chan []byte))
- defer stderr.Close()
+ pullOptions.Writer = writer
- images := make([]string, 0, len(imagesToPull))
+ var pulledImages []*libimage.Image
+ var pullError error
runCtx, cancel := context.WithCancel(context.Background())
- go func(imgs []string) {
+ go func() {
defer cancel()
- // Finally pull the images
- for _, img := range imgs {
- newImage, err := runtime.ImageRuntime().New(
- runCtx,
- img,
- "",
- authfile,
- writer,
- &dockerRegistryOptions,
- image.SigningOptions{},
- nil,
- util.PullImageAlways,
- nil)
- if err != nil {
- stderr.Write([]byte(err.Error() + "\n"))
- } else {
- images = append(images, newImage.ID())
- }
- }
- }(imagesToPull)
+ pulledImages, pullError = runtime.LibimageRuntime().Pull(runCtx, query.Reference, config.PullPolicyAlways, pullOptions)
+ }()
flush := func() {
if flusher, ok := w.(http.Flusher); ok {
@@ -158,45 +103,32 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
enc := json.NewEncoder(w)
enc.SetEscapeHTML(true)
- var failed bool
-loop: // break out of for/select infinite loop
for {
var report entities.ImagePullReport
select {
- case e := <-writer.Chan():
- report.Stream = string(e)
- if err := enc.Encode(report); err != nil {
- stderr.Write([]byte(err.Error()))
- }
- flush()
- case e := <-stderr.Chan():
- failed = true
- report.Error = string(e)
+ case s := <-writer.Chan():
+ report.Stream = string(s)
if err := enc.Encode(report); err != nil {
- logrus.Warnf("Failed to json encode error %q", err.Error())
+ logrus.Warnf("Failed to encode json: %v", err)
}
flush()
case <-runCtx.Done():
- if !failed {
- // Send all image id's pulled in 'images' stanza
- report.Images = images
- if err := enc.Encode(report); err != nil {
- logrus.Warnf("Failed to json encode error %q", err.Error())
- }
-
- report.Images = nil
+ for _, image := range pulledImages {
+ report.Images = append(report.Images, image.ID())
// Pull last ID from list and publish in 'id' stanza. This maintains previous API contract
- report.ID = images[len(images)-1]
- if err := enc.Encode(report); err != nil {
- logrus.Warnf("Failed to json encode error %q", err.Error())
- }
-
- flush()
+ report.ID = image.ID()
+ }
+ if pullError != nil {
+ report.Error = pullError.Error()
+ }
+ if err := enc.Encode(report); err != nil {
+ logrus.Warnf("Failed to encode json: %v", err)
}
- break loop // break out of for/select infinite loop
+ flush()
+ return
case <-r.Context().Done():
// Client has closed connection
- break loop // break out of for/select infinite loop
+ return
}
}
}
diff --git a/pkg/api/handlers/libpod/manifests.go b/pkg/api/handlers/libpod/manifests.go
index 6a491ae48..f21eb2e80 100644
--- a/pkg/api/handlers/libpod/manifests.go
+++ b/pkg/api/handlers/libpod/manifests.go
@@ -9,7 +9,6 @@ import (
"github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/types"
"github.com/containers/podman/v3/libpod"
- "github.com/containers/podman/v3/libpod/image"
"github.com/containers/podman/v3/pkg/api/handlers"
"github.com/containers/podman/v3/pkg/api/handlers/utils"
"github.com/containers/podman/v3/pkg/auth"
@@ -45,13 +44,10 @@ func ManifestCreate(w http.ResponseWriter, r *http.Request) {
}
}
- rtc, err := runtime.GetConfig()
- if err != nil {
- utils.InternalServerError(w, err)
- return
- }
- sc := image.GetSystemContext(rtc.Engine.SignaturePolicyPath, "", false)
- manID, err := image.CreateManifestList(runtime.ImageRuntime(), *sc, query.Name, query.Image, query.All)
+ imageEngine := abi.ImageEngine{Libpod: runtime}
+
+ createOptions := entities.ManifestCreateOptions{All: query.All}
+ manID, err := imageEngine.ManifestCreate(r.Context(), query.Name, query.Image, createOptions)
if err != nil {
utils.InternalServerError(w, err)
return
@@ -64,8 +60,8 @@ func ExistsManifest(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := utils.GetName(r)
- ic := abi.ImageEngine{Libpod: runtime}
- report, err := ic.ManifestExists(r.Context(), name)
+ imageEngine := abi.ImageEngine{Libpod: runtime}
+ report, err := imageEngine.ManifestExists(r.Context(), name)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
return
@@ -80,45 +76,46 @@ func ExistsManifest(w http.ResponseWriter, r *http.Request) {
func ManifestInspect(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := utils.GetName(r)
+
imageEngine := abi.ImageEngine{Libpod: runtime}
- inspectReport, inspectError := imageEngine.ManifestInspect(r.Context(), name)
- if inspectError != nil {
- utils.Error(w, "Something went wrong.", http.StatusNotFound, inspectError)
+ rawManifest, err := imageEngine.ManifestInspect(r.Context(), name)
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusNotFound, err)
return
}
- var list manifest.Schema2List
- if err := json.Unmarshal(inspectReport, &list); err != nil {
- utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Unmarshal()"))
+ var schema2List manifest.Schema2List
+ if err := json.Unmarshal(rawManifest, &schema2List); err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
return
}
- if list.Manifests == nil {
- list.Manifests = make([]manifest.Schema2ManifestDescriptor, 0)
- }
- utils.WriteResponse(w, http.StatusOK, &list)
+ utils.WriteResponse(w, http.StatusOK, schema2List)
}
func ManifestAdd(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
- var manifestInput image.ManifestAddOpts
- if err := json.NewDecoder(r.Body).Decode(&manifestInput); err != nil {
+ var addOptions entities.ManifestAddOptions
+ if err := json.NewDecoder(r.Body).Decode(&addOptions); err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()"))
return
}
+
name := utils.GetName(r)
- newImage, err := runtime.ImageRuntime().NewFromLocal(name)
- if err != nil {
- utils.ImageNotFound(w, name, err)
+ if _, err := runtime.LibimageRuntime().LookupManifestList(name); err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusNotFound, err)
return
}
- rtc, err := runtime.GetConfig()
- if err != nil {
- utils.InternalServerError(w, err)
- 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)
}
- sc := image.GetSystemContext(rtc.Engine.SignaturePolicyPath, "", false)
- newID, err := newImage.AddManifest(*sc, manifestInput)
+
+ imageEngine := abi.ImageEngine{Libpod: runtime}
+ newID, err := imageEngine.ManifestAdd(r.Context(), addOptions)
if err != nil {
utils.InternalServerError(w, err)
return
@@ -140,9 +137,9 @@ func ManifestRemove(w http.ResponseWriter, r *http.Request) {
errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
}
- newImage, err := runtime.ImageRuntime().NewFromLocal(name)
+ manifestList, err := runtime.LibimageRuntime().LookupManifestList(name)
if err != nil {
- utils.ImageNotFound(w, name, err)
+ utils.Error(w, "Something went wrong.", http.StatusNotFound, err)
return
}
d, err := digest.Parse(query.Digest)
@@ -150,13 +147,13 @@ func ManifestRemove(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "invalid digest", http.StatusBadRequest, err)
return
}
- newID, err := newImage.RemoveManifest(d)
- if err != nil {
+ if err := manifestList.RemoveInstance(d); err != nil {
utils.InternalServerError(w, err)
return
}
- utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: newID})
+ utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: manifestList.ID()})
}
+
func ManifestPush(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder)
diff --git a/pkg/api/handlers/libpod/system.go b/pkg/api/handlers/libpod/system.go
index 2b4cef1bb..bca92a4af 100644
--- a/pkg/api/handlers/libpod/system.go
+++ b/pkg/api/handlers/libpod/system.go
@@ -4,21 +4,19 @@ import (
"net/http"
"github.com/containers/podman/v3/libpod"
- "github.com/containers/podman/v3/pkg/api/handlers/compat"
"github.com/containers/podman/v3/pkg/api/handlers/utils"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/domain/infra/abi"
+ "github.com/containers/podman/v3/pkg/util"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
// SystemPrune removes unused data
func SystemPrune(w http.ResponseWriter, r *http.Request) {
- var (
- decoder = r.Context().Value("decoder").(*schema.Decoder)
- runtime = r.Context().Value("runtime").(*libpod.Runtime)
- systemPruneReport = new(entities.SystemPruneReport)
- )
+ decoder := r.Context().Value("decoder").(*schema.Decoder)
+ runtime := r.Context().Value("runtime").(*libpod.Runtime)
+
query := struct {
All bool `schema:"all"`
Volumes bool `schema:"volumes"`
@@ -29,39 +27,27 @@ func SystemPrune(w http.ResponseWriter, r *http.Request) {
errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
}
-
- podPruneReport, err := PodPruneHelper(r)
+ filterMap, err := util.PrepareFilters(r)
if err != nil {
- utils.InternalServerError(w, err)
+ utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
+ errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
}
- systemPruneReport.PodPruneReport = podPruneReport
- // We could parallelize this, should we?
- containerPruneReports, err := compat.PruneContainersHelper(r, nil)
- if err != nil {
- utils.InternalServerError(w, err)
- return
- }
- systemPruneReport.ContainerPruneReports = containerPruneReports
+ containerEngine := abi.ContainerEngine{Libpod: runtime}
- imagePruneReports, err := runtime.ImageRuntime().PruneImages(r.Context(), query.All, nil)
+ pruneOptions := entities.SystemPruneOptions{
+ All: query.All,
+ Volume: query.Volumes,
+ Filters: *filterMap,
+ }
+ report, err := containerEngine.SystemPrune(r.Context(), pruneOptions)
if err != nil {
utils.InternalServerError(w, err)
return
}
- systemPruneReport.ImagePruneReports = imagePruneReports
-
- if query.Volumes {
- volumePruneReports, err := pruneVolumesHelper(r)
- if err != nil {
- utils.InternalServerError(w, err)
- return
- }
- systemPruneReport.VolumePruneReports = volumePruneReports
- }
- utils.WriteResponse(w, http.StatusOK, systemPruneReport)
+ utils.WriteResponse(w, http.StatusOK, report)
}
func DiskUsage(w http.ResponseWriter, r *http.Request) {