summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com>2020-10-08 18:11:59 -0400
committerGitHub <noreply@github.com>2020-10-08 18:11:59 -0400
commit2a63795338e4ccd4066566ac46856f37587d9db2 (patch)
tree35d6394a92732c5b58e95cd83a30689b7fc00a3b
parente9961e053cab35abffc575fb9cbd6e7c4e79a324 (diff)
parent78a06c2802ec7bb91607bb80cdb57ae3f639b448 (diff)
downloadpodman-2a63795338e4ccd4066566ac46856f37587d9db2.tar.gz
podman-2a63795338e4ccd4066566ac46856f37587d9db2.tar.bz2
podman-2a63795338e4ccd4066566ac46856f37587d9db2.zip
Merge pull request #7966 from baude/issue7950
add compatibility endpoint for exporting multiple images
-rw-r--r--pkg/api/handlers/compat/images.go42
-rw-r--r--pkg/api/server/register_images.go25
-rw-r--r--test/apiv2/10-images.at3
3 files changed, 69 insertions, 1 deletions
diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go
index 9d8bc497a..f49ce59da 100644
--- a/pkg/api/handlers/compat/images.go
+++ b/pkg/api/handlers/compat/images.go
@@ -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)
+}
diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go
index cb0d26d1e..ad779203d 100644
--- a/pkg/api/server/register_images.go
+++ b/pkg/api/server/register_images.go
@@ -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:
diff --git a/test/apiv2/10-images.at b/test/apiv2/10-images.at
index bdc298ae3..f669bc892 100644
--- a/test/apiv2/10-images.at
+++ b/test/apiv2/10-images.at
@@ -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