From 8a7e70919f4bab0757523ae97c170396cb13c83d Mon Sep 17 00:00:00 2001 From: Jhon Honce Date: Mon, 6 Dec 2021 16:45:58 -0700 Subject: Refactor manifest list operations * Update method/function signatures use the manifest list name and images associated with the operation explicitly, in general func f(ctx context.Context, manifestListName string, ImageNames []string, options *fOptions) * Leverage gorilla/mux Subrouters to support API v3.x and v4.x for manifests * Make manifest API endpoints more RESTful * Add PUT /manifest/{id} to update existing manifests * Add manifests.Annotate to go bindings, uncommented unit test * Add DELETE /manifest/{Id} to remove existing manifest list, use PUT /manifest/{id} to remove images from a list * Deprecated POST /manifest/{id}/add and /manifest/{id}/remove, use PUT /manifest/{id} instead * Corrected swagger godoc and updated to cover API changes * Update podman manifest commands to use registry.Context() * Expose utils.GetVar() to obtain query parameters by name * Unexpose server.registerSwaggerHandlers, not sure why this was ever exposed. * Refactored code to use http.Header instead of map[string]string when operating on HTTP headers. * Add API-Version header support in bindings to allow calling explicate versions of the API. Header is _NOT_ forwarded to the API service. Signed-off-by: Jhon Honce --- pkg/api/server/register_manifest.go | 177 +++++++++++++++++++++++++++++++----- 1 file changed, 154 insertions(+), 23 deletions(-) (limited to 'pkg/api/server/register_manifest.go') diff --git a/pkg/api/server/register_manifest.go b/pkg/api/server/register_manifest.go index 010d8a79e..8cd3d8b22 100644 --- a/pkg/api/server/register_manifest.go +++ b/pkg/api/server/register_manifest.go @@ -8,7 +8,9 @@ import ( ) func (s *APIServer) registerManifestHandlers(r *mux.Router) error { - // swagger:operation POST /libpod/manifests/create manifests ManifestCreateLibpod + v3 := r.PathPrefix("/v{version:[0-3][0-9A-Za-z.-]*}/libpod/manifests").Subrouter() + v4 := r.PathPrefix("/v{version:[4-9][0-9A-Za-z.-]*}/libpod/manifests").Subrouter() + // swagger:operation POST /libpod/manifests manifests ManifestCreateLibpod // --- // summary: Create // description: Create a manifest list @@ -18,18 +20,30 @@ func (s *APIServer) registerManifestHandlers(r *mux.Router) error { // - in: query // name: name // type: string - // description: manifest list name + // description: manifest list or index name to create // required: true // - in: query - // name: image + // name: images // type: string - // description: name of the image + // required: true + // description: | + // One or more names of an image or a manifest list. Repeat parameter as needed. + // + // Support for multiple images, as of version 4.0.0 + // Alias of `image` is support for compatibility with < 4.0.0 + // Response status code is 200 with < 4.0.0 for compatibility // - in: query // name: all // type: boolean // description: add all contents if given list + // - in: body + // name: options + // description: options for new manifest + // required: false + // schema: + // $ref: "#/definitions/ManifestModifyOptions" // responses: - // 200: + // 201: // schema: // $ref: "#/definitions/IDResponse" // 400: @@ -38,17 +52,21 @@ func (s *APIServer) registerManifestHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchImage" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/manifests/create"), s.APIHandler(libpod.ManifestCreate)).Methods(http.MethodPost) + v3.Handle("/create", s.APIHandler(libpod.ManifestCreate)).Methods(http.MethodPost) + v4.Handle("/{name:.*}", s.APIHandler(libpod.ManifestCreate)).Methods(http.MethodPost) // swagger:operation GET /libpod/manifests/{name}/exists manifests ManifestExistsLibpod // --- // summary: Exists - // description: Check if manifest list exists + // description: | + // Check if manifest list exists + // + // Note: There is no contract that the manifest list will exist for a follow-on operation // parameters: // - in: path // name: name // type: string // required: true - // description: the name of the manifest list + // description: the name or ID of the manifest list // produces: // - application/json // responses: @@ -58,11 +76,12 @@ func (s *APIServer) registerManifestHandlers(r *mux.Router) error { // $ref: '#/responses/NoSuchManifest' // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/libpod/manifests/{name}/exists"), s.APIHandler(libpod.ExistsManifest)).Methods(http.MethodGet) + v3.Handle("/{name:.*}/exists", s.APIHandler(libpod.ManifestExists)).Methods(http.MethodGet) + v4.Handle("/{name:.*}/exists", s.APIHandler(libpod.ManifestExists)).Methods(http.MethodGet) // swagger:operation GET /libpod/manifests/{name}/json manifests ManifestInspectLibpod // --- // summary: Inspect - // description: Display a manifest list + // description: Display attributes of given manifest list // produces: // - application/json // parameters: @@ -70,7 +89,7 @@ func (s *APIServer) registerManifestHandlers(r *mux.Router) error { // name: name // type: string // required: true - // description: the name or ID of the manifest + // description: the name or ID of the manifest list // responses: // 200: // $ref: "#/responses/InspectManifest" @@ -78,11 +97,53 @@ func (s *APIServer) registerManifestHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchManifest" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/manifests/{name:.*}/json"), s.APIHandler(libpod.ManifestInspect)).Methods(http.MethodGet) + v3.Handle("/{name:.*}/json", s.APIHandler(libpod.ManifestInspect)).Methods(http.MethodGet) + v4.Handle("/{name:.*}/json", s.APIHandler(libpod.ManifestInspect)).Methods(http.MethodGet) + // swagger:operation PUT /libpod/manifests/{name} manifests ManifestModifyLibpod + // --- + // summary: Modify manifest list + // description: | + // Add/Remove an image(s) to a manifest list + // + // Note: operations are not atomic when multiple Images are provided. + // + // As of v4.0.0 + // produces: + // - application/json + // parameters: + // - in: path + // name: name + // type: string + // required: true + // description: the name or ID of the manifest + // - in: body + // name: options + // description: options for mutating a manifest + // required: true + // schema: + // $ref: "#/definitions/ManifestModifyOptions" + // responses: + // 200: + // schema: + // $ref: "#/definitions/ManifestModifyReport" + // 404: + // $ref: "#/responses/NoSuchManifest" + // 400: + // $ref: "#/responses/BadParamError" + // 409: + // description: Operation had partial success, both Images and Errors may have members + // schema: + // $ref: "#/definitions/ManifestModifyReport" + // 500: + // $ref: "#/responses/InternalError" + v4.Handle("/{name:.*}", s.APIHandler(libpod.ManifestModify)).Methods(http.MethodPut) // swagger:operation POST /libpod/manifests/{name}/add manifests ManifestAddLibpod // --- // summary: Add image - // description: Add an image to a manifest list + // description: | + // Add an image to a manifest list + // + // Deprecated: As of 4.0.0 use ManifestModifyLibpod instead // produces: // - application/json // parameters: @@ -95,7 +156,7 @@ func (s *APIServer) registerManifestHandlers(r *mux.Router) error { // name: options // description: options for creating a manifest // schema: - // $ref: "#/definitions/ManifestAddOpts" + // $ref: "#/definitions/ManifestAddOptions" // responses: // 200: // schema: @@ -106,11 +167,14 @@ func (s *APIServer) registerManifestHandlers(r *mux.Router) error { // $ref: "#/responses/BadParamError" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/manifests/{name:.*}/add"), s.APIHandler(libpod.ManifestAdd)).Methods(http.MethodPost) - // swagger:operation DELETE /libpod/manifests/{name} manifests ManifestDeleteLibpod + v3.Handle("/{name:.*}/add", s.APIHandler(libpod.ManifestAdd)).Methods(http.MethodPost) + // swagger:operation DELETE /libpod/manifests/{name} manifests ManifestDeleteV3Libpod // --- - // summary: Remove - // description: Remove an image from a manifest list + // summary: Remove image from a manifest list + // description: | + // Remove an image from a manifest list + // + // Deprecated: As of 4.0.0 use ManifestModifyLibpod instead // produces: // - application/json // parameters: @@ -133,11 +197,37 @@ func (s *APIServer) registerManifestHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchManifest" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/manifests/{name:.*}"), s.APIHandler(libpod.ManifestRemove)).Methods(http.MethodDelete) - // swagger:operation POST /libpod/manifests/{name}/push manifests ManifestPushLibpod + v3.Handle("/{name:.*}", s.APIHandler(libpod.ManifestRemoveDigest)).Methods(http.MethodDelete) + // swagger:operation DELETE /libpod/manifests/{name} manifests ManifestDeleteLibpod // --- - // summary: Push - // description: Push a manifest list or image index to a registry + // summary: Delete manifest list + // description: | + // Delete named manifest list + // + // As of v4.0.0 + // produces: + // - application/json + // parameters: + // - in: path + // name: name + // type: string + // required: true + // description: The name or ID of the list to be deleted + // responses: + // 200: + // $ref: "#/responses/DocsLibpodImagesRemoveResponse" + // 404: + // $ref: "#/responses/NoSuchManifest" + // 500: + // $ref: "#/responses/InternalError" + v4.Handle("/{name:.*}", s.APIHandler(libpod.ManifestDelete)).Methods(http.MethodDelete) + // swagger:operation POST /libpod/manifests/{name}/push manifests ManifestPushV3Libpod + // --- + // summary: Push manifest to registry + // description: | + // Push a manifest list or image index to a registry + // + // Deprecated: As of 4.0.0 use ManifestPushLibpod instead // produces: // - application/json // parameters: @@ -165,6 +255,47 @@ func (s *APIServer) registerManifestHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchManifest" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/manifests/{name}/push"), s.APIHandler(libpod.ManifestPush)).Methods(http.MethodPost) + v3.Handle("/{name}/push", s.APIHandler(libpod.ManifestPushV3)).Methods(http.MethodPost) + // swagger:operation POST /libpod/manifests/{name}/registry/{destination} manifests ManifestPushLibpod + // --- + // summary: Push manifest list to registry + // description: | + // Push a manifest list or image index to the named registry + // + // As of v4.0.0 + // produces: + // - application/json + // parameters: + // - in: path + // name: name + // type: string + // required: true + // description: the name or ID of the manifest list + // - in: path + // name: destination + // type: string + // required: true + // description: the registry for the manifest list + // - in: query + // name: all + // description: push all images + // type: boolean + // default: false + // - in: query + // name: tlsVerify + // type: boolean + // default: false + // description: skip TLS verification for registries + // responses: + // 200: + // schema: + // $ref: "#/definitions/IDResponse" + // 400: + // $ref: "#/responses/BadParamError" + // 404: + // $ref: "#/responses/NoSuchManifest" + // 500: + // $ref: "#/responses/InternalError" + v4.Handle("/{name:.*}/registry/{destination:.*}", s.APIHandler(libpod.ManifestPush)).Methods(http.MethodPost) return nil } -- cgit v1.2.3-54-g00ecf