diff options
Diffstat (limited to 'client')
-rw-r--r-- | client/client.go | 103 |
1 files changed, 103 insertions, 0 deletions
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 +} |