summaryrefslogtreecommitdiff
path: root/pkg/api
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/api')
-rw-r--r--pkg/api/handlers/compat/containers_archive.go12
-rw-r--r--pkg/api/handlers/compat/images.go30
-rw-r--r--pkg/api/handlers/compat/images_push.go15
-rw-r--r--pkg/api/handlers/libpod/copy.go12
-rw-r--r--pkg/api/handlers/libpod/images.go71
-rw-r--r--pkg/api/handlers/libpod/manifests.go4
-rw-r--r--pkg/api/handlers/libpod/play.go20
-rw-r--r--pkg/api/handlers/utils/pods.go1
-rw-r--r--pkg/api/server/register_archive.go171
-rw-r--r--pkg/api/server/register_images.go8
-rw-r--r--pkg/api/server/server.go1
-rw-r--r--pkg/api/server/swagger.go7
12 files changed, 293 insertions, 59 deletions
diff --git a/pkg/api/handlers/compat/containers_archive.go b/pkg/api/handlers/compat/containers_archive.go
new file mode 100644
index 000000000..c3a26873e
--- /dev/null
+++ b/pkg/api/handlers/compat/containers_archive.go
@@ -0,0 +1,12 @@
+package compat
+
+import (
+ "errors"
+ "net/http"
+
+ "github.com/containers/libpod/pkg/api/handlers/utils"
+)
+
+func Archive(w http.ResponseWriter, r *http.Request) {
+ utils.Error(w, "not implemented", http.StatusNotImplemented, errors.New("not implemented"))
+}
diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go
index ea9cbd691..b64ed0036 100644
--- a/pkg/api/handlers/compat/images.go
+++ b/pkg/api/handlers/compat/images.go
@@ -15,6 +15,7 @@ import (
image2 "github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/api/handlers"
"github.com/containers/libpod/pkg/api/handlers/utils"
+ "github.com/containers/libpod/pkg/auth"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/pkg/util"
"github.com/docker/docker/api/types"
@@ -251,19 +252,32 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) {
return
}
- /*
- fromImage – Name of the image to pull. The name may include a tag or digest. This parameter may only be used when pulling an image. The pull is cancelled if the HTTP connection is closed.
- repo – Repository name given to an image when it is imported. The repo may include a tag. This parameter may only be used when importing an image.
- tag – Tag or digest. If empty when pulling an image, this causes all tags for the given image to be pulled.
- */
fromImage := query.FromImage
if len(query.Tag) >= 1 {
fromImage = fmt.Sprintf("%s:%s", fromImage, query.Tag)
}
- // TODO
- // We are eating the output right now because we haven't talked about how to deal with multiple responses yet
- img, err := runtime.ImageRuntime().New(r.Context(), fromImage, "", "", nil, &image2.DockerRegistryOptions{}, image2.SigningOptions{}, nil, util.PullImageMissing)
+ authConf, authfile, err := auth.GetCredentials(r)
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse %q header for %s", auth.XRegistryAuthHeader, r.URL.String()))
+ return
+ }
+ defer auth.RemoveAuthfile(authfile)
+
+ registryOpts := image2.DockerRegistryOptions{DockerRegistryCreds: authConf}
+ if sys := runtime.SystemContext(); sys != nil {
+ registryOpts.DockerCertPath = sys.DockerCertPath
+ }
+ img, err := runtime.ImageRuntime().New(r.Context(),
+ fromImage,
+ "", // signature policy
+ authfile,
+ nil, // writer
+ &registryOpts,
+ image2.SigningOptions{},
+ nil, // label
+ util.PullImageMissing,
+ )
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
return
diff --git a/pkg/api/handlers/compat/images_push.go b/pkg/api/handlers/compat/images_push.go
index 2260d5557..47976b7c9 100644
--- a/pkg/api/handlers/compat/images_push.go
+++ b/pkg/api/handlers/compat/images_push.go
@@ -9,6 +9,7 @@ import (
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/api/handlers/utils"
+ "github.com/containers/libpod/pkg/auth"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
@@ -48,13 +49,17 @@ func PushImage(w http.ResponseWriter, r *http.Request) {
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 := ""
+ authConf, authfile, err := auth.GetCredentials(r)
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse %q header for %s", auth.XRegistryAuthHeader, r.URL.String()))
+ return
+ }
+ defer auth.RemoveAuthfile(authfile)
+
+ dockerRegistryOptions := &image.DockerRegistryOptions{DockerRegistryCreds: authConf}
if sys := runtime.SystemContext(); sys != nil {
dockerRegistryOptions.DockerCertPath = sys.DockerCertPath
- authfile = sys.AuthFilePath
+ dockerRegistryOptions.RegistriesConfPath = sys.SystemRegistriesConfPath
}
err = newImage.PushImageToHeuristicDestination(
diff --git a/pkg/api/handlers/libpod/copy.go b/pkg/api/handlers/libpod/copy.go
new file mode 100644
index 000000000..a3b404bce
--- /dev/null
+++ b/pkg/api/handlers/libpod/copy.go
@@ -0,0 +1,12 @@
+package libpod
+
+import (
+ "net/http"
+
+ "github.com/containers/libpod/pkg/api/handlers/utils"
+ "github.com/pkg/errors"
+)
+
+func Archive(w http.ResponseWriter, r *http.Request) {
+ utils.Error(w, "not implemented", http.StatusNotImplemented, errors.New("not implemented"))
+}
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index 1cbcfb52c..54e202103 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -21,6 +21,7 @@ import (
image2 "github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/api/handlers"
"github.com/containers/libpod/pkg/api/handlers/utils"
+ "github.com/containers/libpod/pkg/auth"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/pkg/domain/infra/abi"
"github.com/containers/libpod/pkg/errorhandling"
@@ -28,6 +29,7 @@ import (
utils2 "github.com/containers/libpod/utils"
"github.com/gorilla/schema"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
// Commit
@@ -179,6 +181,12 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String()))
return
}
+ name := utils.GetName(r)
+ newImage, err := runtime.ImageRuntime().NewFromLocal(name)
+ if err != nil {
+ utils.ImageNotFound(w, name, err)
+ return
+ }
switch query.Format {
case define.OCIArchive, define.V2s2Archive:
tmpfile, err := ioutil.TempFile("", "api.tar")
@@ -202,13 +210,6 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "unknown format", http.StatusInternalServerError, errors.Errorf("unknown format %q", query.Format))
return
}
- name := utils.GetName(r)
- newImage, err := runtime.ImageRuntime().NewFromLocal(name)
- if err != nil {
- utils.ImageNotFound(w, name, err)
- return
- }
-
if err := newImage.Save(r.Context(), name, query.Format, output, []string{}, false, query.Compress); err != nil {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, err)
return
@@ -339,7 +340,6 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
Reference string `schema:"reference"`
- Credentials string `schema:"credentials"`
OverrideOS string `schema:"overrideOS"`
OverrideArch string `schema:"overrideArch"`
TLSVerify bool `schema:"tlsVerify"`
@@ -382,20 +382,16 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
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
+ authConf, authfile, err := auth.GetCredentials(r)
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse %q header for %s", auth.XRegistryAuthHeader, r.URL.String()))
+ return
}
+ defer auth.RemoveAuthfile(authfile)
// Setup the registry options
dockerRegistryOptions := image.DockerRegistryOptions{
- DockerRegistryCreds: registryCreds,
+ DockerRegistryCreds: authConf,
OSChoice: query.OverrideOS,
ArchitectureChoice: query.OverrideArch,
}
@@ -403,6 +399,13 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!query.TLSVerify)
}
+ sys := runtime.SystemContext()
+ if sys == nil {
+ sys = image.GetSystemContext("", authfile, false)
+ }
+ dockerRegistryOptions.DockerCertPath = sys.DockerCertPath
+ sys.DockerAuthConfig = authConf
+
// Prepare the images we want to pull
imagesToPull := []string{}
res := []handlers.LibpodImagesPullReport{}
@@ -411,8 +414,7 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
if !query.AllTags {
imagesToPull = append(imagesToPull, imageName)
} else {
- systemContext := image.GetSystemContext("", "", false)
- tags, err := docker.GetRepositoryTags(context.Background(), systemContext, imageRef)
+ tags, err := docker.GetRepositoryTags(context.Background(), sys, imageRef)
if err != nil {
utils.InternalServerError(w, errors.Wrap(err, "error getting repository tags"))
return
@@ -422,12 +424,6 @@ 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(
@@ -456,7 +452,6 @@ func PushImage(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
query := struct {
- Credentials string `schema:"credentials"`
Destination string `schema:"destination"`
TLSVerify bool `schema:"tlsVerify"`
}{
@@ -492,26 +487,20 @@ func PushImage(w http.ResponseWriter, r *http.Request) {
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
+ authConf, authfile, err := auth.GetCredentials(r)
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse %q header for %s", auth.XRegistryAuthHeader, r.URL.String()))
+ return
}
+ defer auth.RemoveAuthfile(authfile)
+ logrus.Errorf("AuthConf: %v", authConf)
- // 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,
+ DockerRegistryCreds: authConf,
}
- authfile := ""
if sys := runtime.SystemContext(); sys != nil {
dockerRegistryOptions.DockerCertPath = sys.DockerCertPath
- authfile = sys.AuthFilePath
+ dockerRegistryOptions.RegistriesConfPath = sys.SystemRegistriesConfPath
}
if _, found := r.URL.Query()["tlsVerify"]; found {
dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!query.TLSVerify)
diff --git a/pkg/api/handlers/libpod/manifests.go b/pkg/api/handlers/libpod/manifests.go
index 93ca367f7..aef92368b 100644
--- a/pkg/api/handlers/libpod/manifests.go
+++ b/pkg/api/handlers/libpod/manifests.go
@@ -120,6 +120,10 @@ func ManifestRemove(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: newID})
}
func ManifestPush(w http.ResponseWriter, r *http.Request) {
+ // FIXME: parameters are missing (tlsVerify, format).
+ // Also, we should use the ABI function to avoid duplicate code.
+ // Also, support for XRegistryAuth headers are missing.
+
runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
diff --git a/pkg/api/handlers/libpod/play.go b/pkg/api/handlers/libpod/play.go
index 26e02bf4f..1cb5cdb6c 100644
--- a/pkg/api/handlers/libpod/play.go
+++ b/pkg/api/handlers/libpod/play.go
@@ -9,6 +9,7 @@ import (
"github.com/containers/image/v5/types"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/api/handlers/utils"
+ "github.com/containers/libpod/pkg/auth"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/pkg/domain/infra/abi"
"github.com/gorilla/schema"
@@ -47,9 +48,26 @@ func PlayKube(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error closing temporary file"))
return
}
+ authConf, authfile, err := auth.GetCredentials(r)
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse %q header for %s", auth.XRegistryAuthHeader, r.URL.String()))
+ return
+ }
+ defer auth.RemoveAuthfile(authfile)
+ var username, password string
+ if authConf != nil {
+ username = authConf.Username
+ password = authConf.Password
+ }
containerEngine := abi.ContainerEngine{Libpod: runtime}
- options := entities.PlayKubeOptions{Network: query.Network, Quiet: true}
+ options := entities.PlayKubeOptions{
+ Authfile: authfile,
+ Username: username,
+ Password: password,
+ Network: query.Network,
+ Quiet: true,
+ }
if _, found := r.URL.Query()["tlsVerify"]; found {
options.SkipTLSVerify = types.NewOptionalBool(!query.TLSVerify)
}
diff --git a/pkg/api/handlers/utils/pods.go b/pkg/api/handlers/utils/pods.go
index fb795fa6a..5b6f6d34d 100644
--- a/pkg/api/handlers/utils/pods.go
+++ b/pkg/api/handlers/utils/pods.go
@@ -66,6 +66,7 @@ func GetPods(w http.ResponseWriter, r *http.Request) ([]*entities.ListPodsReport
Namespace: pod.Namespace(),
Status: status,
InfraId: infraId,
+ Labels: pod.Labels(),
}
for _, ctr := range ctrs {
state, err := ctr.State()
diff --git a/pkg/api/server/register_archive.go b/pkg/api/server/register_archive.go
new file mode 100644
index 000000000..a1d5941bc
--- /dev/null
+++ b/pkg/api/server/register_archive.go
@@ -0,0 +1,171 @@
+package server
+
+import (
+ "net/http"
+
+ "github.com/containers/libpod/pkg/api/handlers/compat"
+ "github.com/containers/libpod/pkg/api/handlers/libpod"
+ "github.com/gorilla/mux"
+)
+
+func (s *APIServer) registerAchiveHandlers(r *mux.Router) error {
+ // swagger:operation POST /containers/{name}/archive compat putArchive
+ // ---
+ // summary: Put files into a container
+ // description: Put a tar archive of files into a container
+ // tags:
+ // - containers (compat)
+ // produces:
+ // - application/json
+ // parameters:
+ // - in: path
+ // name: name
+ // type: string
+ // description: container name or id
+ // required: true
+ // - in: query
+ // name: path
+ // type: string
+ // description: Path to a directory in the container to extract
+ // required: true
+ // - in: query
+ // name: noOverwriteDirNonDir
+ // type: string
+ // description: if unpacking the given content would cause an existing directory to be replaced with a non-directory and vice versa (1 or true)
+ // - in: query
+ // name: copyUIDGID
+ // type: string
+ // description: copy UID/GID maps to the dest file or di (1 or true)
+ // - in: body
+ // name: request
+ // description: tarfile of files to copy into the container
+ // schema:
+ // type: string
+ // responses:
+ // 200:
+ // description: no error
+ // 400:
+ // $ref: "#/responses/BadParamError"
+ // 403:
+ // description: the container rootfs is read-only
+ // 404:
+ // $ref: "#/responses/NoSuchContainer"
+ // 500:
+ // $ref: "#/responses/InternalError"
+
+ // swagger:operation GET /containers/{name}/archive compat getArchive
+ // ---
+ // summary: Get files from a container
+ // description: Get a tar archive of files from a container
+ // tags:
+ // - containers (compat)
+ // produces:
+ // - application/json
+ // parameters:
+ // - in: path
+ // name: name
+ // type: string
+ // description: container name or id
+ // required: true
+ // - in: query
+ // name: path
+ // type: string
+ // description: Path to a directory in the container to extract
+ // required: true
+ // responses:
+ // 200:
+ // description: no error
+ // schema:
+ // type: string
+ // format: binary
+ // 400:
+ // $ref: "#/responses/BadParamError"
+ // 404:
+ // $ref: "#/responses/NoSuchContainer"
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.HandleFunc(VersionedPath("/containers/{name}/archive"), s.APIHandler(compat.Archive)).Methods(http.MethodGet, http.MethodPost)
+ // Added non version path to URI to support docker non versioned paths
+ r.HandleFunc("/containers/{name}/archive", s.APIHandler(compat.Archive)).Methods(http.MethodGet, http.MethodPost)
+
+ /*
+ Libpod
+ */
+
+ // swagger:operation POST /libpod/containers/{name}/copy libpod libpodPutArchive
+ // ---
+ // summary: Copy files into a container
+ // description: Copy a tar archive of files into a container
+ // tags:
+ // - containers
+ // produces:
+ // - application/json
+ // parameters:
+ // - in: path
+ // name: name
+ // type: string
+ // description: container name or id
+ // required: true
+ // - in: query
+ // name: path
+ // type: string
+ // description: Path to a directory in the container to extract
+ // required: true
+ // - in: query
+ // name: pause
+ // type: boolean
+ // description: pause the container while copying (defaults to true)
+ // default: true
+ // - in: body
+ // name: request
+ // description: tarfile of files to copy into the container
+ // schema:
+ // type: string
+ // responses:
+ // 200:
+ // description: no error
+ // 400:
+ // $ref: "#/responses/BadParamError"
+ // 403:
+ // description: the container rootfs is read-only
+ // 404:
+ // $ref: "#/responses/NoSuchContainer"
+ // 500:
+ // $ref: "#/responses/InternalError"
+
+ // swagger:operation GET /libpod/containers/{name}/copy libpod libpodGetArchive
+ // ---
+ // summary: Copy files from a container
+ // description: Copy a tar archive of files from a container
+ // tags:
+ // - containers (compat)
+ // produces:
+ // - application/json
+ // parameters:
+ // - in: path
+ // name: name
+ // type: string
+ // description: container name or id
+ // required: true
+ // - in: query
+ // name: path
+ // type: string
+ // description: Path to a directory in the container to extract
+ // required: true
+ // responses:
+ // 200:
+ // description: no error
+ // schema:
+ // type: string
+ // format: binary
+ // 400:
+ // $ref: "#/responses/BadParamError"
+ // 404:
+ // $ref: "#/responses/NoSuchContainer"
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.HandleFunc(VersionedPath("/libpod/containers/{name}/copy"), s.APIHandler(libpod.Archive)).Methods(http.MethodGet, http.MethodPost)
+ r.HandleFunc(VersionedPath("/libpod/containers/{name}/archive"), s.APIHandler(libpod.Archive)).Methods(http.MethodGet, http.MethodPost)
+
+ return nil
+}
diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go
index 64094e8e4..83584d0f3 100644
--- a/pkg/api/server/register_images.go
+++ b/pkg/api/server/register_images.go
@@ -8,6 +8,10 @@ import (
"github.com/gorilla/mux"
)
+// TODO
+//
+// * /images/create is missing the "message" and "platform" parameters
+
func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// swagger:operation POST /images/create compat createImage
// ---
@@ -635,10 +639,6 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// type: string
// description: Allows for pushing the image to a different destintation than the image refers to.
// - in: query
- // name: credentials
- // description: username:password for the registry.
- // type: string
- // - in: query
// name: tlsVerify
// description: Require TLS verification.
// type: boolean
diff --git a/pkg/api/server/server.go b/pkg/api/server/server.go
index 9cbc66e87..499a4c58a 100644
--- a/pkg/api/server/server.go
+++ b/pkg/api/server/server.go
@@ -102,6 +102,7 @@ func newServer(runtime *libpod.Runtime, duration time.Duration, listener *net.Li
for _, fn := range []func(*mux.Router) error{
server.registerAuthHandlers,
+ server.registerAchiveHandlers,
server.registerContainersHandlers,
server.registerDistributionHandlers,
server.registerEventsHandlers,
diff --git a/pkg/api/server/swagger.go b/pkg/api/server/swagger.go
index ebd99ba27..c463f809e 100644
--- a/pkg/api/server/swagger.go
+++ b/pkg/api/server/swagger.go
@@ -139,6 +139,13 @@ type swagImageSummary struct {
Body []entities.ImageSummary
}
+// Registries summary
+// swagger:response DocsRegistriesList
+type swagRegistriesList struct {
+ // in:body
+ Body entities.ListRegistriesReport
+}
+
// List Containers
// swagger:response DocsListContainer
type swagListContainers struct {