Posted on 

update BIOS attr by redfish

这个 post 来自于早起为开发裸金属管理平台和的核心组建之一的 bmc-server. bmc-server 允许以 RESTful API 的形式去操作物理机的带外管理。

其中有个关键功能就是支持用户修改机器的 BISO 的熟悉,其 POC 如下:

DELL 厂商案例

bios set request, 其中用户名密码就是厂商的默认配置。

1
2
redfishtool -u root -p calvin -r 192.168.156.16 raw PATCH /redfish/v1/Systems/System.Embedded.1/Bios/Settings -d  '{"Attributes":{"SysProfile":"PerfPerWattOptimizedOs","ProcPwrPerf":"OsDbpm","ProcTurboMode":"Enabled","MonitorMwait":"Enabled"},"@Redfish.SettingsApplyTime":{"ApplyTime":"OnReset"}}'
redfishtool -u root -p calvin -r 192.168.156.16 raw POST /redfish/v1/Systems/System.Embedded.1/Actions/ComputerSystem.Reset -d '{"ResetType":"PowerCycle"}'

上面这个redfishtool等价于下面的 curl 指令。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
curl -X PATCH -k -v -H "Authorization: Basic cm9vdDpjYWx2aW4=" -H "Accept: application/json" -H "Content-Type: application/json"  https://192.168.156.16/redfish/v1/Systems/System.Embedded.1/Bios/Settings -d '{"Attributes":{"SysProfile":"PerfPerWattOptimizedOs","ProcPwrPerf":"OsDbpm","ProcTurboMode":"Enabled","MonitorMwait":"Enabled"}}'
whoami: cannot find name for user ID 1007
* Trying 192.168.156.16:443...
* TCP_NODELAY set
* Connected to 192.168.156.16 (192.168.156.16) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: C=US; ST=Texas; L=Round Rock; O=Dell Inc.; OU=Remote Access Group; CN=idrac-SVCTAG; emailAddress=support@dell.com
* start date: Oct 20 17:43:00 2021 GMT
* expire date: Oct 21 17:43:00 2031 GMT
* issuer: C=US; ST=Texas; L=Round Rock; O=Dell Inc.; OU=Remote Access Group; CN=idrac-SVCTAG; emailAddress=support@dell.com
* SSL certificate verify result: self signed certificate (18), continuing anyway.
> PATCH /redfish/v1/Systems/System.Embedded.1/Bios/Settings HTTP/1.1
> Host: 192.168.156.16
> User-Agent: curl/7.68.0
> Authorization: Basic cm9vdDpjYWx2aW4=
> Accept: application/json
> Content-Type: application/json
> Content-Length: 128
>
* upload completely sent off: 128 out of 128 bytes
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Thu, 28 Apr 2022 19:51:52 GMT
< Server: Apache
< OData-Version: 4.0
< Access-Control-Allow-Origin: *
< Cache-Control: no-cache
< X-Frame-Options: DENY
< Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
< Content-Length: 1579
< Vary: Accept-Encoding
< Content-Type: application/json;odata.metadata=minimal;charset=utf-8
<
{"error":{"@Message.ExtendedInfo":[{"Message":"Unable to modify the attribute because the attribute is read-only and depends on other attributes.","MessageArgs":["MonitorMwait"],"MessageArgs@odata.count":1,"MessageId":"IDRAC.2.4.SYS410","RelatedProperties":["#/Attributes/MonitorMwait"],"RelatedProperties@odata.count":1,"Resolution":"Verify if the attribute has dependency on other attributes and retry the operation. To verify, view the attribute registry based on the type of resource.","Severity":"Warning"},{"Message":"Unable to modify the attribute because the attribute is read-only and depends on other attributes.","MessageArgs":["ProcPwrPerf"],"MessageArgs@odata.count":1,"MessageId":"IDRAC.2.4.SYS410","RelatedProperties":["#/Attributes/ProcPwrPerf"],"RelatedProperties@odata.count":1,"Resolution":"Verify if the attribute has dependency on other attributes and retry the operation. To verify, view the attribute registry based on the type of resource.","Severity":"Warning"},{"Message":"Unable to modify the attr* Connection #0 to host 192.168.156.16 left intact
ibute because the attribute is read-only and depends on other attributes.","MessageArgs":["ProcTurboMode"],"MessageArgs@odata.count":1,"MessageId":"IDRAC.2.4.SYS410","RelatedProperties":["#/Attributes/ProcTurboMode"],"RelatedProperties@odata.count":1,"Resolution":"Verify if the attribute has dependency on other attributes and retry the operation. To verify, view the attribute registry based on the type of resource.","Severity":"Warning"}],"code":"Base.1.7.GeneralError","message":"A general error has occurred. See ExtendedInfo for more information"}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
curl -k -v -H "Authorization: Basic cm9vdDpjYWx2aW4=" -H "Accept: application/json" -H "Content-Type: application/json"  https://192.168.156.16/redfish/v1/Systems/System.Embedded.1/Bios/Settings
whoami: cannot find name for user ID 1007
* Trying 192.168.156.16:443...
* TCP_NODELAY set
* Connected to 192.168.156.16 (192.168.156.16) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: C=US; ST=Texas; L=Round Rock; O=Dell Inc.; OU=Remote Access Group; CN=idrac-SVCTAG; emailAddress=support@dell.com
* start date: Oct 20 17:43:00 2021 GMT
* expire date: Oct 21 17:43:00 2031 GMT
* issuer: C=US; ST=Texas; L=Round Rock; O=Dell Inc.; OU=Remote Access Group; CN=idrac-SVCTAG; emailAddress=support@dell.com
* SSL certificate verify result: self signed certificate (18), continuing anyway.
> GET /redfish/v1/Systems/System.Embedded.1/Bios/Settings HTTP/1.1
> Host: 192.168.156.16
> User-Agent: curl/7.68.0
> Authorization: Basic cm9vdDpjYWx2aW4=
> Accept: application/json
> Content-Type: application/json
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Thu, 28 Apr 2022 19:48:10 GMT
< Server: Apache
< Link: </redfish/v1/Schemas/Bios.v1_1_0.json>;rel=describedby
< Allow: GET,HEAD,PATCH
< OData-Version: 4.0
< Cache-Control: no-cache
< X-Frame-Options: DENY
< Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
< Content-Length: 760
< Vary: Accept-Encoding
< Content-Type: application/json;odata.metadata=minimal;charset=utf-8
<
* Connection #0 to host 192.168.156.16 left intact
{"@odata.context":"/redfish/v1/$metadata#Bios.Bios","@odata.id":"/redfish/v1/Systems/System.Embedded.1/Bios/Settings","@odata.type":"#Bios.v1_1_0.Bios","Id":"Settings","Name":"BIOS Configuration Pending Settings","Description":"BIOS Configuration Pending Settings. These settings will be applied on next system reboot.","AttributeRegistry":"BiosAttributeRegistry.v1_0_3","Attributes":{},"Actions":{"Oem":{"DellManager.v1_0_0#DellManager.ClearPending":{"target":"/redfish/v1/Systems/System.Embedded.1/Bios/Settings/Actions/Oem/DellManager.ClearPending"}}},"Oem":{"Dell":{"@odata.context":"/redfish/v1/$metadata#DellManager.DellManager","@odata.type":"#DellManager.v1_1_0.DellManager","Jobs":{"@odata.id":"/redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/Jobs"}}}}

对应的 golang 的关键代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
func (m *Manufacture) SetBIOSAttribute(attrs map[string]any) error {
_, err := m.Machine.Do(http.MethodPatch, "/redfish/v1/Systems/System.Embedded.1/Bios/Settings", http.Header{}, map[string]any{
"Attributes": attrs,
"@Redfish.SettingsApplyTime": map[string]any{"ApplyTime": "OnReset"},
}, nil)
if err != nil {
log.Logger().Error(err.Error())
return err
}

return nil
}