Initial Commit
This commit is contained in:
commit
6ab3ee0124
|
@ -0,0 +1,8 @@
|
||||||
|
module tea.chunkbyte.com/kato/drive-health
|
||||||
|
|
||||||
|
go 1.21.6
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/anatol/smart.go v0.0.0-20230705044831-c3b27137baa3 // indirect
|
||||||
|
golang.org/x/sys v0.9.0 // indirect
|
||||||
|
)
|
|
@ -0,0 +1,4 @@
|
||||||
|
github.com/anatol/smart.go v0.0.0-20230705044831-c3b27137baa3 h1:kAF2MWFD8tyDqD74OQizymjj2cnZAURwSzBrEslCDnI=
|
||||||
|
github.com/anatol/smart.go v0.0.0-20230705044831-c3b27137baa3/go.mod h1:llkexGSe52bW0OjNva0kvIqGZxfSnVfpKHrnKBI2+pU=
|
||||||
|
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
|
||||||
|
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
@ -0,0 +1,62 @@
|
||||||
|
package hardware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetSystemHardDrives() ([]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 hardDrives []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] != "nvme" {
|
||||||
|
hd := HardDrive{
|
||||||
|
Name: cols[0],
|
||||||
|
Transport: cols[1],
|
||||||
|
Size: cols[2],
|
||||||
|
Model: cols[3],
|
||||||
|
Serial: cols[4],
|
||||||
|
Type: cols[5],
|
||||||
|
Temperature: 0,
|
||||||
|
}
|
||||||
|
hardDrives = append(hardDrives, hd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle error
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return hardDrives, nil
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package hardware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/anatol/smart.go"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HardDrive struct {
|
||||||
|
Name string
|
||||||
|
Transport string
|
||||||
|
Size string
|
||||||
|
Model string
|
||||||
|
Serial string
|
||||||
|
Type string
|
||||||
|
Temperature int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch the temperature of the device, optinally update the reference object
|
||||||
|
func (h *HardDrive) GetTemperature(updateTemp bool) int {
|
||||||
|
// Fetch the device by name
|
||||||
|
disk, err := smart.Open("/dev/" + h.Name)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Failed to open device %s: %s\n", h.Name, err)
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
defer disk.Close()
|
||||||
|
|
||||||
|
// Fetch SMART data
|
||||||
|
smartInfo, err := disk.ReadGenericAttributes()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Failed to get SMART data for %s: %s\n", h.Name, err)
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the temperature
|
||||||
|
temperature := int(smartInfo.Temperature)
|
||||||
|
|
||||||
|
// Optionally update the reference object's temperature
|
||||||
|
if updateTemp {
|
||||||
|
h.Temperature = temperature
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the found value
|
||||||
|
return temperature
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"tea.chunkbyte.com/kato/drive-health/lib/hardware"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
hardDrives, err := hardware.GetSystemHardDrives()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, hdd := range hardDrives {
|
||||||
|
fmt.Printf("%s %s [%s]: %vC\n", hdd.Model, hdd.Serial, hdd.Size, hdd.GetTemperature(true))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue