xref: /openbmc/openbmc-test-automation/lib/ipmi_client.robot (revision f329f73269a3a4e50d12d1681596447e7fb3e6cd)
1*** Settings ***
2Documentation   This module is for IPMI client for copying ipmitool to
3...             openbmc box and execute ipmitool IPMI standard
4...             command. IPMI raw command will use dbus-send command
5Resource        ../lib/resource.txt
6Resource        ../lib/connection_client.robot
7Resource        ../lib/utils.robot
8Resource        ../lib/state_manager.robot
9
10Library         String
11Library         ipmi_client.py
12
13*** Variables ***
14${dbusHostIpmicmd1}=   dbus-send --system  ${OPENBMC_BASE_URI}HostIpmi/1
15${dbusHostIpmiCmdReceivedMsg}=   ${OPENBMC_BASE_DBUS}.HostIpmi.ReceivedMessage
16${netfnByte}=          ${EMPTY}
17${cmdByte}=            ${EMPTY}
18${arrayByte}=          array:byte:
19${IPMI_EXT_CMD}        ${EMPTY}
20${IPMI_USER_OPTIONS}   ${EMPTY}
21${IPMI_INBAND_CMD}=    ipmitool -C ${IPMI_CIPHER_LEVEL}
22${HOST}=               -H
23${RAW}=                raw
24
25*** Keywords ***
26
27Run IPMI Command
28    [Documentation]  Run the given IPMI command.
29    [Arguments]  ${args}
30    ${resp}=  Run Keyword If  '${IPMI_COMMAND}' == 'External'
31    ...  Run External IPMI Raw Command  ${args}
32    ...  ELSE IF  '${IPMI_COMMAND}' == 'Inband'
33    ...  Run Inband IPMI Raw Command  ${args}
34    ...  ELSE IF  '${IPMI_COMMAND}' == 'Dbus'
35    ...  Run Dbus IPMI RAW Command  ${args}
36    ...  ELSE  Fail  msg=Invalid IPMI Command type provided : ${IPMI_COMMAND}
37    [Return]  ${resp}
38
39Run IPMI Standard Command
40    [Documentation]  Run the standard IPMI command.
41    [Arguments]  ${args}
42    ${resp}=  Run Keyword If  '${IPMI_COMMAND}' == 'External'
43    ...  Run External IPMI Standard Command  ${args}
44    ...  ELSE IF  '${IPMI_COMMAND}' == 'Inband'
45    ...  Run Inband IPMI Standard Command  ${args}
46    ...  ELSE IF  '${IPMI_COMMAND}' == 'Dbus'
47    ...  Run Dbus IPMI Standard Command  ${args}
48    ...  ELSE  Fail  msg=Invalid IPMI Command type provided : ${IPMI_COMMAND}
49
50    [Return]  ${resp}
51
52Run Dbus IPMI RAW Command
53    [Documentation]  Run the raw IPMI command through dbus.
54    [Arguments]    ${args}
55    ${valueinBytes}=   Byte Conversion  ${args}
56    ${cmd}=   Catenate   ${dbushostipmicmd1} ${dbusHostIpmiCmdReceivedMsg}
57    ${cmd}=   Catenate   ${cmd} ${valueinBytes}
58    ${output}   ${stderr}=  Execute Command  ${cmd}  return_stderr=True
59    Should Be Empty      ${stderr}
60    set test variable    ${OUTPUT}     "${output}"
61
62Run Dbus IPMI Standard Command
63    [Documentation]  Run the standard IPMI command through dbus.
64    [Arguments]    ${args}
65    Copy ipmitool
66    ${stdout}    ${stderr}    ${output}=  Execute Command
67    ...    /tmp/ipmitool -I dbus ${args}    return_stdout=True
68    ...    return_stderr= True    return_rc=True
69    Should Be Equal    ${output}    ${0}    msg=${stderr}
70    [Return]    ${stdout}
71
72Run Inband IPMI Raw Command
73    [Documentation]  Run the raw IPMI command in-band.
74    [Arguments]  ${args}  ${os_host}=${OS_HOST}  ${os_username}=${OS_USERNAME}
75    ...          ${os_password}=${OS_PASSWORD}
76
77    # Description of arguments:
78    # ${args}  parameters to IPMI command.
79    # ${os_host} IP address of the OS Host.
80    # ${os_username}  OS Host Login user name.
81    # ${os_password}  OS Host Login passwrd.
82
83    Login To OS Host  ${os_host}  ${os_username}  ${os_password}
84    Check If IPMI Tool Exist
85
86    ${inband_raw_cmd}=  Catenate  ${IPMI_INBAND_CMD}  ${RAW}  ${args}
87    ${stdout}  ${stderr}=  Execute Command  ${inband_raw_cmd}  return_stderr=True
88    Should Be Empty  ${stderr}  msg=${stdout}
89    [Return]  ${stdout}
90
91Run Inband IPMI Standard Command
92    [Documentation]  Run the standard IPMI command in-band.
93    [Arguments]  ${args}  ${os_host}=${OS_HOST}  ${os_username}=${OS_USERNAME}
94    ...          ${os_password}=${OS_PASSWORD}
95
96    # Description of arguments:
97    # ${args}  parameters to IPMI command.
98    # ${os_host} IP address of the OS Host.
99    # ${os_username}  OS Host Login user name.
100    # ${os_password}  OS Host Login passwrd.
101
102    Login To OS Host  ${os_host}  ${os_username}  ${os_password}
103    Check If IPMI Tool Exist
104
105    ${inband_std_cmd}=  Catenate  ${IPMI_INBAND_CMD}  ${args}
106    ${stdout}  ${stderr}=  Execute Command  ${inband_std_cmd}  return_stderr=True
107    Should Be Empty  ${stderr}  msg=${stdout}
108    [Return]  ${stdout}
109
110Run External IPMI Raw Command
111    [Documentation]  Run the raw IPMI command externally.
112    [Arguments]    ${args}
113
114    ${ipmi_raw_cmd}=   Catenate  SEPARATOR=
115    ...    ${IPMI_EXT_CMD} -P${SPACE}${IPMI_PASSWORD}${SPACE}
116    ...    ${HOST}${SPACE}${OPENBMC_HOST}${SPACE}${RAW}${SPACE}${args}
117    ${rc}    ${output}=    Run and Return RC and Output    ${ipmi_raw_cmd}
118    Should Be Equal    ${rc}    ${0}    msg=${output}
119    [Return]    ${output}
120
121Run External IPMI Standard Command
122    [Documentation]  Run the standard IPMI command in-band.
123    [Arguments]  ${args}  ${fail_on_err}=${1}
124
125    # Description of argument(s):
126    # args         IPMI command to be executed.
127    # fail_on_err  Fail if keyword the IPMI command fails
128
129    ${ipmi_cmd}=  Catenate  SEPARATOR=
130    ...  ${IPMI_EXT_CMD} ${IPMI_USER_OPTIONS} -P${SPACE}${IPMI_PASSWORD}
131    ...  ${SPACE}${HOST}${SPACE}${OPENBMC_HOST}${SPACE}${args}
132    ${rc}  ${output}=  Run And Return RC and Output  ${ipmi_cmd}
133    Return From Keyword If  ${fail_on_err} == ${0}  ${output}
134    Should Be Equal  ${rc}  ${0}  msg=${output}
135    [Return]  ${output}
136
137Check If IPMI Tool Exist
138    [Documentation]  Check if IPMI Tool installed or not.
139    ${output}=  Execute Command  which ipmitool
140    Should Not Be Empty  ${output}  msg=ipmitool not installed.
141
142
143Activate SOL Via IPMI
144    [Documentation]  Start SOL using IPMI and route output to a file.
145    [Arguments]  ${file_path}=/tmp/sol_${OPENBMC_HOST}
146    # Description of argument(s):
147    # file_path  The file path on the local machine (vs OBMC) to collect SOL
148    #            output. By default SOL output is collected at
149    #            /tmp/sol_<BMC_IP> else user input location.
150
151    ${ipmi_cmd}=  Catenate  SEPARATOR=
152    ...  ${IPMI_EXT_CMD} -P${SPACE}${IPMI_PASSWORD}${SPACE}${HOST}
153    ...  ${SPACE}${OPENBMC_HOST}${SPACE}sol activate usesolkeepalive
154
155    Start Process  ${ipmi_cmd}  shell=True  stdout=${file_path}
156    ...  alias=sol_proc
157
158
159Deactivate SOL Via IPMI
160    [Documentation]  Stop SOL using IPMI and return SOL output.
161    [Arguments]  ${file_path}=/tmp/sol_${OPENBMC_HOST}
162    # Description of argument(s):
163    # file_path  The file path on the local machine to copy SOL output
164    #            collected by above "Activate SOL Via IPMI" keyword.
165    #            By default it copies log from /tmp/sol_<BMC_IP>.
166
167    ${ipmi_cmd}=  Catenate  SEPARATOR=
168    ...  ${IPMI_EXT_CMD} -P${SPACE}${IPMI_PASSWORD}${SPACE}
169    ...  ${HOST}${SPACE}${OPENBMC_HOST}${SPACE}sol deactivate
170
171    ${rc}  ${output}=  Run and Return RC and Output  ${ipmi_cmd}
172    Run Keyword If  ${rc} > 0  Run Keywords
173    ...  Run Keyword And Ignore Error  Terminate Process  sol_proc
174    ...  AND  Return From Keyword  ${output}
175
176    ${rc}  ${output}=  Run and Return RC and Output  cat ${file_path}
177    Should Be Equal  ${rc}  ${0}  msg=${output}
178
179    # Logging SOL output for debug purpose.
180    Log  ${output}
181
182    [Return]  ${output}
183
184
185Byte Conversion
186    [Documentation]   Byte Conversion method receives IPMI RAW commands as
187    ...               argument in string format.
188    ...               Sample argument is as follows
189    ...               "0x04 0x30 9 0x01 0x00 0x35 0x00 0x00 0x00 0x00 0x00
190    ...               0x00"
191    ...               IPMI RAW command format is as follows
192    ...               <netfn Byte> <cmd Byte> <Data Bytes..>
193    ...               This method converts IPMI command format into
194    ...               dbus command format  as follows
195    ...               <byte:seq-id> <byte:netfn> <byte:lun> <byte:cmd>
196    ...               <array:byte:data>
197    ...               Sample dbus  Host IPMI Received Message argument
198    ...               byte:0x00 byte:0x04 byte:0x00 byte:0x30
199    ...               array:byte:9,0x01,0x00,0x35,0x00,0x00,0x00,0x00,0x00,0x00
200    [Arguments]     ${args}
201    ${argLength}=   Get Length  ${args}
202    Set Global Variable  ${arrayByte}   array:byte:
203    @{listargs}=   Split String  ${args}
204    ${index}=   Set Variable   ${0}
205    :FOR  ${word}  IN  @{listargs}
206    \    Run Keyword if   ${index} == 0   Set NetFn Byte  ${word}
207    \    Run Keyword if   ${index} == 1   Set Cmd Byte    ${word}
208    \    Run Keyword if   ${index} > 1    Set Array Byte  ${word}
209    \    ${index}=    Set Variable    ${index + 1}
210    ${length}=   Get Length  ${arrayByte}
211    ${length}=   Evaluate  ${length} - 1
212    ${arrayByteLocal}=  Get Substring  ${arrayByte}  0   ${length}
213    Set Global Variable  ${arrayByte}   ${arrayByteLocal}
214    ${valueinBytesWithArray}=   Catenate  byte:0x00   ${netfnByte}  byte:0x00
215    ${valueinBytesWithArray}=   Catenate  ${valueinBytesWithArray}  ${cmdByte}
216    ${valueinBytesWithArray}=   Catenate  ${valueinBytesWithArray} ${arrayByte}
217    ${valueinBytesWithoutArray}=   Catenate  byte:0x00 ${netfnByte}  byte:0x00
218    ${valueinBytesWithoutArray}=   Catenate  ${valueinBytesWithoutArray} ${cmdByte}
219#   To Check scenario for smaller IPMI raw commands with only 2 arguments
220#   instead of usual 12 arguments.
221#   Sample small IPMI raw command: Run IPMI command 0x06 0x36
222#   If IPMI raw argument length is only 9 then return value in bytes without
223#   array population.
224#   Equivalent dbus-send argument for smaller IPMI raw command:
225#   byte:0x00 byte:0x06 byte:0x00 byte:0x36
226    Run Keyword if   ${argLength} == 9     Return from Keyword    ${valueinBytesWithoutArray}
227    [Return]    ${valueinBytesWithArray}
228
229
230Set NetFn Byte
231    [Documentation]  Set the network function byte.
232    [Arguments]    ${word}
233    ${netfnByteLocal}=  Catenate   byte:${word}
234    Set Global Variable  ${netfnByte}  ${netfnByteLocal}
235
236Set Cmd Byte
237    [Documentation]  Set the command byte.
238    [Arguments]    ${word}
239    ${cmdByteLocal}=  Catenate   byte:${word}
240    Set Global Variable  ${cmdByte}  ${cmdByteLocal}
241
242Set Array Byte
243    [Documentation]  Set the array byte.
244    [Arguments]    ${word}
245    ${arrayByteLocal}=   Catenate   SEPARATOR=  ${arrayByte}  ${word}
246    ${arrayByteLocal}=   Catenate   SEPARATOR=  ${arrayByteLocal}   ,
247    Set Global Variable  ${arrayByte}   ${arrayByteLocal}
248
249Copy ipmitool
250    [Documentation]  Copy the ipmitool to the BMC.
251    ${ipmitool_error}=  Catenate  The ipmitool program could not be found in the tools directory.
252    ...  It is not part of the automation code by default. You must manually copy or link the correct openbmc
253    ...  version of the tool in to the tools directory in order to run this test suite.
254
255    OperatingSystem.File Should Exist  tools/ipmitool  msg=${ipmitool_error}
256
257    Import Library      SCPLibrary      WITH NAME       scp
258    scp.Open connection     ${OPENBMC_HOST}     username=${OPENBMC_USERNAME}      password=${OPENBMC_PASSWORD}
259    scp.Put File    tools/ipmitool   /tmp
260    SSHLibrary.Open Connection     ${OPENBMC_HOST}
261    Login   ${OPENBMC_USERNAME}    ${OPENBMC_PASSWORD}
262    Execute Command     chmod +x /tmp/ipmitool
263
264Initiate Host Boot Via External IPMI
265    [Documentation]  Initiate host power on using external IPMI.
266    [Arguments]  ${wait}=${1}
267    # Description of argument(s):
268    # wait  Indicates that this keyword should wait for host running state.
269
270    ${output}=  Run External IPMI Standard Command  chassis power on
271    Should Not Contain  ${output}  Error
272
273    Run Keyword If  '${wait}' == '${0}'  Return From Keyword
274    Wait Until Keyword Succeeds  10 min  10 sec  Is Host Running
275
276Initiate Host PowerOff Via External IPMI
277    [Documentation]  Initiate host power off using external IPMI.
278    [Arguments]  ${wait}=${1}
279    # Description of argument(s):
280    # wait  Indicates that this keyword should wait for host off state.
281
282    ${output}=  Run External IPMI Standard Command  chassis power off
283    Should Not Contain  ${output}  Error
284
285    Run Keyword If  '${wait}' == '${0}'  Return From Keyword
286    Wait Until Keyword Succeeds  3 min  10 sec  Is Host Off
287
288Get Host State Via External IPMI
289    [Documentation]  Returns host state using external IPMI.
290
291    ${output}=  Run External IPMI Standard Command  chassis power status
292    Should Not Contain  ${output}  Error
293    ${output}=  Fetch From Right  ${output}  ${SPACE}
294
295    [Return]  ${output}
296
297
298Set BMC Network From Host
299    [Documentation]  Set BMC network from host.
300    [Arguments]  ${nw_info}
301
302    # Description of argument(s):
303    # nw_info    A dictionary containing the network information to apply.
304
305    Run Inband IPMI Standard Command
306    ...  lan set 1 ipaddr ${nw_info['IP Address']}
307
308    Run Inband IPMI Standard Command
309    ...  lan set 1 netmask ${nw_info['Subnet Mask']}
310
311    Run Inband IPMI Standard Command
312    ...  lan set 1 defgw ipaddr ${nw_info['Default Gateway IP']}
313