crio.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. package containers
  2. import (
  3. "context"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "net"
  8. "net/http"
  9. "os"
  10. "strings"
  11. "time"
  12. "github.com/coroot/coroot-node-agent/common"
  13. "github.com/coroot/coroot-node-agent/proc"
  14. "github.com/coroot/logparser"
  15. klog "github.com/sirupsen/logrus"
  16. )
  17. const crioTimeout = 30 * time.Second
  18. var (
  19. crioClient *http.Client
  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. sockets := []string{
  34. "/var/run/crio/crio.sock",
  35. "/run/crio/crio.sock",
  36. }
  37. var crioSocket string
  38. var err error
  39. for _, socket := range sockets {
  40. socketHostPath := proc.HostPath(socket)
  41. if _, err := os.Stat(socketHostPath); err == nil {
  42. crioSocket = socketHostPath
  43. break
  44. }
  45. }
  46. if err != nil {
  47. return fmt.Errorf("couldn't connect to CRI-O through the following UNIX sockets: [%s]: %s",
  48. strings.Join(sockets, ","), err,
  49. )
  50. }
  51. klog.Infoln("cri-o socket:", crioSocket)
  52. crioClient = &http.Client{
  53. Transport: &http.Transport{
  54. DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
  55. return net.DialTimeout("unix", crioSocket, crioTimeout)
  56. },
  57. DisableCompression: true,
  58. },
  59. }
  60. return nil
  61. }
  62. func CrioInspect(containerID string) (*ContainerMetadata, error) {
  63. if crioClient == nil {
  64. return nil, fmt.Errorf("cri-o client is not initialized")
  65. }
  66. resp, err := crioClient.Get("http://localhost/containers/" + containerID)
  67. if err != nil {
  68. return nil, err
  69. }
  70. defer resp.Body.Close()
  71. if resp.StatusCode != http.StatusOK {
  72. return nil, errors.New(resp.Status)
  73. }
  74. i := &CrioContainerInfo{}
  75. if err = json.NewDecoder(resp.Body).Decode(i); err != nil {
  76. return nil, err
  77. }
  78. res := &ContainerMetadata{
  79. name: i.Name,
  80. labels: i.Labels,
  81. volumes: map[string]string{},
  82. logPath: i.LogPath,
  83. image: i.Image,
  84. logDecoder: logparser.CriDecoder{},
  85. }
  86. var volumes []CrioVolume
  87. if err := json.Unmarshal([]byte(i.CrioAnnotations["io.kubernetes.cri-o.Volumes"]), &volumes); err != nil {
  88. klog.Warningln(err)
  89. } else {
  90. for _, v := range volumes {
  91. res.volumes[v.ContainerPath] = common.ParseKubernetesVolumeSource(v.HostPath)
  92. }
  93. }
  94. return res, nil
  95. }