|
@@ -0,0 +1,151 @@
|
|
|
+package raid
|
|
|
+
|
|
|
+import (
|
|
|
+ "fmt"
|
|
|
+ "os/exec"
|
|
|
+ "strconv"
|
|
|
+ "strings"
|
|
|
+ "time"
|
|
|
+)
|
|
|
+
|
|
|
+// RAIDInfo represents information about a RAID array.
|
|
|
+type RAIDInfo struct {
|
|
|
+ Version string
|
|
|
+ CreationTime time.Time
|
|
|
+ RaidLevel string
|
|
|
+ ArraySize string
|
|
|
+ UsedDevSize string
|
|
|
+ RaidDevices int
|
|
|
+ TotalDevices int
|
|
|
+ Persistence string
|
|
|
+ UpdateTime time.Time
|
|
|
+ State string
|
|
|
+ ActiveDevices int
|
|
|
+ WorkingDevices int
|
|
|
+ FailedDevices int
|
|
|
+ SpareDevices int
|
|
|
+ Consistency string
|
|
|
+ Name string
|
|
|
+ UUID string
|
|
|
+ Events int
|
|
|
+ DeviceInfo []DeviceInfo
|
|
|
+}
|
|
|
+
|
|
|
+// DeviceInfo represents information about a device in a RAID array.
|
|
|
+type DeviceInfo struct {
|
|
|
+ Number int
|
|
|
+ Major int
|
|
|
+ Minor int
|
|
|
+ RaidDevice int
|
|
|
+ State string
|
|
|
+ DevicePath string
|
|
|
+}
|
|
|
+
|
|
|
+// GetRAIDInfo retrieves information about a RAID array using the mdadm command.
|
|
|
+func GetRAIDInfo(arrayName string) (*RAIDInfo, error) {
|
|
|
+ cmd := exec.Command("sudo", "mdadm", "--detail", arrayName)
|
|
|
+
|
|
|
+ output, err := cmd.Output()
|
|
|
+ if err != nil {
|
|
|
+ return nil, fmt.Errorf("error running mdadm command: %v", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ info := parseRAIDInfo(string(output))
|
|
|
+ return info, nil
|
|
|
+}
|
|
|
+
|
|
|
+// parseRAIDInfo parses the output of mdadm --detail command and returns the RAIDInfo struct.
|
|
|
+func parseRAIDInfo(output string) *RAIDInfo {
|
|
|
+ lines := strings.Split(output, "\n")
|
|
|
+
|
|
|
+ raidInfo := &RAIDInfo{}
|
|
|
+ for _, line := range lines {
|
|
|
+ fields := strings.Fields(line)
|
|
|
+ if len(fields) >= 2 {
|
|
|
+ switch fields[0] {
|
|
|
+ case "Version":
|
|
|
+ raidInfo.Version = fields[2]
|
|
|
+ case "Creation":
|
|
|
+ creationTimeStr := strings.Join(fields[4:], " ")
|
|
|
+ creationTime, _ := time.Parse("Mon Jan _2 15:04:05 2006", creationTimeStr)
|
|
|
+ raidInfo.CreationTime = creationTime
|
|
|
+ case "Raid":
|
|
|
+ if fields[1] == "Level" {
|
|
|
+ //Raid Level
|
|
|
+ raidInfo.RaidLevel = fields[3]
|
|
|
+ } else if fields[1] == "Devices" {
|
|
|
+ raidInfo.RaidDevices, _ = strconv.Atoi(fields[3])
|
|
|
+ }
|
|
|
+ case "Array":
|
|
|
+ raidInfo.ArraySize = fields[3]
|
|
|
+ case "Used":
|
|
|
+ raidInfo.UsedDevSize = fields[3]
|
|
|
+ case "Total":
|
|
|
+ raidInfo.TotalDevices, _ = strconv.Atoi(fields[6])
|
|
|
+ case "Persistence":
|
|
|
+ raidInfo.Persistence = strings.Join(fields[3:], " ")
|
|
|
+ case "Update":
|
|
|
+ updateTimeStr := strings.Join(fields[3:], " ")
|
|
|
+ updateTime, _ := time.Parse("Mon Jan _2 15:04:05 2006", updateTimeStr)
|
|
|
+ raidInfo.UpdateTime = updateTime
|
|
|
+ case "State":
|
|
|
+ raidInfo.State = fields[2]
|
|
|
+ case "Active":
|
|
|
+ raidInfo.ActiveDevices, _ = strconv.Atoi(fields[2])
|
|
|
+ raidInfo.WorkingDevices, _ = strconv.Atoi(fields[5])
|
|
|
+ raidInfo.FailedDevices, _ = strconv.Atoi(fields[8])
|
|
|
+ raidInfo.SpareDevices, _ = strconv.Atoi(fields[11])
|
|
|
+ case "Consistency":
|
|
|
+ raidInfo.Consistency = strings.Join(fields[3:], " ")
|
|
|
+ case "Name":
|
|
|
+ raidInfo.Name = fields[2]
|
|
|
+ case "UUID":
|
|
|
+ raidInfo.UUID = fields[2]
|
|
|
+ case "Events":
|
|
|
+ raidInfo.Events, _ = strconv.Atoi(fields[2])
|
|
|
+ default:
|
|
|
+ if len(fields) == 6 && fields[0] != "Number" {
|
|
|
+ deviceInfo := DeviceInfo{}
|
|
|
+ deviceInfo.Number, _ = strconv.Atoi(fields[0])
|
|
|
+ deviceInfo.Major, _ = strconv.Atoi(fields[1])
|
|
|
+ deviceInfo.Minor, _ = strconv.Atoi(fields[2])
|
|
|
+ deviceInfo.RaidDevice, _ = strconv.Atoi(fields[3])
|
|
|
+ deviceInfo.State = fields[4]
|
|
|
+ deviceInfo.DevicePath = fields[5]
|
|
|
+ raidInfo.DeviceInfo = append(raidInfo.DeviceInfo, deviceInfo)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return raidInfo
|
|
|
+}
|
|
|
+
|
|
|
+// PrettyPrintRAIDInfo pretty prints the RAIDInfo struct.
|
|
|
+func (info *RAIDInfo) PrettyPrintRAIDInfo() {
|
|
|
+ fmt.Println("RAID Array Information:")
|
|
|
+ fmt.Printf(" Version: %s\n", info.Version)
|
|
|
+ fmt.Printf(" Creation Time: %s\n", info.CreationTime.Format("Mon Jan _2 15:04:05 2006"))
|
|
|
+ fmt.Printf(" Raid Level: %s\n", info.RaidLevel)
|
|
|
+ fmt.Printf(" Array Size: %s\n", info.ArraySize)
|
|
|
+ fmt.Printf(" Used Dev Size: %s\n", info.UsedDevSize)
|
|
|
+ fmt.Printf(" Raid Devices: %d\n", info.RaidDevices)
|
|
|
+ fmt.Printf(" Total Devices: %d\n", info.TotalDevices)
|
|
|
+ fmt.Printf(" Persistence: %s\n", info.Persistence)
|
|
|
+ fmt.Printf(" Update Time: %s\n", info.UpdateTime.Format("Mon Jan _2 15:04:05 2006"))
|
|
|
+ fmt.Printf(" State: %s\n", info.State)
|
|
|
+ fmt.Printf(" Active Devices: %d\n", info.ActiveDevices)
|
|
|
+ fmt.Printf(" Working Devices: %d\n", info.WorkingDevices)
|
|
|
+ fmt.Printf(" Failed Devices: %d\n", info.FailedDevices)
|
|
|
+ fmt.Printf(" Spare Devices: %d\n", info.SpareDevices)
|
|
|
+ fmt.Printf(" Consistency Policy: %s\n", info.Consistency)
|
|
|
+ fmt.Printf(" Name: %s\n", info.Name)
|
|
|
+ fmt.Printf(" UUID: %s\n", info.UUID)
|
|
|
+ fmt.Printf(" Events: %d\n", info.Events)
|
|
|
+
|
|
|
+ fmt.Println("\nDevice Information:")
|
|
|
+ fmt.Printf("%-10s %-10s %-10s %-12s %-10s %s\n", "Number", "Major", "Minor", "RaidDevice", "State", "DevicePath")
|
|
|
+ for _, device := range info.DeviceInfo {
|
|
|
+ fmt.Printf("%-10d %-10d %-10d %-12d %-10s %s\n", device.Number, device.Major, device.Minor, device.RaidDevice, device.State, device.DevicePath)
|
|
|
+ }
|
|
|
+}
|