mirror of
https://github.com/containers/podman.git
synced 2025-06-21 09:28:09 +08:00
add compatibility endpoint for exporting multiple images
with the recent inclusion of dealing with multiple images in a tar archive, we can now add a compatibility endpoint that was missing images/get?names=one,two. Fixes: #7950 Signed-off-by: baude <bbaude@redhat.com>
This commit is contained in:
@ -55,6 +55,7 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
|
|||||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to create tempfile"))
|
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to create tempfile"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
defer os.Remove(tmpfile.Name())
|
||||||
if err := tmpfile.Close(); err != nil {
|
if err := tmpfile.Close(); err != nil {
|
||||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to close tempfile"))
|
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to close tempfile"))
|
||||||
return
|
return
|
||||||
@ -69,7 +70,6 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer rdr.Close()
|
defer rdr.Close()
|
||||||
defer os.Remove(tmpfile.Name())
|
|
||||||
utils.WriteResponse(w, http.StatusOK, rdr)
|
utils.WriteResponse(w, http.StatusOK, rdr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,3 +398,43 @@ func LoadImages(w http.ResponseWriter, r *http.Request) {
|
|||||||
Stream: fmt.Sprintf("Loaded image: %s\n", id),
|
Stream: fmt.Sprintf("Loaded image: %s\n", id),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExportImages(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// 200 OK
|
||||||
|
// 500 Error
|
||||||
|
decoder := r.Context().Value("decoder").(*schema.Decoder)
|
||||||
|
runtime := r.Context().Value("runtime").(*libpod.Runtime)
|
||||||
|
|
||||||
|
query := struct {
|
||||||
|
Names string `schema:"names"`
|
||||||
|
}{
|
||||||
|
// 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, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
images := make([]string, 0)
|
||||||
|
images = append(images, strings.Split(query.Names, ",")...)
|
||||||
|
tmpfile, err := ioutil.TempFile("", "api.tar")
|
||||||
|
if err != nil {
|
||||||
|
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to create tempfile"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer os.Remove(tmpfile.Name())
|
||||||
|
if err := tmpfile.Close(); err != nil {
|
||||||
|
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to close tempfile"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := runtime.ImageRuntime().SaveImages(r.Context(), images, "docker-archive", tmpfile.Name(), false); err != nil {
|
||||||
|
utils.InternalServerError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rdr, err := os.Open(tmpfile.Name())
|
||||||
|
if err != nil {
|
||||||
|
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to read the exported tarfile"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer rdr.Close()
|
||||||
|
utils.WriteResponse(w, http.StatusOK, rdr)
|
||||||
|
}
|
||||||
|
@ -275,6 +275,31 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
|
|||||||
r.Handle(VersionedPath("/images/{name:.*}/get"), s.APIHandler(compat.ExportImage)).Methods(http.MethodGet)
|
r.Handle(VersionedPath("/images/{name:.*}/get"), s.APIHandler(compat.ExportImage)).Methods(http.MethodGet)
|
||||||
// Added non version path to URI to support docker non versioned paths
|
// Added non version path to URI to support docker non versioned paths
|
||||||
r.Handle("/images/{name:.*}/get", s.APIHandler(compat.ExportImage)).Methods(http.MethodGet)
|
r.Handle("/images/{name:.*}/get", s.APIHandler(compat.ExportImage)).Methods(http.MethodGet)
|
||||||
|
// swagger:operation GET /images/get compat get
|
||||||
|
// ---
|
||||||
|
// tags:
|
||||||
|
// - images (compat)
|
||||||
|
// summary: Export several images
|
||||||
|
// description: Get a tarball containing all images and metadata for several image repositories
|
||||||
|
// parameters:
|
||||||
|
// - in: query
|
||||||
|
// name: names
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// description: one or more image names or IDs comma separated
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// responses:
|
||||||
|
// 200:
|
||||||
|
// description: no error
|
||||||
|
// schema:
|
||||||
|
// type: string
|
||||||
|
// format: binary
|
||||||
|
// 500:
|
||||||
|
// $ref: '#/responses/InternalError'
|
||||||
|
r.Handle(VersionedPath("/images/get"), s.APIHandler(compat.ExportImages)).Methods(http.MethodGet)
|
||||||
|
// Added non version path to URI to support docker non versioned paths
|
||||||
|
r.Handle("/images/get", s.APIHandler(compat.ExportImages)).Methods(http.MethodGet)
|
||||||
// swagger:operation GET /images/{name:.*}/history compat imageHistory
|
// swagger:operation GET /images/{name:.*}/history compat imageHistory
|
||||||
// ---
|
// ---
|
||||||
// tags:
|
// tags:
|
||||||
|
@ -68,4 +68,7 @@ for i in $iid ${iid:0:12} $PODMAN_TEST_IMAGE_NAME; do
|
|||||||
t GET "libpod/images/$i/get?compress=false" 200 '[POSIX tar archive]'
|
t GET "libpod/images/$i/get?compress=false" 200 '[POSIX tar archive]'
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Export more than one image
|
||||||
|
t GET images/get?names=alpine,busybox 200 '[POSIX tar archive]'
|
||||||
|
|
||||||
# vim: filetype=sh
|
# vim: filetype=sh
|
||||||
|
Reference in New Issue
Block a user