Adding Subcontainers to cAdvisor client.

Also refactoring and improvements.
This commit is contained in:
Victor Marmol 2014-10-01 11:51:30 -07:00
parent 6906a8ce90
commit 33ccd0949e
2 changed files with 82 additions and 31 deletions

View File

@ -21,6 +21,7 @@ import (
"fmt"
"io/ioutil"
"net/http"
"path"
"strings"
"github.com/google/cadvisor/info"
@ -32,18 +33,14 @@ type Client struct {
}
// NewClient returns a new client with the specified base URL.
// TODO(cAdvisor): Currently the error result is always nil.
func NewClient(URL string) (*Client, error) {
return &Client{
baseUrl: strings.Join([]string{
URL,
"api/v1.0",
}, "/"),
}, nil
}
func NewClient(url string) (*Client, error) {
if !strings.HasSuffix(url, "/") {
url += "/"
}
func (self *Client) machineInfoUrl() string {
return strings.Join([]string{self.baseUrl, "machine"}, "/")
return &Client{
baseUrl: fmt.Sprintf("%sapi/v1.1/", url),
}, nil
}
// MachineInfo returns the JSON machine information for this client.
@ -59,11 +56,40 @@ func (self *Client) MachineInfo() (minfo *info.MachineInfo, err error) {
return
}
func (self *Client) containerInfoUrl(name string) string {
if name[0] == '/' {
name = name[1:]
// ContainerInfo returns the JSON container information for the specified
// container and request.
func (self *Client) ContainerInfo(name string, query *info.ContainerInfoRequest) (cinfo *info.ContainerInfo, err error) {
u := self.containerInfoUrl(name)
ret := new(info.ContainerInfo)
if err = self.httpGetJsonData(ret, query, u, fmt.Sprintf("container info for %q", name)); err != nil {
return
}
return strings.Join([]string{self.baseUrl, "containers", name}, "/")
cinfo = ret
return
}
// Returns the information about all subcontainers (recursive) of the specified container (including itself).
func (self *Client) SubcontainersInfo(name string, query *info.ContainerInfoRequest) ([]info.ContainerInfo, error) {
var response []info.ContainerInfo
url := self.subcontainersInfoUrl(name)
err := self.httpGetJsonData(&response, query, url, fmt.Sprintf("subcontainers container info for %q", name))
if err != nil {
return []info.ContainerInfo{}, err
}
return response, nil
}
func (self *Client) machineInfoUrl() string {
return self.baseUrl + path.Join("machine")
}
func (self *Client) containerInfoUrl(name string) string {
return self.baseUrl + path.Join("containers", name)
}
func (self *Client) subcontainersInfoUrl(name string) string {
return self.baseUrl + path.Join("subcontainers", name)
}
func (self *Client) httpGetJsonData(data, postData interface{}, url, infoName string) error {
@ -95,16 +121,3 @@ func (self *Client) httpGetJsonData(data, postData interface{}, url, infoName st
}
return nil
}
// ContainerInfo returns the JSON container information for the specified
// container and request.
func (self *Client) ContainerInfo(name string,
query *info.ContainerInfoRequest) (cinfo *info.ContainerInfo, err error) {
u := self.containerInfoUrl(name)
ret := new(info.ContainerInfo)
if err = self.httpGetJsonData(ret, query, u, fmt.Sprintf("container info for %v", name)); err != nil {
return
}
cinfo = ret
return
}

View File

@ -19,6 +19,7 @@ import (
"fmt"
"net/http"
"net/http/httptest"
"path"
"reflect"
"testing"
"time"
@ -56,7 +57,7 @@ func cadvisorTestClient(path string, expectedPostObj, expectedPostObjEmpty, repl
}
encoder := json.NewEncoder(w)
encoder.Encode(replyObj)
} else if r.URL.Path == "/api/v1.0/machine" {
} else if r.URL.Path == "/api/v1.1/machine" {
fmt.Fprint(w, `{"num_cores":8,"memory_capacity":31625871360}`)
} else {
w.WriteHeader(http.StatusNotFound)
@ -78,7 +79,7 @@ func TestGetMachineinfo(t *testing.T) {
NumCores: 8,
MemoryCapacity: 31625871360,
}
client, server, err := cadvisorTestClient("/api/v1.0/machine", nil, nil, minfo, t)
client, server, err := cadvisorTestClient("/api/v1.1/machine", nil, nil, minfo, t)
if err != nil {
t.Fatalf("unable to get a client %v", err)
}
@ -100,7 +101,7 @@ func TestGetContainerInfo(t *testing.T) {
}
containerName := "/some/container"
cinfo := itest.GenerateRandomContainerInfo(containerName, 4, query, 1*time.Second)
client, server, err := cadvisorTestClient(fmt.Sprintf("/api/v1.0/containers%v", containerName), query, &info.ContainerInfoRequest{}, cinfo, t)
client, server, err := cadvisorTestClient(fmt.Sprintf("/api/v1.1/containers%v", containerName), query, &info.ContainerInfoRequest{}, cinfo, t)
if err != nil {
t.Fatalf("unable to get a client %v", err)
}
@ -114,3 +115,40 @@ func TestGetContainerInfo(t *testing.T) {
t.Error("received unexpected ContainerInfo")
}
}
func TestGetSubcontainersInfo(t *testing.T) {
query := &info.ContainerInfoRequest{
NumStats: 3,
}
containerName := "/some/container"
cinfo := itest.GenerateRandomContainerInfo(containerName, 4, query, 1*time.Second)
cinfo1 := itest.GenerateRandomContainerInfo(path.Join(containerName, "sub1"), 4, query, 1*time.Second)
cinfo2 := itest.GenerateRandomContainerInfo(path.Join(containerName, "sub2"), 4, query, 1*time.Second)
response := []info.ContainerInfo{
*cinfo,
*cinfo1,
*cinfo2,
}
client, server, err := cadvisorTestClient(fmt.Sprintf("/api/v1.1/subcontainers%v", containerName), query, &info.ContainerInfoRequest{}, response, t)
if err != nil {
t.Fatalf("unable to get a client %v", err)
}
defer server.Close()
returned, err := client.SubcontainersInfo(containerName, query)
if err != nil {
t.Fatal(err)
}
if len(returned) != 3 {
t.Errorf("unexpected number of results: got %d, expected 3", len(returned))
}
if !returned[0].Eq(cinfo) {
t.Error("received unexpected ContainerInfo")
}
if !returned[1].Eq(cinfo1) {
t.Error("received unexpected ContainerInfo")
}
if !returned[2].Eq(cinfo2) {
t.Error("received unexpected ContainerInfo")
}
}