diff options
Diffstat (limited to 'pkg/api')
-rw-r--r-- | pkg/api/handlers/compat/containers.go | 27 | ||||
-rw-r--r-- | pkg/api/handlers/compat/images_build.go | 1 | ||||
-rw-r--r-- | pkg/api/handlers/compat/networks.go | 301 | ||||
-rw-r--r-- | pkg/api/handlers/compat/swagger.go | 28 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/healthcheck.go | 24 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/manifests.go | 1 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/system.go | 10 | ||||
-rw-r--r-- | pkg/api/handlers/utils/images.go | 33 | ||||
-rw-r--r-- | pkg/api/server/register_images.go | 209 | ||||
-rw-r--r-- | pkg/api/server/register_networks.go | 90 | ||||
-rw-r--r-- | pkg/api/server/register_system.go | 14 | ||||
-rw-r--r-- | pkg/api/server/server.go | 8 | ||||
-rw-r--r-- | pkg/api/tags.yaml | 2 |
13 files changed, 693 insertions, 55 deletions
diff --git a/pkg/api/handlers/compat/containers.go b/pkg/api/handlers/compat/containers.go index 239e41af4..cea4bd0f6 100644 --- a/pkg/api/handlers/compat/containers.go +++ b/pkg/api/handlers/compat/containers.go @@ -4,6 +4,7 @@ import ( "encoding/binary" "encoding/json" "fmt" + "io" "net/http" "strconv" "strings" @@ -295,7 +296,9 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) { }() w.WriteHeader(http.StatusOK) - var builder strings.Builder + + var frame strings.Builder + header := make([]byte, 8) for ok := true; ok; ok = query.Follow { for line := range logChannel { if _, found := r.URL.Query()["until"]; found { @@ -304,10 +307,8 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) { } } - // Reset variables we're ready to loop again - builder.Reset() - header := [8]byte{} - + // Reset buffer we're ready to loop again + frame.Reset() switch line.Device { case "stdout": if !query.Stdout { @@ -327,17 +328,17 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) { } if query.Timestamps { - builder.WriteString(line.Time.Format(time.RFC3339)) - builder.WriteRune(' ') + frame.WriteString(line.Time.Format(time.RFC3339)) + frame.WriteString(" ") } - builder.WriteString(line.Msg) - // Build header and output entry - binary.BigEndian.PutUint32(header[4:], uint32(len(header)+builder.Len())) - if _, err := w.Write(header[:]); err != nil { + frame.WriteString(line.Msg) + + binary.BigEndian.PutUint32(header[4:], uint32(frame.Len())) + if _, err := w.Write(header[0:8]); err != nil { log.Errorf("unable to write log output header: %q", err) } - if _, err := fmt.Fprint(w, builder.String()); err != nil { - log.Errorf("unable to write builder string: %q", err) + if _, err := io.WriteString(w, frame.String()); err != nil { + log.Errorf("unable to write frame string: %q", err) } if flusher, ok := w.(http.Flusher); ok { flusher.Flush() diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go index e208e6ddc..e9d8fd719 100644 --- a/pkg/api/handlers/compat/images_build.go +++ b/pkg/api/handlers/compat/images_build.go @@ -226,6 +226,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { id, _, err := runtime.Build(r.Context(), buildOptions, query.Dockerfile) if err != nil { utils.InternalServerError(w, err) + return } // Find image ID that was built... diff --git a/pkg/api/handlers/compat/networks.go b/pkg/api/handlers/compat/networks.go new file mode 100644 index 000000000..ceeae30fb --- /dev/null +++ b/pkg/api/handlers/compat/networks.go @@ -0,0 +1,301 @@ +package compat + +import ( + "encoding/json" + "net" + "net/http" + "os" + "syscall" + "time" + + "github.com/containernetworking/cni/libcni" + "github.com/containers/libpod/libpod" + "github.com/containers/libpod/pkg/api/handlers/utils" + "github.com/containers/libpod/pkg/domain/entities" + "github.com/containers/libpod/pkg/domain/infra/abi" + "github.com/containers/libpod/pkg/network" + "github.com/docker/docker/api/types" + dockerNetwork "github.com/docker/docker/api/types/network" + "github.com/gorilla/schema" + "github.com/pkg/errors" +) + +type CompatInspectNetwork struct { + types.NetworkResource +} + +func InspectNetwork(w http.ResponseWriter, r *http.Request) { + runtime := r.Context().Value("runtime").(*libpod.Runtime) + + // FYI scope and version are currently unused but are described by the API + // Leaving this for if/when we have to enable these + //query := struct { + // scope string + // verbose bool + //}{ + // // override any golang type defaults + //} + //decoder := r.Context().Value("decoder").(*schema.Decoder) + //if err := decoder.Decode(&query, r.URL.Query()); err != nil { + // utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) + // return + //} + config, err := runtime.GetConfig() + if err != nil { + utils.InternalServerError(w, err) + return + } + name := utils.GetName(r) + _, err = network.InspectNetwork(config, name) + if err != nil { + // TODO our network package does not distinguish between not finding a + // specific network vs not being able to read it + utils.InternalServerError(w, err) + return + } + report, err := getNetworkResourceByName(name, runtime) + if err != nil { + utils.InternalServerError(w, err) + return + } + utils.WriteResponse(w, http.StatusOK, report) +} + +func getNetworkResourceByName(name string, runtime *libpod.Runtime) (*types.NetworkResource, error) { + var ( + ipamConfigs []dockerNetwork.IPAMConfig + ) + config, err := runtime.GetConfig() + if err != nil { + return nil, err + } + containerEndpoints := map[string]types.EndpointResource{} + // Get the network path so we can get created time + networkConfigPath, err := network.GetCNIConfigPathByName(config, name) + if err != nil { + return nil, err + } + f, err := os.Stat(networkConfigPath) + if err != nil { + return nil, err + } + stat := f.Sys().(*syscall.Stat_t) + cons, err := runtime.GetAllContainers() + if err != nil { + return nil, err + } + conf, err := libcni.ConfListFromFile(networkConfigPath) + if err != nil { + return nil, err + } + + // No Bridge plugin means we bail + bridge, err := genericPluginsToBridge(conf.Plugins, network.DefaultNetworkDriver) + if err != nil { + return nil, err + } + for _, outer := range bridge.IPAM.Ranges { + for _, n := range outer { + ipamConfig := dockerNetwork.IPAMConfig{ + Subnet: n.Subnet, + Gateway: n.Gateway, + } + ipamConfigs = append(ipamConfigs, ipamConfig) + } + } + + for _, con := range cons { + data, err := con.Inspect(false) + if err != nil { + return nil, err + } + if netData, ok := data.NetworkSettings.Networks[name]; ok { + containerEndpoint := types.EndpointResource{ + Name: netData.NetworkID, + EndpointID: netData.EndpointID, + MacAddress: netData.MacAddress, + IPv4Address: netData.IPAddress, + IPv6Address: netData.GlobalIPv6Address, + } + containerEndpoints[con.ID()] = containerEndpoint + } + } + report := types.NetworkResource{ + Name: name, + ID: "", + Created: time.Unix(stat.Ctim.Sec, stat.Ctim.Nsec), + Scope: "", + Driver: network.DefaultNetworkDriver, + EnableIPv6: false, + IPAM: dockerNetwork.IPAM{ + Driver: "default", + Options: nil, + Config: ipamConfigs, + }, + Internal: false, + Attachable: false, + Ingress: false, + ConfigFrom: dockerNetwork.ConfigReference{}, + ConfigOnly: false, + Containers: containerEndpoints, + Options: nil, + Labels: nil, + Peers: nil, + Services: nil, + } + return &report, nil +} + +func genericPluginsToBridge(plugins []*libcni.NetworkConfig, pluginType string) (network.HostLocalBridge, error) { + var bridge network.HostLocalBridge + generic, err := findPluginByName(plugins, pluginType) + if err != nil { + return bridge, err + } + err = json.Unmarshal(generic, &bridge) + return bridge, err +} + +func findPluginByName(plugins []*libcni.NetworkConfig, pluginType string) ([]byte, error) { + for _, p := range plugins { + if pluginType == p.Network.Type { + return p.Bytes, nil + } + } + return nil, errors.New("unable to find bridge plugin") +} + +func ListNetworks(w http.ResponseWriter, r *http.Request) { + var ( + reports []*types.NetworkResource + ) + runtime := r.Context().Value("runtime").(*libpod.Runtime) + decoder := r.Context().Value("decoder").(*schema.Decoder) + query := struct { + Filters map[string][]string `schema:"filters"` + }{ + // override any golang type defaults + } + if err := decoder.Decode(&query, r.URL.Query()); err != nil { + utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) + return + } + config, err := runtime.GetConfig() + if err != nil { + utils.InternalServerError(w, err) + return + } + // TODO remove when filters are implemented + if len(query.Filters) > 0 { + utils.InternalServerError(w, errors.New("filters for listing networks is not implemented")) + return + } + netNames, err := network.GetNetworkNamesFromFileSystem(config) + if err != nil { + utils.InternalServerError(w, err) + return + } + for _, name := range netNames { + report, err := getNetworkResourceByName(name, runtime) + if err != nil { + utils.InternalServerError(w, err) + } + reports = append(reports, report) + } + utils.WriteResponse(w, http.StatusOK, reports) +} + +func CreateNetwork(w http.ResponseWriter, r *http.Request) { + var ( + name string + networkCreate types.NetworkCreateRequest + ) + runtime := r.Context().Value("runtime").(*libpod.Runtime) + if err := json.NewDecoder(r.Body).Decode(&networkCreate); err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()")) + return + } + + if len(networkCreate.Name) > 0 { + name = networkCreate.Name + } + // At present I think we should just suport the bridge driver + // and allow demand to make us consider more + if networkCreate.Driver != network.DefaultNetworkDriver { + utils.InternalServerError(w, errors.New("network create only supports the bridge driver")) + return + } + ncOptions := entities.NetworkCreateOptions{ + Driver: network.DefaultNetworkDriver, + Internal: networkCreate.Internal, + } + if networkCreate.IPAM != nil && networkCreate.IPAM.Config != nil { + if len(networkCreate.IPAM.Config) > 1 { + utils.InternalServerError(w, errors.New("compat network create can only support one IPAM config")) + return + } + + if len(networkCreate.IPAM.Config[0].Subnet) > 0 { + _, subnet, err := net.ParseCIDR(networkCreate.IPAM.Config[0].Subnet) + if err != nil { + utils.InternalServerError(w, err) + return + } + ncOptions.Subnet = *subnet + } + if len(networkCreate.IPAM.Config[0].Gateway) > 0 { + ncOptions.Gateway = net.ParseIP(networkCreate.IPAM.Config[0].Gateway) + } + if len(networkCreate.IPAM.Config[0].IPRange) > 0 { + _, IPRange, err := net.ParseCIDR(networkCreate.IPAM.Config[0].IPRange) + if err != nil { + utils.InternalServerError(w, err) + return + } + ncOptions.Range = *IPRange + } + } + ce := abi.ContainerEngine{Libpod: runtime} + _, err := ce.NetworkCreate(r.Context(), name, ncOptions) + if err != nil { + utils.InternalServerError(w, err) + } + report := types.NetworkCreate{ + CheckDuplicate: networkCreate.CheckDuplicate, + Driver: networkCreate.Driver, + Scope: networkCreate.Scope, + EnableIPv6: networkCreate.EnableIPv6, + IPAM: networkCreate.IPAM, + Internal: networkCreate.Internal, + Attachable: networkCreate.Attachable, + Ingress: networkCreate.Ingress, + ConfigOnly: networkCreate.ConfigOnly, + ConfigFrom: networkCreate.ConfigFrom, + Options: networkCreate.Options, + Labels: networkCreate.Labels, + } + utils.WriteResponse(w, http.StatusOK, report) +} + +func RemoveNetwork(w http.ResponseWriter, r *http.Request) { + runtime := r.Context().Value("runtime").(*libpod.Runtime) + config, err := runtime.GetConfig() + if err != nil { + utils.InternalServerError(w, err) + return + } + name := utils.GetName(r) + exists, err := network.Exists(config, name) + if err != nil { + utils.InternalServerError(w, err) + return + } + if !exists { + utils.Error(w, "network not found", http.StatusNotFound, err) + return + } + if err := network.RemoveNetwork(config, name); err != nil { + utils.InternalServerError(w, err) + } + utils.WriteResponse(w, http.StatusNoContent, "") +} diff --git a/pkg/api/handlers/compat/swagger.go b/pkg/api/handlers/compat/swagger.go index ce83aa32f..dc94a7ebd 100644 --- a/pkg/api/handlers/compat/swagger.go +++ b/pkg/api/handlers/compat/swagger.go @@ -3,6 +3,7 @@ package compat import ( "github.com/containers/libpod/pkg/domain/entities" "github.com/containers/storage/pkg/archive" + "github.com/docker/docker/api/types" ) // Create container @@ -35,3 +36,30 @@ type swagChangesResponse struct { Changes []archive.Change } } + +// Network inspect +// swagger:response CompatNetworkInspect +type swagCompatNetworkInspect struct { + // in:body + Body types.NetworkResource +} + +// Network list +// swagger:response CompatNetworkList +type swagCompatNetworkList struct { + // in:body + Body []types.NetworkResource +} + +// Network create +// swagger:model NetworkCreateRequest +type NetworkCreateRequest struct { + types.NetworkCreateRequest +} + +// Network create +// swagger:response CompatNetworkCreate +type swagCompatNetworkCreateResponse struct { + // in:body + Body struct{ types.NetworkCreate } +} diff --git a/pkg/api/handlers/libpod/healthcheck.go b/pkg/api/handlers/libpod/healthcheck.go index 6eb2ab0e3..0ca3574b7 100644 --- a/pkg/api/handlers/libpod/healthcheck.go +++ b/pkg/api/handlers/libpod/healthcheck.go @@ -4,6 +4,7 @@ import ( "net/http" "github.com/containers/libpod/libpod" + "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/api/handlers/utils" ) @@ -12,32 +13,27 @@ func RunHealthCheck(w http.ResponseWriter, r *http.Request) { name := utils.GetName(r) status, err := runtime.HealthCheck(name) if err != nil { - if status == libpod.HealthCheckContainerNotFound { + if status == define.HealthCheckContainerNotFound { utils.ContainerNotFound(w, name, err) return } - if status == libpod.HealthCheckNotDefined { + if status == define.HealthCheckNotDefined { utils.Error(w, "no healthcheck defined", http.StatusConflict, err) return } - if status == libpod.HealthCheckContainerStopped { + if status == define.HealthCheckContainerStopped { utils.Error(w, "container not running", http.StatusConflict, err) return } utils.InternalServerError(w, err) return } - ctr, err := runtime.LookupContainer(name) - if err != nil { - utils.InternalServerError(w, err) - return + hcStatus := define.HealthCheckUnhealthy + if status == define.HealthCheckSuccess { + hcStatus = define.HealthCheckHealthy } - - hcLog, err := ctr.GetHealthCheckLog() - if err != nil { - utils.InternalServerError(w, err) - return + report := define.HealthCheckResults{ + Status: hcStatus, } - - utils.WriteResponse(w, http.StatusOK, hcLog) + utils.WriteResponse(w, http.StatusOK, report) } diff --git a/pkg/api/handlers/libpod/manifests.go b/pkg/api/handlers/libpod/manifests.go index d87ed7eba..93ca367f7 100644 --- a/pkg/api/handlers/libpod/manifests.go +++ b/pkg/api/handlers/libpod/manifests.go @@ -151,6 +151,7 @@ func ManifestPush(w http.ResponseWriter, r *http.Request) { } sc := image.GetSystemContext(rtc.Engine.SignaturePolicyPath, "", false) opts := manifests.PushOptions{ + Store: runtime.GetStore(), ImageListSelection: copy2.CopySpecificImages, SystemContext: sc, } diff --git a/pkg/api/handlers/libpod/system.go b/pkg/api/handlers/libpod/system.go index 81ed37b4a..f575546c9 100644 --- a/pkg/api/handlers/libpod/system.go +++ b/pkg/api/handlers/libpod/system.go @@ -71,16 +71,6 @@ func SystemPrune(w http.ResponseWriter, r *http.Request) { utils.WriteResponse(w, http.StatusOK, systemPruneReport) } -// SystemReset Resets podman storage back to default state -func SystemReset(w http.ResponseWriter, r *http.Request) { - err := r.Context().Value("runtime").(*libpod.Runtime).Reset(r.Context()) - if err != nil { - utils.InternalServerError(w, err) - return - } - utils.WriteResponse(w, http.StatusOK, nil) -} - func DiskUsage(w http.ResponseWriter, r *http.Request) { // Options are only used by the CLI options := entities.SystemDfOptions{} diff --git a/pkg/api/handlers/utils/images.go b/pkg/api/handlers/utils/images.go index 1c67de9db..7fb31a177 100644 --- a/pkg/api/handlers/utils/images.go +++ b/pkg/api/handlers/utils/images.go @@ -62,7 +62,6 @@ func GetImages(w http.ResponseWriter, r *http.Request) ([]*image.Image, error) { }{ // This is where you can override the golang default value for one of fields } - // TODO I think all is implemented with a filter? if err := decoder.Decode(&query, r.URL.Query()); err != nil { return nil, err @@ -71,6 +70,10 @@ func GetImages(w http.ResponseWriter, r *http.Request) ([]*image.Image, error) { if _, found := r.URL.Query()["digests"]; found && query.Digests { UnSupportedParameter("digests") } + var ( + images []*image.Image + err error + ) if len(query.Filters) > 0 { for k, v := range query.Filters { @@ -78,11 +81,33 @@ func GetImages(w http.ResponseWriter, r *http.Request) ([]*image.Image, error) { filters = append(filters, fmt.Sprintf("%s=%s", k, val)) } } - return runtime.ImageRuntime().GetImagesWithFilters(filters) + images, err = runtime.ImageRuntime().GetImagesWithFilters(filters) + if err != nil { + return images, err + } } else { - return runtime.ImageRuntime().GetImages() + images, err = runtime.ImageRuntime().GetImages() + if err != nil { + return images, err + } } - + if query.All { + return images, nil + } + var returnImages []*image.Image + for _, img := range images { + if len(img.Names()) == 0 { + parent, err := img.IsParent(r.Context()) + if err != nil { + return nil, err + } + if parent { + continue + } + } + returnImages = append(returnImages, img) + } + return returnImages, nil } func GetImage(r *http.Request, name string) (*image.Image, error) { diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go index 01854b9c4..c885dc81a 100644 --- a/pkg/api/server/register_images.go +++ b/pkg/api/server/register_images.go @@ -1188,5 +1188,214 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: "#/responses/InternalError" r.HandleFunc(VersionedPath("/libpod/images/{name}/changes"), s.APIHandler(compat.Changes)).Methods(http.MethodGet) + // swagger:operation POST /libpod/build libpod libpodBuildImage + // --- + // tags: + // - images + // summary: Create image + // description: Build an image from the given Dockerfile(s) + // parameters: + // - in: query + // name: dockerfile + // type: string + // default: Dockerfile + // description: | + // Path within the build context to the `Dockerfile`. + // This is ignored if remote is specified and points to an external `Dockerfile`. + // - in: query + // name: t + // type: string + // default: latest + // description: A name and optional tag to apply to the image in the `name:tag` format. + // - in: query + // name: extrahosts + // type: string + // default: + // description: | + // TBD Extra hosts to add to /etc/hosts + // (As of version 1.xx) + // - in: query + // name: remote + // type: string + // default: + // description: | + // A Git repository URI or HTTP/HTTPS context URI. + // If the URI points to a single text file, the file’s contents are placed + // into a file called Dockerfile and the image is built from that file. If + // the URI points to a tarball, the file is downloaded by the daemon and the + // contents therein used as the context for the build. If the URI points to a + // tarball and the dockerfile parameter is also specified, there must be a file + // with the corresponding path inside the tarball. + // (As of version 1.xx) + // - in: query + // name: q + // type: boolean + // default: false + // description: | + // Suppress verbose build output + // - in: query + // name: nocache + // type: boolean + // default: false + // description: | + // Do not use the cache when building the image + // (As of version 1.xx) + // - in: query + // name: cachefrom + // type: string + // default: + // description: | + // JSON array of images used to build cache resolution + // (As of version 1.xx) + // - in: query + // name: pull + // type: boolean + // default: false + // description: | + // Attempt to pull the image even if an older image exists locally + // (As of version 1.xx) + // - in: query + // name: rm + // type: boolean + // default: true + // description: | + // Remove intermediate containers after a successful build + // (As of version 1.xx) + // - in: query + // name: forcerm + // type: boolean + // default: false + // description: | + // Always remove intermediate containers, even upon failure + // (As of version 1.xx) + // - in: query + // name: memory + // type: integer + // description: | + // Memory is the upper limit (in bytes) on how much memory running containers can use + // (As of version 1.xx) + // - in: query + // name: memswap + // type: integer + // description: | + // MemorySwap limits the amount of memory and swap together + // (As of version 1.xx) + // - in: query + // name: cpushares + // type: integer + // description: | + // CPUShares (relative weight + // (As of version 1.xx) + // - in: query + // name: cpusetcpus + // type: string + // description: | + // CPUSetCPUs in which to allow execution (0-3, 0,1) + // (As of version 1.xx) + // - in: query + // name: cpuperiod + // type: integer + // description: | + // CPUPeriod limits the CPU CFS (Completely Fair Scheduler) period + // (As of version 1.xx) + // - in: query + // name: cpuquota + // type: integer + // description: | + // CPUQuota limits the CPU CFS (Completely Fair Scheduler) quota + // (As of version 1.xx) + // - in: query + // name: buildargs + // type: string + // default: + // description: | + // JSON map of string pairs denoting build-time variables. + // For example, the build argument `Foo` with the value of `bar` would be encoded in JSON as `["Foo":"bar"]`. + // + // For example, buildargs={"Foo":"bar"}. + // + // Note(s): + // * This should not be used to pass secrets. + // * The value of buildargs should be URI component encoded before being passed to the API. + // + // (As of version 1.xx) + // - in: query + // name: shmsize + // type: integer + // default: 67108864 + // description: | + // ShmSize is the "size" value to use when mounting an shmfs on the container's /dev/shm directory. + // Default is 64MB + // (As of version 1.xx) + // - in: query + // name: squash + // type: boolean + // default: false + // description: | + // Silently ignored. + // Squash the resulting images layers into a single layer + // (As of version 1.xx) + // - in: query + // name: labels + // type: string + // default: + // description: | + // JSON map of key, value pairs to set as labels on the new image + // (As of version 1.xx) + // - in: query + // name: networkmode + // type: string + // default: bridge + // description: | + // Sets the networking mode for the run commands during build. + // Supported standard values are: + // * `bridge` limited to containers within a single host, port mapping required for external access + // * `host` no isolation between host and containers on this network + // * `none` disable all networking for this container + // * container:<nameOrID> share networking with given container + // ---All other values are assumed to be a custom network's name + // (As of version 1.xx) + // - in: query + // name: platform + // type: string + // default: + // description: | + // Platform format os[/arch[/variant]] + // (As of version 1.xx) + // - in: query + // name: target + // type: string + // default: + // description: | + // Target build stage + // (As of version 1.xx) + // - in: query + // name: outputs + // type: string + // default: + // description: | + // output configuration TBD + // (As of version 1.xx) + // produces: + // - application/json + // responses: + // 200: + // description: OK (As of version 1.xx) + // schema: + // type: object + // required: + // - stream + // properties: + // stream: + // type: string + // description: output from build process + // example: | + // (build details...) + // Successfully built 8ba084515c724cbf90d447a63600c0a6 + // 400: + // $ref: "#/responses/BadParamError" + // 500: + // $ref: "#/responses/InternalError" + r.Handle(VersionedPath("/libpod/build"), s.APIHandler(compat.BuildImage)).Methods(http.MethodPost) return nil } diff --git a/pkg/api/server/register_networks.go b/pkg/api/server/register_networks.go index b1189c1f4..2c60b2b27 100644 --- a/pkg/api/server/register_networks.go +++ b/pkg/api/server/register_networks.go @@ -3,11 +3,96 @@ 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) registerNetworkHandlers(r *mux.Router) error { + // swagger:operation DELETE /networks/{name} compat compatRemoveNetwork + // --- + // tags: + // - networks (compat) + // summary: Remove a network + // description: Remove a network + // parameters: + // - in: path + // name: name + // type: string + // required: true + // description: the name of the network + // produces: + // - application/json + // responses: + // 204: + // description: no error + // 404: + // $ref: "#/responses/NoSuchNetwork" + // 500: + // $ref: "#/responses/InternalError" + r.HandleFunc(VersionedPath("/networks/{name}"), s.APIHandler(compat.RemoveNetwork)).Methods(http.MethodDelete) + r.HandleFunc("/networks/{name}", s.APIHandler(compat.RemoveNetwork)).Methods(http.MethodDelete) + // swagger:operation GET /networks/{name}/json compat compatInspectNetwork + // --- + // tags: + // - networks (compat) + // summary: Inspect a network + // description: Display low level configuration network + // parameters: + // - in: path + // name: name + // type: string + // required: true + // description: the name of the network + // produces: + // - application/json + // responses: + // 200: + // $ref: "#/responses/CompatNetworkInspect" + // 404: + // $ref: "#/responses/NoSuchNetwork" + // 500: + // $ref: "#/responses/InternalError" + r.HandleFunc(VersionedPath("/networks/{name}/json"), s.APIHandler(compat.InspectNetwork)).Methods(http.MethodGet) + r.HandleFunc("/networks/{name}/json", s.APIHandler(compat.InspectNetwork)).Methods(http.MethodGet) + // swagger:operation GET /networks/json compat compatListNetwork + // --- + // tags: + // - networks (compat) + // summary: List networks + // description: Display summary of network configurations + // produces: + // - application/json + // responses: + // 200: + // $ref: "#/responses/CompatNetworkList" + // 500: + // $ref: "#/responses/InternalError" + r.HandleFunc(VersionedPath("/networks/json"), s.APIHandler(compat.ListNetworks)).Methods(http.MethodGet) + r.HandleFunc("/networks", s.APIHandler(compat.ListNetworks)).Methods(http.MethodGet) + // swagger:operation POST /networks/create compat compatCreateNetwork + // --- + // tags: + // - networks (compat) + // summary: Create network + // description: Create a network configuration + // produces: + // - application/json + // parameters: + // - in: body + // name: create + // description: attributes for creating a container + // schema: + // $ref: "#/definitions/NetworkCreateRequest" + // responses: + // 200: + // $ref: "#/responses/CompatNetworkCreate" + // 400: + // $ref: "#/responses/BadParamError" + // 500: + // $ref: "#/responses/InternalError" + r.HandleFunc(VersionedPath("/networks/create"), s.APIHandler(compat.CreateNetwork)).Methods(http.MethodPost) + r.HandleFunc("/networks/create", s.APIHandler(compat.CreateNetwork)).Methods(http.MethodPost) // swagger:operation DELETE /libpod/networks/{name} libpod libpodRemoveNetwork // --- // tags: @@ -33,6 +118,11 @@ func (s *APIServer) registerNetworkHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchNetwork" // 500: // $ref: "#/responses/InternalError" + + /* + Libpod + */ + r.HandleFunc(VersionedPath("/libpod/networks/{name}"), s.APIHandler(libpod.RemoveNetwork)).Methods(http.MethodDelete) // swagger:operation GET /libpod/networks/{name}/json libpod libpodInspectNetwork // --- diff --git a/pkg/api/server/register_system.go b/pkg/api/server/register_system.go index 8a942a888..118ad2d08 100644 --- a/pkg/api/server/register_system.go +++ b/pkg/api/server/register_system.go @@ -27,20 +27,6 @@ func (s *APIServer) registerSystemHandlers(r *mux.Router) error { // 500: // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/system/prune"), s.APIHandler(libpod.SystemPrune)).Methods(http.MethodPost) - // swagger:operation POST /libpod/system/reset libpod resetSystem - // --- - // tags: - // - system - // summary: Reset podman storage - // description: All containers will be stopped and removed, and all images, volumes and container content will be removed. - // produces: - // - application/json - // responses: - // 200: - // description: no error - // 500: - // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/system/reset"), s.APIHandler(libpod.SystemReset)).Methods(http.MethodPost) // swagger:operation GET /libpod/system/df libpod df // --- // tags: diff --git a/pkg/api/server/server.go b/pkg/api/server/server.go index d39528f45..9cbc66e87 100644 --- a/pkg/api/server/server.go +++ b/pkg/api/server/server.go @@ -92,6 +92,14 @@ func newServer(runtime *libpod.Runtime, duration time.Duration, listener *net.Li }, ) + router.MethodNotAllowedHandler = http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + // We can track user errors... + logrus.Infof("Failed Request: (%d:%s) for %s:'%s'", http.StatusMethodNotAllowed, http.StatusText(http.StatusMethodNotAllowed), r.Method, r.URL.String()) + http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed) + }, + ) + for _, fn := range []func(*mux.Router) error{ server.registerAuthHandlers, server.registerContainersHandlers, diff --git a/pkg/api/tags.yaml b/pkg/api/tags.yaml index 1ffb5e940..f86f8dbea 100644 --- a/pkg/api/tags.yaml +++ b/pkg/api/tags.yaml @@ -21,5 +21,7 @@ tags: description: Actions related to exec for the compatibility endpoints - name: images (compat) description: Actions related to images for the compatibility endpoints + - name: networks (compat) + description: Actions related to compatibility networks - name: system (compat) description: Actions related to Podman and compatibility engines |