crio.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package containers
  2. import (
  3. "context"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "net"
  8. "net/http"
  9. "os"
  10. "time"
  11. "github.com/coroot/coroot-node-agent/common"
  12. "github.com/coroot/coroot-node-agent/proc"
  13. "github.com/coroot/logparser"
  14. klog "github.com/sirupsen/logrus"
  15. )
  16. const crioTimeout = 30 * time.Second
  17. var (
  18. crioClient *http.Client
  19. crioSocket = proc.HostPath("/var/run/crio/crio.sock")
  20. )
  21. type CrioContainerInfo struct {
  22. Name string `json:"name"`
  23. Image string `json:"image"`
  24. Labels map[string]string `json:"labels"`
  25. LogPath string `json:"log_path"`
  26. CrioAnnotations map[string]string `json:"crio_annotations"`
  27. }
  28. type CrioVolume struct {
  29. ContainerPath string `json:"container_path"`
  30. HostPath string `json:"host_path"`
  31. }
  32. func CrioInit() error {
  33. if _, err := os.Stat(crioSocket); err != nil {
  34. return err
  35. }
  36. klog.Infoln("cri-o socket:", crioSocket)
  37. crioClient = &http.Client{
  38. Transport: &http.Transport{
  39. DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
  40. return net.DialTimeout("unix", crioSocket, crioTimeout)
  41. },
  42. DisableCompression: true,
  43. },
  44. }
  45. return nil
  46. }
  47. func CrioInspect(containerID string) (*ContainerMetadata, error) {
  48. if crioClient == nil {
  49. return nil, fmt.Errorf("cri-o client is not initialized")
  50. }
  51. resp, err := crioClient.Get("http://localhost/containers/" + containerID)
  52. if err != nil {
  53. return nil, err
  54. }
  55. defer resp.Body.Close()
  56. if resp.StatusCode != http.StatusOK {
  57. return nil, errors.New(resp.Status)
  58. }
  59. i := &CrioContainerInfo{}
  60. if err = json.NewDecoder(resp.Body).Decode(i); err != nil {
  61. return nil, err
  62. }
  63. res := &ContainerMetadata{
  64. name: i.Name,
  65. labels: i.Labels,
  66. volumes: map[string]string{},
  67. logPath: i.LogPath,
  68. image: i.Image,
  69. logDecoder: logparser.CriDecoder{},
  70. }
  71. var volumes []CrioVolume
  72. if err := json.Unmarshal([]byte(i.CrioAnnotations["io.kubernetes.cri-o.Volumes"]), &volumes); err != nil {
  73. klog.Warningln(err)
  74. } else {
  75. for _, v := range volumes {
  76. res.volumes[v.ContainerPath] = common.ParseKubernetesVolumeSource(v.HostPath)
  77. }
  78. }
  79. return res, nil
  80. }