From 301ce8b85165aa45e4ee8083a14f09fb29b6b9fe Mon Sep 17 00:00:00 2001 From: Doctor Vince Date: Thu, 17 Oct 2024 10:15:50 -0400 Subject: [PATCH] expand response payload processing (#399) In contrast to other server-vendors, SMC does not return the task id in the Location header of the response to a firmware upload. In BMC version 1.05.03 (Redfish version 1.14.0) the payload format changes from a TaskAccepted message to a Redfish task, which breaks task id detection. This change adds an attempt to deserialize the task structure before falling back to the earlier TaskAccepted message type. This also corrects the startUpdateURI. --- internal/redfishwrapper/firmware.go | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/internal/redfishwrapper/firmware.go b/internal/redfishwrapper/firmware.go index 81c3f1a5..aed6e3fe 100644 --- a/internal/redfishwrapper/firmware.go +++ b/internal/redfishwrapper/firmware.go @@ -16,6 +16,7 @@ import ( "time" "github.com/pkg/errors" + "github.com/stmcginnis/gofish/redfish" "github.com/bmc-toolbox/bmclib/v2/constants" bmclibErrs "github.com/bmc-toolbox/bmclib/v2/errors" @@ -31,7 +32,7 @@ const ( var ( // the URI for starting a firmware update via StartUpdate is defined in the Redfish Resource and // Schema Guide (2024.1) - startUpdateURI = "redfish/v1/UpdateService/Actions/UpdateService.StartUpdate" + startUpdateURI = "/redfish/v1/UpdateService/Actions/UpdateService.StartUpdate" ) var ( @@ -112,6 +113,16 @@ func (c *Client) FirmwareUpload(ctx context.Context, updateFile *os.File, params return taskIDFromLocationHeader(location) } + rfTask := &redfish.Task{} + if err := rfTask.UnmarshalJSON(response); err != nil { + // we got invalid JSON + return "", fmt.Errorf("unmarshaling redfish response: %w", err) + } + // it's possible to get well-formed JSON that isn't a Task (thanks SMC). Test that we have something sensible. + if strings.Contains(rfTask.ODataType, "Task") { + return rfTask.ID, nil + } + return taskIDFromResponseBody(response) } @@ -146,6 +157,15 @@ func (c *Client) StartUpdateForUploadedFirmware(ctx context.Context) (taskID str return taskIDFromLocationHeader(location) } + rfTask := &redfish.Task{} + if err := rfTask.UnmarshalJSON(response); err != nil { + // we got invalid JSON + return "", fmt.Errorf("unmarshaling redfish response: %w", err) + } + if strings.Contains(rfTask.ODataType, "Task") { + return rfTask.ID, nil + } + return taskIDFromResponseBody(response) }