Skip to content

Commit

Permalink
FS-1123: Supermicro (SMC) BIOS config Get, Set and Reset support via SUM
Browse files Browse the repository at this point in the history
  • Loading branch information
splaspood committed May 28, 2024
1 parent 877feee commit 81bff4b
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 7 deletions.
24 changes: 24 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/bmc-toolbox/bmclib/v2/providers/openbmc"
"github.com/bmc-toolbox/bmclib/v2/providers/redfish"
"github.com/bmc-toolbox/bmclib/v2/providers/rpc"
"github.com/bmc-toolbox/bmclib/v2/providers/sum"

Check failure on line 26 in client.go

View workflow job for this annotation

GitHub Actions / test

no required module provides package github.com/bmc-toolbox/bmclib/v2/providers/sum; to add it:

Check failure on line 26 in client.go

View workflow job for this annotation

GitHub Actions / test

no required module provides package github.com/bmc-toolbox/bmclib/v2/providers/sum; to add it:
"github.com/bmc-toolbox/bmclib/v2/providers/supermicro"
"github.com/bmc-toolbox/common"
"github.com/go-logr/logr"
Expand Down Expand Up @@ -72,6 +73,7 @@ type providerConfig struct {
supermicro supermicro.Config
rpc rpc.Provider
openbmc openbmc.Config
sum sum.Exec
}

// NewClient returns a new Client struct
Expand Down Expand Up @@ -109,6 +111,7 @@ func NewClient(host, user, pass string, opts ...Option) *Client {
openbmc: openbmc.Config{
Port: "443",
},
sum: sum.Exec{},
},
}

Expand Down Expand Up @@ -262,6 +265,23 @@ func (c *Client) registerOpenBMCProvider() {
c.Registry.Register(openbmc.ProviderName, openbmc.ProviderProtocol, openbmc.Features, nil, driver)
}

// register sum provider
func (c *Client) registerSumProvider() error {
sumOpts := []sum.Option{
sum.WithLogger(c.Logger),
sum.WithSumPath(c.providerConfig.sum.SumPath),
}

driverSum, err := sum.New(c.Auth.Host, c.Auth.User, c.Auth.Pass, sumOpts...)
if err != nil {
return err
}

c.Registry.Register(sum.ProviderName, sum.ProviderProtocol, sum.Features, nil, driverSum)

return nil
}

