raiddetails.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package raid
  2. import (
  3. "fmt"
  4. "os/exec"
  5. "strconv"
  6. "strings"
  7. "time"
  8. )
  9. // RAIDInfo represents information about a RAID array.
  10. type RAIDInfo struct {
  11. Version string
  12. CreationTime time.Time
  13. RaidLevel string
  14. ArraySize int
  15. UsedDevSize int
  16. RaidDevices int
  17. TotalDevices int
  18. Persistence string
  19. UpdateTime time.Time
  20. State string
  21. ActiveDevices int
  22. WorkingDevices int
  23. FailedDevices int
  24. SpareDevices int
  25. Consistency string
  26. Name string
  27. UUID string
  28. Events int
  29. DeviceInfo []DeviceInfo
  30. }
  31. // DeviceInfo represents information about a device in a RAID array.
  32. type DeviceInfo struct {
  33. State []string
  34. DevicePath string
  35. }
  36. // GetRAIDInfo retrieves information about a RAID array using the mdadm command.
  37. func GetRAIDInfo(arrayName string) (*RAIDInfo, error) {
  38. cmd := exec.Command("sudo", "mdadm", "--detail", arrayName)
  39. output, err := cmd.Output()
  40. if err != nil {
  41. return nil, fmt.Errorf("error running mdadm command: %v", err)
  42. }
  43. info := parseRAIDInfo(string(output))
  44. return info, nil
  45. }
  46. // parseRAIDInfo parses the output of mdadm --detail command and returns the RAIDInfo struct.
  47. func parseRAIDInfo(output string) *RAIDInfo {
  48. lines := strings.Split(output, "\n")
  49. raidInfo := &RAIDInfo{}
  50. for _, line := range lines {
  51. fields := strings.Fields(line)
  52. if len(fields) >= 2 {
  53. switch fields[0] {
  54. case "Version":
  55. raidInfo.Version = fields[2]
  56. case "Creation":
  57. creationTimeStr := strings.Join(fields[3:], " ")
  58. creationTime, _ := time.Parse("Mon Jan 02 15:04:05 2006", creationTimeStr)
  59. raidInfo.CreationTime = creationTime
  60. case "Raid":
  61. if fields[1] == "Level" {
  62. //Raid Level
  63. raidInfo.RaidLevel = fields[3]
  64. } else if fields[1] == "Devices" {
  65. raidInfo.RaidDevices, _ = strconv.Atoi(fields[3])
  66. }
  67. case "Array":
  68. raidInfo.ArraySize, _ = strconv.Atoi(fields[3])
  69. case "Used":
  70. raidInfo.UsedDevSize, _ = strconv.Atoi(fields[4])
  71. case "Total":
  72. raidInfo.TotalDevices, _ = strconv.Atoi(fields[3])
  73. case "Persistence":
  74. raidInfo.Persistence = strings.Join(fields[3:], " ")
  75. case "Update":
  76. updateTimeStr := strings.Join(fields[3:], " ")
  77. updateTime, _ := time.Parse("Mon Jan 02 15:04:05 2006", updateTimeStr)
  78. raidInfo.UpdateTime = updateTime
  79. case "State":
  80. raidInfo.State = fields[2]
  81. case "Active":
  82. raidInfo.ActiveDevices, _ = strconv.Atoi(fields[3])
  83. case "Working":
  84. raidInfo.WorkingDevices, _ = strconv.Atoi(fields[3])
  85. case "Failed":
  86. raidInfo.FailedDevices, _ = strconv.Atoi(fields[3])
  87. case "Spare":
  88. raidInfo.SpareDevices, _ = strconv.Atoi(fields[3])
  89. case "Consistency":
  90. raidInfo.Consistency = strings.Join(fields[3:], " ")
  91. case "Name":
  92. raidInfo.Name = strings.Join(fields[2:], " ")
  93. case "UUID":
  94. raidInfo.UUID = fields[2]
  95. case "Events":
  96. raidInfo.Events, _ = strconv.Atoi(fields[2])
  97. default:
  98. if len(fields) >= 6 && fields[0] != "Number" {
  99. deviceInfo := DeviceInfo{}
  100. deviceInfo.State = fields[4 : len(fields)-1]
  101. deviceInfo.DevicePath = fields[len(fields)-1]
  102. raidInfo.DeviceInfo = append(raidInfo.DeviceInfo, deviceInfo)
  103. }
  104. }
  105. }
  106. }
  107. return raidInfo
  108. }
  109. // PrettyPrintRAIDInfo pretty prints the RAIDInfo struct.
  110. func (info *RAIDInfo) PrettyPrintRAIDInfo() {
  111. fmt.Println("RAID Array Information:")
  112. fmt.Printf(" Version: %s\n", info.Version)
  113. fmt.Printf(" Creation Time: %s\n", info.CreationTime.Format("Mon Jan 02 15:04:05 2006"))
  114. fmt.Printf(" Raid Level: %s\n", info.RaidLevel)
  115. fmt.Printf(" Array Size: %d\n", info.ArraySize)
  116. fmt.Printf(" Used Dev Size: %d\n", info.UsedDevSize)
  117. fmt.Printf(" Raid Devices: %d\n", info.RaidDevices)
  118. fmt.Printf(" Total Devices: %d\n", info.TotalDevices)
  119. fmt.Printf(" Persistence: %s\n", info.Persistence)
  120. fmt.Printf(" Update Time: %s\n", info.UpdateTime.Format("Mon Jan 02 15:04:05 2006"))
  121. fmt.Printf(" State: %s\n", info.State)
  122. fmt.Printf(" Active Devices: %d\n", info.ActiveDevices)
  123. fmt.Printf(" Working Devices: %d\n", info.WorkingDevices)
  124. fmt.Printf(" Failed Devices: %d\n", info.FailedDevices)
  125. fmt.Printf(" Spare Devices: %d\n", info.SpareDevices)
  126. fmt.Printf(" Consistency Policy: %s\n", info.Consistency)
  127. fmt.Printf(" Name: %s\n", info.Name)
  128. fmt.Printf(" UUID: %s\n", info.UUID)
  129. fmt.Printf(" Events: %d\n", info.Events)
  130. fmt.Println("\nDevice Information:")
  131. fmt.Printf("%s %s\n", "State", "DevicePath")
  132. for _, device := range info.DeviceInfo {
  133. fmt.Printf("%s %s\n", strings.Join(device.State, ","), device.DevicePath)
  134. }
  135. }