github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/pkg/api/handlers/libpod/manifests.go (about)

     1  package libpod
     2  
     3  import (
     4  	"encoding/json"
     5  	"net/http"
     6  
     7  	"github.com/containers/buildah/manifests"
     8  	copy2 "github.com/containers/image/v5/copy"
     9  	"github.com/containers/image/v5/transports/alltransports"
    10  	"github.com/containers/libpod/libpod"
    11  	"github.com/containers/libpod/libpod/image"
    12  	"github.com/containers/libpod/pkg/api/handlers"
    13  	"github.com/containers/libpod/pkg/api/handlers/utils"
    14  	"github.com/gorilla/schema"
    15  	"github.com/opencontainers/go-digest"
    16  	"github.com/pkg/errors"
    17  )
    18  
    19  func ManifestCreate(w http.ResponseWriter, r *http.Request) {
    20  	runtime := r.Context().Value("runtime").(*libpod.Runtime)
    21  	decoder := r.Context().Value("decoder").(*schema.Decoder)
    22  	query := struct {
    23  		Name  []string `schema:"name"`
    24  		Image []string `schema:"image"`
    25  		All   bool     `schema:"all"`
    26  	}{
    27  		// Add defaults here once needed.
    28  	}
    29  	if err := decoder.Decode(&query, r.URL.Query()); err != nil {
    30  		utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
    31  			errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
    32  		return
    33  	}
    34  	rtc, err := runtime.GetConfig()
    35  	if err != nil {
    36  		utils.InternalServerError(w, err)
    37  		return
    38  	}
    39  	sc := image.GetSystemContext(rtc.Engine.SignaturePolicyPath, "", false)
    40  	manID, err := image.CreateManifestList(runtime.ImageRuntime(), *sc, query.Name, query.Image, query.All)
    41  	if err != nil {
    42  		utils.InternalServerError(w, err)
    43  		return
    44  	}
    45  	utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: manID})
    46  }
    47  
    48  func ManifestInspect(w http.ResponseWriter, r *http.Request) {
    49  	runtime := r.Context().Value("runtime").(*libpod.Runtime)
    50  	name := utils.GetName(r)
    51  	newImage, err := runtime.ImageRuntime().NewFromLocal(name)
    52  	if err != nil {
    53  		utils.ImageNotFound(w, name, err)
    54  		return
    55  	}
    56  	data, err := newImage.InspectManifest()
    57  	if err != nil {
    58  		utils.InternalServerError(w, err)
    59  		return
    60  	}
    61  	utils.WriteResponse(w, http.StatusOK, data)
    62  }
    63  
    64  func ManifestAdd(w http.ResponseWriter, r *http.Request) {
    65  	runtime := r.Context().Value("runtime").(*libpod.Runtime)
    66  	var manifestInput image.ManifestAddOpts
    67  	if err := json.NewDecoder(r.Body).Decode(&manifestInput); err != nil {
    68  		utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()"))
    69  		return
    70  	}
    71  	name := utils.GetName(r)
    72  	newImage, err := runtime.ImageRuntime().NewFromLocal(name)
    73  	if err != nil {
    74  		utils.ImageNotFound(w, name, err)
    75  		return
    76  	}
    77  	rtc, err := runtime.GetConfig()
    78  	if err != nil {
    79  		utils.InternalServerError(w, err)
    80  		return
    81  	}
    82  	sc := image.GetSystemContext(rtc.Engine.SignaturePolicyPath, "", false)
    83  	newID, err := newImage.AddManifest(*sc, manifestInput)
    84  	if err != nil {
    85  		utils.InternalServerError(w, err)
    86  		return
    87  	}
    88  	utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: newID})
    89  }
    90  
    91  func ManifestRemove(w http.ResponseWriter, r *http.Request) {
    92  	runtime := r.Context().Value("runtime").(*libpod.Runtime)
    93  	decoder := r.Context().Value("decoder").(*schema.Decoder)
    94  	query := struct {
    95  		Digest string `schema:"digest"`
    96  	}{
    97  		// Add defaults here once needed.
    98  	}
    99  	name := utils.GetName(r)
   100  	if err := decoder.Decode(&query, r.URL.Query()); err != nil {
   101  		utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
   102  			errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
   103  		return
   104  	}
   105  	newImage, err := runtime.ImageRuntime().NewFromLocal(name)
   106  	if err != nil {
   107  		utils.ImageNotFound(w, name, err)
   108  		return
   109  	}
   110  	d, err := digest.Parse(query.Digest)
   111  	if err != nil {
   112  		utils.Error(w, "invalid digest", http.StatusBadRequest, err)
   113  		return
   114  	}
   115  	newID, err := newImage.RemoveManifest(d)
   116  	if err != nil {
   117  		utils.InternalServerError(w, err)
   118  		return
   119  	}
   120  	utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: newID})
   121  }
   122  func ManifestPush(w http.ResponseWriter, r *http.Request) {
   123  	runtime := r.Context().Value("runtime").(*libpod.Runtime)
   124  	decoder := r.Context().Value("decoder").(*schema.Decoder)
   125  	query := struct {
   126  		All         bool   `schema:"all"`
   127  		Destination string `schema:"destination"`
   128  	}{
   129  		// Add defaults here once needed.
   130  	}
   131  	if err := decoder.Decode(&query, r.URL.Query()); err != nil {
   132  		utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
   133  			errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
   134  		return
   135  	}
   136  	name := utils.GetName(r)
   137  	newImage, err := runtime.ImageRuntime().NewFromLocal(name)
   138  	if err != nil {
   139  		utils.ImageNotFound(w, name, err)
   140  		return
   141  	}
   142  	dest, err := alltransports.ParseImageName(query.Destination)
   143  	if err != nil {
   144  		utils.Error(w, "invalid destination parameter", http.StatusBadRequest, errors.Errorf("invalid destination parameter %q", query.Destination))
   145  		return
   146  	}
   147  	rtc, err := runtime.GetConfig()
   148  	if err != nil {
   149  		utils.InternalServerError(w, err)
   150  		return
   151  	}
   152  	sc := image.GetSystemContext(rtc.Engine.SignaturePolicyPath, "", false)
   153  	opts := manifests.PushOptions{
   154  		ImageListSelection: copy2.CopySpecificImages,
   155  		SystemContext:      sc,
   156  	}
   157  	if query.All {
   158  		opts.ImageListSelection = copy2.CopyAllImages
   159  	}
   160  	newD, err := newImage.PushManifest(dest, opts)
   161  	if err != nil {
   162  		utils.InternalServerError(w, err)
   163  		return
   164  	}
   165  	utils.WriteResponse(w, http.StatusOK, newD.String())
   166  }