[CI:DOCS]swagger cleanup and left-hand nav

add a static tags file so we can dictate the left-hand navigation. in
doing so we now override the tag in the swagger:operation. we now have
images and images (compat) as a way to differentiate.

Signed-off-by: baude <bbaude@redhat.com>
This commit is contained in:
baude
2020-01-15 12:28:46 -06:00
parent 34429f3b53
commit a6ea17455c
14 changed files with 422 additions and 95 deletions

View File

@ -103,7 +103,7 @@ gating_task:
gate_script:
# TODO: remove once the image doesn't ship with pre-installed tools
- rm /go/bin/*
# - rm /go/bin/*
# N/B: entrypoint.sh resets $GOSRC (same as make clean)
- '/usr/local/bin/entrypoint.sh install.tools |& ${TIMESTAMP}'
- '/usr/local/bin/entrypoint.sh validate |& ${TIMESTAMP}'

3
pkg/api/Makefile Normal file
View File

@ -0,0 +1,3 @@
swagger:
swagger generate spec -o swagger.yaml -w ./
cat tags.yaml >> swagger.yaml

View File

@ -30,11 +30,6 @@ func ContainerExists(w http.ResponseWriter, r *http.Request) {
}
func RemoveContainer(w http.ResponseWriter, r *http.Request) {
// 204 no error
// 400 bad param
// 404 no such container
// 409 conflict
// 500 internal error
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
Force bool `schema:"force"`

View File

@ -57,9 +57,7 @@ type swagLibpodInspectImageResponse struct {
// swagger:response DocsContainerPruneReport
type swagContainerPruneReport struct {
// in: body
Body struct {
ContainersPruneReport
}
Body []ContainersPruneReport
}
// Inspect container
@ -84,9 +82,7 @@ type swagDockerTopResponse struct {
// swagger:response LibpodListContainersResponse
type swagLibpodListContainersResponse struct {
// in:body
Body struct {
shared.PsContainerOutput
}
Body []shared.PsContainerOutput
}
// Inspect container

View File

@ -10,30 +10,34 @@ import (
)
func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// swagger:operation POST /containers/create containers createContainer
// swagger:operation POST /containers/create compat containerCreate
// ---
// summary: Create a container
// produces:
// - application/json
// parameters:
// - in: query
// name: name
// type: string
// description: container name
// responses:
// '201':
// $ref: "#/responses/ContainerCreateResponse"
// '400':
// "$ref": "#/responses/BadParamError"
// '404':
// "$ref": "#/responses/NoSuchContainer"
// '409':
// "$ref": "#/responses/ConflictError"
// '500':
// "$ref": "#/responses/InternalError"
// summary: Create a container
// tags:
// - containers (compat)
// produces:
// - application/json
// parameters:
// - in: query
// name: name
// type: string
// description: container name
// responses:
// '201':
// $ref: "#/responses/ContainerCreateResponse"
// '400':
// "$ref": "#/responses/BadParamError"
// '404':
// "$ref": "#/responses/NoSuchContainer"
// '409':
// "$ref": "#/responses/ConflictError"
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/containers/create"), APIHandler(s.Context, generic.CreateContainer)).Methods(http.MethodPost)
// swagger:operation GET /containers/json containers listContainers
// swagger:operation GET /containers/json compat listContainers
// ---
// tags:
// - containers (compat)
// summary: List containers
// description: Returns a list of containers
// parameters:
@ -66,8 +70,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/containers/json"), APIHandler(s.Context, generic.ListContainers)).Methods(http.MethodGet)
// swagger:operation POST /containers/prune containers pruneContainers
// swagger:operation POST /containers/prune compat pruneContainers
// ---
// tags:
// - containers (compat)
// summary: Delete stopped containers
// description: Remove containers not in use
// parameters:
@ -86,8 +92,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/containers/prune"), APIHandler(s.Context, generic.PruneContainers)).Methods(http.MethodPost)
// swagger:operation DELETE /containers/{nameOrID} containers removeContainer
// swagger:operation DELETE /containers/{nameOrID} compat removeContainer
// ---
// tags:
// - containers (compat)
// summary: Remove a container
// parameters:
// - in: path
@ -122,8 +130,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/containers/{name:..*}"), APIHandler(s.Context, generic.RemoveContainer)).Methods(http.MethodDelete)
// swagger:operation GET /containers/{nameOrID}/json containers getContainer
// swagger:operation GET /containers/{nameOrID}/json compat getContainer
// ---
// tags:
// - containers (compat)
// summary: Inspect container
// description: Return low-level information about a container.
// parameters:
@ -146,8 +156,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/containers/{name:..*}/json"), APIHandler(s.Context, generic.GetContainer)).Methods(http.MethodGet)
// swagger:operation post /containers/{nameOrID}/kill containers killcontainer
// swagger:operation post /containers/{nameOrID}/kill compat killcontainer
// ---
// tags:
// - containers (compat)
// summary: Kill container
// description: Signal to send to the container as an integer or string (e.g. SIGINT)
// parameters:
@ -171,8 +183,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/containers/{name:..*}/kill"), APIHandler(s.Context, generic.KillContainer)).Methods(http.MethodPost)
// swagger:operation GET /containers/{nameOrID}/logs containers LogsFromContainer
// swagger:operation GET /containers/{nameOrID}/logs compat LogsFromContainer
// ---
// tags:
// - containers (compat)
// summary: Get container logs
// description: Get stdout and stderr logs from a container.
// parameters:
@ -220,8 +234,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/containers/{name:..*}/logs"), APIHandler(s.Context, generic.LogsFromContainer)).Methods(http.MethodGet)
// swagger:operation POST /containers/{nameOrID}/pause containers pauseContainer
// swagger:operation POST /containers/{nameOrID}/pause compat pauseContainer
// ---
// tags:
// - containers (compat)
// summary: Pause container
// description: Use the cgroups freezer to suspend all processes in a container.
// parameters:
@ -240,8 +256,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/containers/{name:..*}/pause"), APIHandler(s.Context, handlers.PauseContainer)).Methods(http.MethodPost)
r.HandleFunc(VersionedPath("/containers/{name:..*}/rename"), APIHandler(s.Context, handlers.UnsupportedHandler)).Methods(http.MethodPost)
// swagger:operation POST /containers/{nameOrID}/restart containers restartContainer
// swagger:operation POST /containers/{nameOrID}/restart compat restartContainer
// ---
// tags:
// - containers (compat)
// summary: Restart container
// parameters:
// - in: path
@ -262,8 +280,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/containers/{name:..*}/restart"), APIHandler(s.Context, handlers.RestartContainer)).Methods(http.MethodPost)
// swagger:operation POST /containers/{nameOrID}/start containers startContainer
// swagger:operation POST /containers/{nameOrID}/start compat startContainer
// ---
// tags:
// - containers (compat)
// summary: Start a container
// parameters:
// - in: path
@ -286,8 +306,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/containers/{name:..*}/start"), APIHandler(s.Context, handlers.StartContainer)).Methods(http.MethodPost)
// swagger:operation GET /containers/{nameOrID}/stats containers statsContainer
// swagger:operation GET /containers/{nameOrID}/stats compat statsContainer
// ---
// tags:
// - containers (compat)
// summary: Get stats for a container
// description: This returns a live stream of a containers resource usage statistics.
// parameters:
@ -310,8 +332,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/containers/{name:..*}/stats"), APIHandler(s.Context, generic.StatsContainer)).Methods(http.MethodGet)
// swagger:operation POST /containers/{nameOrID}/stop containers stopContainer
// swagger:operation POST /containers/{nameOrID}/stop compat stopContainer
// ---
// tags:
// - containers (compat)
// summary: Stop a container
// parameters:
// - in: path
@ -334,8 +358,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/containers/{name:..*}/stop"), APIHandler(s.Context, handlers.StopContainer)).Methods(http.MethodPost)
// swagger:operation GET /containers/{nameOrID}/top containers topContainer
// swagger:operation GET /containers/{nameOrID}/top compat topContainer
// ---
// tags:
// - containers (compat)
// summary: List processes running inside a container
// parameters:
// - in: path
@ -356,8 +382,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/containers/{name:..*}/top"), APIHandler(s.Context, handlers.TopContainer)).Methods(http.MethodGet)
// swagger:operation POST /containers/{nameOrID}/unpause containers unpauseContainer
// swagger:operation POST /containers/{nameOrID}/unpause compat unpauseContainer
// ---
// tags:
// - containers (compat)
// summary: Unpause container
// description: Resume a paused container
// parameters:
@ -375,8 +403,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/containers/{name:..*}/unpause"), APIHandler(s.Context, handlers.UnpauseContainer)).Methods(http.MethodPost)
// swagger:operation POST /containers/{nameOrID}/wait containers waitContainer
// swagger:operation POST /containers/{nameOrID}/wait compat waitContainer
// ---
// tags:
// - containers (compat)
// summary: Wait on a container to exit
// description: Block until a container stops, then returns the exit code.
// parameters:
@ -404,8 +434,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
*/
r.HandleFunc(VersionedPath("/libpod/containers/create"), APIHandler(s.Context, libpod.CreateContainer)).Methods(http.MethodPost)
// swagger:operation GET /libpod/containers/json containers libpodListContainers
// swagger:operation GET /libpod/containers/json libpod libpodListContainers
// ---
// tags:
// - containers
// summary: List containers
// description: Returns a list of containers
// produces:
@ -413,16 +445,16 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// responses:
// '200':
// schema:
// type: array
// items:
// "$ref": "#/responses/LibpodListContainersResponse"
// '400':
// "$ref": "#/responses/BadParamError"
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/json"), APIHandler(s.Context, libpod.ListContainers)).Methods(http.MethodGet)
// swagger:operation POST /libpod/containers/prune containers libpodPruneContainers
// swagger:operation POST /libpod/containers/prune libpod libpodPruneContainers
// ---
// tags:
// - containers
// summary: Prune unused containers
// description: Remove stopped and exited containers
// parameters:
@ -445,8 +477,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/prune"), APIHandler(s.Context, libpod.PruneContainers)).Methods(http.MethodPost)
// swagger:operation GET /libpod/containers/showmounted containers showMounterContainers
// swagger:operation GET /libpod/containers/showmounted libpod showMounterContainers
// ---
// tags:
// - containers
// summary: Show mounted containers
// description: Lists all mounted containers mount points
// produces:
@ -461,8 +495,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/showmounted"), APIHandler(s.Context, libpod.ShowMountedContainers)).Methods(http.MethodGet)
// swagger:operation DELETE /libpod/containers/json containers libpodRemoveContainer
// swagger:operation DELETE /libpod/containers/json libpod libpodRemoveContainer
// ---
// tags:
// - containers
// summary: Delete container
// parameters:
// - in: path
@ -491,8 +527,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}"), APIHandler(s.Context, libpod.RemoveContainer)).Methods(http.MethodDelete)
// swagger:operation GET /libpod/containers/{nameOrID}/json containers libpodGetContainer
// swagger:operation GET /libpod/containers/{nameOrID}/json libpod libpodGetContainer
// ---
// tags:
// - containers
// summary: Inspect container
// description: Return low-level information about a container.
// parameters:
@ -514,8 +552,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/json"), APIHandler(s.Context, libpod.GetContainer)).Methods(http.MethodGet)
// swagger:operation POST /libpod/containers/{nameOrID}/kill containers libpodKillContainer
// swagger:operation POST /libpod/containers/{nameOrID}/kill libpod libpodKillContainer
// ---
// tags:
// - containers
// summary: Kill container
// description: send a signal to a container, defaults to killing the container
// parameters:
@ -540,8 +580,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/kill"), APIHandler(s.Context, libpod.KillContainer)).Methods(http.MethodGet)
// swagger:operation GET /libpod/containers/{nameOrID}/mount containers mountContainer
// swagger:operation GET /libpod/containers/{nameOrID}/mount libpod mountContainer
// ---
// tags:
// - containers
// summary: Mount a container
// description: Mount a container to the filesystem
// parameters:
@ -564,8 +606,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/mount"), APIHandler(s.Context, libpod.MountContainer)).Methods(http.MethodPost)
r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/logs"), APIHandler(s.Context, libpod.LogsFromContainer)).Methods(http.MethodGet)
// swagger:operation POST /libpod/containers/{nameOrID}/pause containers libpodPauseContainer
// swagger:operation POST /libpod/containers/{nameOrID}/pause libpod libpodPauseContainer
// ---
// tags:
// - containers
// summary: Pause a container
// description: Use the cgroups freezer to suspend all processes in a container.
// parameters:
@ -583,8 +627,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/pause"), APIHandler(s.Context, handlers.PauseContainer)).Methods(http.MethodPost)
// swagger:operation POST /libpod/containers/{nameOrID}/restart containers libpodRestartContainer
// swagger:operation POST /libpod/containers/{nameOrID}/restart libpod libpodRestartContainer
// ---
// tags:
// - containers
// summary: Restart a container
// parameters:
// - in: path
@ -605,8 +651,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/restart"), APIHandler(s.Context, handlers.RestartContainer)).Methods(http.MethodPost)
// swagger:operation POST /libpod/containers/{nameOrID}/start containers libpodStartContainer
// swagger:operation POST /libpod/containers/{nameOrID}/start libpod libpodStartContainer
// ---
// tags:
// - containers
// summary: Start a container
// parameters:
// - in: path
@ -629,8 +677,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/start"), APIHandler(s.Context, handlers.StartContainer)).Methods(http.MethodPost)
// swagger:operation GET /libpod/containers/{nameOrID}/stats containers statsContainer
// swagger:operation GET /libpod/containers/{nameOrID}/stats libpod statsContainer
// ---
// tags:
// - containers
// summary: Get stats for a container
// description: This returns a live stream of a containers resource usage statistics.
// parameters:
@ -654,8 +704,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/stats"), APIHandler(s.Context, generic.StatsContainer)).Methods(http.MethodGet)
r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/top"), APIHandler(s.Context, handlers.TopContainer)).Methods(http.MethodGet)
// swagger:operation POST /libpod/containers/{nameOrID}/unpause containers libpodUnpauseContainer
// swagger:operation POST /libpod/containers/{nameOrID}/unpause libpod libpodUnpauseContainer
// ---
// tags:
// - containers
// summary: Unpause Container
// parameters:
// - in: path
@ -672,8 +724,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/unpause"), APIHandler(s.Context, handlers.UnpauseContainer)).Methods(http.MethodPost)
// swagger:operation POST /libpod/containers/{nameOrID}/wait containers libpodWaitContainer
// swagger:operation POST /libpod/containers/{nameOrID}/wait libpod libpodWaitContainer
// ---
// tags:
// - containers
// summary: Wait on a container to exit
// parameters:
// - in: path
@ -694,8 +748,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/wait"), APIHandler(s.Context, libpod.WaitContainer)).Methods(http.MethodPost)
// swagger:operation POST /libpod/containers/{nameOrID}/exists containers containerExists
// swagger:operation POST /libpod/containers/{nameOrID}/exists libpod containerExists
// ---
// tags:
// - containers
// summary: Check if container exists
// description: Quick way to determine if a container exists by name or ID
// parameters:
@ -713,8 +769,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/exists"), APIHandler(s.Context, libpod.ContainerExists)).Methods(http.MethodGet)
// swagger:operation POST /libpod/containers/{nameOrID}/stop containers libpodStopContainer
// swagger:operation POST /libpod/containers/{nameOrID}/stop libpod libpodStopContainer
// ---
// tags:
// - containers
// summary: Stop a container
// parameters:
// - in: path

