mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #28524 from aluzzardi/experimental-routes
router: Return explicit error rather than 404 for experimental.
This commit is contained in:
commit
c3fab6d473
5 changed files with 89 additions and 40 deletions
|
@ -29,8 +29,8 @@ func (r *checkpointRouter) Routes() []router.Route {
|
||||||
|
|
||||||
func (r *checkpointRouter) initRoutes() {
|
func (r *checkpointRouter) initRoutes() {
|
||||||
r.routes = []router.Route{
|
r.routes = []router.Route{
|
||||||
router.NewGetRoute("/containers/{name:.*}/checkpoints", r.getContainerCheckpoints),
|
router.Experimental(router.NewGetRoute("/containers/{name:.*}/checkpoints", r.getContainerCheckpoints)),
|
||||||
router.NewPostRoute("/containers/{name:.*}/checkpoints", r.postContainerCheckpoint),
|
router.Experimental(router.NewPostRoute("/containers/{name:.*}/checkpoints", r.postContainerCheckpoint)),
|
||||||
router.NewDeleteRoute("/containers/{name}/checkpoints/{checkpoint}", r.deleteContainerCheckpoint),
|
router.Experimental(router.NewDeleteRoute("/containers/{name}/checkpoints/{checkpoint}", r.deleteContainerCheckpoint)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
67
api/server/router/experimental.go
Normal file
67
api/server/router/experimental.go
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
|
apierrors "github.com/docker/docker/api/errors"
|
||||||
|
"github.com/docker/docker/api/server/httputils"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
errExperimentalFeature = errors.New("This experimental feature is disabled by default. Start the Docker daemon with --experimental in order to enable it.")
|
||||||
|
)
|
||||||
|
|
||||||
|
// ExperimentalRoute defines an experimental API route that can be enabled or disabled.
|
||||||
|
type ExperimentalRoute interface {
|
||||||
|
Route
|
||||||
|
|
||||||
|
Enable()
|
||||||
|
Disable()
|
||||||
|
}
|
||||||
|
|
||||||
|
// experimentalRoute defines an experimental API route that can be enabled or disabled.
|
||||||
|
// It implements ExperimentalRoute
|
||||||
|
type experimentalRoute struct {
|
||||||
|
local Route
|
||||||
|
handler httputils.APIFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable enables this experimental route
|
||||||
|
func (r *experimentalRoute) Enable() {
|
||||||
|
r.handler = r.local.Handler()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable disables the experimental route
|
||||||
|
func (r *experimentalRoute) Disable() {
|
||||||
|
r.handler = experimentalHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func experimentalHandler(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||||
|
return apierrors.NewErrorWithStatusCode(errExperimentalFeature, http.StatusNotImplemented)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handler returns returns the APIFunc to let the server wrap it in middlewares.
|
||||||
|
func (r *experimentalRoute) Handler() httputils.APIFunc {
|
||||||
|
return r.handler
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method returns the http method that the route responds to.
|
||||||
|
func (r *experimentalRoute) Method() string {
|
||||||
|
return r.local.Method()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Path returns the subpath where the route responds to.
|
||||||
|
func (r *experimentalRoute) Path() string {
|
||||||
|
return r.local.Path()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Experimental will mark a route as experimental.
|
||||||
|
func Experimental(r Route) Route {
|
||||||
|
return &experimentalRoute{
|
||||||
|
local: r,
|
||||||
|
handler: experimentalHandler,
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,6 @@
|
||||||
package swarm
|
package swarm
|
||||||
|
|
||||||
import (
|
import "github.com/docker/docker/api/server/router"
|
||||||
"github.com/docker/docker/api/server/router"
|
|
||||||
"github.com/docker/docker/daemon"
|
|
||||||
)
|
|
||||||
|
|
||||||
// swarmRouter is a router to talk with the build controller
|
// swarmRouter is a router to talk with the build controller
|
||||||
type swarmRouter struct {
|
type swarmRouter struct {
|
||||||
|
@ -12,14 +9,11 @@ type swarmRouter struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRouter initializes a new build router
|
// NewRouter initializes a new build router
|
||||||
func NewRouter(d *daemon.Daemon, b Backend) router.Router {
|
func NewRouter(b Backend) router.Router {
|
||||||
r := &swarmRouter{
|
r := &swarmRouter{
|
||||||
backend: b,
|
backend: b,
|
||||||
}
|
}
|
||||||
r.initRoutes()
|
r.initRoutes()
|
||||||
if d.HasExperimental() {
|
|
||||||
r.addExperimentalRoutes()
|
|
||||||
}
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,12 +22,6 @@ func (sr *swarmRouter) Routes() []router.Route {
|
||||||
return sr.routes
|
return sr.routes
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sr *swarmRouter) addExperimentalRoutes() {
|
|
||||||
sr.routes = append(sr.routes,
|
|
||||||
router.Cancellable(router.NewGetRoute("/services/{id}/logs", sr.getServiceLogs)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sr *swarmRouter) initRoutes() {
|
func (sr *swarmRouter) initRoutes() {
|
||||||
sr.routes = []router.Route{
|
sr.routes = []router.Route{
|
||||||
router.NewPostRoute("/swarm/init", sr.initCluster),
|
router.NewPostRoute("/swarm/init", sr.initCluster),
|
||||||
|
@ -48,6 +36,7 @@ func (sr *swarmRouter) initRoutes() {
|
||||||
router.NewPostRoute("/services/create", sr.createService),
|
router.NewPostRoute("/services/create", sr.createService),
|
||||||
router.NewPostRoute("/services/{id}/update", sr.updateService),
|
router.NewPostRoute("/services/{id}/update", sr.updateService),
|
||||||
router.NewDeleteRoute("/services/{id}", sr.removeService),
|
router.NewDeleteRoute("/services/{id}", sr.removeService),
|
||||||
|
router.Experimental(router.Cancellable(router.NewGetRoute("/services/{id}/logs", sr.getServiceLogs))),
|
||||||
router.NewGetRoute("/nodes", sr.getNodes),
|
router.NewGetRoute("/nodes", sr.getNodes),
|
||||||
router.NewGetRoute("/nodes/{id}", sr.getNode),
|
router.NewGetRoute("/nodes/{id}", sr.getNode),
|
||||||
router.NewDeleteRoute("/nodes/{id}", sr.removeNode),
|
router.NewDeleteRoute("/nodes/{id}", sr.removeNode),
|
||||||
|
|
|
@ -17,6 +17,7 @@ import (
|
||||||
"github.com/docker/docker/api/server/middleware"
|
"github.com/docker/docker/api/server/middleware"
|
||||||
"github.com/docker/docker/api/server/router"
|
"github.com/docker/docker/api/server/router"
|
||||||
"github.com/docker/docker/api/server/router/build"
|
"github.com/docker/docker/api/server/router/build"
|
||||||
|
checkpointrouter "github.com/docker/docker/api/server/router/checkpoint"
|
||||||
"github.com/docker/docker/api/server/router/container"
|
"github.com/docker/docker/api/server/router/container"
|
||||||
"github.com/docker/docker/api/server/router/image"
|
"github.com/docker/docker/api/server/router/image"
|
||||||
"github.com/docker/docker/api/server/router/network"
|
"github.com/docker/docker/api/server/router/network"
|
||||||
|
@ -461,25 +462,32 @@ func loadDaemonCliConfig(opts daemonOptions) (*daemon.Config, error) {
|
||||||
func initRouter(s *apiserver.Server, d *daemon.Daemon, c *cluster.Cluster) {
|
func initRouter(s *apiserver.Server, d *daemon.Daemon, c *cluster.Cluster) {
|
||||||
decoder := runconfig.ContainerDecoder{}
|
decoder := runconfig.ContainerDecoder{}
|
||||||
|
|
||||||
routers := []router.Router{}
|
routers := []router.Router{
|
||||||
|
// we need to add the checkpoint router before the container router or the DELETE gets masked
|
||||||
// we need to add the checkpoint router before the container router or the DELETE gets masked
|
checkpointrouter.NewRouter(d, decoder),
|
||||||
routers = addExperimentalRouters(routers, d, decoder)
|
|
||||||
|
|
||||||
routers = append(routers, []router.Router{
|
|
||||||
container.NewRouter(d, decoder),
|
container.NewRouter(d, decoder),
|
||||||
image.NewRouter(d, decoder),
|
image.NewRouter(d, decoder),
|
||||||
systemrouter.NewRouter(d, c),
|
systemrouter.NewRouter(d, c),
|
||||||
volume.NewRouter(d),
|
volume.NewRouter(d),
|
||||||
build.NewRouter(dockerfile.NewBuildManager(d)),
|
build.NewRouter(dockerfile.NewBuildManager(d)),
|
||||||
swarmrouter.NewRouter(d, c),
|
swarmrouter.NewRouter(c),
|
||||||
pluginrouter.NewRouter(plugin.GetManager()),
|
pluginrouter.NewRouter(plugin.GetManager()),
|
||||||
}...)
|
}
|
||||||
|
|
||||||
if d.NetworkControllerEnabled() {
|
if d.NetworkControllerEnabled() {
|
||||||
routers = append(routers, network.NewRouter(d, c))
|
routers = append(routers, network.NewRouter(d, c))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if d.HasExperimental() {
|
||||||
|
for _, r := range routers {
|
||||||
|
for _, route := range r.Routes() {
|
||||||
|
if experimental, ok := route.(router.ExperimentalRoute); ok {
|
||||||
|
experimental.Enable()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
s.InitRouter(utils.IsDebugEnabled(), routers...)
|
s.InitRouter(utils.IsDebugEnabled(), routers...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/docker/docker/api/server/httputils"
|
|
||||||
"github.com/docker/docker/api/server/router"
|
|
||||||
checkpointrouter "github.com/docker/docker/api/server/router/checkpoint"
|
|
||||||
"github.com/docker/docker/daemon"
|
|
||||||
)
|
|
||||||
|
|
||||||
func addExperimentalRouters(routers []router.Router, d *daemon.Daemon, decoder httputils.ContainerDecoder) []router.Router {
|
|
||||||
if !d.HasExperimental() {
|
|
||||||
return []router.Router{}
|
|
||||||
}
|
|
||||||
return append(routers, checkpointrouter.NewRouter(d, decoder))
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue