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

Supermicro X13 inventory/firmware support FS-1671 #394

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
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
4 changes: 2 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ jobs:
- name: Run golangci-lint
uses: golangci/golangci-lint-action@v3
with:
args: -v --config .golangci.yml --timeout=5m
version: latest
args: -v --config .golangci.yml --timeout=5m --out-format=colored-line-number
version: v1.55.2
- name: make all-checks
run: make all-checks
test:
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ github.com/VictorLowther/simplexml v0.0.0-20180716164440-0bff93621230 h1:t95Grn2
github.com/VictorLowther/simplexml v0.0.0-20180716164440-0bff93621230/go.mod h1:t2EzW1qybnPDQ3LR/GgeF0GOzHUXT5IVMLP2gkW1cmc=
github.com/VictorLowther/soap v0.0.0-20150314151524-8e36fca84b22 h1:a0MBqYm44o0NcthLKCljZHe1mxlN6oahCQHHThnSwB4=
github.com/VictorLowther/soap v0.0.0-20150314151524-8e36fca84b22/go.mod h1:/B7V22rcz4860iDqstGvia/2+IYWXf3/JdQCVd/1D2A=
github.com/bmc-toolbox/common v0.0.0-20240805193945-ce25765471a7 h1:+NcnInwZxn25daBCb3d1y3x9QF23uob1ghdiimj2Dwo=
github.com/bmc-toolbox/common v0.0.0-20240805193945-ce25765471a7/go.mod h1:Cdnkm+edb6C0pVkyCrwh3JTXAe0iUF9diDG/DztPI9I=
github.com/bmc-toolbox/common v0.0.0-20240806132831-ba8adc6a35e3 h1:/BjZSX/sphptIdxpYo4wxAQkgMLyMMgfdl48J9DKNeE=
github.com/bmc-toolbox/common v0.0.0-20240806132831-ba8adc6a35e3/go.mod h1:Cdnkm+edb6C0pVkyCrwh3JTXAe0iUF9diDG/DztPI9I=
github.com/bombsimon/logrusr/v2 v2.0.1 h1:1VgxVNQMCvjirZIYaT9JYn6sAVGVEcNtRE0y4mvaOAM=
Expand Down
9 changes: 9 additions & 0 deletions internal/redfishwrapper/firmware.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (

"github.com/bmc-toolbox/bmclib/v2/constants"
bmclibErrs "github.com/bmc-toolbox/bmclib/v2/errors"
redfish "github.com/stmcginnis/gofish/redfish"
)

type installMethod string
Expand Down Expand Up @@ -99,6 +100,14 @@ func (c *Client) FirmwareUpload(ctx context.Context, updateFile *os.File, params
)
}

// For X13 the full Task structure is returned in the body. If we can Unmarshall then we can safely assume
// that redfishTask.ID contains the ID.
redfishTask := &redfish.Task{}
err = json.Unmarshal(response, redfishTask)
if err == nil {
return redfishTask.ID, nil
}

// The response contains a location header pointing to the task URI
// Location: /redfish/v1/TaskService/Tasks/JID_467696020275
var location = resp.Header.Get("Location")
Expand Down
3 changes: 2 additions & 1 deletion providers/supermicro/firmware.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ var (
"X11SSE-F",
"X12STH-SYS",
"X12SPO-NTF",
"X13DEM",
}

errUploadTaskIDExpected = errors.New("expected an firmware upload taskID")
Expand All @@ -46,7 +47,7 @@ func (c *Client) FirmwareUpload(ctx context.Context, component string, file *os.
return "", err
}

