From 51e2c1794b50295607c6eddb29edf39d40816a88 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Wed, 11 Dec 2013 10:35:21 -0800 Subject: [PATCH 1/2] move docker info to the job api --- api.go | 3 +- api_params.go | 17 ----------- commands.go | 66 +++++++++++++++++++++++++---------------- integration/api_test.go | 12 +++++--- server.go | 44 ++++++++++++++++----------- 5 files changed, 77 insertions(+), 65 deletions(-) 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) { From 85b9338205da0c8f1d62f277db342cf4b9feaf13 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Thu, 12 Dec 2013 13:35:50 -0800 Subject: [PATCH 2/2] add GetenvInt64 ans SetenvInt64 --- commands.go | 17 ++++++----------- engine/env.go | 14 +++++++++++--- engine/job.go | 12 ++++++++++-- integration/api_test.go | 2 +- server.go | 12 ++++++------ 5 files changed, 34 insertions(+), 23 deletions(-) diff --git a/commands.go b/commands.go index 982d4b3d84..df49b54492 100644 --- a/commands.go +++ b/commands.go @@ -448,17 +448,12 @@ func (cli *DockerCli) CmdInfo(args ...string) error { 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]) - } - } - } + var driverStatus [][2]string + if err := remoteInfo.GetJson("DriverStatus", &driverStatus); err != nil { + return err + } + for _, pair := range driverStatus { + fmt.Fprintf(cli.out, " %s: %s\n", pair[0], pair[1]) } if remoteInfo.GetBool("Debug") || os.Getenv("DEBUG") != "" { fmt.Fprintf(cli.out, "Debug mode (server): %v\n", remoteInfo.GetBool("Debug")) diff --git a/engine/env.go b/engine/env.go index 81c76d5adb..a65c8438d2 100644 --- a/engine/env.go +++ b/engine/env.go @@ -51,7 +51,11 @@ func (env *Env) SetBool(key string, value bool) { } } -func (env *Env) GetInt(key string) int64 { +func (env *Env) GetInt(key string) int { + return int(env.GetInt64(key)) +} + +func (env *Env) GetInt64(key string) int64 { s := strings.Trim(env.Get(key), " \t") val, err := strconv.ParseInt(s, 10, 64) if err != nil { @@ -60,7 +64,11 @@ func (env *Env) GetInt(key string) int64 { return val } -func (env *Env) SetInt(key string, value int64) { +func (env *Env) SetInt(key string, value int) { + env.Set(key, fmt.Sprintf("%d", value)) +} + +func (env *Env) SetInt64(key string, value int64) { env.Set(key, fmt.Sprintf("%d", value)) } @@ -145,7 +153,7 @@ func (env *Env) SetAuto(k string, v interface{}) { // encoding/json decodes integers to float64, but cannot encode them back. // (See http://golang.org/src/pkg/encoding/json/decode.go#L46) if fval, ok := v.(float64); ok { - env.SetInt(k, int64(fval)) + env.SetInt64(k, int64(fval)) } else if sval, ok := v.(string); ok { env.Set(k, sval) } else if val, err := json.Marshal(v); err == nil { diff --git a/engine/job.go b/engine/job.go index e960cffda3..68b1715d92 100644 --- a/engine/job.go +++ b/engine/job.go @@ -113,11 +113,19 @@ func (job *Job) SetenvBool(key string, value bool) { job.env.SetBool(key, value) } -func (job *Job) GetenvInt(key string) int64 { +func (job *Job) GetenvInt64(key string) int64 { + return job.env.GetInt64(key) +} + +func (job *Job) GetenvInt(key string) int { return job.env.GetInt(key) } -func (job *Job) SetenvInt(key string, value int64) { +func (job *Job) SetenvInt64(key string, value int64) { + job.env.SetInt64(key, value) +} + +func (job *Job) SetenvInt(key string, value int) { job.env.SetInt(key, value) } diff --git a/integration/api_test.go b/integration/api_test.go index 90a63ba554..b635dd81c0 100644 --- a/integration/api_test.go +++ b/integration/api_test.go @@ -81,7 +81,7 @@ func TestGetInfo(t *testing.T) { t.Fatal(err) } out.Close() - if images := i.GetInt("Images"); images != int64(len(initialImages)) { + if images := i.GetInt("Images"); images != len(initialImages) { t.Errorf("Expected images: %d, %d found", len(initialImages), images) } } diff --git a/server.go b/server.go index 1a168fe591..a0e6191090 100644 --- a/server.go +++ b/server.go @@ -616,11 +616,11 @@ func (srv *Server) Images(all bool, filter string) ([]APIImages, error) { func (srv *Server) DockerInfo(job *engine.Job) engine.Status { images, _ := srv.runtime.graph.Map() - var imgcount int64 + var imgcount int if images == nil { imgcount = 0 } else { - imgcount = int64(len(images)) + imgcount = len(images) } lxcVersion := "" if output, err := exec.Command("lxc-version").CombinedOutput(); err == nil { @@ -635,7 +635,7 @@ func (srv *Server) DockerInfo(job *engine.Job) engine.Status { } v := &engine.Env{} - v.SetInt("Containers", int64(len(srv.runtime.List()))) + v.SetInt("Containers", len(srv.runtime.List())) v.SetInt("Images", imgcount) v.Set("Driver", srv.runtime.driver.String()) v.SetJson("DriverStatus", srv.runtime.driver.Status()) @@ -643,10 +643,10 @@ func (srv *Server) DockerInfo(job *engine.Job) engine.Status { 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.SetInt("NFd", utils.GetTotalUsedFds()) + v.SetInt("NGoroutines", runtime.NumGoroutine()) v.Set("LXCVersion", lxcVersion) - v.SetInt("NEventsListener", int64(len(srv.events))) + v.SetInt("NEventsListener", len(srv.events)) v.Set("KernelVersion", kernelVersion) v.Set("IndexServerAddress", auth.IndexServerAddress()) if _, err := v.WriteTo(job.Stdout); err != nil {