diff --git a/api/api.go b/api/api.go index 03c581de5f..812a4dcc7d 100644 --- a/api/api.go +++ b/api/api.go @@ -1,24 +1,50 @@ package api import ( + "encoding/json" "fmt" "log" "net/http" + "sort" + "strings" + "github.com/docker/libcluster" "github.com/gorilla/mux" + "github.com/samalba/dockerclient" ) -type HttpApiFunc func(w http.ResponseWriter, r *http.Request) +type HttpApiFunc func(c *libcluster.Cluster, w http.ResponseWriter, r *http.Request) -func ping(w http.ResponseWriter, r *http.Request) { +func getContainersJSON(c *libcluster.Cluster, w http.ResponseWriter, r *http.Request) { + if err := r.ParseForm(); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + all := r.Form.Get("all") == "1" + + out := []dockerclient.Container{} + for _, container := range c.Containers() { + // Skip stopped containers unless -a was specified. + if !strings.Contains(container.Status, "Up") && !all { + continue + } + out = append(out, container.Container) + } + + sort.Sort(sort.Reverse(ContainerSorter(out))) + json.NewEncoder(w).Encode(out) +} + +func ping(c *libcluster.Cluster, w http.ResponseWriter, r *http.Request) { w.Write([]byte{'O', 'K'}) } -func notImplementedHandler(w http.ResponseWriter, r *http.Request) { +func notImplementedHandler(c *libcluster.Cluster, w http.ResponseWriter, r *http.Request) { http.Error(w, "Not supported in clustering mode.", http.StatusNotImplemented) } -func createRouter() (*mux.Router, error) { +func createRouter(c *libcluster.Cluster) (*mux.Router, error) { r := mux.NewRouter() m := map[string]map[string]HttpApiFunc{ "GET": { @@ -33,8 +59,8 @@ func createRouter() (*mux.Router, error) { "/images/{name:.*}/get": notImplementedHandler, "/images/{name:.*}/history": notImplementedHandler, "/images/{name:.*}/json": notImplementedHandler, - "/containers/ps": notImplementedHandler, - "/containers/json": notImplementedHandler, + "/containers/ps": getContainersJSON, + "/containers/json": getContainersJSON, "/containers/{name:.*}/export": notImplementedHandler, "/containers/{name:.*}/changes": notImplementedHandler, "/containers/{name:.*}/json": notImplementedHandler, @@ -82,7 +108,7 @@ func createRouter() (*mux.Router, error) { localFct := fct wrap := func(w http.ResponseWriter, r *http.Request) { fmt.Printf("-> %s %s\n", r.Method, r.RequestURI) - localFct(w, r) + localFct(c, w, r) } localMethod := method @@ -95,8 +121,8 @@ func createRouter() (*mux.Router, error) { return r, nil } -func ListenAndServe(addr string) error { - r, err := createRouter() +func ListenAndServe(c *libcluster.Cluster, addr string) error { + r, err := createRouter(c) if err != nil { return err } diff --git a/api/sorter.go b/api/sorter.go new file mode 100644 index 0000000000..6681a44934 --- /dev/null +++ b/api/sorter.go @@ -0,0 +1,19 @@ +package api + +import ( + "github.com/samalba/dockerclient" +) + +type ContainerSorter []dockerclient.Container + +func (s ContainerSorter) Len() int { + return len(s) +} + +func (s ContainerSorter) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +func (s ContainerSorter) Less(i, j int) bool { + return s[i].Created < s[j].Created +} diff --git a/swarmd/main.go b/swarmd/main.go index 6f802a3434..17ca52e20b 100644 --- a/swarmd/main.go +++ b/swarmd/main.go @@ -24,5 +24,5 @@ func main() { log.Fatal(err) } } - api.ListenAndServe(":4243") + api.ListenAndServe(c, ":4243") }