// // expect atleast 5 minutes left in the deadline to proceed with the upload
// expect atleast 5 minutes left in the deadline to proceed with the upload
d, _ := ctx.Deadline()
if time.Until(d) < 5*time.Minute {
return "", errors.New("remaining context deadline insufficient to perform update: " + time.Until(d).String())
Expand Down
47 changes: 39 additions & 8 deletions providers/supermicro/supermicro.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,14 @@ func (c *Client) Open(ctx context.Context) (err error) {
return err
}

if !bytes.Contains(body, []byte(`url_redirect.cgi?url_name=mainmenu`)) &&
!bytes.Contains(body, []byte(`url_redirect.cgi?url_name=topmenu`)) {
// X13 appears to have dropped the initial 'mainmenu' redirect
if !bytes.Contains(body, []byte(`url_redirect.cgi?url_name=topmenu`)) {
return closeWithError(ctx, errors.Wrap(bmclibErrs.ErrLoginFailed, "unexpected response contents"))
}
// if !bytes.Contains(body, []byte(`url_redirect.cgi?url_name=mainmenu`)) &&
// !bytes.Contains(body, []byte(`url_redirect.cgi?url_name=topmenu`)) {
// return closeWithError(ctx, errors.Wrap(bmclibErrs.ErrLoginFailed, "unexpected response contents"))
// }

contentsTopMenu, status, err := c.serviceClient.query(ctx, "cgi/url_redirect.cgi?url_name=topmenu", http.MethodGet, nil, nil, 0)
if err != nil {
Expand All @@ -193,6 +197,7 @@ func (c *Client) Open(ctx context.Context) (err error) {
c.serviceClient.setCsrfToken(csrfToken)

c.bmc, err = c.bmcQueryor(ctx)

if err != nil {
return closeWithError(ctx, errors.Wrap(bmclibErrs.ErrLoginFailed, err.Error()))
}
Expand Down Expand Up @@ -277,15 +282,36 @@ func (c *Client) ResetBiosConfiguration(ctx context.Context) (err error) {
}

func (c *Client) bmcQueryor(ctx context.Context) (bmcQueryor, error) {
x11 := newX11Client(c.serviceClient, c.log)
x12 := newX12Client(c.serviceClient, c.log)
x11bmc := newX11Client(c.serviceClient, c.log)
x12bmc := newX12Client(c.serviceClient, c.log)
x13bmc := newX13Client(c.serviceClient, c.log)

var queryor bmcQueryor

for _, bmc := range []bmcQueryor{x11, x12} {
expected := func(deviceModel string, bmc bmcQueryor) bool {
deviceModel = strings.ToLower(deviceModel)
switch bmc.(type) {
case *x11:
if strings.HasPrefix(deviceModel, "x11") {
return true
}
case *x12:
if strings.HasPrefix(deviceModel, "x12") {
return true
}
case *x13:
if strings.HasPrefix(deviceModel, "x13") {
return true
}
}

return false
}

for _, bmc := range []bmcQueryor{x11bmc, x12bmc, x13bmc} {
var err error

_, err = bmc.queryDeviceModel(ctx)
deviceModel, err := bmc.queryDeviceModel(ctx)
if err != nil {
if errors.Is(err, ErrXMLAPIUnsupported) {
continue
Expand All @@ -294,6 +320,11 @@ func (c *Client) bmcQueryor(ctx context.Context) (bmcQueryor, error) {
return nil, errors.Wrap(ErrModelUnknown, err.Error())
}

// ensure the device model matches the expected queryor
if !expected(deviceModel, bmc) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

include a bmc.Close() before the continue here to ensure we don't leave a successful connection open

continue
}

queryor = bmc
break
}
Expand All @@ -303,8 +334,8 @@ func (c *Client) bmcQueryor(ctx context.Context) (bmcQueryor, error) {
}

model := strings.ToLower(queryor.deviceModel())
if !strings.HasPrefix(model, "x12") && !strings.HasPrefix(model, "x11") {
return nil, errors.Wrap(ErrModelUnsupported, "expected one of X11* or X12*, got:"+model)
if !strings.HasPrefix(model, "x13") && !strings.HasPrefix(model, "x12") && !strings.HasPrefix(model, "x11") {
return nil, errors.Wrap(ErrModelUnsupported, "expected one of X11*, X12* or X13*, got:"+model)
}

return queryor, nil
Expand Down
2 changes: 1 addition & 1 deletion providers/supermicro/supermicro_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ func TestOpen(t *testing.T) {
<title></title>
<script language="JavaScript" type="text/javascript">
<!--
self.location = "../cgi/url_redirect.cgi?url_name=mainmenu";
self.location = "../cgi/url_redirect.cgi?url_name=topmenu";
-->
</script>
</head>
Expand Down
2 changes: 1 addition & 1 deletion providers/supermicro/x11.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (c *x11) queryDeviceModel(ctx context.Context) (string, error) {
errBoardPartNumUnknown := errors.New("baseboard part number unknown")
data, err := c.fruInfo(ctx)
if err != nil {
if strings.Contains(err.Error(), "404") {
if strings.Contains(err.Error(), "404") || strings.Contains(err.Error(), "<html>") {
return "", ErrXMLAPIUnsupported
}

Expand Down
6 changes: 5 additions & 1 deletion providers/supermicro/x12.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ func (c *x12) firmwareTaskActive(ctx context.Context, component string) error {

// noTasksRunning returns an error if a firmware related task was found active
func noTasksRunning(component string, t *redfish.Task) error {
if t.TaskState == "Killed" {
return nil
}

errTaskActive := errors.New("A firmware task was found active for component: " + component)

const (
Expand Down Expand Up @@ -222,7 +226,7 @@ func (c *x12) biosFwInstallParams() (map[string]bool, error) {
}, nil
default:
// ideally we never get in this position, since theres model number validation in parent callers.
return nil, errors.New("unsupported model for BIOS fw install: " + c.model)
return nil, errors.New("unsupported model for x12 BIOS fw install: " + c.model)
}
}

Expand Down
Loading
Loading