Skip to content

Commit

Permalink
Merge branch 'main' into get-systemeventlog
Browse files Browse the repository at this point in the history
  • Loading branch information
mattcburns authored Nov 29, 2023
2 parents 34de741 + 0df7b75 commit 3469c21
Show file tree
Hide file tree
Showing 39 changed files with 1,161 additions and 1,457 deletions.
152 changes: 114 additions & 38 deletions bmc/firmware.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type firmwareInstallerProvider struct {

// firmwareInstall uploads and initiates firmware update for the component
func firmwareInstall(ctx context.Context, component, operationApplyTime string, forceInstall bool, reader io.Reader, generic []firmwareInstallerProvider) (taskID string, metadata Metadata, err error) {
var metadataLocal Metadata
metadata = newMetadata()

for _, elem := range generic {
if elem.FirmwareInstaller == nil {
Expand All @@ -49,20 +49,20 @@ func firmwareInstall(ctx context.Context, component, operationApplyTime string,

return taskID, metadata, err
default:
metadataLocal.ProvidersAttempted = append(metadataLocal.ProvidersAttempted, elem.name)
metadata.ProvidersAttempted = append(metadata.ProvidersAttempted, elem.name)
taskID, vErr := elem.FirmwareInstall(ctx, component, operationApplyTime, forceInstall, reader)
if vErr != nil {
err = multierror.Append(err, errors.WithMessagef(vErr, "provider: %v", elem.name))
err = multierror.Append(err, vErr)
metadata.FailedProviderDetail[elem.name] = err.Error()
continue

}
metadataLocal.SuccessfulProvider = elem.name
return taskID, metadataLocal, nil
metadata.SuccessfulProvider = elem.name
return taskID, metadata, nil
}
}

return taskID, metadataLocal, multierror.Append(err, errors.New("failure in FirmwareInstall"))
return taskID, metadata, multierror.Append(err, errors.New("failure in FirmwareInstall"))
}

// FirmwareInstallFromInterfaces identifies implementations of the FirmwareInstaller interface and passes the found implementations to the firmwareInstall() wrapper
Expand Down Expand Up @@ -118,7 +118,7 @@ type firmwareInstallVerifierProvider struct {

// firmwareInstallStatus returns the status of the firmware install process
func firmwareInstallStatus(ctx context.Context, installVersion, component, taskID string, generic []firmwareInstallVerifierProvider) (status string, metadata Metadata, err error) {
var metadataLocal Metadata
metadata = newMetadata()

for _, elem := range generic {
if elem.FirmwareInstallVerifier == nil {
Expand All @@ -130,20 +130,20 @@ func firmwareInstallStatus(ctx context.Context, installVersion, component, taskI

return status, metadata, err
default:
metadataLocal.ProvidersAttempted = append(metadataLocal.ProvidersAttempted, elem.name)
metadata.ProvidersAttempted = append(metadata.ProvidersAttempted, elem.name)
status, vErr := elem.FirmwareInstallStatus(ctx, installVersion, component, taskID)
if vErr != nil {
err = multierror.Append(err, errors.WithMessagef(vErr, "provider: %v", elem.name))
err = multierror.Append(err, vErr)
metadata.FailedProviderDetail[elem.name] = err.Error()
continue

}
metadataLocal.SuccessfulProvider = elem.name
return status, metadataLocal, nil
metadata.SuccessfulProvider = elem.name
return status, metadata, nil
}
}

return status, metadataLocal, multierror.Append(err, errors.New("failure in FirmwareInstallStatus"))
return status, metadata, multierror.Append(err, errors.New("failure in FirmwareInstallStatus"))
}

// FirmwareInstallStatusFromInterfaces identifies implementations of the FirmwareInstallVerifier interface and passes the found implementations to the firmwareInstallStatus() wrapper.
Expand Down Expand Up @@ -175,7 +175,82 @@ func FirmwareInstallStatusFromInterfaces(ctx context.Context, installVersion, co
return firmwareInstallStatus(ctx, installVersion, component, taskID, implementations)
}

// FirmwareInstallerWithOpts defines an interface to install firmware that was previously uploaded with FirmwareUpload
// FirmwareInstallProvider defines an interface to upload and initiate a firmware install in the same implementation method
//
// Its intended to deprecate the FirmwareInstall interface
type FirmwareInstallProvider interface {
// FirmwareInstallUploadAndInitiate uploads _and_ initiates the firmware install process.
//
// return values:
// taskID - A taskID is returned if the update process on the BMC returns an identifier for the update process.
FirmwareInstallUploadAndInitiate(ctx context.Context, component string, file *os.File) (taskID string, err error)
}

// firmwareInstallProvider is an internal struct to correlate an implementation/provider and its name
type firmwareInstallProvider struct {
name string
FirmwareInstallProvider
}

// firmwareInstall uploads and initiates firmware update for the component
func firmwareInstallUploadAndInitiate(ctx context.Context, component string, file *os.File, generic []firmwareInstallProvider) (taskID string, metadata Metadata, err error) {
metadata = newMetadata()

for _, elem := range generic {
if elem.FirmwareInstallProvider == nil {
continue
}
select {
case <-ctx.Done():
err = multierror.Append(err, ctx.Err())

return taskID, metadata, err
default:
metadata.ProvidersAttempted = append(metadata.ProvidersAttempted, elem.name)
taskID, vErr := elem.FirmwareInstallUploadAndInitiate(ctx, component, file)
if vErr != nil {
err = multierror.Append(err, errors.WithMessagef(vErr, "provider: %v", elem.name))
metadata.FailedProviderDetail[elem.name] = err.Error()
continue
}
metadata.SuccessfulProvider = elem.name
return taskID, metadata, nil
}
}

return taskID, metadata, multierror.Append(err, errors.New("failure in FirmwareInstallUploadAndInitiate"))
}

// FirmwareInstallUploadAndInitiateFromInterfaces identifies implementations of the FirmwareInstallProvider interface and passes the found implementations to the firmwareInstallUploadAndInitiate() wrapper
func FirmwareInstallUploadAndInitiateFromInterfaces(ctx context.Context, component string, file *os.File, generic []interface{}) (taskID string, metadata Metadata, err error) {
metadata = newMetadata()

implementations := make([]firmwareInstallProvider, 0)
for _, elem := range generic {
temp := firmwareInstallProvider{name: getProviderName(elem)}
switch p := elem.(type) {
case FirmwareInstallProvider:
temp.FirmwareInstallProvider = p
implementations = append(implementations, temp)
default:
e := fmt.Sprintf("not a FirmwareInstallProvider implementation: %T", p)
err = multierror.Append(err, errors.New(e))
}
}
if len(implementations) == 0 {
return taskID, metadata, multierror.Append(
err,
errors.Wrap(
bmclibErrs.ErrProviderImplementation,
("no FirmwareInstallProvider implementations found"),
),
)
}

return firmwareInstallUploadAndInitiate(ctx, component, file, implementations)
}

// FirmwareInstallerUploaded defines an interface to install firmware that was previously uploaded with FirmwareUpload
type FirmwareInstallerUploaded interface {
// FirmwareInstallUploaded uploads firmware update payload to the BMC returning the firmware install task ID
//
Expand All @@ -196,7 +271,7 @@ type firmwareInstallerWithOptionsProvider struct {

// firmwareInstallUploaded uploads and initiates firmware update for the component
func firmwareInstallUploaded(ctx context.Context, component, uploadTaskID string, generic []firmwareInstallerWithOptionsProvider) (installTaskID string, metadata Metadata, err error) {
var metadataLocal Metadata
metadata = newMetadata()

for _, elem := range generic {
if elem.FirmwareInstallerUploaded == nil {
Expand All @@ -208,21 +283,21 @@ func firmwareInstallUploaded(ctx context.Context, component, uploadTaskID string

return installTaskID, metadata, err
default:
metadataLocal.ProvidersAttempted = append(metadataLocal.ProvidersAttempted, elem.name)
metadata.ProvidersAttempted = append(metadata.ProvidersAttempted, elem.name)
var vErr error
installTaskID, vErr = elem.FirmwareInstallUploaded(ctx, component, uploadTaskID)
if vErr != nil {
err = multierror.Append(err, errors.WithMessagef(vErr, "provider: %v", elem.name))
err = multierror.Append(err, vErr)
metadata.FailedProviderDetail[elem.name] = err.Error()
continue

}
metadataLocal.SuccessfulProvider = elem.name
return installTaskID, metadataLocal, nil
metadata.SuccessfulProvider = elem.name
return installTaskID, metadata, nil
}
}

return installTaskID, metadataLocal, multierror.Append(err, errors.New("failure in FirmwareInstallUploaded"))
return installTaskID, metadata, multierror.Append(err, errors.New("failure in FirmwareInstallUploaded"))
}

// FirmwareInstallerUploadedFromInterfaces identifies implementations of the FirmwareInstallUploaded interface and passes the found implementations to the firmwareInstallUploaded() wrapper
Expand Down Expand Up @@ -294,7 +369,7 @@ func FirmwareInstallStepsFromInterfaces(ctx context.Context, component string, g
}

func firmwareInstallSteps(ctx context.Context, component string, generic []firmwareInstallStepsGetterProvider) (steps []constants.FirmwareInstallStep, metadata Metadata, err error) {
var metadataLocal Metadata
metadata = newMetadata()

for _, elem := range generic {
if elem.FirmwareInstallStepsGetter == nil {
Expand All @@ -306,20 +381,20 @@ func firmwareInstallSteps(ctx context.Context, component string, generic []firmw

return steps, metadata, err
default:
metadataLocal.ProvidersAttempted = append(metadataLocal.ProvidersAttempted, elem.name)
metadata.ProvidersAttempted = append(metadata.ProvidersAttempted, elem.name)
steps, vErr := elem.FirmwareInstallSteps(ctx, component)
if vErr != nil {
err = multierror.Append(err, errors.WithMessagef(vErr, "provider: %v", elem.name))
err = multierror.Append(err, vErr)
metadata.FailedProviderDetail[elem.name] = err.Error()
continue

}
metadataLocal.SuccessfulProvider = elem.name
return steps, metadataLocal, nil
metadata.SuccessfulProvider = elem.name
return steps, metadata, nil
}
}

return steps, metadataLocal, multierror.Append(err, errors.New("failure in FirmwareInstallSteps"))
return steps, metadata, multierror.Append(err, errors.New("failure in FirmwareInstallSteps"))
}

type FirmwareUploader interface {
Expand Down Expand Up @@ -362,7 +437,7 @@ func FirmwareUploadFromInterfaces(ctx context.Context, component string, file *o
}

func firmwareUpload(ctx context.Context, component string, file *os.File, generic []firmwareUploaderProvider) (taskID string, metadata Metadata, err error) {
var metadataLocal Metadata
metadata = newMetadata()

for _, elem := range generic {
if elem.FirmwareUploader == nil {
Expand All @@ -374,20 +449,20 @@ func firmwareUpload(ctx context.Context, component string, file *os.File, generi

return taskID, metadata, err
default:
metadataLocal.ProvidersAttempted = append(metadataLocal.ProvidersAttempted, elem.name)
metadata.ProvidersAttempted = append(metadata.ProvidersAttempted, elem.name)
taskID, vErr := elem.FirmwareUpload(ctx, component, file)
if vErr != nil {
err = multierror.Append(err, errors.WithMessagef(vErr, "provider: %v", elem.name))
err = multierror.Append(err, vErr)
metadata.FailedProviderDetail[elem.name] = err.Error()
continue

}
metadataLocal.SuccessfulProvider = elem.name
return taskID, metadataLocal, nil
metadata.SuccessfulProvider = elem.name
return taskID, metadata, nil
}
}

return taskID, metadataLocal, multierror.Append(err, errors.New("failure in FirmwareUpload"))
return taskID, metadata, multierror.Append(err, errors.New("failure in FirmwareUpload"))
}

// FirmwareTaskVerifier defines an interface to check the status for firmware related tasks queued on the BMC.
Expand Down Expand Up @@ -416,8 +491,9 @@ type firmwareTaskVerifierProvider struct {
}

// firmwareTaskStatus returns the status of the firmware upload process.

func firmwareTaskStatus(ctx context.Context, kind bconsts.FirmwareInstallStep, component, taskID, installVersion string, generic []firmwareTaskVerifierProvider) (state constants.TaskState, status string, metadata Metadata, err error) {
var metadataLocal Metadata
metadata = newMetadata()

for _, elem := range generic {
if elem.FirmwareTaskVerifier == nil {
Expand All @@ -429,20 +505,20 @@ func firmwareTaskStatus(ctx context.Context, kind bconsts.FirmwareInstallStep, c

return state, status, metadata, err
default:
metadataLocal.ProvidersAttempted = append(metadataLocal.ProvidersAttempted, elem.name)
metadata.ProvidersAttempted = append(metadata.ProvidersAttempted, elem.name)
state, status, vErr := elem.FirmwareTaskStatus(ctx, kind, component, taskID, installVersion)
if vErr != nil {
err = multierror.Append(err, errors.WithMessagef(vErr, "provider: %v", elem.name))
err = multierror.Append(err, vErr)
metadata.FailedProviderDetail[elem.name] = err.Error()
continue

}
metadataLocal.SuccessfulProvider = elem.name
return state, status, metadataLocal, nil

metadata.SuccessfulProvider = elem.name
return state, status, metadata, nil
}
}

return state, status, metadataLocal, multierror.Append(err, errors.New("failure in FirmwareTaskStatus"))
return state, status, metadata, multierror.Append(err, errors.New("failure in FirmwareTaskStatus"))
}

// FirmwareTaskStatusFromInterfaces identifies implementations of the FirmwareTaskVerifier interface and passes the found implementations to the firmwareTaskStatus() wrapper.
Expand Down
Loading

0 comments on commit 3469c21

Please sign in to comment.