View File

@ -10,9 +10,11 @@ import (
)
func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// swagger:operation POST /images/create compat_images createImage
// swagger:operation POST /images/create compat createImage
//
// ---
// tags:
// - images (compat)
// summary: Create an image from an image
// description: Create an image by either pulling it from a registry or importing it.
// produces:
@ -40,8 +42,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// schema:
// $ref: '#/responses/GenericError'
r.Handle(VersionedPath("/images/create"), APIHandler(s.Context, generic.CreateImageFromImage)).Methods(http.MethodPost).Queries("fromImage", "{fromImage}")
// swagger:operation POST /images/create compat_images createImage
// swagger:operation POST /images/create compat createImage
// ---
// tags:
// - images (compat)
// summary: Create an image from Source
// description: Create an image by either pulling it from a registry or importing it.
// produces:
@ -69,8 +73,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// schema:
// $ref: '#/responses/GenericError'
r.Handle(VersionedPath("/images/create"), APIHandler(s.Context, generic.CreateImageFromSrc)).Methods(http.MethodPost).Queries("fromSrc", "{fromSrc}")
// swagger:operation GET /images/json compat_images listImages
// swagger:operation GET /images/json compat listImages
// ---
// tags:
// - images (compat)
// summary: List Images
// description: Returns a list of images on the server. Note that it uses a different, smaller representation of an image than inspecting a single image.
// produces:
@ -85,9 +91,11 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// '500':
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/images/json"), APIHandler(s.Context, generic.GetImages)).Methods(http.MethodGet)
// swagger:operation POST /images/load compat_images loadImage
// swagger:operation POST /images/load compat loadImage
//
// ---
// tags:
// - images (compat)
// summary: Import image
// description: Load a set of images and tags into a repository.
// parameters:
@ -107,8 +115,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// '500':
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/images/load"), APIHandler(s.Context, handlers.LoadImage)).Methods(http.MethodPost)
// swagger:operation POST /images/prune compat_images pruneImages
// swagger:operation POST /images/prune compat pruneImages
// ---
// tags:
// - images (compat)
// summary: Prune unused images
// description: Remove images from local storage that are not being used by a container
// parameters:
@ -132,8 +142,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// '500':
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/images/prune"), APIHandler(s.Context, generic.PruneImages)).Methods(http.MethodPost)
// swagger:operation GET /images/search compat_images searchImages
// swagger:operation GET /images/search compat searchImages
// ---
// tags:
// - images (compat)
// summary: Search images
// description: Search registries for an image
// parameters:
@ -161,8 +173,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// '500':
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/images/search"), APIHandler(s.Context, handlers.SearchImages)).Methods(http.MethodGet)
// swagger:operation DELETE /images/{nameOrID} compat_images removeImage
// swagger:operation DELETE /images/{nameOrID} compat removeImage
// ---
// tags:
// - images (compat)
// summary: Remove Image
// description: Delete an image from local storage
// parameters:
@ -186,8 +200,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// '500':
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/images/{name:..*}"), APIHandler(s.Context, handlers.RemoveImage)).Methods(http.MethodDelete)
// swagger:operation GET /images/{nameOrID}/get compat_images exportImage
// swagger:operation GET /images/{nameOrID}/get compat exportImage
// ---
// tags:
// - images (compat)
// summary: Export an image
// description: Export an image in tarball format
// parameters:
@ -206,8 +222,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// '500':
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/images/{name:..*}/get"), APIHandler(s.Context, generic.ExportImage)).Methods(http.MethodGet)
// swagger:operation GET /images/{nameOrID}/history compat_images imageHistory
// swagger:operation GET /images/{nameOrID}/history compat imageHistory
// ---
// tags:
// - images (compat)
// summary: History of an image
// description: Return parent layers of an image.
// parameters:
@ -225,8 +243,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// '500':
// $ref: "#/responses/InternalError"
r.Handle(VersionedPath("/images/{name:..*}/history"), APIHandler(s.Context, handlers.HistoryImage)).Methods(http.MethodGet)
// swagger:operation GET /images/{nameOrID}/json compat_images inspectImage
// swagger:operation GET /images/{nameOrID}/json compat inspectImage
// ---
// tags:
// - images (compat)
// summary: Inspect an image
// description: Return low-level information about an image.
// parameters:
@ -244,8 +264,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// '500':
// $ref: "#/responses/InternalError"
r.Handle(VersionedPath("/images/{name:..*}/json"), APIHandler(s.Context, generic.GetImage))
// swagger:operation POST /images/{nameOrID}/tag compat_images tagImage
// swagger:operation POST /images/{nameOrID}/tag compat tagImage
// ---
// tags:
// - images (compat)
// summary: Tag an image
// description: Tag an image so that it becomes part of a repository.
// parameters:
@ -275,8 +297,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// 500:
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/images/{name:..*}/tag"), APIHandler(s.Context, handlers.TagImage)).Methods(http.MethodPost)
// swagger:operation POST /commit/ compat_commit commitContainer
// swagger:operation POST /commit/ compat commitContainer
// ---
// tags:
// - commit (compat)
// summary: Create a new image from a container
// parameters:
// - in: query
@ -322,8 +346,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
libpod endpoints
*/
// swagger:operation POST /libpod/images/{nameOrID}/exists images libpodImageExists
// swagger:operation POST /libpod/images/{nameOrID}/exists libpod libpodImageExists
// ---
// tags:
// - images
// summary: Image exists
// description: Check if image exists in local store
// parameters:
@ -342,8 +368,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/libpod/images/{name:..*}/exists"), APIHandler(s.Context, libpod.ImageExists))
r.Handle(VersionedPath("/libpod/images/{name:..*}/tree"), APIHandler(s.Context, libpod.ImageTree))
// swagger:operation GET /libpod/images/{nameOrID}/history images libpodImageHistory
// swagger:operation GET /libpod/images/{nameOrID}/history libpod libpodImageHistory
// ---
// tags:
// - images
// summary: History of an image
// description: Return parent layers of an image.
// parameters:
@ -363,22 +391,24 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// '500':
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/libpod/images/history"), APIHandler(s.Context, handlers.HistoryImage)).Methods(http.MethodGet)
// swagger:operation GET /libpod/images/json images libpodListImages
// swagger:operation GET /libpod/images/json libpod libpodListImages
// ---
// tags:
// - images
// summary: List Images
// description: Returns a list of images on the server
// produces:
// - application/json
// responses:
// '200':
// schema:
// items:
// $ref: "#/responses/DockerImageSummary"
// '500':
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/libpod/images/json"), APIHandler(s.Context, libpod.GetImages)).Methods(http.MethodGet)
// swagger:operation POST /libpod/images/load images libpodLoadImage
// swagger:operation POST /libpod/images/load libpod libpodLoadImage
// ---
// tags:
// - images
// summary: Import image
// description: Load a set of images and tags into a repository.
// parameters:
@ -398,8 +428,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// '500':
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/libpod/images/load"), APIHandler(s.Context, handlers.LoadImage)).Methods(http.MethodPost)
// swagger:operation POST /libpod/images/prune images libpodPruneImages
// swagger:operation POST /libpod/images/prune libpod libpodPruneImages
// ---
// tags:
// - images
// summary: Prune unused images
// description: Remove images that are not being used by a container
// parameters:
@ -426,8 +458,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// '500':
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/libpod/images/prune"), APIHandler(s.Context, libpod.PruneImages)).Methods(http.MethodPost)
// swagger:operation GET /libpod/images/search images libpodSearchImages
// swagger:operation GET /libpod/images/search libpod libpodSearchImages
// ---
// tags:
// - images
// summary: Search images
// description: Search registries for images
// parameters:
@ -457,8 +491,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// '500':
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/libpod/images/search"), APIHandler(s.Context, handlers.SearchImages)).Methods(http.MethodGet)
// swagger:operation DELETE /libpod/images/{nameOrID} images libpodRemoveImage
// swagger:operation DELETE /libpod/images/{nameOrID} libpod libpodRemoveImage
// ---
// tags:
// - images
// summary: Remove Image
// description: Delete an image from local store
// parameters:
@ -482,8 +518,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// '500':
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/libpod/images/{name:..*}"), APIHandler(s.Context, handlers.RemoveImage)).Methods(http.MethodDelete)
// swagger:operation GET /libpod/images/{nameOrID}/get images libpoodExportImage
// swagger:operation GET /libpod/images/{nameOrID}/get libpod libpoodExportImage
// ---
// tags:
// - images
// summary: Export an image
// description: Export an image as a tarball
// parameters:
@ -512,8 +550,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// '500':
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/libpod/images/{name:..*}/get"), APIHandler(s.Context, libpod.ExportImage)).Methods(http.MethodGet)
// swagger:operation GET /libpod/images/{nameOrID}/json images libpodInspectImage
// swagger:operation GET /libpod/images/{nameOrID}/json libpod libpodInspectImage
// ---
// tags:
// - images
// summary: Inspect an image
// description: Obtain low-level information about an image
// parameters:
@ -531,8 +571,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// '500':
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/libpod/images/{name:..*}/json"), APIHandler(s.Context, libpod.GetImage))
// swagger:operation POST /libpod/images/{nameOrID}/tag images libpodTagImage
// swagger:operation POST /libpod/images/{nameOrID}/tag libpod libpodTagImage
// ---
// tags:
// - images
// summary: Tag an image
// description: Tag an image so that it becomes part of a repository.
// parameters:

