Skip to content

Instantly share code, notes, and snippets.

@Civil
Last active February 5, 2025 18:32
Show Gist options
  • Save Civil/62dc563ac82f912a84b6a21f3f0c102e to your computer and use it in GitHub Desktop.
Save Civil/62dc563ac82f912a84b6a21f3f0c102e to your computer and use it in GitHub Desktop.
Bluefield-2 BMC firmware update script from old ones to 24.10
#!/bin/bash
# SPDX-License-Identifier: Apache-2.0
# NOTE: This script was tested only on bluefield-2, running it on any other bluefield devices might brick them
BMC_HOST="<your bmc host goes here>"
USERNAME="root"
PASSWORD="<put password here>"
declare -A bmcver2obmc
declare -A bmcver2file
declare -A bmcver2url
declare -A bmcver2updatever
bmcver2updatever["2.8.2"]="23.04"
bmcver2updatever["23.04"]="23.10"
bmcver2updatever["23.10"]="24.10"
bmcver2updatever["24.10"]="latest"
bmcver2obmc["2.8.2"]="openbmctool.py"
bmcver2obmc["23.04"]="openbmctool.py"
bmcver2obmc["23.10"]="openbmctool_1.25.py"
bmcver2obmc["24.10"]="openbmctool_1.25.py"
bmcver2file["2.8.2"]="bf2-bmc-ota-2.8.2-51-opn.tar"
bmcver2file["23.04"]="bf2-bmc-ota-23.04-3-OPN.tar"
bmcver2file["23.10"]="bf2-bmc-ota-23.10-5-OPN.tar"
bmcver2file["24.10"]="bf2-bmc-ota-24.10-17-opn.tar"
bmcver2url["2.8.2"]="https://www.mellanox.com/downloads/BlueField/BMC/2.8.2-Dec-2024/bf2-bmc-ota-2.8.2-51-opn.tar"
bmcver2url["23.04"]="https://www.mellanox.com/downloads/BlueField/BMC/23.04-3-April-2023/bf2-bmc-ota-23.04-3-OPN.tar"
bmcver2url["23.10"]="https://www.mellanox.com/downloads/BlueField/BMC/23.10-1-oct-2023/bf2-bmc-ota-23.10-5-OPN.tar"
bmcver2url["24.10"]="https://www.mellanox.com/downloads/BlueField/BMC/24.10-17-Nov-2024/bf2-bmc-ota-24.10-17-opn.tar"
get_obmctool() {
obmctool="https://www.mellanox.com/downloads/BlueField/BMC/2.8.2-Oct-2022/openbmctool.py"
obmctool_1_25="https://www.mellanox.com/downloads/BlueField/BMC/23.04-3-April-2023/openbmctool_1.25.py"
cat > openbmctool.patch << EOF
--- openbmctool.py.old 2023-05-08 11:49:37.000000000 +0200
+++ openbmctool.py 2025-02-05 16:45:15.800956756 +0100
@@ -134,7 +134,7 @@
resp = mysess.post('https://'+args.host+'/login', headers=jsonHeader,json={"data":[args.user,args.PW]},verify=False)
if resp.status_code == 200:
cookie = resp.headers['Set-Cookie']
- match = re.search('SESSION=(\w+);', cookie)
+ match = re.search(r'SESSION=(\w+);', cookie)
return match.group(1)
@@ -366,7 +366,7 @@
@return list containing the broken up string parts by integers and strings
"""
stringPartList = []
- for c in re.split('(\d+)', text):
+ for c in re.split(r'(\d+)', text):
stringPartList.append(stringToInt(c))
return stringPartList
@@ -741,7 +741,7 @@
r = mysess.post('https://'+host+'/login', headers=jsonHeader, json = {"data": [username, pw]}, verify=False, timeout=baseTimeout)
if r.status_code == 200:
cookie = r.headers['Set-Cookie']
- match = re.search('SESSION=(\w+);', cookie)
+ match = re.search(r'SESSION=(\w+);', cookie)
if match:
xAuthHeader['X-Auth-Token'] = match.group(1)
jsonHeader.update(xAuthHeader)
EOF
sed -i.orig 's/openbmctool\.py/openbmctool_1.25.py/g' openbmctool.patch
if [[ ! -f openbmctool.py ]]; then
wget "${obmctool}"
patch -p0 < openbmctool.patch.orig
fi
if [[ ! -f openbmctool_1.25.py ]]; then
wget "${obmctool_1_25}"
patch -p0 < openbmctool.patch
fi
rm -f openbmctool.patch{,.orig}
}
check_obmctool() {
python3 -mscp -mrequests -mjson -murllib3 ''
if [[ $? -ne 0 ]]; then
echo "Dependencies for openbmc script are missing. Please install them and try again"
exit 1
fi
}
check_version() {
OUTPUT=$(./openbmctool_1.25.py -H ${BMC_HOST} -U ${USERNAME} -P ${PASSWORD} firmware running_version 2>/dev/null | grep Running)
if [[ -z "${OUTPUT}" ]]; then
OUTPUT=$(curl -k -u root:${PASSWORD} -H 'Content-Type: application/json' -X GET "https://${BMC_HOST}/redfish/v1/Managers/Bluefield_BMC/" 2>/dev/null)
fi
grep "FirmwareVersion" <<< ${OUTPUT}
}
wait_for_update() {
PREV=0
TASK_ID="${1}"
while :; do
OUTPUT=$(python3 ./openbmctool.py -H ${BMC_HOST} -U ${USERNAME} -P ${PASSWORD} task status -i ${TASK_ID} 2>/dev/null)
TASK_PROGRESS=$(echo "${OUTPUT}" | grep TaskProgress | cut -d '"' -f 2)
if [[ "${TASK_PROGRESS}" == "Not available" ]]; then
echo "Failed to update BMC..."
return 1
fi
if [[ "${TASK_PROGRESS}" == "100" ]]; then
echo "Update complete"
return 0
fi
if [[ "${TASK_PROGRESS}" -ne "${PREV}" ]]; then
echo "progress: ${TASK_PROGRESS}% complete"
PREV="${TASK_PROGRESS}"
fi
sleep 10
done
}
restart_bmc() {
OUTPUT=$(python3 ./openbmctool_1.25.py -H ${BMC_HOST} -U ${USERNAME} -P ${PASSWORD} bmc reset warm 2>/dev/null)
timeout=900
while :; do
if [[ ${timeout} -le 0 ]]; then
echo "BMC doesn't respond after 900s, something went wrong"
return 1
fi
VER=$(check_version)
if [[ ! -z ${VER} ]]; then
echo "${VER}"
return 0
fi
timeout=$((timeout-10))
sleep 10
done
}
update_fw() {
firmware_version=${1}
obmc=${bmcver2obmc["${firmware_version}"]}
fw_file=${bmcver2file["${firmware_version}"]}
if [[ ! -f ${fw_file} ]]; then
url=${bmcver2url["${firmware_version}"]}
OUTPUT=$(wget "${url}" 2>&1)
if [[ $? -ne 0 ]]; then
echo "Failed to download ${url}:"
echo "${OUTPUT}"
return 1
fi
fi
OUTPUT=$(./${obmc} -H ${BMC_HOST} -U ${USERNAME} -P ${PASSWORD} firmware flash bmc -f "$(pwd)/${fw_file}")
TASK_ID=$(echo "${OUTPUT}" | grep "activation task" | grep -o 'id="[0-9]\+"' | cut -d '"' -f 2)
wait_for_update ${TASK_ID}
if [[ $? -ne 0 ]]; then
echo "Failed to update firmware"
return 2
fi
restart_bmc
rm -f "${fw_file}"
}
get_obmctool
check_obmctool
while :; do
VER=$(check_version | grep -E -i -o 'bf-[0-9.]+' | cut -d '-' -f 2)
echo "Running on ${VER}"
update2ver=""
if [[ ! -z ${VER} ]]; then
update2ver=${bmcver2updatever[${VER}]}
if [[ -z ${update2ver} ]]; then
major=$(cut -d. -f 1 <<< ${VER})
minor=$(cut -d. -f 2 <<< ${VER})
case ${major} in
2)
update2ver=2.8.2
;;
22)
update2ver=23.04
;;
23)
case ${minor} in
0[0-3])
update2ver=23.04
;;
0[4-9])
update2ver=23.10
;;
*)
update2ver=24.10
;;
esac
;;
24)
update2ver=24.10
;;
*)
echo "Unsuported version to update: ${VER}"
exit 1
;;
esac
fi
fi
case ${update2ver} in
"")
echo "Updating to 2.8.2"
update2ver=2.8.2
exit 1
;;
"latest")
echo "Nothing to update"
exit 0
;;
esac
update_fw ${update2ver}
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment