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:
baude
2020-10-08 09:47:07 -05:00
parent 59b5f0ac32
commit 78a06c2802
3 changed files with 69 additions and 1 deletions

View File

@ -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"))
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
@ -69,7 +70,6 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
return
}
defer rdr.Close()
defer os.Remove(tmpfile.Name())
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),
})
}
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)
}

View File

@ -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)
// Added non version path to URI to support docker non versioned paths
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
// ---
// tags:

View File

@ -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]'
done
# Export more than one image
t GET images/get?names=alpine,busybox 200 '[POSIX tar archive]'
# vim: filetype=sh