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