Skip to content

Commit

Permalink
expand response payload processing (#399)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
DoctorVin authored Oct 17, 2024
1 parent eba5356 commit 301ce8b
Showing 1 changed file with 21 additions and 1 deletion.
22 changes: 21 additions & 1 deletion internal/redfishwrapper/firmware.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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 (
Expand Down Expand Up @@ -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)
}

Expand Down Expand Up @@ -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)
}

Expand Down

0 comments on commit 301ce8b

Please sign in to comment.