changed not found errors to 404, added inspect, wait and diff

This commit is contained in:
Victor Vieux 2013-04-24 14:01:40 +02:00
parent cf19be44a8
commit 1e357c6969
3 changed files with 135 additions and 58 deletions

94
api.go
View File

@ -42,12 +42,46 @@ func ListenAndServe(addr string, rtime *Runtime) error {
return
}
} else {
http.Error(w, "No such container: "+name, http.StatusInternalServerError)
http.Error(w, "No such container: "+name, http.StatusNotFound)
return
}
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) {
log.Println(r.Method, r.RequestURI)
if err := r.ParseForm(); err != nil {
@ -211,7 +245,33 @@ func ListenAndServe(addr string, rtime *Runtime) error {
}
} 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"]
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
} else {
if frontend, exists := container.NetworkSettings.PortMapping[privatePort]; !exists {
@ -423,7 +483,7 @@ func ListenAndServe(addr string, rtime *Runtime) error {
return
}
} else {
http.Error(w, "No such container: "+name, http.StatusInternalServerError)
http.Error(w, "No such container: "+name, http.StatusNotFound)
return
}
w.WriteHeader(200)
@ -439,7 +499,7 @@ func ListenAndServe(addr string, rtime *Runtime) error {
return
}
} else {
http.Error(w, "No such container: "+name, http.StatusInternalServerError)
http.Error(w, "No such container: "+name, http.StatusNotFound)
return
}
w.WriteHeader(200)
@ -452,7 +512,7 @@ func ListenAndServe(addr string, rtime *Runtime) error {
img, err := rtime.repositories.LookupImage(name)
if err != nil {
http.Error(w, "No such image: "+name, http.StatusInternalServerError)
http.Error(w, "No such image: "+name, http.StatusNotFound)
return
} else {
if err := rtime.graph.Delete(img.Id); err != nil {
@ -473,7 +533,7 @@ func ListenAndServe(addr string, rtime *Runtime) error {
return
}
} else {
http.Error(w, "No such container: "+name, http.StatusInternalServerError)
http.Error(w, "No such container: "+name, http.StatusNotFound)
return
}
w.WriteHeader(200)
@ -489,11 +549,29 @@ func ListenAndServe(addr string, rtime *Runtime) error {
return
}
} else {
http.Error(w, "No such container: "+name, http.StatusInternalServerError)
http.Error(w, "No such container: "+name, http.StatusNotFound)
return
}
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)
}

View File

@ -44,3 +44,7 @@ type ApiVersion struct {
GitCommit string
MemoryLimitDisabled bool
}
type ApiWait struct {
StatusCode int
}

View File

@ -26,8 +26,10 @@ var (
func ParseCommands(args []string) error {
cmds := map[string]func(args []string) error{
"diff": CmdDiff,
"images": CmdImages,
"info": CmdInfo,
"inspect": CmdInspect,
"history": CmdHistory,
"kill": CmdKill,
"logs": CmdLogs,
@ -42,6 +44,7 @@ func ParseCommands(args []string) error {
"start": CmdStart,
"stop": CmdStop,
"version": CmdVersion,
"wait": CmdWait,
}
if len(args) > 0 {
@ -60,13 +63,13 @@ func cmdHelp(args []string) error {
for _, cmd := range [][]string{
// {"attach", "Attach to a running container"},
// {"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"},
{"history", "Show the history of an image"},
{"images", "List images"},
// {"import", "Create a new filesystem image from the contents of a tarball"},
{"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"},
// {"login", "Register or Login to the docker registry server"},
{"logs", "Fetch the logs of a container"},
@ -82,7 +85,7 @@ func cmdHelp(args []string) error {
{"stop", "Stop a running container"},
{"tag", "Tag an image into a repository"},
{"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])
}
@ -190,10 +193,9 @@ func (srv *Server) CmdLogin(stdin io.ReadCloser, stdout rcli.DockerConn, args ..
}
*/
/*
// 'docker wait': block until a container stops
func (srv *Server) CmdWait(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout, "wait", "CONTAINER [CONTAINER...]", "Block until a container stops, then print its exit code.")
func CmdWait(args []string) error {
cmd := Subcmd("wait", "CONTAINER [CONTAINER...]", "Block until a container stops, then print its exit code.")
if err := cmd.Parse(args); err != nil {
return nil
}
@ -202,15 +204,20 @@ func (srv *Server) CmdWait(stdin io.ReadCloser, stdout io.Writer, args ...string
return nil
}
for _, name := range cmd.Args() {
if container := srv.runtime.Get(name); container != nil {
fmt.Fprintln(stdout, container.Wait())
body, err := call("POST", "/containers/"+name+"/wait")
if err != nil {
fmt.Printf("%s", err)
} 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
}
*/
// 'docker version': show version information
func CmdVersion(args []string) error {
@ -334,42 +341,31 @@ func CmdStart(args []string) error {
return nil
}
/*
func (srv *Server) CmdInspect(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout, "inspect", "CONTAINER", "Return low-level information on a container")
func CmdInspect(args []string) error {
cmd := Subcmd("inspect", "CONTAINER|IMAGE", "Return low-level information on a container/image")
if err := cmd.Parse(args); err != nil {
return nil
}
if cmd.NArg() < 1 {
if cmd.NArg() != 1 {
cmd.Usage()
return nil
}
name := cmd.Arg(0)
var obj interface{}
if container := srv.runtime.Get(name); container != nil {
obj = container
} else if image, err := srv.runtime.repositories.LookupImage(name); err == nil && image != nil {
obj = image
} else {
// No output means the object does not exist
// (easier to script since stdout and stderr are not differentiated atm)
return nil
var err error
obj, err = call("GET", "/containers/"+cmd.Arg(0))
if err != nil {
obj, err = call("GET", "/images/"+cmd.Arg(0))
if err != nil {
return err
}
}
data, err := json.Marshal(obj)
b, err := json.MarshalIndent(obj, "", " ")
if err != nil {
return err
}
indented := new(bytes.Buffer)
if err = json.Indent(indented, data, "", " "); err != nil {
return err
}
if _, err := io.Copy(stdout, indented); err != nil {
return err
}
stdout.Write([]byte{'\n'})
fmt.Printf("%s\n", b)
return nil
}
*/
func CmdPort(args []string) error {
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 (srv *Server) CmdDiff(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout,
"diff", "CONTAINER",
"Inspect changes on a container's filesystem")
func CmdDiff(args []string) error {
cmd := Subcmd("diff", "CONTAINER", "Inspect changes on a container's filesystem")
if err := cmd.Parse(args); err != nil {
return nil
}
if cmd.NArg() < 1 {
if cmd.NArg() != 1 {
cmd.Usage()
return nil
}
if container := srv.runtime.Get(cmd.Arg(0)); container == nil {
return fmt.Errorf("No such container")
} else {
changes, err := container.Changes()
if err != nil {
return err
}
for _, change := range changes {
fmt.Fprintln(stdout, change.String())
}
body, err := call("GET", "/containers/"+cmd.Arg(0)+"/changes")
if err != nil {
return err
}
var changes []string
err = json.Unmarshal(body, &changes)
if err != nil {
return err
}
for _, change := range changes {
fmt.Println(change)
}
return nil
}
*/
func CmdLogs(args []string) error {
cmd := Subcmd("logs", "CONTAINER", "Fetch the logs of a container")