diff options
Diffstat (limited to 'pkg/api')
-rw-r--r-- | pkg/api/handlers/compat/images_build.go | 12 | ||||
-rw-r--r-- | pkg/api/handlers/compat/networks.go | 4 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/manifests.go | 265 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/networks.go | 2 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/swagger.go | 2 | ||||
-rw-r--r-- | pkg/api/handlers/utils/handler.go | 4 | ||||
-rw-r--r-- | pkg/api/server/register_images.go | 14 | ||||
-rw-r--r-- | pkg/api/server/register_manifest.go | 177 | ||||
-rw-r--r-- | pkg/api/server/register_swagger.go | 4 | ||||
-rw-r--r-- | pkg/api/server/server.go | 2 |
10 files changed, 423 insertions, 63 deletions
diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go index 2d296b5ce..6d4fe5513 100644 --- a/pkg/api/handlers/compat/images_build.go +++ b/pkg/api/handlers/compat/images_build.go @@ -16,7 +16,6 @@ import ( "github.com/containers/buildah" buildahDefine "github.com/containers/buildah/define" "github.com/containers/buildah/pkg/parse" - "github.com/containers/buildah/util" "github.com/containers/image/v5/types" "github.com/containers/podman/v3/libpod" "github.com/containers/podman/v3/pkg/api/handlers/utils" @@ -74,6 +73,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { AdditionalCapabilities string `schema:"addcaps"` Annotations string `schema:"annotations"` AppArmor string `schema:"apparmor"` + AllPlatforms bool `schema:"allplatforms"` BuildArgs string `schema:"buildargs"` CacheFrom string `schema:"cachefrom"` Compression uint64 `schema:"compression"` @@ -122,6 +122,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { Target string `schema:"target"` Timestamp int64 `schema:"timestamp"` Ulimits string `schema:"ulimits"` + UnsetEnvs []string `schema:"unsetenv"` Secrets string `schema:"secrets"` }{ Dockerfile: "Dockerfile", @@ -491,16 +492,12 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { defer reporter.Close() runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) - rtc, err := runtime.GetConfig() - if err != nil { - utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()")) - return - } buildOptions := buildahDefine.BuildOptions{ AddCapabilities: addCaps, AdditionalTags: additionalTags, Annotations: annotations, Args: buildArgs, + AllPlatforms: query.AllPlatforms, CommonBuildOpts: &buildah.CommonBuildOptions{ AddHost: addhosts, ApparmorProfile: apparmor, @@ -522,8 +519,6 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { Ulimit: ulimits, Secrets: secrets, }, - CNIConfigDir: rtc.Network.CNIPluginDirs[0], - CNIPluginPath: util.DefaultCNIPluginPath, Compression: compression, ConfigureNetwork: parseNetworkConfigurationPolicy(query.ConfigureNetwork), ContextDirectory: contextDirectory, @@ -556,6 +551,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { Squash: query.Squash, Target: query.Target, SystemContext: systemContext, + UnsetEnvs: query.UnsetEnvs, } for _, platformSpec := range query.Platform { diff --git a/pkg/api/handlers/compat/networks.go b/pkg/api/handlers/compat/networks.go index db3af7d0b..3345a9cfe 100644 --- a/pkg/api/handlers/compat/networks.go +++ b/pkg/api/handlers/compat/networks.go @@ -6,10 +6,10 @@ import ( "net" "net/http" + nettypes "github.com/containers/common/libnetwork/types" + netutil "github.com/containers/common/libnetwork/util" "github.com/containers/podman/v3/libpod" "github.com/containers/podman/v3/libpod/define" - nettypes "github.com/containers/podman/v3/libpod/network/types" - netutil "github.com/containers/podman/v3/libpod/network/util" "github.com/containers/podman/v3/pkg/api/handlers/utils" api "github.com/containers/podman/v3/pkg/api/types" "github.com/containers/podman/v3/pkg/domain/entities" diff --git a/pkg/api/handlers/libpod/manifests.go b/pkg/api/handlers/libpod/manifests.go index eb0b6827f..ef0839d1f 100644 --- a/pkg/api/handlers/libpod/manifests.go +++ b/pkg/api/handlers/libpod/manifests.go @@ -3,7 +3,11 @@ package libpod import ( "context" "encoding/json" + "fmt" + "io/ioutil" "net/http" + "net/url" + "strings" "github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/manifest" @@ -15,6 +19,8 @@ import ( "github.com/containers/podman/v3/pkg/auth" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/domain/infra/abi" + "github.com/containers/podman/v3/pkg/errorhandling" + "github.com/gorilla/mux" "github.com/gorilla/schema" "github.com/opencontainers/go-digest" "github.com/pkg/errors" @@ -24,40 +30,93 @@ func ManifestCreate(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) query := struct { - Name []string `schema:"name"` - Image []string `schema:"image"` - All bool `schema:"all"` + Name string `schema:"name"` + Images []string `schema:"images"` + All bool `schema:"all"` }{ // Add defaults here once needed. } + + // Support 3.x API calls, alias image to images + if image, ok := r.URL.Query()["image"]; ok { + query.Images = image + } + if err := decoder.Decode(&query, r.URL.Query()); err != nil { utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) return } - // TODO: (jhonce) When c/image is refactored the roadmap calls for this check to be pushed into that library. - for _, n := range query.Name { - if _, err := reference.ParseNormalizedNamed(n); err != nil { + // Support 4.x API calls, map query parameter to path + if name, ok := mux.Vars(r)["name"]; ok { + n, err := url.QueryUnescape(name) + if err != nil { utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, - errors.Wrapf(err, "invalid image name %s", n)) + errors.Wrapf(err, "failed to parse name parameter %q", name)) return } + query.Name = n + } + + if _, err := reference.ParseNormalizedNamed(query.Name); err != nil { + utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, + errors.Wrapf(err, "invalid image name %s", query.Name)) + return } imageEngine := abi.ImageEngine{Libpod: runtime} createOptions := entities.ManifestCreateOptions{All: query.All} - manID, err := imageEngine.ManifestCreate(r.Context(), query.Name, query.Image, createOptions) + manID, err := imageEngine.ManifestCreate(r.Context(), query.Name, query.Images, createOptions) + if err != nil { + utils.InternalServerError(w, err) + return + } + + status := http.StatusOK + if _, err := utils.SupportedVersion(r, "< 4.0.0"); err == utils.ErrVersionNotSupported { + status = http.StatusCreated + } + + buffer, err := ioutil.ReadAll(r.Body) + if err != nil { + utils.InternalServerError(w, err) + return + } + + // Treat \r\n as empty body + if len(buffer) < 3 { + utils.WriteResponse(w, status, handlers.IDResponse{ID: manID}) + return + } + + body := new(entities.ManifestModifyOptions) + if err := json.Unmarshal(buffer, body); err != nil { + utils.InternalServerError(w, errors.Wrap(err, "Decode()")) + return + } + + // gather all images for manifest list + var images []string + if len(query.Images) > 0 { + images = append(query.Images) + } + if len(body.Images) > 0 { + images = append(body.Images) + } + + id, err := imageEngine.ManifestAdd(r.Context(), query.Name, images, body.ManifestAddOptions) if err != nil { utils.InternalServerError(w, err) return } - utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: manID}) + + utils.WriteResponse(w, status, handlers.IDResponse{ID: id}) } -// ExistsManifest check if a manifest list exists -func ExistsManifest(w http.ResponseWriter, r *http.Request) { +// ManifestExists return true if manifest list exists. +func ManifestExists(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) name := utils.GetName(r) @@ -94,10 +153,18 @@ func ManifestInspect(w http.ResponseWriter, r *http.Request) { utils.WriteResponse(w, http.StatusOK, schema2List) } +// ManifestAdd remove digest from manifest list +// +// Deprecated: As of 4.0.0 use ManifestModify instead func ManifestAdd(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) - var addOptions entities.ManifestAddOptions - if err := json.NewDecoder(r.Body).Decode(&addOptions); err != nil { + + // Wrapper to support 3.x with 4.x libpod + query := struct { + entities.ManifestAddOptions + Images []string + }{} + if err := json.NewDecoder(r.Body).Decode(&query); err != nil { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()")) return } @@ -108,15 +175,8 @@ func ManifestAdd(w http.ResponseWriter, r *http.Request) { return } - // FIXME: we really need to clean up the manifest API. Swagger states - // the arguments were strings not string slices. The use of string - // slices, mixing lists and images is incredibly confusing. - if len(addOptions.Images) == 1 { - addOptions.Images = append(addOptions.Images, name) - } - imageEngine := abi.ImageEngine{Libpod: runtime} - newID, err := imageEngine.ManifestAdd(r.Context(), addOptions) + newID, err := imageEngine.ManifestAdd(r.Context(), name, query.Images, query.ManifestAddOptions) if err != nil { utils.InternalServerError(w, err) return @@ -124,7 +184,10 @@ func ManifestAdd(w http.ResponseWriter, r *http.Request) { utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: newID}) } -func ManifestRemove(w http.ResponseWriter, r *http.Request) { +// ManifestRemoveDigest remove digest from manifest list +// +// Deprecated: As of 4.0.0 use ManifestModify instead +func ManifestRemoveDigest(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) query := struct { @@ -155,7 +218,10 @@ func ManifestRemove(w http.ResponseWriter, r *http.Request) { utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: manifestList.ID()}) } -func ManifestPush(w http.ResponseWriter, r *http.Request) { +// ManifestPushV3 push image to registry +// +// Deprecated: As of 4.0.0 use ManifestPush instead +func ManifestPushV3(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) query := struct { @@ -207,3 +273,156 @@ func ManifestPush(w http.ResponseWriter, r *http.Request) { } utils.WriteResponse(w, http.StatusOK, digest) } + +// ManifestPush push image to registry +// +// As of 4.0.0 +func ManifestPush(w http.ResponseWriter, r *http.Request) { + runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) + decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) + + query := struct { + All bool `schema:"all"` + TLSVerify bool `schema:"tlsVerify"` + }{ + // Add defaults here once needed. + } + if err := decoder.Decode(&query, r.URL.Query()); err != nil { + utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, + errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) + return + } + + destination := utils.GetVar(r, "destination") + if err := utils.IsRegistryReference(destination); err != nil { + utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, err) + return + } + + authconf, authfile, err := auth.GetCredentials(r) + if err != nil { + utils.Error(w, "failed to retrieve repository credentials", http.StatusBadRequest, errors.Wrapf(err, "failed to parse registry header for %s", r.URL.String())) + return + } + defer auth.RemoveAuthfile(authfile) + var username, password string + if authconf != nil { + username = authconf.Username + password = authconf.Password + } + options := entities.ImagePushOptions{ + Authfile: authfile, + Username: username, + Password: password, + All: query.All, + } + if sys := runtime.SystemContext(); sys != nil { + options.CertDir = sys.DockerCertPath + } + if _, found := r.URL.Query()["tlsVerify"]; found { + options.SkipTLSVerify = types.NewOptionalBool(!query.TLSVerify) + } + + imageEngine := abi.ImageEngine{Libpod: runtime} + source := utils.GetName(r) + digest, err := imageEngine.ManifestPush(context.Background(), source, destination, options) + 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, handlers.IDResponse{ID: digest}) +} + +// ManifestModify efficiently updates the named manifest list +func ManifestModify(w http.ResponseWriter, r *http.Request) { + runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) + imageEngine := abi.ImageEngine{Libpod: runtime} + + body := new(entities.ManifestModifyOptions) + if err := json.NewDecoder(r.Body).Decode(body); err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()")) + return + } + + name := utils.GetName(r) + if _, err := runtime.LibimageRuntime().LookupManifestList(name); err != nil { + utils.Error(w, "Something went wrong.", http.StatusNotFound, err) + return + } + + var report entities.ManifestModifyReport + switch { + case strings.EqualFold("update", body.Operation): + id, err := imageEngine.ManifestAdd(r.Context(), name, body.Images, body.ManifestAddOptions) + if err != nil { + report.Errors = append(report.Errors, err) + break + } + report = entities.ManifestModifyReport{ + ID: id, + Images: body.Images, + } + case strings.EqualFold("remove", body.Operation): + for _, image := range body.Images { + id, err := imageEngine.ManifestRemoveDigest(r.Context(), name, image) + if err != nil { + report.Errors = append(report.Errors, err) + continue + } + report.ID = id + report.Images = append(report.Images, image) + } + case strings.EqualFold("annotate", body.Operation): + options := entities.ManifestAnnotateOptions{ + Annotation: body.Annotation, + Arch: body.Arch, + Features: body.Features, + OS: body.OS, + OSFeatures: body.OSFeatures, + OSVersion: body.OSVersion, + Variant: body.Variant, + } + for _, image := range body.Images { + id, err := imageEngine.ManifestAnnotate(r.Context(), name, image, options) + if err != nil { + report.Errors = append(report.Errors, err) + continue + } + report.ID = id + report.Images = append(report.Images, image) + } + default: + utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, + fmt.Errorf("illegal operation %q for %q", body.Operation, r.URL.String())) + return + } + + statusCode := http.StatusOK + switch { + case len(report.Errors) > 0 && len(report.Images) > 0: + statusCode = http.StatusConflict + case len(report.Errors) > 0: + statusCode = http.StatusInternalServerError + } + utils.WriteResponse(w, statusCode, report) +} + +// ManifestDelete removes a manifest list from storage +func ManifestDelete(w http.ResponseWriter, r *http.Request) { + runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) + imageEngine := abi.ImageEngine{Libpod: runtime} + + name := utils.GetName(r) + if _, err := runtime.LibimageRuntime().LookupManifestList(name); err != nil { + utils.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound, err) + return + } + + results, errs := imageEngine.ManifestRm(r.Context(), []string{name}) + errsString := errorhandling.ErrorsToStrings(errs) + report := handlers.LibpodImagesRemoveReport{ + ImageRemoveReport: *results, + Errors: errsString, + } + utils.WriteResponse(w, http.StatusOK, report) +} diff --git a/pkg/api/handlers/libpod/networks.go b/pkg/api/handlers/libpod/networks.go index a28c3c57c..d140ec07f 100644 --- a/pkg/api/handlers/libpod/networks.go +++ b/pkg/api/handlers/libpod/networks.go @@ -4,9 +4,9 @@ import ( "encoding/json" "net/http" + "github.com/containers/common/libnetwork/types" "github.com/containers/podman/v3/libpod" "github.com/containers/podman/v3/libpod/define" - "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/api/handlers/utils" api "github.com/containers/podman/v3/pkg/api/types" "github.com/containers/podman/v3/pkg/domain/entities" diff --git a/pkg/api/handlers/libpod/swagger.go b/pkg/api/handlers/libpod/swagger.go index 8d7058b1e..db93d7ac6 100644 --- a/pkg/api/handlers/libpod/swagger.go +++ b/pkg/api/handlers/libpod/swagger.go @@ -4,9 +4,9 @@ import ( "net/http" "os" + "github.com/containers/common/libnetwork/types" "github.com/containers/image/v5/manifest" "github.com/containers/podman/v3/libpod/define" - "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/api/handlers/utils" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/pkg/errors" diff --git a/pkg/api/handlers/utils/handler.go b/pkg/api/handlers/utils/handler.go index 96b7a957c..ee83755a1 100644 --- a/pkg/api/handlers/utils/handler.go +++ b/pkg/api/handlers/utils/handler.go @@ -174,7 +174,7 @@ func FilterMapToString(filters map[string][]string) (string, error) { return string(f), nil } -func getVar(r *http.Request, k string) string { +func GetVar(r *http.Request, k string) string { val := mux.Vars(r)[k] safeVal, err := url.PathUnescape(val) if err != nil { @@ -186,5 +186,5 @@ func getVar(r *http.Request, k string) string { // GetName extracts the name from the mux func GetName(r *http.Request) string { - return getVar(r, "name") + return GetVar(r, "name") } diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go index bf8eeef40..d9cda8579 100644 --- a/pkg/api/server/register_images.go +++ b/pkg/api/server/register_images.go @@ -1388,6 +1388,14 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // default: latest // description: A name and optional tag to apply to the image in the `name:tag` format. If you omit the tag the default latest value is assumed. You can provide several t parameters. // - in: query + // name: allplatforms + // type: boolean + // default: false + // description: | + // Instead of building for a set of platforms specified using the platform option, inspect the build's base images, + // and build for all of the platforms that are available. Stages that use *scratch* as a starting point can not be inspected, + // so at least one non-*scratch* stage must be present for detection to work usefully. + // - in: query // name: extrahosts // type: string // default: @@ -1570,6 +1578,12 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // description: | // Inject http proxy environment variables into container // (As of version 2.0.0) + // - in: query + // name: unsetenv + // description: Unset environment variables from the final image. + // type: array + // items: + // type: string // produces: // - application/json // responses: 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 } diff --git a/pkg/api/server/register_swagger.go b/pkg/api/server/register_swagger.go index dca1df14b..48af7713f 100644 --- a/pkg/api/server/register_swagger.go +++ b/pkg/api/server/register_swagger.go @@ -7,8 +7,8 @@ import ( "github.com/gorilla/mux" ) -// RegisterSwaggerHandlers maps the swagger endpoint for the server -func (s *APIServer) RegisterSwaggerHandlers(r *mux.Router) error { +// registerSwaggerHandlers maps the swagger endpoint for the server +func (s *APIServer) registerSwaggerHandlers(r *mux.Router) error { // This handler does _*NOT*_ provide an UI rather just a swagger spec that an UI could render r.HandleFunc(VersionedPath("/libpod/swagger"), s.APIHandler(libpod.ServeSwagger)).Methods(http.MethodGet) return nil diff --git a/pkg/api/server/server.go b/pkg/api/server/server.go index 8c5c7aeeb..65b7e2474 100644 --- a/pkg/api/server/server.go +++ b/pkg/api/server/server.go @@ -151,7 +151,7 @@ func newServer(runtime *libpod.Runtime, listener *net.Listener, opts entities.Se server.registerPluginsHandlers, server.registerPodsHandlers, server.registerSecretHandlers, - server.RegisterSwaggerHandlers, + server.registerSwaggerHandlers, server.registerSwarmHandlers, server.registerSystemHandlers, server.registerVersionHandlers, |