mirror of https://github.com/docker/docs.git
Merge pull request #271 from vieux/history_inspect
add support for history, inspect for images and improve inspect for containers
This commit is contained in:
commit
7dd2d2440b
|
@ -10,8 +10,6 @@ Here are the main differences:
|
|||
```
|
||||
GET "/images/get"
|
||||
GET "/images/{name:.*}/get"
|
||||
GET "/images/{name:.*}/history"
|
||||
GET "/images/{name:.*}/json"
|
||||
GET "/containers/{name:.*}/attach/ws"
|
||||
|
||||
POST "/commit"
|
||||
|
|
78
api/api.go
78
api/api.go
|
@ -163,36 +163,39 @@ func getContainersJSON(c *context, w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// GET /containers/{name:.*}/json
|
||||
func getContainerJSON(c *context, w http.ResponseWriter, r *http.Request) {
|
||||
container := c.cluster.Container(mux.Vars(r)["name"])
|
||||
if container != nil {
|
||||
client, scheme := newClientAndScheme(c.tlsConfig)
|
||||
|
||||
resp, err := client.Get(scheme + "://" + container.Node.Addr + "/containers/" + container.Id + "/json")
|
||||
if err != nil {
|
||||
httpError(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
httpError(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
n, err := json.Marshal(container.Node)
|
||||
if err != nil {
|
||||
httpError(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// insert Node field
|
||||
data = bytes.Replace(data, []byte("\"Name\":\"/"), []byte(fmt.Sprintf("\"Node\":%s,\"Name\":\"/", n)), -1)
|
||||
|
||||
// insert node IP
|
||||
data = bytes.Replace(data, []byte("\"HostIp\":\"0.0.0.0\""), []byte(fmt.Sprintf("\"HostIp\":%q", container.Node.IP)), -1)
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(data)
|
||||
name := mux.Vars(r)["name"]
|
||||
container := c.cluster.Container(name)
|
||||
if container == nil {
|
||||
httpError(w, fmt.Sprintf("No such container %s", name), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
client, scheme := newClientAndScheme(c.tlsConfig)
|
||||
|
||||
resp, err := client.Get(scheme + "://" + container.Node.Addr + "/containers/" + container.Id + "/json")
|
||||
if err != nil {
|
||||
httpError(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
httpError(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
n, err := json.Marshal(container.Node)
|
||||
if err != nil {
|
||||
httpError(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// insert Node field
|
||||
data = bytes.Replace(data, []byte("\"Name\":\"/"), []byte(fmt.Sprintf("\"Node\":%s,\"Name\":\"/", n)), -1)
|
||||
|
||||
// insert node IP
|
||||
data = bytes.Replace(data, []byte("\"HostIp\":\"0.0.0.0\""), []byte(fmt.Sprintf("\"HostIp\":%q", container.Node.IP)), -1)
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(data)
|
||||
}
|
||||
|
||||
// POST /containers/create
|
||||
|
@ -292,6 +295,19 @@ func proxyContainer(c *context, w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
// Proxy a request to the right node
|
||||
func proxyImage(c *context, w http.ResponseWriter, r *http.Request) {
|
||||
name := mux.Vars(r)["name"]
|
||||
|
||||
for _, node := range c.cluster.Nodes() {
|
||||
if node.Image(name) != nil {
|
||||
proxy(c.tlsConfig, node.Addr, w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
httpError(w, fmt.Sprintf("No such image: %s", name), http.StatusNotFound)
|
||||
}
|
||||
|
||||
// Proxy a request to a random node
|
||||
func proxyRandom(c *context, w http.ResponseWriter, r *http.Request) {
|
||||
candidates := c.cluster.Nodes()
|
||||
|
@ -355,8 +371,8 @@ func createRouter(c *context, enableCors bool) *mux.Router {
|
|||
"/images/search": proxyRandom,
|
||||
"/images/get": notImplementedHandler,
|
||||
"/images/{name:.*}/get": notImplementedHandler,
|
||||
"/images/{name:.*}/history": notImplementedHandler,
|
||||
"/images/{name:.*}/json": notImplementedHandler,
|
||||
"/images/{name:.*}/history": proxyImage,
|
||||
"/images/{name:.*}/json": proxyImage,
|
||||
"/containers/ps": getContainersJSON,
|
||||
"/containers/json": getContainersJSON,
|
||||
"/containers/{name:.*}/export": proxyContainer,
|
||||
|
|
|
@ -25,7 +25,7 @@ func getContainerFromVars(c *context, vars map[string]string) (*cluster.Containe
|
|||
if container := c.cluster.Container(name); container != nil {
|
||||
return container, nil
|
||||
}
|
||||
return nil, fmt.Errorf("Container %s not found", name)
|
||||
return nil, fmt.Errorf("No such container: %s", name)
|
||||
|
||||
}
|
||||
if ID, ok := vars["execid"]; ok {
|
||||
|
|
|
@ -132,7 +132,7 @@ func (c *Cluster) Containers() []*Container {
|
|||
return out
|
||||
}
|
||||
|
||||
// Container returns the container with ID in the cluster
|
||||
// Container returns the container with IdOrName in the cluster
|
||||
func (c *Cluster) Container(IdOrName string) *Container {
|
||||
// Abort immediately if the name is empty.
|
||||
if len(IdOrName) == 0 {
|
||||
|
|
|
@ -414,6 +414,22 @@ func (n *Node) Images() []*dockerclient.Image {
|
|||
return images
|
||||
}
|
||||
|
||||
// Image returns the image with IdOrName in the node
|
||||
func (n *Node) Image(IdOrName string) *dockerclient.Image {
|
||||
size := len(IdOrName)
|
||||
for _, image := range n.Images() {
|
||||
if image.Id == IdOrName || (size > 2 && strings.HasPrefix(image.Id, IdOrName)) {
|
||||
return image
|
||||
}
|
||||
for _, t := range image.RepoTags {
|
||||
if t == IdOrName || (size > 2 && strings.HasPrefix(t, IdOrName)) {
|
||||
return image
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *Node) String() string {
|
||||
return fmt.Sprintf("node %s addr %s", n.ID, n.Addr)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue