summaryrefslogtreecommitdiff
path: root/pkg/api/handlers/libpod/images.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/api/handlers/libpod/images.go')
-rw-r--r--pkg/api/handlers/libpod/images.go96
1 files changed, 91 insertions, 5 deletions
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index cfd3b993e..4b24d7d9f 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -10,14 +10,18 @@ import (
"strconv"
"strings"
+ "github.com/containers/buildah"
"github.com/containers/image/v5/docker"
"github.com/containers/image/v5/docker/reference"
+ "github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/transports/alltransports"
"github.com/containers/image/v5/types"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/image"
+ image2 "github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/api/handlers"
"github.com/containers/libpod/pkg/api/handlers/utils"
+ "github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/pkg/util"
"github.com/gorilla/schema"
"github.com/pkg/errors"
@@ -98,7 +102,7 @@ func GetImages(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Failed get images"))
return
}
- var summaries = make([]*handlers.ImageSummary, len(images))
+ var summaries = make([]*entities.ImageSummary, len(images))
for j, img := range images {
is, err := handlers.ImageToImageSummary(img)
if err != nil {
@@ -106,7 +110,7 @@ func GetImages(w http.ResponseWriter, r *http.Request) {
return
}
// libpod has additional fields that we need to populate.
- is.CreatedTime = img.Created()
+ is.Created = img.Created().Unix()
is.ReadOnly = img.IsReadOnly()
summaries[j] = is
}
@@ -115,12 +119,12 @@ func GetImages(w http.ResponseWriter, r *http.Request) {
func PruneImages(w http.ResponseWriter, r *http.Request) {
var (
- all bool
err error
)
runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
+ All bool `schema:"all"`
Filters map[string][]string `schema:"filters"`
}{
// override any golang type defaults
@@ -136,7 +140,7 @@ func PruneImages(w http.ResponseWriter, r *http.Request) {
if _, found := r.URL.Query()["filters"]; found {
dangling := query.Filters["all"]
if len(dangling) > 0 {
- all, err = strconv.ParseBool(query.Filters["all"][0])
+ query.All, err = strconv.ParseBool(query.Filters["all"][0])
if err != nil {
utils.InternalServerError(w, err)
return
@@ -148,7 +152,8 @@ func PruneImages(w http.ResponseWriter, r *http.Request) {
libpodFilters = append(libpodFilters, fmt.Sprintf("%s=%s", k, v[0]))
}
}
- cids, err := runtime.ImageRuntime().PruneImages(r.Context(), all, libpodFilters)
+
+ cids, err := runtime.ImageRuntime().PruneImages(r.Context(), query.All, libpodFilters)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
return
@@ -416,3 +421,84 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, res)
}
+
+func CommitContainer(w http.ResponseWriter, r *http.Request) {
+ var (
+ destImage string
+ mimeType string
+ )
+ decoder := r.Context().Value("decoder").(*schema.Decoder)
+ runtime := r.Context().Value("runtime").(*libpod.Runtime)
+
+ query := struct {
+ Author string `schema:"author"`
+ Changes []string `schema:"changes"`
+ Comment string `schema:"comment"`
+ Container string `schema:"container"`
+ Format string `schema:"format"`
+ Pause bool `schema:"pause"`
+ Repo string `schema:"repo"`
+ Tag string `schema:"tag"`
+ }{
+ Format: "oci",
+ }
+
+ 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
+ }
+ rtc, err := runtime.GetConfig()
+ if err != nil {
+ utils.Error(w, "failed to get runtime config", http.StatusInternalServerError, errors.Wrap(err, "failed to get runtime config"))
+ return
+ }
+ sc := image2.GetSystemContext(rtc.Engine.SignaturePolicyPath, "", false)
+ tag := "latest"
+ options := libpod.ContainerCommitOptions{
+ Pause: true,
+ }
+ switch query.Format {
+ case "oci":
+ mimeType = buildah.OCIv1ImageManifest
+ if len(query.Comment) > 0 {
+ utils.InternalServerError(w, errors.New("messages are only compatible with the docker image format (-f docker)"))
+ return
+ }
+ case "docker":
+ mimeType = manifest.DockerV2Schema2MediaType
+ default:
+ utils.InternalServerError(w, errors.Errorf("unrecognized image format %q", query.Format))
+ return
+ }
+ options.CommitOptions = buildah.CommitOptions{
+ SignaturePolicyPath: rtc.Engine.SignaturePolicyPath,
+ ReportWriter: os.Stderr,
+ SystemContext: sc,
+ PreferredManifestType: mimeType,
+ }
+
+ if len(query.Tag) > 0 {
+ tag = query.Tag
+ }
+ options.Message = query.Comment
+ options.Author = query.Author
+ options.Pause = query.Pause
+ options.Changes = query.Changes
+ ctr, err := runtime.LookupContainer(query.Container)
+ if err != nil {
+ utils.Error(w, "failed to lookup container", http.StatusNotFound, err)
+ return
+ }
+
+ // I know mitr hates this ... but doing for now
+ if len(query.Repo) > 1 {
+ destImage = fmt.Sprintf("%s:%s", query.Repo, tag)
+ }
+
+ commitImage, err := ctr.Commit(r.Context(), destImage, options)
+ if err != nil && !strings.Contains(err.Error(), "is not running") {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "CommitFailure"))
+ return
+ }
+ utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: commitImage.ID()}) // nolint
+}