mirror of https://github.com/docker/docs.git
Merge pull request #603 from vieux/add_build
Proposal: Add build support on a random node
This commit is contained in:
commit
9ac7dd2402
|
@ -15,7 +15,6 @@ Some endpoints have not yet been implemented and will return a 404 error.
|
|||
```
|
||||
GET "/images/get"
|
||||
|
||||
POST "/build"
|
||||
POST "/images/load"
|
||||
POST "/images/create" : "docker import" flow not implement
|
||||
```
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"runtime"
|
||||
"sort"
|
||||
|
@ -14,8 +13,6 @@ import (
|
|||
|
||||
dockerfilters "github.com/docker/docker/pkg/parsers/filters"
|
||||
"github.com/docker/swarm/cluster"
|
||||
"github.com/docker/swarm/scheduler/filter"
|
||||
"github.com/docker/swarm/scheduler/node"
|
||||
"github.com/docker/swarm/version"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/samalba/dockerclient"
|
||||
|
@ -398,24 +395,46 @@ func proxyImage(c *context, w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// Proxy a request to a random node
|
||||
func proxyRandom(c *context, w http.ResponseWriter, r *http.Request) {
|
||||
candidates := []*node.Node{}
|
||||
|
||||
// FIXME: doesn't work if there are no container in the cluster
|
||||
// remove proxyRandom and implemente the features locally
|
||||
for _, container := range c.cluster.Containers() {
|
||||
candidates = append(candidates, node.NewNode(container.Engine))
|
||||
}
|
||||
|
||||
healthFilter := &filter.HealthFilter{}
|
||||
accepted, err := healthFilter.Filter(nil, candidates)
|
||||
engine, err := c.cluster.RANDOMENGINE()
|
||||
if err != nil {
|
||||
httpError(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if err := proxy(c.tlsConfig, accepted[rand.Intn(len(accepted))].Addr, w, r); err != nil {
|
||||
if engine == nil {
|
||||
httpError(w, "no node available in the cluster", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if err := proxy(c.tlsConfig, engine.Addr, w, r); err != nil {
|
||||
httpError(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Proxy a request to a random node and force refresh
|
||||
func proxyRandomAndForceRefresh(c *context, w http.ResponseWriter, r *http.Request) {
|
||||
engine, err := c.cluster.RANDOMENGINE()
|
||||
if err != nil {
|
||||
httpError(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if engine == nil {
|
||||
httpError(w, "no node available in the cluster", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
cb := func(resp *http.Response) {
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
engine.RefreshImages()
|
||||
}
|
||||
}
|
||||
|
||||
if err := proxyAsync(c.tlsConfig, engine.Addr, w, r, cb); err != nil {
|
||||
httpError(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// POST /commit
|
||||
|
|
|
@ -46,7 +46,7 @@ var routes = map[string]map[string]handler{
|
|||
"POST": {
|
||||
"/auth": proxyRandom,
|
||||
"/commit": postCommit,
|
||||
"/build": notImplementedHandler,
|
||||
"/build": proxyRandomAndForceRefresh,
|
||||
"/images/create": postImagesCreate,
|
||||
"/images/load": notImplementedHandler,
|
||||
"/images/{name:.*}/push": proxyImage,
|
||||
|
|
10
api/utils.go
10
api/utils.go
|
@ -63,7 +63,7 @@ func closeIdleConnections(client *http.Client) {
|
|||
}
|
||||
}
|
||||
|
||||
func proxy(tlsConfig *tls.Config, addr string, w http.ResponseWriter, r *http.Request) error {
|
||||
func proxyAsync(tlsConfig *tls.Config, addr string, w http.ResponseWriter, r *http.Request, callback func(*http.Response)) error {
|
||||
// Use a new client for each request
|
||||
client, scheme := newClientAndScheme(tlsConfig)
|
||||
// RequestURI may not be sent to client
|
||||
|
@ -86,9 +86,17 @@ func proxy(tlsConfig *tls.Config, addr string, w http.ResponseWriter, r *http.Re
|
|||
resp.Body.Close()
|
||||
closeIdleConnections(client)
|
||||
|
||||
if callback != nil {
|
||||
callback(resp)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func proxy(tlsConfig *tls.Config, addr string, w http.ResponseWriter, r *http.Request) error {
|
||||
return proxyAsync(tlsConfig, addr, w, r, nil)
|
||||
}
|
||||
|
||||
func hijack(tlsConfig *tls.Config, addr string, w http.ResponseWriter, r *http.Request) error {
|
||||
if parts := strings.SplitN(addr, "://", 2); len(parts) == 2 {
|
||||
addr = parts[1]
|
||||
|
|
|
@ -39,4 +39,8 @@ type Cluster interface {
|
|||
|
||||
// Register an event handler for cluster-wide events.
|
||||
RegisterEventHandler(h EventHandler) error
|
||||
|
||||
// FIXME: remove this method
|
||||
// Return a random engine
|
||||
RANDOMENGINE() (*Engine, error)
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ func (e *Engine) connectClient(client dockerclient.Client) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if err := e.refreshImages(); err != nil {
|
||||
if err := e.RefreshImages(); err != nil {
|
||||
e.client = nil
|
||||
return err
|
||||
}
|
||||
|
@ -155,8 +155,8 @@ func (e *Engine) RemoveImage(image *Image) ([]*dockerclient.ImageDelete, error)
|
|||
return e.client.RemoveImage(image.Id)
|
||||
}
|
||||
|
||||
// Refresh the list of images on the engine.
|
||||
func (e *Engine) refreshImages() error {
|
||||
// RefreshImages refreshes the list of images on the engine.
|
||||
func (e *Engine) RefreshImages() error {
|
||||
images, err := e.client.ListImages()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -275,7 +275,7 @@ func (e *Engine) refreshLoop() {
|
|||
}
|
||||
|
||||
if err == nil {
|
||||
err = e.refreshImages()
|
||||
err = e.RefreshImages()
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
@ -490,7 +490,7 @@ func (e *Engine) handler(ev *dockerclient.Event, _ chan error, args ...interface
|
|||
case "pull", "untag", "delete":
|
||||
// These events refer to images so there's no need to update
|
||||
// containers.
|
||||
e.refreshImages()
|
||||
e.RefreshImages()
|
||||
case "start", "die":
|
||||
// If the container is started or stopped, we have to do an inspect in
|
||||
// order to get the new NetworkSettings.
|
||||
|
|
|
@ -314,3 +314,15 @@ func (c *Cluster) Info() [][2]string {
|
|||
|
||||
return info
|
||||
}
|
||||
|
||||
// RANDOMENGINE returns a random engine.
|
||||
func (c *Cluster) RANDOMENGINE() (*cluster.Engine, error) {
|
||||
n, err := c.scheduler.SelectNodeForContainer(c.listNodes(), &dockerclient.ContainerConfig{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if n != nil {
|
||||
return c.engines[n.ID], nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
@ -12,9 +12,20 @@ function teardown() {
|
|||
skip
|
||||
}
|
||||
|
||||
# FIXME
|
||||
@test "docker build" {
|
||||
skip
|
||||
start_docker 3
|
||||
swarm_manage
|
||||
|
||||
run docker_swarm images
|
||||
[ "$status" -eq 0 ]
|
||||
[ "${#lines[@]}" -eq 1 ]
|
||||
|
||||
run docker_swarm build -t test $BATS_TEST_DIRNAME/testdata/build
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
run docker_swarm images
|
||||
[ "$status" -eq 0 ]
|
||||
[ "${#lines[@]}" -eq 3 ]
|
||||
}
|
||||
|
||||
# FIXME
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
FROM busybox
|
||||
RUN ls
|
Loading…
Reference in New Issue