2017-08-30 01:12:10 +00:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2017-09-12 10:17:44 +00:00
|
|
|
"errors"
|
2017-08-30 01:12:10 +00:00
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
|
|
|
|
"github.com/go-zoo/bone"
|
2017-09-12 10:17:44 +00:00
|
|
|
"github.com/kubernetes-incubator/cri-o/libkpod/sandbox"
|
|
|
|
"github.com/kubernetes-incubator/cri-o/oci"
|
|
|
|
"github.com/sirupsen/logrus"
|
2017-08-30 01:12:10 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// ContainerInfo stores information about containers
|
|
|
|
type ContainerInfo struct {
|
2017-09-04 16:11:32 +00:00
|
|
|
Name string `json:"name"`
|
2017-08-30 01:12:10 +00:00
|
|
|
Pid int `json:"pid"`
|
|
|
|
Image string `json:"image"`
|
|
|
|
CreatedTime int64 `json:"created_time"`
|
|
|
|
Labels map[string]string `json:"labels"`
|
|
|
|
Annotations map[string]string `json:"annotations"`
|
2017-08-31 13:16:25 +00:00
|
|
|
LogPath string `json:"log_path"`
|
|
|
|
Root string `json:"root"`
|
2017-09-01 18:50:18 +00:00
|
|
|
Sandbox string `json:"sandbox"`
|
2017-09-04 16:11:32 +00:00
|
|
|
IP string `json:"ip_address"`
|
2017-08-30 01:12:10 +00:00
|
|
|
}
|
|
|
|
|
2017-08-30 23:25:48 +00:00
|
|
|
// CrioInfo stores information about the crio daemon
|
|
|
|
type CrioInfo struct {
|
|
|
|
StorageDriver string `json:"storage_driver"`
|
|
|
|
StorageRoot string `json:"storage_root"`
|
2017-09-05 22:24:39 +00:00
|
|
|
CgroupDriver string `json:"cgroup_driver"`
|
2017-08-30 23:25:48 +00:00
|
|
|
}
|
|
|
|
|
2017-09-12 10:17:44 +00:00
|
|
|
func (s *Server) getInfo() CrioInfo {
|
|
|
|
return CrioInfo{
|
|
|
|
StorageDriver: s.config.Config.Storage,
|
|
|
|
StorageRoot: s.config.Config.Root,
|
|
|
|
CgroupDriver: s.config.Config.CgroupManager,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
errCtrNotFound = errors.New("container not found")
|
|
|
|
errCtrStateNil = errors.New("container state is nil")
|
|
|
|
errSandboxNotFound = errors.New("sandbox for container not found")
|
|
|
|
)
|
|
|
|
|
|
|
|
func (s *Server) getContainerInfo(id string, getContainerFunc func(id string) *oci.Container, getInfraContainerFunc func(id string) *oci.Container, getSandboxFunc func(id string) *sandbox.Sandbox) (ContainerInfo, error) {
|
|
|
|
ctr := getContainerFunc(id)
|
|
|
|
if ctr == nil {
|
|
|
|
ctr = getInfraContainerFunc(id)
|
|
|
|
if ctr == nil {
|
|
|
|
return ContainerInfo{}, errCtrNotFound
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// TODO(mrunalp): should we call UpdateStatus()?
|
|
|
|
ctrState := ctr.State()
|
|
|
|
if ctrState == nil {
|
|
|
|
return ContainerInfo{}, errCtrStateNil
|
|
|
|
}
|
|
|
|
sb := getSandboxFunc(ctr.Sandbox())
|
|
|
|
if sb == nil {
|
|
|
|
logrus.Debugf("can't find sandbox %s for container %s", ctr.Sandbox(), id)
|
|
|
|
return ContainerInfo{}, errSandboxNotFound
|
|
|
|
}
|
|
|
|
return ContainerInfo{
|
|
|
|
Name: ctr.Name(),
|
|
|
|
Pid: ctrState.Pid,
|
|
|
|
Image: ctr.Image(),
|
|
|
|
CreatedTime: ctrState.Created.UnixNano(),
|
|
|
|
Labels: ctr.Labels(),
|
|
|
|
Annotations: ctr.Annotations(),
|
|
|
|
Root: ctr.MountPoint(),
|
|
|
|
LogPath: ctr.LogPath(),
|
|
|
|
Sandbox: ctr.Sandbox(),
|
|
|
|
IP: sb.IP(),
|
|
|
|
}, nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-09-01 10:37:10 +00:00
|
|
|
// GetInfoMux returns the mux used to serve info requests
|
|
|
|
func (s *Server) GetInfoMux() *bone.Mux {
|
2017-08-30 01:12:10 +00:00
|
|
|
mux := bone.New()
|
|
|
|
|
2017-08-30 23:25:48 +00:00
|
|
|
mux.Get("/info", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
2017-09-12 10:17:44 +00:00
|
|
|
ci := s.getInfo()
|
2017-08-30 23:25:48 +00:00
|
|
|
js, err := json.Marshal(ci)
|
|
|
|
if err != nil {
|
|
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
|
|
w.Write(js)
|
|
|
|
}))
|
|
|
|
|
2017-08-30 01:12:10 +00:00
|
|
|
mux.Get("/containers/:id", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
|
|
|
containerID := bone.GetValue(req, "id")
|
2017-09-12 10:17:44 +00:00
|
|
|
ci, err := s.getContainerInfo(containerID, s.GetContainer, s.getInfraContainer, s.getSandbox)
|
|
|
|
if err != nil {
|
|
|
|
switch err {
|
|
|
|
case errCtrNotFound:
|
|
|
|
http.Error(w, fmt.Sprintf("can't find the container with id %s", containerID), http.StatusNotFound)
|
|
|
|
case errCtrStateNil:
|
|
|
|
http.Error(w, fmt.Sprintf("can't find container state for container with id %s", containerID), http.StatusInternalServerError)
|
|
|
|
case errSandboxNotFound:
|
|
|
|
http.Error(w, fmt.Sprintf("can't find the sandbox for container id %s", containerID), http.StatusNotFound)
|
|
|
|
default:
|
|
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
2017-09-01 15:50:17 +00:00
|
|
|
}
|
2017-09-04 16:11:32 +00:00
|
|
|
return
|
|
|
|
}
|
2017-08-30 01:12:10 +00:00
|
|
|
js, err := json.Marshal(ci)
|
|
|
|
if err != nil {
|
|
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
|
|
w.Write(js)
|
|
|
|
}))
|
|
|
|
|
2017-09-01 10:37:10 +00:00
|
|
|
return mux
|
2017-08-30 01:12:10 +00:00
|
|
|
}
|