Skip to content

Instantly share code, notes, and snippets.

@chadleeshaw
Last active December 17, 2024 03:05
Show Gist options
  • Save chadleeshaw/abede6259b3b7493c7fe7702fd1818f7 to your computer and use it in GitHub Desktop.
Save chadleeshaw/abede6259b3b7493c7fe7702fd1818f7 to your computer and use it in GitHub Desktop.
Golang: Create a memory struct based on DmiDecode data from standard output.
package main
import (
"encoding/json"
"fmt"
"log"
"os/exec"
"strings"
)
// memory represents the structure of memory information from dmidecode output.
type memory struct {
MemType string `json:"type,omitempty"`
MemForm string `json:"form_factor,omitempty"`
MemLocation string `json:"locator,omitempty"`
MemSize string `json:"size,omitempty"`
MemSpeed string `json:"speed,omitempty"`
MemSerial string `json:"serial_number,omitempty"`
MemManufacturer string `json:"manufacturer,omitempty"`
MemPartNumber string `json:"part_number,omitempty"`
}
func main() {
memModules, err := memInfo()
if err != nil {
log.Fatalf("Failed to retrieve memory information: %v", err)
}
jsonBytes, err := json.MarshalIndent(memModules, "", " ")
if err != nil {
log.Fatalf("Failed to marshal JSON: %v", err)
}
fmt.Println(string(jsonBytes))
}
// readDmiDecode runs dmidecode for the specified hardware type and returns the output split into blocks.
func readDmiDecode(hwtype string) ([]string, error) {
cmd := exec.Command("dmidecode", "--type", hwtype)
output, err := cmd.Output()
if err != nil {
return nil, fmt.Errorf("failed to execute dmidecode: %w", err)
}
return strings.Split(string(output), "\n\n"), nil
}
// memInfo parses the dmidecode output for memory information into a slice of memory structs.
func memInfo() ([]memory, error) {
blocks, err := readDmiDecode("memory")
if err != nil {
return nil, err
}
var memModules []memory
for _, block := range blocks {
if !strings.Contains(block, "Memory Device") || strings.Contains(block, "No Module Installed") {
continue
}
var mem memory
lines := strings.Split(block, "\n")
for _, line := range lines {
parts := strings.SplitN(strings.TrimSpace(line), ":", 2)
if len(parts) != 2 {
continue
}
key, value := strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1])
switch key {
case "Size":
mem.MemSize = value
case "Form Factor":
mem.MemForm = value
case "Locator":
mem.MemLocation = value
case "Type":
mem.MemType = value
case "Speed":
mem.MemSpeed = value
case "Serial Number":
mem.MemSerial = value
case "Manufacturer":
mem.MemManufacturer = value
case "Part Number":
mem.MemPartNumber = value
}
}
memModules = append(memModules, mem)
}
return memModules, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment