summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/client.go103
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
+}