Skip to content

Commit a1b87e2

Browse files
authored
Merge pull request #337 from bmc-toolbox/redfish-override-timeout
Redfish override timeout for FirmwareInstall
2 parents 13adab0 + c13e347 commit a1b87e2

File tree

4 files changed

+68
-11
lines changed

4 files changed

+68
-11
lines changed

internal/redfishwrapper/client.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,16 @@ func (c *Client) SessionActive() error {
161161
return nil
162162
}
163163

164+
// Overrides the HTTP client timeout
165+
func (c *Client) SetHttpClientTimeout(t time.Duration) {
166+
c.client.HTTPClient.Timeout = t
167+
}
168+
169+
// retrieve the current HTTP client timeout
170+
func (c *Client) HttpClientTimeout() time.Duration {
171+
return c.client.HTTPClient.Timeout
172+
}
173+
164174
// RunRawRequestWithHeaders wraps the gofish client method RunRawRequestWithHeaders
165175
func (c *Client) RunRawRequestWithHeaders(method, url string, payloadBuffer io.ReadSeeker, contentType string, customHeaders map[string]string) (*http.Response, error) {
166176
if err := c.SessionActive(); err != nil {

providers/redfish/firmware.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"path/filepath"
1414
"strconv"
1515
"strings"
16+
"time"
1617

1718
"github.com/pkg/errors"
1819
gofishrf "github.com/stmcginnis/gofish/redfish"
@@ -22,6 +23,10 @@ import (
2223
"github.com/bmc-toolbox/bmclib/v2/internal"
2324
)
2425

26+
var (
27+
errInsufficientCtxTimeout = errors.New("remaining context timeout insufficient to install firmware")
28+
)
29+
2530
// SupportedFirmwareApplyAtValues returns the supported redfish firmware applyAt values
2631
func SupportedFirmwareApplyAtValues() []string {
2732
return []string{
@@ -43,6 +48,14 @@ func (c *Conn) FirmwareInstall(ctx context.Context, component, applyAt string, f
4348
return "", errors.Wrap(bmclibErrs.ErrFirmwareInstall, "invalid applyAt parameter: "+applyAt)
4449
}
4550

51+
// expect atleast 10 minutes left in the deadline to proceed with the update
52+
//
53+
// this gives the BMC enough time to have the firmware uploaded and return a response to the client.
54+
ctxDeadline, _ := ctx.Deadline()
55+
if time.Until(ctxDeadline) < 10*time.Minute {
56+
return "", errors.Wrap(errInsufficientCtxTimeout, " "+time.Until(ctxDeadline).String())
57+
}
58+
4659
// list redfish firmware install task if theres one present
4760
task, err := c.GetFirmwareInstallTaskQueued(ctx, component)
4861
if err != nil {
@@ -77,6 +90,17 @@ func (c *Conn) FirmwareInstall(ctx context.Context, component, applyAt string, f
7790
return "", errors.Wrap(bmclibErrs.ErrFirmwareInstall, err.Error())
7891
}
7992

93+
// override the gofish HTTP client timeout,
94+
// since the context timeout is set at Open() and is at a lower value than required for this operation.
95+
//
96+
// record the http client time to be restored
97+
httpClientTimeout := c.redfishwrapper.HttpClientTimeout()
98+
defer func() {
99+
c.redfishwrapper.SetHttpClientTimeout(httpClientTimeout)
100+
}()
101+
102+
c.redfishwrapper.SetHttpClientTimeout(time.Until(ctxDeadline))
103+
80104
payload := map[string]io.Reader{
81105
"UpdateParameters": bytes.NewReader(updateParameters),
82106
"UpdateFile": reader,

providers/redfish/firmware_test.go

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"path/filepath"
1111
"strings"
1212
"testing"
13+
"time"
1314

1415
"github.com/stretchr/testify/assert"
1516

@@ -70,19 +71,32 @@ func Test_FirmwareInstall(t *testing.T) {
7071
defer os.Remove(binPath)
7172

7273
tests := []struct {
73-
component string
74-
applyAt string
75-
forceInstall bool
76-
reader io.Reader
77-
expectTaskID string
78-
expectErr error
79-
expectErrSubStr string
80-
testName string
74+
component string
75+
applyAt string
76+
forceInstall bool
77+
setRequiredTimeout bool
78+
reader io.Reader
79+
expectTaskID string
80+
expectErr error
81+
expectErrSubStr string
82+
testName string
8183
}{
84+
{
85+
common.SlugBIOS,
86+
constants.FirmwareApplyOnReset,
87+
false,
88+
false,
89+
nil,
90+
"",
91+
errInsufficientCtxTimeout,
92+
"",
93+
"remaining context deadline",
94+
},
8295
{
8396
common.SlugBIOS,
8497
"invalidApplyAt",
8598
false,
99+
true,
86100
nil,
87101
"",
88102
bmclibErrs.ErrFirmwareInstall,
@@ -93,6 +107,7 @@ func Test_FirmwareInstall(t *testing.T) {
93107
common.SlugBIOS,
94108
constants.FirmwareApplyOnReset,
95109
false,
110+
true,
96111
fh,
97112
"467696020275",
98113
bmclibErrs.ErrFirmwareInstall,
@@ -103,6 +118,7 @@ func Test_FirmwareInstall(t *testing.T) {
103118
common.SlugBIOS,
104119
constants.FirmwareApplyOnReset,
105120
true,
121+
true,
106122
fh,
107123
"467696020275",
108124
nil,
@@ -113,7 +129,12 @@ func Test_FirmwareInstall(t *testing.T) {
113129

114130
for _, tc := range tests {
115131
t.Run(tc.testName, func(t *testing.T) {
116-
taskID, err := mockClient.FirmwareInstall(context.TODO(), tc.component, tc.applyAt, tc.forceInstall, tc.reader)
132+
ctx, cancel := context.WithTimeout(context.TODO(), 1*time.Second)
133+
if tc.setRequiredTimeout {
134+
ctx, cancel = context.WithTimeout(context.TODO(), 20*time.Minute)
135+
}
136+
137+
taskID, err := mockClient.FirmwareInstall(ctx, tc.component, tc.applyAt, tc.forceInstall, tc.reader)
117138
if tc.expectErr != nil {
118139
assert.ErrorIs(t, err, tc.expectErr)
119140
if tc.expectErrSubStr != "" {
@@ -123,6 +144,8 @@ func Test_FirmwareInstall(t *testing.T) {
123144
assert.Nil(t, err)
124145
assert.Equal(t, tc.expectTaskID, taskID)
125146
}
147+
148+
defer cancel()
126149
})
127150
}
128151

providers/supermicro/firmware.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ func (c *Client) FirmwareInstall(ctx context.Context, component, applyAt string,
2828
size = finfo.Size()
2929
}
3030

31-
// expect atleast 30 minutes left in the deadline to proceed with the update
31+
// expect atleast 10 minutes left in the deadline to proceed with the update
3232
d, _ := ctx.Deadline()
33-
if time.Until(d) < 30*time.Minute {
33+
if time.Until(d) < 10*time.Minute {
3434
return "", errors.New("remaining context deadline insufficient to perform update: " + time.Until(d).String())
3535
}
3636

0 commit comments

Comments
 (0)