package raid import ( "fmt" "log" "os/exec" "strconv" "strings" "git.lxtend.com/qqbot/constants" "git.lxtend.com/qqbot/handler" "git.lxtend.com/qqbot/model" ) func init() { handler.RegisterHandler("!raid", RaidHandler, constants.LEVEL_USER) } func RaidHandler(msg model.Message) (reply *model.Reply) { diskInfoList := GetDiskInfo() if len(diskInfoList) == 0 { return &model.Reply{ FromMsg: msg, ReplyMsg: "未获取到阵列信息", ReferOriginMsg: false, } } sb := strings.Builder{} sb.WriteString("阵列信息:\n") for _, diskInfo := range diskInfoList { sb.WriteString(diskInfo.String()) } return &model.Reply{ FromMsg: msg, ReplyMsg: sb.String(), ReferOriginMsg: false, } } // MegaCli64 -PDList -aALL | grep -E "Slot Number|Drive Temperature|Inquiry Data|Firmware state|S.M.A.R.T alert" | cat // Slot Number: 0 // Firmware state: Online, Spun Up // Inquiry Data: TOSHIBA MG04SCA60EE 010356A0A001FWWB // Drive Temperature :56C (132.80 F) // Drive has flagged a S.M.A.R.T alert : No // Slot Number: 1 // Firmware state: Online, Spun Up // Inquiry Data: TOSHIBA MG04SCA60EE 0103X6S0A0LRFWWB // Drive Temperature :54C (129.20 F) // Drive has flagged a S.M.A.R.T alert : No // Slot Number: 2 // Firmware state: Online, Spun Up // Inquiry Data: TOSHIBA MG04SCA60EE 010356F0A00AFWWB // Drive Temperature :51C (123.80 F) // Drive has flagged a S.M.A.R.T alert : No // Slot Number: 3 // Firmware state: Online, Spun Up // Inquiry Data: TOSHIBA MG04SCA60EE 0103X6Q0A0RZFWWB // Drive Temperature :46C (114.80 F) // Drive has flagged a S.M.A.R.T alert : No // Slot Number: 4 // Firmware state: Unconfigured(bad) // Inquiry Data: TOSHIBA MG04SCA60EE 0103X6R0A09VFWWB // Drive Temperature :49C (120.20 F) // Drive has flagged a S.M.A.R.T alert : No // Slot Number: 5 // Firmware state: Online, Spun Up // Inquiry Data: TOSHIBA MG04SCA60EE 0103X6R0A0JZFWWB // Drive Temperature :53C (127.40 F) // Drive has flagged a S.M.A.R.T alert : No // Slot Number: 6 // Firmware state: Online, Spun Up // Inquiry Data: TOSHIBA MG04SCA60EE 010356F0A004FWWB // Drive Temperature :56C (132.80 F) // Drive has flagged a S.M.A.R.T alert : No // Slot Number: 7 // Firmware state: Online, Spun Up // Inquiry Data: TOSHIBA MG04SCA60EE 01034680A01WFWWB // Drive Temperature :58C (136.40 F) // Drive has flagged a S.M.A.R.T alert : No type DiskInfo struct { SlotNumber int DriveTemperature string Type string Sn string FirmwareState string SmartAlert bool } func (d *DiskInfo) String() string { sb := strings.Builder{} sb.WriteString(fmt.Sprintf("槽位: %d\n", d.SlotNumber)) sb.WriteString(fmt.Sprintf("温度: %s\n", d.DriveTemperature)) sb.WriteString(fmt.Sprintf("型号: %s\n", d.Type)) sb.WriteString(fmt.Sprintf("SN: %s\n", d.Sn)) sb.WriteString(fmt.Sprintf("状态: %s\n", d.FirmwareState)) sb.WriteString(fmt.Sprintf("S.M.A.R.T报警: %t\n", d.SmartAlert)) return sb.String() } func ParseDiskInfoList(lines []string) []*DiskInfo { var diskInfoList []*DiskInfo var currentDisk *DiskInfo for _, line := range lines { line = strings.TrimSpace(line) if strings.HasPrefix(line, "Slot Number:") { // 新的磁盘信息开始 if currentDisk != nil { diskInfoList = append(diskInfoList, currentDisk) } slotStr := strings.TrimSpace(strings.TrimPrefix(line, "Slot Number:")) slotNum, err := strconv.Atoi(slotStr) if err != nil { log.Printf("解析槽位号失败: %v", err) slotNum = -1 } currentDisk = &DiskInfo{ SlotNumber: slotNum, } } else if currentDisk != nil { // 处理当前磁盘的其他信息 if strings.HasPrefix(line, "Firmware state:") { currentDisk.FirmwareState = strings.TrimSpace(strings.TrimPrefix(line, "Firmware state:")) } else if strings.HasPrefix(line, "Inquiry Data:") { inquiryData := strings.TrimSpace(strings.TrimPrefix(line, "Inquiry Data:")) parts := strings.Fields(inquiryData) if len(parts) >= 2 { currentDisk.Type = strings.Join(parts[:len(parts)-1], " ") currentDisk.Sn = parts[len(parts)-1] } } else if strings.HasPrefix(line, "Drive Temperature") { tempParts := strings.Split(line, ":") if len(tempParts) >= 2 { currentDisk.DriveTemperature = strings.TrimSpace(tempParts[1]) } } else if strings.HasPrefix(line, "Drive has flagged a S.M.A.R.T alert") { smartParts := strings.Split(line, ":") if len(smartParts) >= 2 { currentDisk.SmartAlert = strings.TrimSpace(smartParts[1]) != "No" } } } } // 添加最后一个磁盘 if currentDisk != nil { diskInfoList = append(diskInfoList, currentDisk) } return diskInfoList } func GetDiskInfo() []*DiskInfo { // 首先尝试运行MegaCli64命令 cmd := exec.Command("MegaCli64", "-PDList", "-aALL") outputBytes, err := cmd.Output() if err != nil { log.Printf("运行MegaCli64失败: %v", err) // 尝试运行grep命令模拟示例输出 grepCmd := exec.Command("grep", "-E", "Slot Number|Drive Temperature|Inquiry Data|Firmware state|S.M.A.R.T alert") outputBytes, err = grepCmd.Output() if err != nil { log.Printf("获取磁盘信息失败: %v", err) return nil } } output := string(outputBytes) lines := strings.Split(output, "\n") return ParseDiskInfoList(lines) }