drive-health/lib/hardware/logic.go

93 lines
2.1 KiB
Go

package hardware
import (
"bufio"
"bytes"
"fmt"
"os/exec"
"strings"
"time"
"gorm.io/gorm"
)
func GetSystemHardDrives(db *gorm.DB, olderThan *time.Time, newerThan *time.Time) ([]*HardDrive, error) {
// Execute the lsblk command to get detailed block device information
cmd := exec.Command("lsblk", "-d", "-o", "NAME,TRAN,SIZE,MODEL,SERIAL,TYPE")
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
fmt.Println("Failed to execute command:", err)
return nil, err
}
var systemHardDrives []*HardDrive
// Scan the output line by line
scanner := bufio.NewScanner(&out)
for scanner.Scan() {
line := scanner.Text()
// Skip the header line
if strings.Contains(line, "NAME") {
continue
}
// Split the line into columns
cols := strings.Fields(line)
if len(cols) < 6 {
continue
}
// Filter out nvme drives (M.2)
if cols[1] != "usb" {
hd := &HardDrive{
Name: cols[0],
Transport: cols[1],
Size: cols[2],
Model: cols[3],
Serial: cols[4],
Type: cols[5],
}
systemHardDrives = append(systemHardDrives, hd)
}
}
// Handle error
if err := scanner.Err(); err != nil {
return nil, err
}
var updatedHardDrives []*HardDrive
for _, sysHDD := range systemHardDrives {
var existingHD HardDrive
q := db.Where("serial = ? AND model = ? AND type = ?", sysHDD.Serial, sysHDD.Model, sysHDD.Type)
if newerThan != nil && olderThan != nil {
q = q.Preload("Temperatures", "time_stamp < ? AND time_stamp > ?", newerThan, olderThan)
}
result := q.First(&existingHD)
if result.Error == gorm.ErrRecordNotFound {
// Hard drive not found, create new
db.Create(&sysHDD)
updatedHardDrives = append(updatedHardDrives, sysHDD)
} else {
// Hard drive found, update existing
existingHD.Name = sysHDD.Name
existingHD.Transport = sysHDD.Transport
existingHD.Size = sysHDD.Size
existingHD.Model = sysHDD.Model
existingHD.Type = sysHDD.Type
db.Save(&existingHD)
updatedHardDrives = append(updatedHardDrives, &existingHD)
}
}
return updatedHardDrives, nil
}