View File

@ -117,9 +117,7 @@ type swagPodAlreadyStopped struct {
// swagger:response DockerImageSummary
type swagImageSummary struct {
// in:body
Body struct {
handlers.ImageSummary
}
Body []handlers.ImageSummary
}
// List Containers
@ -128,7 +126,7 @@ type swagListContainers struct {
// in:body
Body struct {
// This causes go-swagger to crash
//handlers.Container
// handlers.Container
}
}

13
pkg/api/tags.yaml Normal file
View File

@ -0,0 +1,13 @@
tags:
- name: containers
description: Actions related to containers
- name: images
description: Actions related to images
- name: pods
description: Actions related to pods
- name: volumes
description: Actions related to volumes
- name: containers (compat)
description: Actions related to containers for the compatibility endpoints
- name: images (compat)
description: Actions related to images for the compatibility endpoints

View File

@ -0,0 +1,62 @@
package bindings
import (
"fmt"
"io"
"net/http"
)
const (
defaultConnection string = "http://localhost:8080/v1.24/libpod"
pingConnection string = "http://localhost:8080/_ping"
)
type APIResponse struct {
*http.Response
Request *http.Request
}
type Connection struct {
url string
client *http.Client
}
func NewConnection(url string) (Connection, error) {
if len(url) < 1 {
url = defaultConnection
}
newConn := Connection{
url: url,
client: &http.Client{},
}
response, err := http.Get(pingConnection)
if err != nil {
return newConn, err
}
if err := response.Body.Close(); err != nil {
return newConn, err
}
return newConn, err
}
func (c Connection) makeEndpoint(u string) string {
return fmt.Sprintf("%s%s", defaultConnection, u)
}
func (c Connection) newRequest(httpMethod, endpoint string, httpBody io.Reader, params map[string]string) (*APIResponse, error) {
e := c.makeEndpoint(endpoint)
req, err := http.NewRequest(httpMethod, e, httpBody)
if err != nil {
return nil, err
}
if len(params) > 0 {
// if more desirable we could use url to form the encoded endpoint with params
r := req.URL.Query()
for k, v := range params {
r.Add(k, v)
}
req.URL.RawQuery = r.Encode()
}
response, err := c.client.Do(req) // nolint
return &APIResponse{response, req}, err
}

View File

@ -109,12 +109,14 @@ func (c Connection) UnpauseContainer(nameOrID string) error {
}
func (c Connection) WaitContainer(nameOrID string) error {
_, err := http.Post(c.makeEndpoint(fmt.Sprintf("containers/%s/wait", nameOrID)), "application/json", nil)
// TODO when returns are ironed out, we can should use the newRequest approach
_, err := http.Post(c.makeEndpoint(fmt.Sprintf("containers/%s/wait", nameOrID)), "application/json", nil) // nolint
return err
}
func (c Connection) ContainerExists(nameOrID string) (bool, error) {
response, err := http.Get(c.makeEndpoint(fmt.Sprintf("/containers/%s/exists", nameOrID)))
response, err := http.Get(c.makeEndpoint(fmt.Sprintf("/containers/%s/exists", nameOrID))) // nolint
defer closeResponseBody(response)
if err != nil {
return false, err
}

46
pkg/bindings/errors.go Normal file
View File

@ -0,0 +1,46 @@
package bindings
import (
"encoding/json"
"io/ioutil"
"net/http"
"github.com/containers/libpod/pkg/api/handlers/utils"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
var (
ErrNotImplemented = errors.New("function not implemented")
)
func handleError(data []byte) error {
e := utils.ErrorModel{}
if err := json.Unmarshal(data, &e); err != nil {
return err
}
return e
}
func (a APIResponse) Process(unmarshalInto interface{}) error {
data, err := ioutil.ReadAll(a.Response.Body)
if err != nil {
return errors.Wrap(err, "unable to process API response")
}
if a.Response.StatusCode == http.StatusOK {
if unmarshalInto != nil {
return json.Unmarshal(data, unmarshalInto)
}
return nil
}
// TODO should we add a debug here with the response code?
return handleError(data)
}
func closeResponseBody(r *http.Response) {
if r != nil {
if err := r.Body.Close(); err != nil {
logrus.Error(errors.Wrap(err, "unable to close response body"))
}
}
}

111
pkg/bindings/images.go Normal file
View File

@ -0,0 +1,111 @@
package bindings
import (
"fmt"
"io"
"net/http"
"strconv"
"github.com/containers/libpod/pkg/api/handlers"
"github.com/containers/libpod/pkg/inspect"
)
func (c Connection) ImageExists(nameOrID string) (bool, error) {
response, err := http.Get(c.makeEndpoint(fmt.Sprintf("/images/%s/exists", nameOrID))) // nolint
defer closeResponseBody(response)
if err != nil {
return false, err
}
if response.StatusCode == http.StatusOK {
return true, nil
}
return false, nil
}
func (c Connection) ListImages() ([]handlers.ImageSummary, error) {
imageSummary := []handlers.ImageSummary{}
response, err := c.newRequest(http.MethodGet, "/images/json", nil, nil)
if err != nil {
return imageSummary, err
}
return imageSummary, response.Process(&imageSummary)
}
func (c Connection) GetImage(nameOrID string) (*inspect.ImageData, error) {
inspectedData := inspect.ImageData{}
response, err := c.newRequest(http.MethodGet, fmt.Sprintf("/images/%s/json", nameOrID), nil, nil)
if err != nil {
return &inspectedData, err
}
return &inspectedData, response.Process(&inspectedData)
}
func (c Connection) ImageTree(nameOrId string) error {
return ErrNotImplemented
}
func (c Connection) ImageHistory(nameOrID string) ([]handlers.HistoryResponse, error) {
history := []handlers.HistoryResponse{}
response, err := c.newRequest(http.MethodGet, fmt.Sprintf("/images/%s/history", nameOrID), nil, nil)
if err != nil {
return history, err
}
return history, response.Process(&history)
}
func (c Connection) LoadImage(r io.Reader) error {
// TODO this still needs error handling added
_, err := http.Post(c.makeEndpoint("/images/loads"), "application/json", r) //nolint
return err
}
func (c Connection) RemoveImage(nameOrID string, force bool) ([]map[string]string, error) {
deletes := []map[string]string{}
params := make(map[string]string)
params["force"] = strconv.FormatBool(force)
response, err := c.newRequest(http.MethodDelete, fmt.Sprintf("/images/%s", nameOrID), nil, params)
if err != nil {
return nil, err
}
return deletes, response.Process(&deletes)
}
func (c Connection) ExportImage(nameOrID string, w io.Writer, format string, compress bool) error {
params := make(map[string]string)
params["format"] = format
params["compress"] = strconv.FormatBool(compress)
response, err := c.newRequest(http.MethodGet, fmt.Sprintf("/images/%s/get", nameOrID), nil, params)
if err != nil {
return err
}
if err := response.Process(nil); err != nil {
return err
}
_, err = io.Copy(w, response.Body)
return err
}
func (c Connection) PruneImages(all bool, filters []string) ([]string, error) {
var (
deleted []string
)
params := make(map[string]string)
// FIXME How do we do []strings?
//params["filters"] = format
response, err := c.newRequest(http.MethodPost, "/images/prune", nil, params)
if err != nil {
return deleted, err
}
return deleted, response.Process(nil)
}
func (c Connection) TagImage(nameOrID string) error {
var ()
response, err := c.newRequest(http.MethodPost, fmt.Sprintf("/images/%s/tag", nameOrID), nil, nil)
if err != nil {
return err
}
return response.Process(nil)
}
func (c Connection) BuildImage(nameOrId string) {}

View File

@ -14,7 +14,8 @@ func (c Connection) CreatePod() error {
}
func (c Connection) PodExists(nameOrID string) (bool, error) {
response, err := http.Get(c.makeEndpoint(fmt.Sprintf("/pods/%s/exists", nameOrID)))
response, err := http.Get(c.makeEndpoint(fmt.Sprintf("/pods/%s/exists", nameOrID))) // nolint
defer closeResponseBody(response)
if err != nil {
return false, err
}

View File

@ -52,7 +52,7 @@ func (c Connection) PruneVolumes() ([]string, error) {
func (c Connection) RemoveVolume(nameOrID string, force bool) error {
params := make(map[string]string)
params["force"] = strconv.FormatBool(force)
response, err := c.newRequest(http.MethodPost, fmt.Sprintf("/volumes/prune", nameOrID), nil, params)
response, err := c.newRequest(http.MethodPost, "/volumes/prune", nil, params)
if err != nil {
return err
}