diff --git a/api/api.go b/api/api.go index 00f1b73a8d..4ea18d5242 100644 --- a/api/api.go +++ b/api/api.go @@ -202,6 +202,22 @@ func ping(c *context, w http.ResponseWriter, r *http.Request) { w.Write([]byte{'O', 'K'}) } +// Proxy a request to the right node and do a force refresh +func proxyContainerAndForceRefresh(c *context, w http.ResponseWriter, r *http.Request) { + container, err := getContainerFromVars(c, mux.Vars(r)) + if err != nil { + httpError(w, err.Error(), http.StatusNotFound) + return + } + + if err := proxy(container, w, r); err != nil { + httpError(w, err.Error(), http.StatusInternalServerError) + } + + log.Debugf("[REFRESH CONTAINER] --> %s", container.Id) + container.Node().ForceRefreshContainer(container.Container) +} + // Proxy a request to the right node func proxyContainer(c *context, w http.ResponseWriter, r *http.Request) { container, err := getContainerFromVars(c, mux.Vars(r)) @@ -271,7 +287,7 @@ func createRouter(c *context, enableCors bool) (*mux.Router, error) { "/containers/{name:.*}/top": proxyContainer, "/containers/{name:.*}/logs": proxyContainer, "/containers/{name:.*}/attach/ws": notImplementedHandler, - "/exec/{id:.*}/json": proxyContainer, + "/exec/{execid:.*}/json": proxyContainer, }, "POST": { "/auth": notImplementedHandler, @@ -292,9 +308,9 @@ func createRouter(c *context, enableCors bool) (*mux.Router, error) { "/containers/{name:.*}/resize": proxyContainer, "/containers/{name:.*}/attach": proxyHijack, "/containers/{name:.*}/copy": notImplementedHandler, - "/containers/{name:.*}/exec": notImplementedHandler, - "/exec/{name:.*}/start": notImplementedHandler, - "/exec/{name:.*}/resize": proxyContainer, + "/containers/{name:.*}/exec": proxyContainerAndForceRefresh, + "/exec/{execid:.*}/start": proxyHijack, + "/exec/{execid:.*}/resize": proxyContainer, }, "DELETE": { "/containers/{name:.*}": deleteContainer, diff --git a/api/utils.go b/api/utils.go index 96d3ca7fd8..5c8396432a 100644 --- a/api/utils.go +++ b/api/utils.go @@ -20,6 +20,16 @@ func getContainerFromVars(c *context, vars map[string]string) (*cluster.Containe return nil, fmt.Errorf("Container %s not found", name) } + if ID, ok := vars["execid"]; ok { + for _, container := range c.cluster.Containers() { + for _, execID := range container.Info.ExecIDs { + if ID == execID { + return container, nil + } + } + } + return nil, fmt.Errorf("Exec %s not found", ID) + } return nil, errors.New("Not found") } diff --git a/cluster/node.go b/cluster/node.go index 358e3b715a..201de9688c 100644 --- a/cluster/node.go +++ b/cluster/node.go @@ -177,6 +177,27 @@ func (n *Node) refreshContainer(ID string) error { return err } +func (n *Node) ForceRefreshContainer(c dockerclient.Container) error { + container := &Container{} + container.Container = c + container.node = n + + info, err := n.client.InspectContainer(c.Id) + if err != nil { + return err + } + container.Info = *info + + // real CpuShares -> nb of CPUs + container.Info.Config.CpuShares = container.Info.Config.CpuShares / 100.0 * n.Cpus + + n.Lock() + n.containers[container.Id] = container + n.Unlock() + + return nil +} + func (n *Node) updateContainer(c dockerclient.Container, containers map[string]*Container) (map[string]*Container, error) { if current, exists := n.containers[c.Id]; exists { // The container exists. Update its state.