Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for mlx NIC and micron drive firmware updates #174

Merged
merged 6 commits into from
Aug 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion actions/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ type DriveUpdater interface {
// NICUpdater defines an interface to update NIC firmware
type NICUpdater interface {
UtilAttributeGetter
UpdateNIC(ctx context.Context, updateFile, modelNumber string) error
UpdateNIC(ctx context.Context, updateFile, modelNumber string, force bool) error
UpdateRequirements() model.UpdateRequirements
}

// BMCUpdater defines an interface to update BMC firmware
Expand Down
7 changes: 4 additions & 3 deletions actions/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,16 +124,17 @@ func GetNICUpdater(vendor string) (NICUpdater, error) {
// UpdateNIC identifies the nic eligible for update from the inventory and runs the firmware update utility based on the nic vendor
func UpdateNIC(ctx context.Context, nics []*common.NIC, options *model.UpdateOptions) error {
for _, nic := range nics {
if !strings.EqualFold(options.Vendor, nic.Vendor) {
nicVendor := common.FormatVendorName(nic.Vendor)
if !strings.EqualFold(options.Vendor, nicVendor) {
continue
}

updater, err := GetNICUpdater(nic.Vendor)
updater, err := GetNICUpdater(nicVendor)
if err != nil {
return err
}

return updater.UpdateNIC(ctx, options.UpdateFile, options.Model)
return updater.UpdateNIC(ctx, options.UpdateFile, options.Model, options.ForceInstall)
}

return errors.Wrap(ErrUpdaterUtilNotIdentified, options.Vendor)
Expand Down
7 changes: 6 additions & 1 deletion model/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package model

// UpdateOptions sets firmware update options for a device component
type UpdateOptions struct {
AllowDowngrade bool // Allow firmware to be downgraded
ForceInstall bool // Allow firmware to be downgraded
InstallAll bool // Install all available updates (vendor tooling like DSU fetches the updates and installs them)
DownloadOnly bool // Only download updates, skip install - Works with InstallAll (where updates are fetched by the vendor tooling)
Serial string
Expand All @@ -15,3 +15,8 @@ type UpdateOptions struct {
RepositoryVersion string // The update repository version to activate when defined
BaseURL string // The BaseURL for the updates
}

// UpdateRequirements holds attributes that indicate requirements for before/after a component firmware install
type UpdateRequirements struct {
PostInstallPowerCycle bool
}
2 changes: 1 addition & 1 deletion providers/dell/dell.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func (d *dell) InstallUpdates(ctx context.Context, options *model.UpdateOptions)
return d.installAvailableUpdates(ctx, options.DownloadOnly)
}

exitCode, err := d.installUpdate(ctx, options.Slug, options.AllowDowngrade)
exitCode, err := d.installUpdate(ctx, options.Slug, options.ForceInstall)
if err != nil {
return err
}
Expand Down
7 changes: 4 additions & 3 deletions utils/lsblk.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import (
)

const (
EnvLsblkUtility = "IRONLIB_UTIL_LSBLK"
EnvLsblkUtility = "IRONLIB_UTIL_LSBLK"
LsblkUtility model.CollectorUtility = "lsblk"
)

var ErrLsblkTransportUnsupported = errors.New("Unsupported transport type")
Expand All @@ -32,7 +33,7 @@ type lsblkDeviceAttributes struct {

// Return a new lsblk executor
func NewLsblkCmd(trace bool) *Lsblk {
utility := "lsblk"
utility := string(LsblkUtility)

// lookup env var for util
if eVar := os.Getenv(EnvLsblkUtility); eVar != "" {
Expand All @@ -54,7 +55,7 @@ func (l *Lsblk) Attributes() (utilName model.CollectorUtility, absolutePath stri
// Call CheckExecutable first so that the Executable CmdPath is resolved.
er := l.Executor.CheckExecutable()

return "lsblk", l.Executor.CmdPath(), er
return LsblkUtility, l.Executor.CmdPath(), er
DoctorVin marked this conversation as resolved.
Show resolved Hide resolved
}

// Executes lsblk list, parses the output and returns a slice of *common.Drive
Expand Down
15 changes: 13 additions & 2 deletions utils/mlxup.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,13 @@ func setNICFirmware(d *MlxupDevice, firmware *common.Firmware) {
}
}

// UpdateRequirements implements the actions/NICUpdater interface to return any pre/post firmware install requirements.
func (m *Mlxup) UpdateRequirements() model.UpdateRequirements {
return model.UpdateRequirements{PostInstallPowerCycle: true}
}

// UpdateNIC updates mellanox NIC with the given update file
func (m *Mlxup) UpdateNIC(ctx context.Context, updateFile, modelNumber string) error {
func (m *Mlxup) UpdateNIC(ctx context.Context, updateFile, modelNumber string, force bool) error {
// query list of nics
nics, err := m.Query(ctx)
if err != nil {
Expand All @@ -165,7 +170,13 @@ func (m *Mlxup) UpdateNIC(ctx context.Context, updateFile, modelNumber string) e
}
}

m.Executor.SetArgs("--yes", "--dev", nic.PCIDeviceName, "--image-file", updateFile)
args := []string{"--yes", "--dev", nic.PCIDeviceName, "--image-file", updateFile}

if force {
args = append(args, "--force")
}

m.Executor.SetArgs(args...)
result, err := m.Executor.Exec(ctx)
if err != nil {
return err
Expand Down
35 changes: 30 additions & 5 deletions utils/msecli.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,23 +124,26 @@ func (m *Msecli) UpdateDrive(ctx context.Context, updateFile, modelNumber, seria
}
}

// get the product name from the model number - msecli expects the product name
modelNForMsecli := model.FormatProductName(d.ModelNumber)

return m.updateDrive(ctx, modelNForMsecli, updateFile)
return m.updateDrive(ctx, d.ModelNumber, updateFile)
}

return ErrMseCliDriveNotIdentified
}

// updateDrive installs the given updatefile
func (m *Msecli) updateDrive(ctx context.Context, modelNumber, updateFile string) error {
// get the product name from the model number - msecli expects the product name
modelNForMsecli, err := mseCLIModelType(modelNumber)
if err != nil {
return err
}

// echo 'y'
m.Executor.SetStdin(bytes.NewReader([]byte("y\n")))
m.Executor.SetArgs(
"-U", // update
"-m", // model
modelNumber,
modelNForMsecli,
"-i", // directory containing the update file
filepath.Dir(updateFile),
)
Expand Down Expand Up @@ -219,3 +222,25 @@ func parseMsecliDeviceAttributes(bSlice []byte) *MsecliDevice {

return device
}

// msecli expects a model type which we derive from the model number
//
// Invalid model type MICRON_5200_MTFDDAK480TDN! Valid options are:
// M500, M510, M550, MX100, M600, M500DC, MX200, BX100, P400M, P400E, M510DC,
// M500IT, BX200, BX300, S610DC, S630DC, S650DC, S655DC, 9100PRO, 9100MAX, 2100,
// TX3, MX300, 1100, M500ITL, 7100ECO, 7100MAX, 5100ECO, 5100PRO, 5100MAX, 5300PRO,
// 5300MAX, 5300BOOT, 5200ECO, 5200PRO, 5200MAX, 9200ECO, 9200MAX, 9200PRO, 9300ECO, 9300MAX,
// 9300PRO, 7300ECO, 7300MAX, 7300PRO, MX500, 5210, 1300, MX600, BX500, P1,
// 2200, 2200S, P4, 2300, 2300V, 2210, P1W2, 2100IT, 3400, 2450,
// BX503, BX504, P7
func mseCLIModelType(mseModel string) (string, error) {
errUnsupported := errors.New("unsupported model number: " + mseModel)
switch mseModel {
case "Micron_5300_MTFDDAK480TDT":
return "5300MAX", nil
case "Micron_5200_MTFDDAK480TDN":
return "5200MAX", nil
default:
return "", errors.Wrap(errUnsupported, mseModel)
}
}
7 changes: 4 additions & 3 deletions utils/uefi_firmware_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import (
// https://github.com/linuxboot/fiano

const (
EnvUefiFirmwareParserUtility = "IRONLIB_UTIL_UTIL_UEFI_FIRMWARE_PARSER"
EnvUefiFirmwareParserUtility = "IRONLIB_UTIL_UTIL_UEFI_FIRMWARE_PARSER"
UefiFirmwareParserUtility model.CollectorUtility = "uefi-firmware-parser"
)

type UefiFirmwareParser struct {
Expand All @@ -24,7 +25,7 @@ var directoryPermissions fs.FileMode = 0o750

// Return a new UefiFirmwareParser executor
func NewUefiFirmwareParserCmd(trace bool) *UefiFirmwareParser {
utility := "uefi-firmware-parser"
utility := string(UefiFirmwareParserUtility)

// lookup env var for util
if eVar := os.Getenv(EnvUefiFirmwareParserUtility); eVar != "" {
Expand All @@ -46,7 +47,7 @@ func (u *UefiFirmwareParser) Attributes() (model.CollectorUtility, string, error
// Call CheckExecutable first so that the Executable CmdPath is resolved.
err := u.Executor.CheckExecutable()

return "uefi-firmware-parser", u.Executor.CmdPath(), err
return UefiFirmwareParserUtility, u.Executor.CmdPath(), err
DoctorVin marked this conversation as resolved.
Show resolved Hide resolved
}

// ExtractLogo extracts the Logo BMP image. It creates the output directory if required.
Expand Down
6 changes: 5 additions & 1 deletion utils/uefi_vars.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ import (
"github.com/metal-toolbox/ironlib/model"
)

const (
UefiVariableCollectorUtility model.CollectorUtility = "uefi-variable-collector"
)

type UEFIVariableCollector struct{}

func (UEFIVariableCollector) Attributes() (model.CollectorUtility, string, error) {
return "uefi-variable-collector", "", nil
return UefiVariableCollectorUtility, "", nil
DoctorVin marked this conversation as resolved.
Show resolved Hide resolved
}

type UEFIVarEntry struct {
Expand Down
Loading