From a031b83a09a8628435317a03f199cdc18b78262f Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Wed, 1 Nov 2017 11:24:59 -0400 Subject: Initial checkin from CRI-O repo Signed-off-by: Matthew Heon --- client/client.go | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 client/client.go (limited to 'client') diff --git a/client/client.go b/client/client.go new file mode 100644 index 000000000..ad717b970 --- /dev/null +++ b/client/client.go @@ -0,0 +1,103 @@ +package client + +import ( + "encoding/json" + "fmt" + "net" + "net/http" + "syscall" + "time" + + "github.com/kubernetes-incubator/cri-o/types" +) + +const ( + maxUnixSocketPathSize = len(syscall.RawSockaddrUnix{}.Path) +) + +// CrioClient is an interface to get information from crio daemon endpoint. +type CrioClient interface { + DaemonInfo() (types.CrioInfo, error) + ContainerInfo(string) (*types.ContainerInfo, error) +} + +type crioClientImpl struct { + client *http.Client + crioSocketPath string +} + +func configureUnixTransport(tr *http.Transport, proto, addr string) error { + if len(addr) > maxUnixSocketPathSize { + return fmt.Errorf("Unix socket path %q is too long", addr) + } + // No need for compression in local communications. + tr.DisableCompression = true + tr.Dial = func(_, _ string) (net.Conn, error) { + return net.DialTimeout(proto, addr, 32*time.Second) + } + return nil +} + +// New returns a crio client +func New(crioSocketPath string) (CrioClient, error) { + tr := new(http.Transport) + configureUnixTransport(tr, "unix", crioSocketPath) + c := &http.Client{ + Transport: tr, + } + return &crioClientImpl{ + client: c, + crioSocketPath: crioSocketPath, + }, nil +} + +func (c *crioClientImpl) getRequest(path string) (*http.Request, error) { + req, err := http.NewRequest("GET", path, nil) + if err != nil { + return nil, err + } + // For local communications over a unix socket, it doesn't matter what + // the host is. We just need a valid and meaningful host name. + req.Host = "crio" + req.URL.Host = c.crioSocketPath + req.URL.Scheme = "http" + return req, nil +} + +// DaemonInfo return cri-o daemon info from the cri-o +// info endpoint. +func (c *crioClientImpl) DaemonInfo() (types.CrioInfo, error) { + info := types.CrioInfo{} + req, err := c.getRequest("/info") + if err != nil { + return info, err + } + resp, err := c.client.Do(req) + if err != nil { + return info, err + } + defer resp.Body.Close() + if err := json.NewDecoder(resp.Body).Decode(&info); err != nil { + return info, err + } + return info, nil +} + +// ContainerInfo returns container info by querying +// the cri-o container endpoint. +func (c *crioClientImpl) ContainerInfo(id string) (*types.ContainerInfo, error) { + req, err := c.getRequest("/containers/" + id) + if err != nil { + return nil, err + } + resp, err := c.client.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + cInfo := types.ContainerInfo{} + if err := json.NewDecoder(resp.Body).Decode(&cInfo); err != nil { + return nil, err + } + return &cInfo, nil +} -- cgit v1.2.3-54-g00ecf