summaryrefslogtreecommitdiff
path: root/pkg/api
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/api')
-rw-r--r--pkg/api/handlers/compat/containers_export.go42
-rw-r--r--pkg/api/handlers/compat/images_push.go80
-rw-r--r--pkg/api/handlers/libpod/images.go162
-rw-r--r--pkg/api/handlers/swagger.go4
-rw-r--r--pkg/api/handlers/types.go4
-rw-r--r--pkg/api/handlers/utils/images.go41
-rw-r--r--pkg/api/handlers/utils/pods.go5
-rw-r--r--pkg/api/server/register_containers.go45
-rw-r--r--pkg/api/server/register_images.go106
9 files changed, 459 insertions, 30 deletions
diff --git a/pkg/api/handlers/compat/containers_export.go b/pkg/api/handlers/compat/containers_export.go
new file mode 100644
index 000000000..37b9fbf2b
--- /dev/null
+++ b/pkg/api/handlers/compat/containers_export.go
@@ -0,0 +1,42 @@
+package compat
+
+import (
+ "io/ioutil"
+ "net/http"
+ "os"
+
+ "github.com/containers/libpod/libpod"
+ "github.com/containers/libpod/pkg/api/handlers/utils"
+ "github.com/pkg/errors"
+)
+
+func ExportContainer(w http.ResponseWriter, r *http.Request) {
+ runtime := r.Context().Value("runtime").(*libpod.Runtime)
+ name := utils.GetName(r)
+ con, err := runtime.LookupContainer(name)
+ if err != nil {
+ utils.ContainerNotFound(w, name, err)
+ return
+ }
+ tmpfile, err := ioutil.TempFile("", "api.tar")
+ if err != nil {
+ utils.Error(w, "unable to create tarball tempfile", http.StatusInternalServerError, errors.Wrap(err, "unable to create tempfile"))
+ return
+ }
+ defer os.Remove(tmpfile.Name())
+ if err := tmpfile.Close(); err != nil {
+ utils.Error(w, "unable to close tempfile", http.StatusInternalServerError, errors.Wrap(err, "unable to close tempfile"))
+ return
+ }
+ if err := con.Export(tmpfile.Name()); err != nil {
+ utils.Error(w, "failed to save the image", http.StatusInternalServerError, errors.Wrap(err, "failed to save image"))
+ return
+ }
+ rdr, err := os.Open(tmpfile.Name())
+ if err != nil {
+ utils.Error(w, "failed to read temp tarball", 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/handlers/compat/images_push.go b/pkg/api/handlers/compat/images_push.go
new file mode 100644
index 000000000..2260d5557
--- /dev/null
+++ b/pkg/api/handlers/compat/images_push.go
@@ -0,0 +1,80 @@
+package compat
+
+import (
+ "context"
+ "net/http"
+ "os"
+ "strings"
+
+ "github.com/containers/libpod/libpod"
+ "github.com/containers/libpod/libpod/image"
+ "github.com/containers/libpod/pkg/api/handlers/utils"
+ "github.com/gorilla/schema"
+ "github.com/pkg/errors"
+)
+
+// PushImage is the handler for the compat http endpoint for pushing images.
+func PushImage(w http.ResponseWriter, r *http.Request) {
+ decoder := r.Context().Value("decoder").(*schema.Decoder)
+ runtime := r.Context().Value("runtime").(*libpod.Runtime)
+
+ query := struct {
+ Tag string `schema:"tag"`
+ }{
+ // 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
+ }
+
+ // Note that Docker's docs state "Image name or ID" to be in the path
+ // parameter but it really must be a name as Docker does not allow for
+ // pushing an image by ID.
+ imageName := strings.TrimSuffix(utils.GetName(r), "/push") // GetName returns the entire path
+ if query.Tag != "" {
+ imageName += ":" + query.Tag
+ }
+ if _, err := utils.ParseStorageReference(imageName); err != nil {
+ utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
+ errors.Wrapf(err, "image source %q is not a containers-storage-transport reference", imageName))
+ return
+ }
+
+ newImage, err := runtime.ImageRuntime().NewFromLocal(imageName)
+ if err != nil {
+ utils.ImageNotFound(w, imageName, errors.Wrapf(err, "Failed to find image %s", imageName))
+ return
+ }
+
+ // TODO: the X-Registry-Auth header is not checked yet here nor in any other
+ // endpoint. Pushing does NOT work with authentication at the moment.
+ dockerRegistryOptions := &image.DockerRegistryOptions{}
+ authfile := ""
+ if sys := runtime.SystemContext(); sys != nil {
+ dockerRegistryOptions.DockerCertPath = sys.DockerCertPath
+ authfile = sys.AuthFilePath
+ }
+
+ err = newImage.PushImageToHeuristicDestination(
+ context.Background(),
+ imageName,
+ "", // manifest type
+ authfile,
+ "", // digest file
+ "", // signature policy
+ os.Stderr,
+ false, // force compression
+ image.SigningOptions{},
+ dockerRegistryOptions,
+ nil, // additional tags
+ )
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Error pushing image %q", imageName))
+ return
+ }
+
+ utils.WriteResponse(w, http.StatusOK, "")
+
+}
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index 4b24d7d9f..e7f20854c 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -14,7 +14,6 @@ import (
"github.com/containers/image/v5/docker"
"github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/manifest"
- "github.com/containers/image/v5/transports/alltransports"
"github.com/containers/image/v5/types"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/image"
@@ -254,7 +253,7 @@ func ImagesLoad(w http.ResponseWriter, r *http.Request) {
return
}
}
- utils.WriteResponse(w, http.StatusOK, handlers.LibpodImagesLoadReport{ID: loadedImage})
+ utils.WriteResponse(w, http.StatusOK, entities.ImageLoadReport{Name: loadedImage})
}
func ImagesImport(w http.ResponseWriter, r *http.Request) {
@@ -300,9 +299,13 @@ func ImagesImport(w http.ResponseWriter, r *http.Request) {
return
}
- utils.WriteResponse(w, http.StatusOK, handlers.LibpodImagesImportReport{ID: importedImage})
+ utils.WriteResponse(w, http.StatusOK, entities.ImageImportReport{Id: importedImage})
}
+// ImagesPull is the v2 libpod endpoint for pulling images. Note that the
+// mandatory `reference` must be a reference to a registry (i.e., of docker
+// transport or be normalized to one). Other transports are rejected as they
+// do not make sense in a remote context.
func ImagesPull(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder)
@@ -327,36 +330,27 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
utils.InternalServerError(w, errors.New("reference parameter cannot be empty"))
return
}
- // Enforce the docker transport. This is just a precaution as some callers
- // might accustomed to using the "transport:reference" notation. Using
- // another than the "docker://" transport does not really make sense for a
- // remote case. For loading tarballs, the load and import endpoints should
- // be used.
- imageRef, err := alltransports.ParseImageName(query.Reference)
- if err == nil && imageRef.Transport().Name() != docker.Transport.Name() {
+
+ imageRef, err := utils.ParseDockerReference(query.Reference)
+ if err != nil {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
- errors.Errorf("reference %q must be a docker reference", query.Reference))
+ errors.Wrapf(err, "image destination %q is not a docker-transport reference", query.Reference))
return
- } else if err != nil {
- origErr := err
- imageRef, err = alltransports.ParseImageName(fmt.Sprintf("%s://%s", docker.Transport.Name(), query.Reference))
- if err != nil {
- utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
- errors.Wrapf(origErr, "reference %q must be a docker reference", query.Reference))
- return
- }
}
+ // Trim the docker-transport prefix.
+ rawImage := strings.TrimPrefix(query.Reference, fmt.Sprintf("%s://", docker.Transport.Name()))
+
// all-tags doesn't work with a tagged reference, so let's check early
- namedRef, err := reference.Parse(query.Reference)
+ namedRef, err := reference.Parse(rawImage)
if err != nil {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
- errors.Wrapf(err, "error parsing reference %q", query.Reference))
+ errors.Wrapf(err, "error parsing reference %q", rawImage))
return
}
if _, isTagged := namedRef.(reference.Tagged); isTagged && query.AllTags {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
- errors.Errorf("reference %q must not have a tag for all-tags", query.Reference))
+ errors.Errorf("reference %q must not have a tag for all-tags", rawImage))
return
}
@@ -377,7 +371,7 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
OSChoice: query.OverrideOS,
ArchitectureChoice: query.OverrideArch,
}
- if query.TLSVerify {
+ if _, found := r.URL.Query()["tlsVerify"]; found {
dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!query.TLSVerify)
}
@@ -400,13 +394,19 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
}
}
+ authfile := ""
+ if sys := runtime.SystemContext(); sys != nil {
+ dockerRegistryOptions.DockerCertPath = sys.DockerCertPath
+ authfile = sys.AuthFilePath
+ }
+
// Finally pull the images
for _, img := range imagesToPull {
newImage, err := runtime.ImageRuntime().New(
context.Background(),
img,
"",
- "",
+ authfile,
os.Stderr,
&dockerRegistryOptions,
image.SigningOptions{},
@@ -422,6 +422,94 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, res)
}
+// PushImage is the handler for the compat http endpoint for pushing images.
+func PushImage(w http.ResponseWriter, r *http.Request) {
+ decoder := r.Context().Value("decoder").(*schema.Decoder)
+ runtime := r.Context().Value("runtime").(*libpod.Runtime)
+
+ query := struct {
+ Credentials string `schema:"credentials"`
+ Destination string `schema:"destination"`
+ TLSVerify bool `schema:"tlsVerify"`
+ }{
+ // 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
+ }
+
+ source := strings.TrimSuffix(utils.GetName(r), "/push") // GetName returns the entire path
+ if _, err := utils.ParseStorageReference(source); err != nil {
+ utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
+ errors.Wrapf(err, "image source %q is not a containers-storage-transport reference", source))
+ return
+ }
+
+ destination := query.Destination
+ if destination == "" {
+ destination = source
+ }
+
+ if _, err := utils.ParseDockerReference(destination); err != nil {
+ utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
+ errors.Wrapf(err, "image destination %q is not a docker-transport reference", destination))
+ return
+ }
+
+ newImage, err := runtime.ImageRuntime().NewFromLocal(source)
+ if err != nil {
+ utils.ImageNotFound(w, source, errors.Wrapf(err, "Failed to find image %s", source))
+ return
+ }
+
+ var registryCreds *types.DockerAuthConfig
+ if len(query.Credentials) != 0 {
+ creds, err := util.ParseRegistryCreds(query.Credentials)
+ if err != nil {
+ utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
+ errors.Wrapf(err, "error parsing credentials %q", query.Credentials))
+ return
+ }
+ registryCreds = creds
+ }
+
+ // TODO: the X-Registry-Auth header is not checked yet here nor in any other
+ // endpoint. Pushing does NOT work with authentication at the moment.
+ dockerRegistryOptions := &image.DockerRegistryOptions{
+ DockerRegistryCreds: registryCreds,
+ }
+ authfile := ""
+ if sys := runtime.SystemContext(); sys != nil {
+ dockerRegistryOptions.DockerCertPath = sys.DockerCertPath
+ authfile = sys.AuthFilePath
+ }
+ if _, found := r.URL.Query()["tlsVerify"]; found {
+ dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!query.TLSVerify)
+ }
+
+ err = newImage.PushImageToHeuristicDestination(
+ context.Background(),
+ destination,
+ "", // manifest type
+ authfile,
+ "", // digest file
+ "", // signature policy
+ os.Stderr,
+ false, // force compression
+ image.SigningOptions{},
+ dockerRegistryOptions,
+ nil, // additional tags
+ )
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Error pushing image %q", destination))
+ return
+ }
+
+ utils.WriteResponse(w, http.StatusOK, "")
+}
+
func CommitContainer(w http.ResponseWriter, r *http.Request) {
var (
destImage string
@@ -502,3 +590,29 @@ func CommitContainer(w http.ResponseWriter, r *http.Request) {
}
utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: commitImage.ID()}) // nolint
}
+
+func UntagImage(w http.ResponseWriter, r *http.Request) {
+ runtime := r.Context().Value("runtime").(*libpod.Runtime)
+
+ name := utils.GetName(r)
+ newImage, err := runtime.ImageRuntime().NewFromLocal(name)
+ if err != nil {
+ utils.ImageNotFound(w, name, errors.Wrapf(err, "Failed to find image %s", name))
+ return
+ }
+ tag := "latest"
+ if len(r.Form.Get("tag")) > 0 {
+ tag = r.Form.Get("tag")
+ }
+ if len(r.Form.Get("repo")) < 1 {
+ utils.Error(w, "repo tag is required", http.StatusBadRequest, errors.New("repo parameter is required to tag an image"))
+ return
+ }
+ repo := r.Form.Get("repo")
+ tagName := fmt.Sprintf("%s:%s", repo, tag)
+ if err := newImage.UntagImage(tagName); err != nil {
+ utils.Error(w, "failed to untag", http.StatusInternalServerError, err)
+ return
+ }
+ utils.WriteResponse(w, http.StatusCreated, "")
+}
diff --git a/pkg/api/handlers/swagger.go b/pkg/api/handlers/swagger.go
index 52763a050..33a9fdd58 100644
--- a/pkg/api/handlers/swagger.go
+++ b/pkg/api/handlers/swagger.go
@@ -31,14 +31,14 @@ type swagImageInspect struct {
// swagger:response DocsLibpodImagesLoadResponse
type swagLibpodImagesLoadResponse struct {
// in:body
- Body []LibpodImagesLoadReport
+ Body entities.ImageLoadReport
}
// Import response
// swagger:response DocsLibpodImagesImportResponse
type swagLibpodImagesImportResponse struct {
// in:body
- Body LibpodImagesImportReport
+ Body entities.ImageImportReport
}
// Pull response
diff --git a/pkg/api/handlers/types.go b/pkg/api/handlers/types.go
index 89a571e67..496512f2e 100644
--- a/pkg/api/handlers/types.go
+++ b/pkg/api/handlers/types.go
@@ -38,10 +38,6 @@ type LibpodImagesLoadReport struct {
ID string `json:"id"`
}
-type LibpodImagesImportReport struct {
- ID string `json:"id"`
-}
-
type LibpodImagesPullReport struct {
ID string `json:"id"`
}
diff --git a/pkg/api/handlers/utils/images.go b/pkg/api/handlers/utils/images.go
index 696d5f745..1c67de9db 100644
--- a/pkg/api/handlers/utils/images.go
+++ b/pkg/api/handlers/utils/images.go
@@ -4,11 +4,52 @@ import (
"fmt"
"net/http"
+ "github.com/containers/image/v5/docker"
+ "github.com/containers/image/v5/storage"
+ "github.com/containers/image/v5/transports/alltransports"
+ "github.com/containers/image/v5/types"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/image"
"github.com/gorilla/schema"
+ "github.com/pkg/errors"
)
+// ParseDockerReference parses the specified image name to a
+// `types.ImageReference` and enforces it to refer to a docker-transport
+// reference.
+func ParseDockerReference(name string) (types.ImageReference, error) {
+ dockerPrefix := fmt.Sprintf("%s://", docker.Transport.Name())
+ imageRef, err := alltransports.ParseImageName(name)
+ if err == nil && imageRef.Transport().Name() != docker.Transport.Name() {
+ return nil, errors.Errorf("reference %q must be a docker reference", name)
+ } else if err != nil {
+ origErr := err
+ imageRef, err = alltransports.ParseImageName(fmt.Sprintf("%s%s", dockerPrefix, name))
+ if err != nil {
+ return nil, errors.Wrapf(origErr, "reference %q must be a docker reference", name)
+ }
+ }
+ return imageRef, nil
+}
+
+// ParseStorageReference parses the specified image name to a
+// `types.ImageReference` and enforces it to refer to a
+// containers-storage-transport reference.
+func ParseStorageReference(name string) (types.ImageReference, error) {
+ storagePrefix := fmt.Sprintf("%s:", storage.Transport.Name())
+ imageRef, err := alltransports.ParseImageName(name)
+ if err == nil && imageRef.Transport().Name() != docker.Transport.Name() {
+ return nil, errors.Errorf("reference %q must be a storage reference", name)
+ } else if err != nil {
+ origErr := err
+ imageRef, err = alltransports.ParseImageName(fmt.Sprintf("%s%s", storagePrefix, name))
+ if err != nil {
+ return nil, errors.Wrapf(origErr, "reference %q must be a storage reference", name)
+ }
+ }
+ return imageRef, nil
+}
+
// GetImages is a common function used to get images for libpod and other compatibility
// mechanisms
func GetImages(w http.ResponseWriter, r *http.Request) ([]*image.Image, error) {
diff --git a/pkg/api/handlers/utils/pods.go b/pkg/api/handlers/utils/pods.go
index 79d1a5090..d47053eda 100644
--- a/pkg/api/handlers/utils/pods.go
+++ b/pkg/api/handlers/utils/pods.go
@@ -59,6 +59,10 @@ func GetPods(w http.ResponseWriter, r *http.Request) ([]*entities.ListPodsReport
if err != nil {
return nil, err
}
+ infraId, err := pod.InfraContainerID()
+ if err != nil {
+ return nil, err
+ }
lp := entities.ListPodsReport{
Cgroup: pod.CgroupParent(),
Created: pod.CreatedTime(),
@@ -66,6 +70,7 @@ func GetPods(w http.ResponseWriter, r *http.Request) ([]*entities.ListPodsReport
Name: pod.Name(),
Namespace: pod.Namespace(),
Status: status,
+ InfraId: infraId,
}
for _, ctr := range ctrs {
state, err := ctr.State()
diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go
index 08834ff01..145c054c0 100644
--- a/pkg/api/server/register_containers.go
+++ b/pkg/api/server/register_containers.go
@@ -587,6 +587,29 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
r.HandleFunc(VersionedPath("/containers/{name}/resize"), s.APIHandler(compat.ResizeContainer)).Methods(http.MethodPost)
// Added non version path to URI to support docker non versioned paths
r.HandleFunc("/containers/{name}/resize", s.APIHandler(compat.ResizeContainer)).Methods(http.MethodPost)
+ // swagger:operation GET /containers/{name}/export compat exportContainer
+ // ---
+ // tags:
+ // - containers (compat)
+ // summary: Export a container
+ // description: Export the contents of a container as a tarball.
+ // parameters:
+ // - in: path
+ // name: name
+ // type: string
+ // required: true
+ // description: the name or ID of the container
+ // produces:
+ // - application/json
+ // responses:
+ // 200:
+ // description: tarball is returned in body
+ // 404:
+ // $ref: "#/responses/NoSuchContainer"
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.HandleFunc(VersionedPath("/containers/{name}/export"), s.APIHandler(compat.ExportContainer)).Methods(http.MethodGet)
+ r.HandleFunc("/containers/{name}/export", s.APIHandler(compat.ExportContainer)).Methods(http.MethodGet)
/*
libpod endpoints
@@ -1237,5 +1260,27 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// 500:
// $ref: "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/{name}/resize"), s.APIHandler(compat.ResizeContainer)).Methods(http.MethodPost)
+ // swagger:operation GET /libpod/containers/{name}/export libpod libpodExportContainer
+ // ---
+ // tags:
+ // - containers
+ // summary: Export a container
+ // description: Export the contents of a container as a tarball.
+ // parameters:
+ // - in: path
+ // name: name
+ // type: string
+ // required: true
+ // description: the name or ID of the container
+ // produces:
+ // - application/json
+ // responses:
+ // 200:
+ // description: tarball is returned in body
+ // 404:
+ // $ref: "#/responses/NoSuchContainer"
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.HandleFunc(VersionedPath("/libpod/containers/{name}/export"), s.APIHandler(compat.ExportContainer)).Methods(http.MethodGet)
return nil
}
diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go
index e8dfe2fa8..e4e46025b 100644
--- a/pkg/api/server/register_images.go
+++ b/pkg/api/server/register_images.go
@@ -211,6 +211,41 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
r.Handle(VersionedPath("/images/{name:.*}"), s.APIHandler(compat.RemoveImage)).Methods(http.MethodDelete)
// Added non version path to URI to support docker non versioned paths
r.Handle("/images/{name:.*}", s.APIHandler(compat.RemoveImage)).Methods(http.MethodDelete)
+ // swagger:operation POST /images/{name:.*}/push compat pushImage
+ // ---
+ // tags:
+ // - images (compat)
+ // summary: Push Image
+ // description: Push an image to a container registry
+ // parameters:
+ // - in: path
+ // name: name:.*
+ // type: string
+ // required: true
+ // description: Name of image to push.
+ // - in: query
+ // name: tag
+ // type: string
+ // description: The tag to associate with the image on the registry.
+ // - in: header
+ // name: X-Registry-Auth
+ // type: string
+ // description: A base64-encoded auth configuration.
+ // produces:
+ // - application/json
+ // responses:
+ // 200:
+ // description: no error
+ // schema:
+ // type: string
+ // format: binary
+ // 404:
+ // $ref: '#/responses/NoSuchImage'
+ // 500:
+ // $ref: '#/responses/InternalError'
+ r.Handle(VersionedPath("/images/{name:.*}/push"), s.APIHandler(compat.PushImage)).Methods(http.MethodPost)
+ // Added non version path to URI to support docker non versioned paths
+ r.Handle("/images/{name:.*}/push", s.APIHandler(compat.PushImage)).Methods(http.MethodPost)
// swagger:operation GET /images/{name:.*}/get compat exportImage
// ---
// tags:
@@ -583,6 +618,43 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
libpod endpoints
*/
+ // swagger:operation POST /libpod/images/{name:.*}/push libpod libpodPushImage
+ // ---
+ // tags:
+ // - images (libpod)
+ // summary: Push Image
+ // description: Push an image to a container registry
+ // parameters:
+ // - in: path
+ // name: name:.*
+ // type: string
+ // required: true
+ // description: Name of image to push.
+ // - in: query
+ // name: tag
+ // type: string
+ // description: The tag to associate with the image on the registry.
+ // - in: query
+ // name: credentials
+ // description: username:password for the registry.
+ // type: string
+ // - in: header
+ // name: X-Registry-Auth
+ // type: string
+ // description: A base64-encoded auth configuration.
+ // produces:
+ // - application/json
+ // responses:
+ // 200:
+ // description: no error
+ // schema:
+ // type: string
+ // format: binary
+ // 404:
+ // $ref: '#/responses/NoSuchImage'
+ // 500:
+ // $ref: '#/responses/InternalError'
+ r.Handle(VersionedPath("/libpod/images/{name:.*}/push"), s.APIHandler(libpod.PushImage)).Methods(http.MethodPost)
// swagger:operation GET /libpod/images/{name:.*}/exists libpod libpodImageExists
// ---
// tags:
@@ -1019,5 +1091,39 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// 500:
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/libpod/commit"), s.APIHandler(libpod.CommitContainer)).Methods(http.MethodPost)
+ // swagger:operation POST /libpod/images/{name:.*}/untag libpod libpodUntagImage
+ // ---
+ // tags:
+ // - images
+ // summary: Untag an image
+ // description: Untag an image
+ // parameters:
+ // - in: path
+ // name: name:.*
+ // type: string
+ // required: true
+ // description: the name or ID of the container
+ // - in: query
+ // name: repo
+ // type: string
+ // description: the repository to untag
+ // - in: query
+ // name: tag
+ // type: string
+ // description: the name of the tag to untag
+ // produces:
+ // - application/json
+ // responses:
+ // 201:
+ // description: no error
+ // 400:
+ // $ref: '#/responses/BadParamError'
+ // 404:
+ // $ref: '#/responses/NoSuchImage'
+ // 409:
+ // $ref: '#/responses/ConflictError'
+ // 500:
+ // $ref: '#/responses/InternalError'
+ r.Handle(VersionedPath("/libpod/images/{name:.*}/untag"), s.APIHandler(libpod.UntagImage)).Methods(http.MethodPost)
return nil
}