mirror of https://github.com/docker/docs.git
more accurate http errors, attach handle tty correctly now
This commit is contained in:
parent
e5104a4cb4
commit
131c6ab3e6
104
api.go
104
api.go
|
@ -45,24 +45,7 @@ func ListenAndServe(addr string, rtime *Runtime) error {
|
||||||
http.Error(w, "No such container: "+name, http.StatusNotFound)
|
http.Error(w, "No such container: "+name, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.WriteHeader(200)
|
w.WriteHeader(http.StatusOK)
|
||||||
})
|
|
||||||
|
|
||||||
r.Path("/images/{name:.*}").Methods("GET").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
log.Println(r.Method, r.RequestURI)
|
|
||||||
vars := mux.Vars(r)
|
|
||||||
name := vars["name"]
|
|
||||||
|
|
||||||
if image, err := rtime.repositories.LookupImage(name); err == nil && image != nil {
|
|
||||||
b, err := json.Marshal(image)
|
|
||||||
if err != nil {
|
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
||||||
} else {
|
|
||||||
w.Write(b)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
http.Error(w, "No such image: "+name, http.StatusNotFound)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
r.Path("/containers/{name:.*}/export").Methods("GET").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
r.Path("/containers/{name:.*}/export").Methods("GET").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -102,23 +85,6 @@ func ListenAndServe(addr string, rtime *Runtime) error {
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
r.Path("/containers/{name:.*}").Methods("GET").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
log.Println(r.Method, r.RequestURI)
|
|
||||||
vars := mux.Vars(r)
|
|
||||||
name := vars["name"]
|
|
||||||
|
|
||||||
if container := rtime.Get(name); container != nil {
|
|
||||||
b, err := json.Marshal(container)
|
|
||||||
if err != nil {
|
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
||||||
} else {
|
|
||||||
w.Write(b)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
http.Error(w, "No such container: "+name, http.StatusNotFound)
|
|
||||||
})
|
|
||||||
|
|
||||||
r.Path("/images").Methods("GET").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
r.Path("/images").Methods("GET").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Println(r.Method, r.RequestURI)
|
log.Println(r.Method, r.RequestURI)
|
||||||
if err := r.ParseForm(); err != nil {
|
if err := r.ParseForm(); err != nil {
|
||||||
|
@ -428,7 +394,7 @@ func ListenAndServe(addr string, rtime *Runtime) error {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.WriteHeader(200)
|
w.WriteHeader(http.StatusCreated)
|
||||||
})
|
})
|
||||||
|
|
||||||
r.Path("/images/{name:.*}/pull").Methods("POST").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
r.Path("/images/{name:.*}/pull").Methods("POST").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -491,10 +457,13 @@ func ListenAndServe(addr string, rtime *Runtime) error {
|
||||||
} else {
|
} else {
|
||||||
defer RestoreTerminal(oldState)
|
defer RestoreTerminal(oldState)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintln(file, "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n")
|
// Flush the options to make sure the client sets the raw mode
|
||||||
|
// or tell the client there is no options
|
||||||
|
conn.Write([]byte{})
|
||||||
|
|
||||||
|
fmt.Fprintln(file, "HTTP/1.1 201 Created\r\nContent-Type: application/json\r\n\r\n")
|
||||||
container, err := rtime.Create(&config)
|
container, err := rtime.Create(&config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If container not found, try to pull it
|
// If container not found, try to pull it
|
||||||
|
@ -576,6 +545,21 @@ func ListenAndServe(addr string, rtime *Runtime) error {
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
|
if container.Config.Tty {
|
||||||
|
oldState, err := SetRawTerminal()
|
||||||
|
if err != nil {
|
||||||
|
if os.Getenv("DEBUG") != "" {
|
||||||
|
log.Printf("Can't set the terminal in raw mode: %s", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
defer RestoreTerminal(oldState)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush the options to make sure the client sets the raw mode
|
||||||
|
conn.Write([]byte{})
|
||||||
|
|
||||||
fmt.Fprintln(file, "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n")
|
fmt.Fprintln(file, "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n")
|
||||||
r, w := io.Pipe()
|
r, w := io.Pipe()
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -607,7 +591,7 @@ func ListenAndServe(addr string, rtime *Runtime) error {
|
||||||
http.Error(w, "No such container: "+name, http.StatusNotFound)
|
http.Error(w, "No such container: "+name, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.WriteHeader(200)
|
w.WriteHeader(http.StatusOK)
|
||||||
})
|
})
|
||||||
|
|
||||||
r.Path("/containers/{name:.*}").Methods("DELETE").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
r.Path("/containers/{name:.*}").Methods("DELETE").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -623,7 +607,7 @@ func ListenAndServe(addr string, rtime *Runtime) error {
|
||||||
http.Error(w, "No such container: "+name, http.StatusNotFound)
|
http.Error(w, "No such container: "+name, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.WriteHeader(200)
|
w.WriteHeader(http.StatusOK)
|
||||||
})
|
})
|
||||||
|
|
||||||
r.Path("/images/{name:.*}").Methods("DELETE").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
r.Path("/images/{name:.*}").Methods("DELETE").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -641,7 +625,7 @@ func ListenAndServe(addr string, rtime *Runtime) error {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.WriteHeader(200)
|
w.WriteHeader(http.StatusOK)
|
||||||
})
|
})
|
||||||
|
|
||||||
r.Path("/containers/{name:.*}/start").Methods("POST").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
r.Path("/containers/{name:.*}/start").Methods("POST").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -657,7 +641,7 @@ func ListenAndServe(addr string, rtime *Runtime) error {
|
||||||
http.Error(w, "No such container: "+name, http.StatusNotFound)
|
http.Error(w, "No such container: "+name, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.WriteHeader(200)
|
w.WriteHeader(http.StatusOK)
|
||||||
})
|
})
|
||||||
|
|
||||||
r.Path("/containers/{name:.*}/stop").Methods("POST").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
r.Path("/containers/{name:.*}/stop").Methods("POST").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -673,7 +657,7 @@ func ListenAndServe(addr string, rtime *Runtime) error {
|
||||||
http.Error(w, "No such container: "+name, http.StatusNotFound)
|
http.Error(w, "No such container: "+name, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.WriteHeader(200)
|
w.WriteHeader(http.StatusOK)
|
||||||
})
|
})
|
||||||
|
|
||||||
r.Path("/containers/{name:.*}/wait").Methods("POST").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
r.Path("/containers/{name:.*}/wait").Methods("POST").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -694,5 +678,39 @@ func ListenAndServe(addr string, rtime *Runtime) error {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
r.Path("/containers/{name:.*}").Methods("GET").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Println(r.Method, r.RequestURI)
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
name := vars["name"]
|
||||||
|
|
||||||
|
if container := rtime.Get(name); container != nil {
|
||||||
|
b, err := json.Marshal(container)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
} else {
|
||||||
|
w.Write(b)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
http.Error(w, "No such container: "+name, http.StatusNotFound)
|
||||||
|
})
|
||||||
|
|
||||||
|
r.Path("/images/{name:.*}").Methods("GET").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Println(r.Method, r.RequestURI)
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
name := vars["name"]
|
||||||
|
|
||||||
|
if image, err := rtime.repositories.LookupImage(name); err == nil && image != nil {
|
||||||
|
b, err := json.Marshal(image)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
} else {
|
||||||
|
w.Write(b)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
http.Error(w, "No such image: "+name, http.StatusNotFound)
|
||||||
|
})
|
||||||
|
|
||||||
return http.ListenAndServe(addr, r)
|
return http.ListenAndServe(addr, r)
|
||||||
}
|
}
|
||||||
|
|
13
commands.go
13
commands.go
|
@ -834,7 +834,18 @@ func CmdAttach(args []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := callStream("POST", "/containers/"+cmd.Arg(0)+"/attach", nil, true); err != nil {
|
body, err := call("GET", "/containers/"+cmd.Arg(0))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var container Container
|
||||||
|
err = json.Unmarshal(body, &container)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := callStream("POST", "/containers/"+cmd.Arg(0)+"/attach", nil, container.Config.Tty); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in New Issue