feat: 添加新的 raid 处理程序以获取和显示磁盘阵列信息
This commit is contained in:
parent
98c9073f0d
commit
95ccd1f8f3
181
handler/raid/raid.go
Normal file
181
handler/raid/raid.go
Normal file
@ -0,0 +1,181 @@
|
||||
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)
|
||||
}
|
@ -16,6 +16,7 @@ import (
|
||||
_ "git.lxtend.com/qqbot/handler/kfccrazy"
|
||||
_ "git.lxtend.com/qqbot/handler/kw"
|
||||
_ "git.lxtend.com/qqbot/handler/newbond"
|
||||
_ "git.lxtend.com/qqbot/handler/raid"
|
||||
_ "git.lxtend.com/qqbot/handler/restart"
|
||||
_ "git.lxtend.com/qqbot/handler/roll"
|
||||
_ "git.lxtend.com/qqbot/handler/scoresaber"
|
||||
|
Loading…
x
Reference in New Issue
Block a user