Skip to content

Commit

Permalink
Update redfish/ipmi for the new readinfo
Browse files Browse the repository at this point in the history
  • Loading branch information
5kt authored and Gchbg committed May 3, 2024
1 parent 514f75c commit 028e2eb
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 132 deletions.
61 changes: 2 additions & 59 deletions internal/bmc/ipmi.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ import (
"time"

"github.com/hashicorp/go-multierror"
"golang.org/x/text/cases"
"golang.org/x/text/language"

"github.com/ironcore-dev/metal/internal/log"
)

Expand Down Expand Up @@ -146,62 +143,8 @@ func (b *IPMIBMC) Connect(ctx context.Context) error {

func (b *IPMIBMC) ReadInfo(ctx context.Context) (Info, error) {
log.Debug(ctx, "Reading BMC info", "host", b.host)
info := make(map[string]string)

out, serr, err := ipmiExecuteCommand(ctx, b.host, b.port, b.creds, "ipmitool", "fru", "list", "0")
if err != nil {
return Info{}, fmt.Errorf("cannot get fru info, stderr: %s: %w", serr, err)
}
outputmap(out, &info)

out, serr, err = ipmiExecuteCommand(ctx, b.host, b.port, b.creds, "ipmitool", "mc", "guid")
if err != nil {
return Info{}, fmt.Errorf("cannot get mc info, stderr: %s: %w", serr, err)
}
outputmap(out, &info)

out, serr, err = ipmiExecuteCommand(ctx, b.host, b.port, b.creds, "ipmi-chassis", "--get-chassis-status")
if err != nil {
return Info{}, fmt.Errorf("cannot get chassis status, stderr: %s: %w", serr, err)
}
outputmap(out, &info)

out, serr, err = ipmiExecuteCommand(ctx, b.host, b.port, b.creds, "ipmitool", "bmc", "info")
if err != nil {
return Info{}, fmt.Errorf("cannot get bmc info, stderr: %s: %w", serr, err)
}
outputmap(out, &info)

uuid, ok := info["System GUID"]
if !ok {
return Info{}, fmt.Errorf("cannot determine uuid for machine")
}
uuid = strings.ToLower(uuid)
powerstate, ok := info["System Power"]
if !ok {
return Info{}, fmt.Errorf("cannot determine the power state for machine")
}
serial := info["Product Serial"]
sku := info["Product SKU"]
manufacturer := info["Manufacturer"]
//TODO: currently we can't handle this correctly as we can't read the state on most hardware
//led, ok := info["Chassis Identify State"]
led := ""
fw := info["Firmware Revision"]

//TODO: properly detect if sol is supported
return Info{
UUID: uuid,
Type: "BMC",
Capabilities: []string{"credentials", "power", "led", "console"},
SerialNumber: serial,
SKU: sku,
Manufacturer: manufacturer,
LocatorLED: LED(led),
Power: Power(cases.Title(language.English).String(powerstate)),
Console: "ipmi",
FWVersion: fw,
}, nil
// TODO: implement proper ipmi readinfo
return Info{}, nil
}

func ipmiGenerateCommand(ctx context.Context, host string, port int32, creds Credentials, cmd ...string) ([]string, error) {
Expand Down
97 changes: 24 additions & 73 deletions internal/bmc/redfish.go
Original file line number Diff line number Diff line change
Expand Up @@ -601,60 +601,9 @@ func (b *RedfishBMC) ReadInfo(ctx context.Context) (Info, error) {
defer c.Logout()

log.Debug(ctx, "Reading BMC info")
systems, err := c.Service.Systems()
if err != nil {
return Info{}, fmt.Errorf("cannot get systems information: %w", err)
}
if len(systems) == 0 {
return Info{}, fmt.Errorf("cannot get systems information")
}

uuid := systems[0].UUID
if uuid == "" {
return Info{}, fmt.Errorf("BMC has no UUID attribute")
}
uuid = strings.ToLower(uuid)

led := LED(systems[0].IndicatorLED)

// Reading the OS state is supported only on Lenovo hardware
var os, osReason string
if len(systems) > 0 {
sys := systems[0]
sysRaw, err := c.Get(sys.ODataID)
if err != nil {
return Info{}, fmt.Errorf("cannot get systems (raw): %w", err)
}
osStatus := struct {
OEM struct {
Lenovo struct {
SystemStatus *string `json:"SystemStatus"`
} `json:"Lenovo"`
} `json:"OEM"`
}{}

decoder := json.NewDecoder(sysRaw.Body)
err = decoder.Decode(&osStatus)
if err != nil {
return Info{}, fmt.Errorf("cannot decode information for OS status: %w", err)
}

if osStatus.OEM.Lenovo.SystemStatus != nil {
if sys.PowerState == redfish.OffPowerState {
osReason = "PoweredOff"
} else if state := *osStatus.OEM.Lenovo.SystemStatus; state == "OSBooted" || state == "BootingOSOrInUndetectedOS" {
os = "Ok"
osReason = state
} else {
osReason = state
}
}
}

manufacturer := systems[0].Manufacturer
capabilities := []string{"credentials", "power", "led"}
console := ""
fw := ""
info := Info{}
manufacturer := c.Service.Vendor
info.Manufacturer = manufacturer

mgr, err := c.Service.Managers()
if err != nil {
Expand All @@ -664,30 +613,32 @@ func (b *RedfishBMC) ReadInfo(ctx context.Context) (Info, error) {
consoleList := mgr[0].SerialConsole.ConnectTypesSupported
if mgr[0].SerialConsole.ServiceEnabled {
if strings.ToLower(manufacturer) == "lenovo" && isConsoleTypeSupported(consoleList, redfish.SSHSerialConnectTypesSupported) {
capabilities = append(capabilities, "console")
console = "ssh-lenovo"
info.Console = "ssh-lenovo"
} else if isConsoleTypeSupported(consoleList, redfish.IPMISerialConnectTypesSupported) {
capabilities = append(capabilities, "console")
console = "ipmi"
info.Console = "ipmi"
}
fw = mgr[0].FirmwareVersion
info.FirmwareVersion = mgr[0].FirmwareVersion
}
}

return Info{
UUID: uuid,
Type: "BMC",
Capabilities: capabilities,
SerialNumber: systems[0].SerialNumber,
SKU: systems[0].SKU,
Manufacturer: manufacturer,
LocatorLED: led,
Power: Power(fmt.Sprintf("%v", systems[0].PowerState)),
OS: os,
OSReason: osReason,
Console: console,
FWVersion: fw,
}, nil
systems, err := c.Service.Systems()
if err != nil {
return Info{}, fmt.Errorf("cannot get systems information: %w", err)
}
for _, system := range systems {
machine := Machine{}
machine.Manufacturer = manufacturer
machine.Power = Power(fmt.Sprintf("%v", system.PowerState))
machine.SKU = system.SKU
machine.LocatorLED = LED(system.IndicatorLED)
machine.SerialNumber = system.SerialNumber
machine.UUID = strings.ToLower(system.UUID)
if machine.UUID == "" {
return Info{}, fmt.Errorf("System has no UUID")
}
info.Machines = append(info.Machines, machine)
}
return info, nil
}

func isConsoleTypeSupported(consoleList []redfish.SerialConnectTypesSupported, console redfish.SerialConnectTypesSupported) bool {
Expand Down

0 comments on commit 028e2eb

Please sign in to comment.