func (c *Client) registerProviders() {
// register the rpc provider
// without the consumer URL there is no way to send RPC requests.
Expand All @@ -279,6 +299,10 @@ func (c *Client) registerProviders() {
c.Logger.Info("ipmitool provider not available", "error", err.Error())
}

if err := c.registerSumProvider(); err != nil {
c.Logger.Info("sum provider not available", "error", err.Error())
}

c.registerASRRProvider()
c.registerGofishProvider()
c.registerIntelAMTProvider()
Expand Down
37 changes: 35 additions & 2 deletions examples/bios/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,19 @@ func main() {

// Logger configuration
l := logrus.New()
l.Level = logrus.DebugLevel
// l.Level = logrus.TraceLevel
logger := logrusr.New(l)
logger.V(9)

// bmclib client abstraction
clientOpts := []bmclib.Option{bmclib.WithLogger(logger)}

client := bmclib.NewClient(*host, *user, *pass, clientOpts...)
client.Registry.Drivers = client.Registry.Supports(providers.FeatureGetBiosConfiguration, providers.FeatureSetBiosConfiguration, providers.FeatureResetBiosConfiguration)
client.Registry.Drivers = client.Registry.Supports(
providers.FeatureGetBiosConfiguration,
providers.FeatureSetBiosConfiguration,
providers.FeatureResetBiosConfiguration,
providers.FeatureSetBiosConfigurationFromFile)

err := client.Open(ctx)
if err != nil {
Expand Down Expand Up @@ -82,6 +87,34 @@ func main() {
fmt.Println("Attempting to set BIOS configuration:")
fmt.Printf("exampleConfig: %+v\n", exampleConfig)

err := client.SetBiosConfiguration(ctx, exampleConfig)
if err != nil {
l.Error(err)
}
case "setfile":
exampleConfig := make(map[string]string)

if *dfile != "" {
jsonFile, err := os.Open(*dfile)
if err != nil {
l.Fatal(err)
}

defer jsonFile.Close()

jsonData, _ := io.ReadAll(jsonFile)

err = json.Unmarshal(jsonData, &exampleConfig)
if err != nil {
l.Fatal(err)
}
} else {
exampleConfig["TpmSecurity"] = "Off"
}

fmt.Println("Attempting to set BIOS configuration:")
fmt.Printf("exampleConfig: %+v\n", exampleConfig)

err := client.SetBiosConfiguration(ctx, exampleConfig)
if err != nil {
l.Error(err)
Expand Down
3 changes: 3 additions & 0 deletions providers/providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ const (
// FeatureSetBiosConfiguration means an implementation that can set bios configuration from an input k/v map
FeatureSetBiosConfiguration registrar.Feature = "setbiosconfig"

// FeatureSetBiosConfigurationFromFile means an implementation that can set bios configuration from a vendor specific text file
FeatureSetBiosConfigurationFromFile registrar.Feature = "setbiosconfigfile"

// FeatureGetBiosConfiguration means an implementation that can get bios configuration in a simple k/v map
FeatureGetBiosConfiguration registrar.Feature = "getbiosconfig"
)
8 changes: 8 additions & 0 deletions providers/redfish/redfish.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ var (
providers.FeatureInventoryRead,
providers.FeatureBmcReset,
providers.FeatureClearSystemEventLog,
providers.FeatureGetBiosConfiguration,
providers.FeatureSetBiosConfiguration,
providers.FeatureResetBiosConfiguration,
}
)

Expand Down Expand Up @@ -223,6 +226,11 @@ func (c *Conn) SetBiosConfiguration(ctx context.Context, biosConfig map[string]s
return c.redfishwrapper.SetBiosConfiguration(ctx, biosConfig)
}

// ResetBiosConfiguration set bios configuration
func (c *Conn) ResetBiosConfiguration(ctx context.Context) (err error) {
return c.redfishwrapper.ResetBiosConfiguration(ctx)
}

// SendNMI tells the BMC to issue an NMI to the device
func (c *Conn) SendNMI(ctx context.Context) error {
return c.redfishwrapper.SendNMI(ctx)
Expand Down
8 changes: 4 additions & 4 deletions providers/supermicro/firmware.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ var (

// bmc client interface implementations methods
func (c *Client) FirmwareInstallSteps(ctx context.Context, component string) ([]constants.FirmwareInstallStep, error) {
if err := c.serviceClient.supportsFirmwareInstall(ctx, c.bmc.deviceModel()); err != nil {
if err := c.serviceClient.supportsFirmwareInstall(c.bmc.deviceModel()); err != nil {
return nil, err
}

return c.bmc.firmwareInstallSteps(component)
}

func (c *Client) FirmwareUpload(ctx context.Context, component string, file *os.File) (taskID string, err error) {
if err := c.serviceClient.supportsFirmwareInstall(ctx, c.bmc.deviceModel()); err != nil {
if err := c.serviceClient.supportsFirmwareInstall(c.bmc.deviceModel()); err != nil {
return "", err
}

Expand All @@ -56,7 +56,7 @@ func (c *Client) FirmwareUpload(ctx context.Context, component string, file *os.
}

func (c *Client) FirmwareInstallUploaded(ctx context.Context, component, uploadTaskID string) (installTaskID string, err error) {
if err := c.serviceClient.supportsFirmwareInstall(ctx, c.bmc.deviceModel()); err != nil {
if err := c.serviceClient.supportsFirmwareInstall(c.bmc.deviceModel()); err != nil {
return "", err
}

Expand All @@ -70,7 +70,7 @@ func (c *Client) FirmwareInstallUploaded(ctx context.Context, component, uploadT

// FirmwareTaskStatus returns the status of a firmware related task queued on the BMC.
func (c *Client) FirmwareTaskStatus(ctx context.Context, kind constants.FirmwareInstallStep, component, taskID, installVersion string) (state constants.TaskState, status string, err error) {
if err := c.serviceClient.supportsFirmwareInstall(ctx, c.bmc.deviceModel()); err != nil {
if err := c.serviceClient.supportsFirmwareInstall(c.bmc.deviceModel()); err != nil {
return "", "", errors.Wrap(bmclibErrs.ErrFirmwareInstallStatus, err.Error())
}

Expand Down
2 changes: 1 addition & 1 deletion providers/supermicro/supermicro.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ func (c *serviceClient) redfishSession(ctx context.Context) (err error) {
return nil
}

func (c *serviceClient) supportsFirmwareInstall(ctx context.Context, model string) error {
func (c *serviceClient) supportsFirmwareInstall(model string) error {
if model == "" {
return errors.Wrap(ErrModelUnknown, "unable to determine firmware install compatibility")
}
Expand Down

0 comments on commit 81bff4b

Please sign in to comment.