Skip to content

Commit

Permalink
Progress
Browse files Browse the repository at this point in the history
  • Loading branch information
majst01 committed Nov 14, 2024
1 parent 6e69d5b commit 1f4d720
Show file tree
Hide file tree
Showing 6 changed files with 203 additions and 32 deletions.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,25 @@ func main() {
err = smcInBand.PowerOff()
}
```

## Dell

Sample Lab Machines
172.19.100.107
Default PW: 9XW9FR9PN3FF

172.19.100.108
Default PW: K4P4NVAK9KVK

TODO:

- Console access must be switched to ssh root@<IP> console com2
Can password access switched to pubkey ?

- Identify LED ON/OFF and State does not work

- IPMI is disabled by default, unsure if Redfish Password can be set from Inband

- Redfish Sessions must be closed, see: https://github.com/stmcginnis/gofish/blob/main/examples/query_sessions.md

- Dell iDrac Redfish Samples: https://github.com/dell/iDRAC-Redfish-Scripting
69 changes: 43 additions & 26 deletions cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,42 +82,59 @@ func outband(log logger.Logger) {
if ps == hal.PowerUnknownState {
uu["PowerState"] = "unexpected power state: PowerUnknownState"
}

err = ob.PowerOff()
if err != nil {
fmt.Printf("error during power off: %v\n", err)
}

time.Sleep(10 * time.Second)
board := ob.Board()
fmt.Println("LED: " + board.IndicatorLED)

err = ob.PowerOn()
err = ob.PowerCycle()
if err != nil {
fmt.Printf("error during power on: %v\n", err)
ee["PowerCycle"] = err
}

// ipmitool sel
err = ob.IdentifyLEDState(hal.IdentifyLEDStateOff)
if err != nil {
ee["IdentifyLEDState"] = err
}
err = ob.IdentifyLEDOn()
if err != nil {
ee["IdentifyLEDOn"] = err
}
err = ob.IdentifyLEDOff()
if err != nil {
ee["IdentifyLEDOff"] = err
}
board = ob.Board()
fmt.Println("LED: " + board.IndicatorLED)

if false {
err = ob.PowerOff()
if err != nil {
fmt.Printf("error during power off: %v\n", err)
}

//_, err = ob.UpdateBIOS()
//if err != nil {
// ee["UpdateBIOS"] = err
//}
//
//_, err = ob.UpdateBMC()
//if err != nil {
// ee["UpdateBMC"] = err
//}
time.Sleep(10 * time.Second)

err = ob.PowerOn()
if err != nil {
fmt.Printf("error during power on: %v\n", err)
}

// ipmitool sel
err = ob.IdentifyLEDState(hal.IdentifyLEDStateOff)
if err != nil {
ee["IdentifyLEDState"] = err
}
err = ob.IdentifyLEDOn()
if err != nil {
ee["IdentifyLEDOn"] = err
}
err = ob.IdentifyLEDOff()
if err != nil {
ee["IdentifyLEDOff"] = err
}

//_, err = ob.UpdateBIOS()
//if err != nil {
// ee["UpdateBIOS"] = err
//}
//
//_, err = ob.UpdateBMC()
//if err != nil {
// ee["UpdateBMC"] = err
//}
}

if len(uu) > 0 {
fmt.Println("Unexpected things:")
Expand Down
71 changes: 71 additions & 0 deletions cli/redfish/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package main

import (
"log/slog"
"os"

"github.com/google/uuid"
"github.com/stmcginnis/gofish"
)

func main() {
log := slog.Default()
ip := os.Args[1]
pw := os.Args[2]
user := "root"

config := gofish.ClientConfig{
Endpoint: "https://" + ip,
Username: user,
Password: pw,
Insecure: true,
}
c, err := gofish.Connect(config)
if err != nil {
panic(err)
}
defer c.Logout()

systems, err := c.Service.Systems()
if err != nil {
panic(err)
}

for _, system := range systems {
log.Info("System", "indicator led", system.IndicatorLED, "locator led", system.LocationIndicatorActive)
system.LocationIndicatorActive = false
log.Info("System", "system", string(system.RawData))
}

systems, err = c.Service.Systems()
if err != nil {
panic(err)
}
for _, system := range systems {
log.Info("System", "indicator led", system.IndicatorLED, "locator led", system.LocationIndicatorActive)
}

chassis, err := c.Service.Chassis()
if err != nil {
panic(err)
}

for _, chass := range chassis {
log.Info("Chassis", "indicator led", chass.IndicatorLED, "locator led", chass.LocationIndicatorActive)
}

uid := ""
for _, system := range systems {
if system.UUID != "" {
uid = system.UUID
break
}
}

u, err := uuid.Parse(uid)
if err != nil {
panic(err)
}

log.Info("BMC", "UUID", u.String())
}
5 changes: 4 additions & 1 deletion hal.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package hal

import (
"github.com/gliderlabs/ssh"
"strings"

"github.com/gliderlabs/ssh"

"github.com/google/uuid"
"github.com/metal-stack/go-hal/pkg/api"
)
Expand Down Expand Up @@ -42,6 +43,8 @@ const (
IdentifyLEDStateOn
// IdentifyLEDStateOff the LED is off
IdentifyLEDStateOff
// IdentifyLEDStateBlinking the LED is blinking
IdentifyLEDStateBlinking
)
const (
// FirmwareModeUnknown server is in unknown firmware state
Expand Down
59 changes: 58 additions & 1 deletion internal/redfish/redfish.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ func (c *APIClient) PowerState() (hal.PowerState, error) {
}

func (c *APIClient) PowerOn() error {
return c.setPower(redfish.ForceOnResetType)
// TODO: check if this is enough for supermicro
return c.setPower(redfish.OnResetType)
}

func (c *APIClient) PowerOff() error {
Expand Down Expand Up @@ -348,3 +349,59 @@ func (c *APIClient) BMC() (*api.BMC, error) {

return bmc, nil
}

func (c *APIClient) IdentifyLEDState(state hal.IdentifyLEDState) error {
chassis, err := c.Service.Chassis()
if err != nil {
c.log.Warnw("ignore system query", "error", err.Error())
}

systems, err := c.Service.Systems()
if err != nil {
return err
}
// Not sure if system or chassis is responsible for LED
for _, system := range systems {
c.log.Infow("setting indicator led via system", "system", system.ID, "state", state)
switch state {
case hal.IdentifyLEDStateOff:
system.LocationIndicatorActive = false
system.IndicatorLED = common.OffIndicatorLED
case hal.IdentifyLEDStateOn:
system.LocationIndicatorActive = true
system.IndicatorLED = common.LitIndicatorLED
case hal.IdentifyLEDStateBlinking:
system.IndicatorLED = common.BlinkingIndicatorLED
case hal.IdentifyLEDStateUnknown:
return fmt.Errorf("unknown LED state:%s", state)
}
}

for _, chass := range chassis {
if chass.ChassisType != redfish.RackMountChassisType {
continue
}
c.log.Infow("setting indicator led via chassis", "chassis", chass.ID, "state", state)
switch state {
case hal.IdentifyLEDStateOff:
chass.LocationIndicatorActive = false
chass.IndicatorLED = common.OffIndicatorLED
case hal.IdentifyLEDStateOn:
chass.LocationIndicatorActive = true
chass.IndicatorLED = common.LitIndicatorLED
case hal.IdentifyLEDStateBlinking:
chass.IndicatorLED = common.BlinkingIndicatorLED
case hal.IdentifyLEDStateUnknown:
return fmt.Errorf("unknown LED state:%s", state)
}
}
return nil
}

func (c *APIClient) IdentifyLEDOn() error {
return c.IdentifyLEDState(hal.IdentifyLEDStateOn)
}

func (c *APIClient) IdentifyLEDOff() error {
return c.IdentifyLEDState(hal.IdentifyLEDStateOff)
}
9 changes: 5 additions & 4 deletions internal/vendors/dell/dell.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ func (o *outBand) BootFrom(hal.BootTarget) error {

// Console implements hal.OutBand.
func (o *outBand) Console(ssh.Session) error {
// Console access must be switched to ssh root@<IP> console com2
panic("unimplemented")
}

Expand All @@ -83,17 +84,17 @@ func (o *outBand) IPMIConnection() (ip string, port int, user string, password s

// IdentifyLEDOff implements hal.OutBand.
func (o *outBand) IdentifyLEDOff() error {
panic("unimplemented")
return o.Redfish.IdentifyLEDState(hal.IdentifyLEDStateOff)
}

// IdentifyLEDOn implements hal.OutBand.
func (o *outBand) IdentifyLEDOn() error {
panic("unimplemented")
return o.Redfish.IdentifyLEDState(hal.IdentifyLEDStateOn)
}

// IdentifyLEDState implements hal.OutBand.
func (o *outBand) IdentifyLEDState(hal.IdentifyLEDState) error {
panic("unimplemented")
func (o *outBand) IdentifyLEDState(state hal.IdentifyLEDState) error {
return o.Redfish.IdentifyLEDState(state)
}

// PowerCycle implements hal.OutBand.
Expand Down

0 comments on commit 1f4d720

Please sign in to comment.