mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
changed not found errors to 404, added inspect, wait and diff
This commit is contained in:
parent
cf19be44a8
commit
1e357c6969
3 changed files with 135 additions and 58 deletions
94
api.go
94
api.go
|
@ -42,12 +42,46 @@ func ListenAndServe(addr string, rtime *Runtime) error {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
http.Error(w, "No such container: "+name, http.StatusInternalServerError)
|
http.Error(w, "No such container: "+name, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.WriteHeader(200)
|
w.WriteHeader(200)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
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:.*}").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 {
|
||||||
|
@ -211,7 +245,33 @@ func ListenAndServe(addr string, rtime *Runtime) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
http.Error(w, "No such container: "+name, http.StatusInternalServerError)
|
http.Error(w, "No such container: "+name, http.StatusNotFound)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
r.Path("/containers/{name:.*}/changes").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 {
|
||||||
|
changes, err := container.Changes()
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var changesStr []string
|
||||||
|
for _, name := range changes {
|
||||||
|
changesStr = append(changesStr, name.String())
|
||||||
|
}
|
||||||
|
b, err := json.Marshal(changesStr)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
} else {
|
||||||
|
w.Write(b)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
http.Error(w, "No such container: "+name, http.StatusNotFound)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -225,7 +285,7 @@ func ListenAndServe(addr string, rtime *Runtime) error {
|
||||||
name := vars["name"]
|
name := vars["name"]
|
||||||
|
|
||||||
if container := rtime.Get(name); container == nil {
|
if container := rtime.Get(name); container == nil {
|
||||||
http.Error(w, "No such container: "+name, http.StatusInternalServerError)
|
http.Error(w, "No such container: "+name, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
if frontend, exists := container.NetworkSettings.PortMapping[privatePort]; !exists {
|
if frontend, exists := container.NetworkSettings.PortMapping[privatePort]; !exists {
|
||||||
|
@ -423,7 +483,7 @@ func ListenAndServe(addr string, rtime *Runtime) error {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
http.Error(w, "No such container: "+name, http.StatusInternalServerError)
|
http.Error(w, "No such container: "+name, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.WriteHeader(200)
|
w.WriteHeader(200)
|
||||||
|
@ -439,7 +499,7 @@ func ListenAndServe(addr string, rtime *Runtime) error {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
http.Error(w, "No such container: "+name, http.StatusInternalServerError)
|
http.Error(w, "No such container: "+name, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.WriteHeader(200)
|
w.WriteHeader(200)
|
||||||
|
@ -452,7 +512,7 @@ func ListenAndServe(addr string, rtime *Runtime) error {
|
||||||
|
|
||||||
img, err := rtime.repositories.LookupImage(name)
|
img, err := rtime.repositories.LookupImage(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "No such image: "+name, http.StatusInternalServerError)
|
http.Error(w, "No such image: "+name, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
if err := rtime.graph.Delete(img.Id); err != nil {
|
if err := rtime.graph.Delete(img.Id); err != nil {
|
||||||
|
@ -473,7 +533,7 @@ func ListenAndServe(addr string, rtime *Runtime) error {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
http.Error(w, "No such container: "+name, http.StatusInternalServerError)
|
http.Error(w, "No such container: "+name, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.WriteHeader(200)
|
w.WriteHeader(200)
|
||||||
|
@ -489,11 +549,29 @@ func ListenAndServe(addr string, rtime *Runtime) error {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
http.Error(w, "No such container: "+name, http.StatusInternalServerError)
|
http.Error(w, "No such container: "+name, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.WriteHeader(200)
|
w.WriteHeader(200)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
r.Path("/containers/{name:.*}/wait").Methods("POST").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(ApiWait{container.Wait()})
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
} else {
|
||||||
|
w.Write(b)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
http.Error(w, "No such container: "+name, http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
return http.ListenAndServe(addr, r)
|
return http.ListenAndServe(addr, r)
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,3 +44,7 @@ type ApiVersion struct {
|
||||||
GitCommit string
|
GitCommit string
|
||||||
MemoryLimitDisabled bool
|
MemoryLimitDisabled bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ApiWait struct {
|
||||||
|
StatusCode int
|
||||||
|
}
|
||||||
|
|
95
commands.go
95
commands.go
|
@ -26,8 +26,10 @@ var (
|
||||||
func ParseCommands(args []string) error {
|
func ParseCommands(args []string) error {
|
||||||
|
|
||||||
cmds := map[string]func(args []string) error{
|
cmds := map[string]func(args []string) error{
|
||||||
|
"diff": CmdDiff,
|
||||||
"images": CmdImages,
|
"images": CmdImages,
|
||||||
"info": CmdInfo,
|
"info": CmdInfo,
|
||||||
|
"inspect": CmdInspect,
|
||||||
"history": CmdHistory,
|
"history": CmdHistory,
|
||||||
"kill": CmdKill,
|
"kill": CmdKill,
|
||||||
"logs": CmdLogs,
|
"logs": CmdLogs,
|
||||||
|
@ -42,6 +44,7 @@ func ParseCommands(args []string) error {
|
||||||
"start": CmdStart,
|
"start": CmdStart,
|
||||||
"stop": CmdStop,
|
"stop": CmdStop,
|
||||||
"version": CmdVersion,
|
"version": CmdVersion,
|
||||||
|
"wait": CmdWait,
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
|
@ -60,13 +63,13 @@ func cmdHelp(args []string) error {
|
||||||
for _, cmd := range [][]string{
|
for _, cmd := range [][]string{
|
||||||
// {"attach", "Attach to a running container"},
|
// {"attach", "Attach to a running container"},
|
||||||
// {"commit", "Create a new image from a container's changes"},
|
// {"commit", "Create a new image from a container's changes"},
|
||||||
// {"diff", "Inspect changes on a container's filesystem"},
|
{"diff", "Inspect changes on a container's filesystem"},
|
||||||
// {"export", "Stream the contents of a container as a tar archive"},
|
// {"export", "Stream the contents of a container as a tar archive"},
|
||||||
{"history", "Show the history of an image"},
|
{"history", "Show the history of an image"},
|
||||||
{"images", "List images"},
|
{"images", "List images"},
|
||||||
// {"import", "Create a new filesystem image from the contents of a tarball"},
|
// {"import", "Create a new filesystem image from the contents of a tarball"},
|
||||||
{"info", "Display system-wide information"},
|
{"info", "Display system-wide information"},
|
||||||
// {"inspect", "Return low-level information on a container"},
|
{"inspect", "Return low-level information on a container/image"},
|
||||||
{"kill", "Kill a running container"},
|
{"kill", "Kill a running container"},
|
||||||
// {"login", "Register or Login to the docker registry server"},
|
// {"login", "Register or Login to the docker registry server"},
|
||||||
{"logs", "Fetch the logs of a container"},
|
{"logs", "Fetch the logs of a container"},
|
||||||
|
@ -82,7 +85,7 @@ func cmdHelp(args []string) error {
|
||||||
{"stop", "Stop a running container"},
|
{"stop", "Stop a running container"},
|
||||||
{"tag", "Tag an image into a repository"},
|
{"tag", "Tag an image into a repository"},
|
||||||
{"version", "Show the docker version information"},
|
{"version", "Show the docker version information"},
|
||||||
// {"wait", "Block until a container stops, then print its exit code"},
|
{"wait", "Block until a container stops, then print its exit code"},
|
||||||
} {
|
} {
|
||||||
help += fmt.Sprintf(" %-10.10s%s\n", cmd[0], cmd[1])
|
help += fmt.Sprintf(" %-10.10s%s\n", cmd[0], cmd[1])
|
||||||
}
|
}
|
||||||
|
@ -190,10 +193,9 @@ func (srv *Server) CmdLogin(stdin io.ReadCloser, stdout rcli.DockerConn, args ..
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
// 'docker wait': block until a container stops
|
// 'docker wait': block until a container stops
|
||||||
func (srv *Server) CmdWait(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
|
func CmdWait(args []string) error {
|
||||||
cmd := rcli.Subcmd(stdout, "wait", "CONTAINER [CONTAINER...]", "Block until a container stops, then print its exit code.")
|
cmd := Subcmd("wait", "CONTAINER [CONTAINER...]", "Block until a container stops, then print its exit code.")
|
||||||
if err := cmd.Parse(args); err != nil {
|
if err := cmd.Parse(args); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -202,15 +204,20 @@ func (srv *Server) CmdWait(stdin io.ReadCloser, stdout io.Writer, args ...string
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
for _, name := range cmd.Args() {
|
for _, name := range cmd.Args() {
|
||||||
if container := srv.runtime.Get(name); container != nil {
|
body, err := call("POST", "/containers/"+name+"/wait")
|
||||||
fmt.Fprintln(stdout, container.Wait())
|
if err != nil {
|
||||||
|
fmt.Printf("%s", err)
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("No such container: %s", name)
|
var out ApiWait
|
||||||
|
err = json.Unmarshal(body, &out)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println(out.StatusCode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
// 'docker version': show version information
|
// 'docker version': show version information
|
||||||
func CmdVersion(args []string) error {
|
func CmdVersion(args []string) error {
|
||||||
|
@ -334,42 +341,31 @@ func CmdStart(args []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
func CmdInspect(args []string) error {
|
||||||
func (srv *Server) CmdInspect(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
|
cmd := Subcmd("inspect", "CONTAINER|IMAGE", "Return low-level information on a container/image")
|
||||||
cmd := rcli.Subcmd(stdout, "inspect", "CONTAINER", "Return low-level information on a container")
|
|
||||||
if err := cmd.Parse(args); err != nil {
|
if err := cmd.Parse(args); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if cmd.NArg() < 1 {
|
if cmd.NArg() != 1 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
name := cmd.Arg(0)
|
|
||||||
var obj interface{}
|
var obj interface{}
|
||||||
if container := srv.runtime.Get(name); container != nil {
|
var err error
|
||||||
obj = container
|
obj, err = call("GET", "/containers/"+cmd.Arg(0))
|
||||||
} else if image, err := srv.runtime.repositories.LookupImage(name); err == nil && image != nil {
|
if err != nil {
|
||||||
obj = image
|
obj, err = call("GET", "/images/"+cmd.Arg(0))
|
||||||
} else {
|
if err != nil {
|
||||||
// No output means the object does not exist
|
return err
|
||||||
// (easier to script since stdout and stderr are not differentiated atm)
|
}
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
data, err := json.Marshal(obj)
|
b, err := json.MarshalIndent(obj, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
indented := new(bytes.Buffer)
|
fmt.Printf("%s\n", b)
|
||||||
if err = json.Indent(indented, data, "", " "); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err := io.Copy(stdout, indented); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
stdout.Write([]byte{'\n'})
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
func CmdPort(args []string) error {
|
func CmdPort(args []string) error {
|
||||||
cmd := Subcmd("port", "CONTAINER PRIVATE_PORT", "Lookup the public-facing port which is NAT-ed to PRIVATE_PORT")
|
cmd := Subcmd("port", "CONTAINER PRIVATE_PORT", "Lookup the public-facing port which is NAT-ed to PRIVATE_PORT")
|
||||||
|
@ -778,32 +774,31 @@ func (srv *Server) CmdExport(stdin io.ReadCloser, stdout io.Writer, args ...stri
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
func CmdDiff(args []string) error {
|
||||||
func (srv *Server) CmdDiff(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
|
cmd := Subcmd("diff", "CONTAINER", "Inspect changes on a container's filesystem")
|
||||||
cmd := rcli.Subcmd(stdout,
|
|
||||||
"diff", "CONTAINER",
|
|
||||||
"Inspect changes on a container's filesystem")
|
|
||||||
if err := cmd.Parse(args); err != nil {
|
if err := cmd.Parse(args); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if cmd.NArg() < 1 {
|
if cmd.NArg() != 1 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if container := srv.runtime.Get(cmd.Arg(0)); container == nil {
|
|
||||||
return fmt.Errorf("No such container")
|
body, err := call("GET", "/containers/"+cmd.Arg(0)+"/changes")
|
||||||
} else {
|
if err != nil {
|
||||||
changes, err := container.Changes()
|
return err
|
||||||
if err != nil {
|
}
|
||||||
return err
|
|
||||||
}
|
var changes []string
|
||||||
for _, change := range changes {
|
err = json.Unmarshal(body, &changes)
|
||||||
fmt.Fprintln(stdout, change.String())
|
if err != nil {
|
||||||
}
|
return err
|
||||||
|
}
|
||||||
|
for _, change := range changes {
|
||||||
|
fmt.Println(change)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
func CmdLogs(args []string) error {
|
func CmdLogs(args []string) error {
|
||||||
cmd := Subcmd("logs", "CONTAINER", "Fetch the logs of a container")
|
cmd := Subcmd("logs", "CONTAINER", "Fetch the logs of a container")
|
||||||
|
|
Loading…
Add table
Reference in a new issue