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