diff --git a/api.go b/api.go index 0999ebaa03..819926692b 100644 --- a/api.go +++ b/api.go @@ -216,7 +216,8 @@ func getImagesViz(srv *Server, version float64, w http.ResponseWriter, r *http.R } func getInfo(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - return writeJSON(w, http.StatusOK, srv.DockerInfo()) + srv.Eng.ServeHTTP(w, r) + return nil } func getEvents(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error { diff --git a/api_params.go b/api_params.go index 411cafae2e..fa9eab0c15 100644 --- a/api_params.go +++ b/api_params.go @@ -29,23 +29,6 @@ type ( VirtualSize int64 } - APIInfo struct { - Debug bool - Containers int - Images int - Driver string `json:",omitempty"` - DriverStatus [][2]string `json:",omitempty"` - NFd int `json:",omitempty"` - NGoroutines int `json:",omitempty"` - MemoryLimit bool `json:",omitempty"` - SwapLimit bool `json:",omitempty"` - IPv4Forwarding bool `json:",omitempty"` - LXCVersion string `json:",omitempty"` - NEventsListener int `json:",omitempty"` - KernelVersion string `json:",omitempty"` - IndexServerAddress string `json:",omitempty"` - } - APITop struct { Titles []string Processes [][]string diff --git a/commands.go b/commands.go index 1ec7774243..982d4b3d84 100644 --- a/commands.go +++ b/commands.go @@ -433,42 +433,58 @@ func (cli *DockerCli) CmdInfo(args ...string) error { return err } - var out APIInfo - if err := json.Unmarshal(body, &out); err != nil { + out := engine.NewOutput() + remoteInfo, err := out.AddEnv() + if err != nil { return err } - fmt.Fprintf(cli.out, "Containers: %d\n", out.Containers) - fmt.Fprintf(cli.out, "Images: %d\n", out.Images) - fmt.Fprintf(cli.out, "Driver: %s\n", out.Driver) - for _, pair := range out.DriverStatus { - fmt.Fprintf(cli.out, " %s: %s\n", pair[0], pair[1]) - } - if out.Debug || os.Getenv("DEBUG") != "" { - fmt.Fprintf(cli.out, "Debug mode (server): %v\n", out.Debug) - fmt.Fprintf(cli.out, "Debug mode (client): %v\n", os.Getenv("DEBUG") != "") - fmt.Fprintf(cli.out, "Fds: %d\n", out.NFd) - fmt.Fprintf(cli.out, "Goroutines: %d\n", out.NGoroutines) - fmt.Fprintf(cli.out, "LXC Version: %s\n", out.LXCVersion) - fmt.Fprintf(cli.out, "EventsListeners: %d\n", out.NEventsListener) - fmt.Fprintf(cli.out, "Kernel Version: %s\n", out.KernelVersion) + if _, err := out.Write(body); err != nil { + utils.Errorf("Error reading remote info: %s\n", err) + return err } + out.Close() - if len(out.IndexServerAddress) != 0 { - cli.LoadConfigFile() - u := cli.configFile.Configs[out.IndexServerAddress].Username - if len(u) > 0 { - fmt.Fprintf(cli.out, "Username: %v\n", u) - fmt.Fprintf(cli.out, "Registry: %v\n", out.IndexServerAddress) + fmt.Fprintf(cli.out, "Containers: %d\n", remoteInfo.GetInt("Containers")) + fmt.Fprintf(cli.out, "Images: %d\n", remoteInfo.GetInt("Images")) + fmt.Fprintf(cli.out, "Driver: %s\n", remoteInfo.Get("Driver")) + + //FIXME:Cleanup this mess + DriverStatus := remoteInfo.GetJson("DriverStatus") + if DriverStatus != nil { + if tab, ok := DriverStatus.([]interface{}); ok { + for _, line := range tab { + if pair, ok := line.([]interface{}); ok { + fmt.Fprintf(cli.out, " %s: %s\n", pair[0], pair[1]) + } + } } } - if !out.MemoryLimit { + if remoteInfo.GetBool("Debug") || os.Getenv("DEBUG") != "" { + fmt.Fprintf(cli.out, "Debug mode (server): %v\n", remoteInfo.GetBool("Debug")) + fmt.Fprintf(cli.out, "Debug mode (client): %v\n", os.Getenv("DEBUG") != "") + fmt.Fprintf(cli.out, "Fds: %d\n", remoteInfo.GetInt("NFd")) + fmt.Fprintf(cli.out, "Goroutines: %d\n", remoteInfo.GetInt("NGoroutines")) + fmt.Fprintf(cli.out, "LXC Version: %s\n", remoteInfo.Get("LXCVersion")) + fmt.Fprintf(cli.out, "EventsListeners: %d\n", remoteInfo.GetInt("NEventsListener")) + fmt.Fprintf(cli.out, "Kernel Version: %s\n", remoteInfo.Get("KernelVersion")) + } + + if len(remoteInfo.GetList("IndexServerAddress")) != 0 { + cli.LoadConfigFile() + u := cli.configFile.Configs[remoteInfo.Get("IndexServerAddress")].Username + if len(u) > 0 { + fmt.Fprintf(cli.out, "Username: %v\n", u) + fmt.Fprintf(cli.out, "Registry: %v\n", remoteInfo.GetList("IndexServerAddress")) + } + } + if !remoteInfo.GetBool("MemoryLimit") { fmt.Fprintf(cli.err, "WARNING: No memory limit support\n") } - if !out.SwapLimit { + if !remoteInfo.GetBool("SwapLimit") { fmt.Fprintf(cli.err, "WARNING: No swap limit support\n") } - if !out.IPv4Forwarding { + if !remoteInfo.GetBool("IPv4Forwarding") { fmt.Fprintf(cli.err, "WARNING: IPv4 forwarding is disabled.\n") } return nil diff --git a/integration/api_test.go b/integration/api_test.go index eed17c9084..90a63ba554 100644 --- a/integration/api_test.go +++ b/integration/api_test.go @@ -72,13 +72,17 @@ func TestGetInfo(t *testing.T) { } assertHttpNotError(r, t) - infos := &docker.APIInfo{} - err = json.Unmarshal(r.Body.Bytes(), infos) + out := engine.NewOutput() + i, err := out.AddEnv() if err != nil { t.Fatal(err) } - if infos.Images != len(initialImages) { - t.Errorf("Expected images: %d, %d found", len(initialImages), infos.Images) + if _, err := io.Copy(out, r.Body); err != nil { + t.Fatal(err) + } + out.Close() + if images := i.GetInt("Images"); images != int64(len(initialImages)) { + t.Errorf("Expected images: %d, %d found", len(initialImages), images) } } diff --git a/server.go b/server.go index ee1ca939e3..1a168fe591 100644 --- a/server.go +++ b/server.go @@ -111,6 +111,10 @@ func jobInitApi(job *engine.Job) engine.Status { job.Error(err) return engine.StatusErr } + if err := job.Eng.Register("info", srv.DockerInfo); err != nil { + job.Error(err) + return engine.StatusErr + } return engine.StatusOK } @@ -610,13 +614,13 @@ func (srv *Server) Images(all bool, filter string) ([]APIImages, error) { return outs, nil } -func (srv *Server) DockerInfo() *APIInfo { +func (srv *Server) DockerInfo(job *engine.Job) engine.Status { images, _ := srv.runtime.graph.Map() - var imgcount int + var imgcount int64 if images == nil { imgcount = 0 } else { - imgcount = len(images) + imgcount = int64(len(images)) } lxcVersion := "" if output, err := exec.Command("lxc-version").CombinedOutput(); err == nil { @@ -630,22 +634,26 @@ func (srv *Server) DockerInfo() *APIInfo { kernelVersion = kv.String() } - return &APIInfo{ - Containers: len(srv.runtime.List()), - Images: imgcount, - Driver: srv.runtime.driver.String(), - DriverStatus: srv.runtime.driver.Status(), - MemoryLimit: srv.runtime.capabilities.MemoryLimit, - SwapLimit: srv.runtime.capabilities.SwapLimit, - IPv4Forwarding: !srv.runtime.capabilities.IPv4ForwardingDisabled, - Debug: os.Getenv("DEBUG") != "", - NFd: utils.GetTotalUsedFds(), - NGoroutines: runtime.NumGoroutine(), - LXCVersion: lxcVersion, - NEventsListener: len(srv.events), - KernelVersion: kernelVersion, - IndexServerAddress: auth.IndexServerAddress(), + v := &engine.Env{} + v.SetInt("Containers", int64(len(srv.runtime.List()))) + v.SetInt("Images", imgcount) + v.Set("Driver", srv.runtime.driver.String()) + v.SetJson("DriverStatus", srv.runtime.driver.Status()) + v.SetBool("MemoryLimit", srv.runtime.capabilities.MemoryLimit) + v.SetBool("SwapLimit", srv.runtime.capabilities.SwapLimit) + v.SetBool("IPv4Forwarding", !srv.runtime.capabilities.IPv4ForwardingDisabled) + v.SetBool("Debug", os.Getenv("DEBUG") != "") + v.SetInt("NFd", int64(utils.GetTotalUsedFds())) + v.SetInt("NGoroutines", int64(runtime.NumGoroutine())) + v.Set("LXCVersion", lxcVersion) + v.SetInt("NEventsListener", int64(len(srv.events))) + v.Set("KernelVersion", kernelVersion) + v.Set("IndexServerAddress", auth.IndexServerAddress()) + if _, err := v.WriteTo(job.Stdout); err != nil { + job.Error(err) + return engine.StatusErr } + return engine.StatusOK } func (srv *Server) ImageHistory(name string) ([]APIHistory, error) {