]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-cm-ansible.git/commitdiff
testnode: add Micron NVMe firmware update task 856/head
authorAdam Kraitman <akraitma@redhat.com>
Thu, 9 Jul 2026 12:10:55 +0000 (15:10 +0300)
committerAdam Kraitman <akraitma@redhat.com>
Tue, 14 Jul 2026 12:02:36 +0000 (15:02 +0300)
roles/testnode/defaults/main.yml
roles/testnode/tasks/check-micron-nvme-firmware.yml [new file with mode: 0644]
roles/testnode/tasks/main.yml
roles/testnode/tasks/micron_nvme_firmware.yml [new file with mode: 0644]
roles/testnode/vars/centos_9_stream.yml
roles/testnode/vars/redhat_9.yml
roles/testnode/vars/rocky_10.yml
roles/testnode/vars/rocky_9.yml
roles/testnode/vars/ubuntu.yml

index fb2e34c0c23e2493b742c2112a9705b18d4a91e5..e649d695bb235806041a9f7b2c99bbe5df892dc4 100644 (file)
@@ -68,6 +68,11 @@ ntp_servers:
 # Set to true in group_vars if the testnode/machine type should have an NVMe device
 check_for_nvme: false
 
+# Micron NVMe firmware update settings
+micron_nvme_firmware_base_url: "https://{{ mirror_host }}/lab-extras/micron-nvme-firmware"
+micron_nvme_firmware_workdir: "/tmp/micron-nvme-firmware"
+micron_nvme_firmware_slot: 2
+
 # packages to install via pip
 pip_packages_to_install: []
 
diff --git a/roles/testnode/tasks/check-micron-nvme-firmware.yml b/roles/testnode/tasks/check-micron-nvme-firmware.yml
new file mode 100644 (file)
index 0000000..7defda1
--- /dev/null
@@ -0,0 +1,48 @@
+---
+- name: Check if Micron NVMe firmware update is needed
+  shell: |
+    set +e
+
+    BASE_URL="{{ micron_nvme_firmware_base_url }}"
+
+    for dev in /dev/nvme[0-9]; do
+      [ -e "$dev" ] || continue
+
+      id_ctrl="$(nvme id-ctrl "$dev" 2>/dev/null)"
+      [ "$?" -eq 0 ] || continue
+
+      model="$(echo "$id_ctrl" | sed -n 's/^mn[[:space:]]*:[[:space:]]*//p' | head -n1 | xargs)"
+      current_fw="$(echo "$id_ctrl" | sed -n 's/^fr[[:space:]]*:[[:space:]]*//p' | head -n1 | xargs)"
+      subnqn="$(echo "$id_ctrl" | sed -n 's/^subnqn[[:space:]]*:[[:space:]]*//p' | head -n1 | xargs)"
+
+      echo "$model $subnqn" | grep -qi micron || continue
+
+      case "$model" in
+        *Micron_7450*) family="7450" ;;
+        *MTFDKCC1T9TGP*) family="7500" ;;
+        *) continue ;;
+      esac
+
+      latest_fw="$(curl -k -fsSL "$BASE_URL/$family/" 2>/dev/null | \
+        sed -n 's/.*href="\([^"?/][^"?]*\)\/".*/\1/p' | \
+        grep -v '^\.\.$' | sort -V | tail -n1)"
+
+      if [ -z "$latest_fw" ]; then
+        echo "WARN: could not determine latest firmware for $family"
+        continue
+      fi
+
+      echo "$dev model=$model current=$current_fw latest=$latest_fw"
+
+      if [ "$current_fw" != "$latest_fw" ]; then
+        echo "UPDATE_NEEDED: $dev $current_fw -> $latest_fw"
+      fi
+    done
+
+    exit 0
+  args:
+    executable: /bin/bash
+  register: micron_nvme_firmware_check
+  changed_when: false
+  failed_when: false
+  ignore_errors: true
index 703db5aef06ac56e25d9e44adfe5cfef00798f33..1b73716eb401dbbd992df1c68158388608451579 100644 (file)
 - import_tasks: check-for-nvme.yml
   when: check_for_nvme == true
 
+- import_tasks: check-micron-nvme-firmware.yml
+
+- import_tasks: micron_nvme_firmware.yml
+  when:
+    - micron_nvme_firmware_check is defined
+    - micron_nvme_firmware_check.stdout is search("UPDATE_NEEDED:")
+
 - import_tasks: zap_disks.yml
   tags:
     - zap
diff --git a/roles/testnode/tasks/micron_nvme_firmware.yml b/roles/testnode/tasks/micron_nvme_firmware.yml
new file mode 100644 (file)
index 0000000..9e3575c
--- /dev/null
@@ -0,0 +1,205 @@
+---
+- name: Create Micron NVMe firmware workdir
+  file:
+    path: "{{ micron_nvme_firmware_workdir }}"
+    state: directory
+    owner: root
+    group: root
+    mode: "0755"
+  ignore_errors: true
+  failed_when: false
+
+- name: Discover and update Micron NVMe firmware
+  shell: |
+    set +e
+
+    BASE_URL="{{ micron_nvme_firmware_base_url }}"
+    WORKDIR="{{ micron_nvme_firmware_workdir }}"
+    SLOT="{{ micron_nvme_firmware_slot | default(2) }}"
+
+    mkdir -p "$WORKDIR"
+
+    echo "Micron NVMe firmware base URL: $BASE_URL"
+    echo "Micron NVMe firmware workdir: $WORKDIR"
+
+    nvme_help="$(nvme help 2>&1)"
+
+    if echo "$nvme_help" | grep -q "fw-commit"; then
+      NVME_COMMIT_CMD="fw-commit"
+    elif echo "$nvme_help" | grep -q "fw-activate"; then
+      NVME_COMMIT_CMD="fw-activate"
+    else
+      NVME_COMMIT_CMD=""
+    fi
+
+    echo "NVMe firmware activation command: ${NVME_COMMIT_CMD:-none}"
+
+    for dev in /dev/nvme[0-9]; do
+      [ -e "$dev" ] || continue
+
+      echo
+      echo "===== Checking $dev ====="
+
+      id_ctrl="$(nvme id-ctrl "$dev" 2>&1)"
+      if [ "$?" -ne 0 ]; then
+        echo "WARN: failed to read controller info for $dev"
+        echo "$id_ctrl"
+        continue
+      fi
+
+      model="$(echo "$id_ctrl" | sed -n 's/^mn[[:space:]]*:[[:space:]]*//p' | head -n1 | xargs)"
+      current_fw="$(echo "$id_ctrl" | sed -n 's/^fr[[:space:]]*:[[:space:]]*//p' | head -n1 | xargs)"
+      serial="$(echo "$id_ctrl" | sed -n 's/^sn[[:space:]]*:[[:space:]]*//p' | head -n1 | xargs)"
+      subnqn="$(echo "$id_ctrl" | sed -n 's/^subnqn[[:space:]]*:[[:space:]]*//p' | head -n1 | xargs)"
+
+      echo "Device: $dev"
+      echo "Serial: $serial"
+      echo "Model: $model"
+      echo "Current firmware: $current_fw"
+      echo "SubNQN: $subnqn"
+
+      echo "$model $subnqn" | grep -qi micron
+      if [ "$?" -ne 0 ]; then
+        echo "SKIP: $dev is not detected as Micron"
+        continue
+      fi
+
+      case "$model" in
+        *Micron_7450*)
+          family="7450"
+          firmware_file="Micron_7450_E2MU300_release.ubi"
+          ;;
+        *MTFDKCC1T9TGP*)
+          family="7500"
+          firmware_file="Micron_7500_E3MQ005_release.ubi"
+          ;;
+        *)
+          echo "SKIP: unsupported Micron model: $model"
+          continue
+          ;;
+      esac
+
+      target_fw="$(curl -k -fsSL "$BASE_URL/$family/" 2>/dev/null | \
+        sed -n 's/.*href="\([^"?/][^"?]*\)\/".*/\1/p' | \
+        grep -v '^\.\.$' | sort -V | tail -n1)"
+
+      if [ -z "$target_fw" ]; then
+        echo "WARN: could not determine latest firmware for $family"
+        continue
+      fi
+
+      firmware_url="$BASE_URL/$family/$target_fw/$firmware_file"
+      local_firmware="$WORKDIR/$firmware_file"
+
+      echo "Detected Micron family: $family"
+      echo "Target firmware: $target_fw"
+
+      if [ "$current_fw" = "$target_fw" ]; then
+        echo "SKIP: $dev already running $target_fw"
+        continue
+      fi
+
+      echo "Checking firmware file URL: $firmware_url"
+      curl -k -fI "$firmware_url"
+      if [ "$?" -ne 0 ]; then
+        echo "WARN: firmware file is not reachable: $firmware_url"
+        continue
+      fi
+
+      echo "Downloading firmware file"
+      curl -k -fL "$firmware_url" -o "$local_firmware"
+      if [ "$?" -ne 0 ]; then
+        echo "WARN: failed to download $firmware_url"
+        continue
+      fi
+
+      target_dev="${dev}n1"
+      [ -e "$target_dev" ] || target_dev="$dev"
+
+      if [ -z "$NVME_COMMIT_CMD" ]; then
+        echo "WARN: nvme-cli supports neither fw-commit nor fw-activate"
+        continue
+      fi
+
+      echo "Updating $target_dev from $current_fw to $target_fw"
+
+      echo "Running: nvme fw-download $target_dev --fw=$local_firmware"
+      fw_download_output="$(nvme fw-download "$target_dev" --fw="$local_firmware" 2>&1)"
+      fw_download_rc=$?
+      echo "$fw_download_output"
+
+      if [ "$fw_download_rc" -ne 0 ]; then
+        echo "WARN: fw-download failed for $target_dev"
+        continue
+      fi
+
+      echo "Running: nvme $NVME_COMMIT_CMD $target_dev -s $SLOT -a 3"
+      fw_commit_output="$(nvme "$NVME_COMMIT_CMD" "$target_dev" -s "$SLOT" -a 3 2>&1)"
+      fw_commit_rc=$?
+      echo "$fw_commit_output"
+
+      if [ "$fw_commit_rc" -ne 0 ]; then
+        echo "WARN: $NVME_COMMIT_CMD failed for $target_dev"
+        continue
+      fi
+
+      echo "UPDATED: $target_dev $model $current_fw -> $target_fw"
+    done
+
+    exit 0
+  args:
+    executable: /bin/bash
+  register: micron_nvme_firmware_update
+  changed_when: "'UPDATED:' in micron_nvme_firmware_update.stdout"
+  ignore_errors: true
+  failed_when: false
+
+- name: Show Micron NVMe firmware update output
+  debug:
+    var: micron_nvme_firmware_update.stdout_lines
+  ignore_errors: true
+  failed_when: false
+
+- name: Reboot after Micron NVMe firmware update
+  reboot:
+    msg: "Rebooting after Micron NVMe firmware update"
+    reboot_timeout: 900
+  when:
+    - micron_nvme_firmware_update is defined
+    - micron_nvme_firmware_update.stdout is search("UPDATED:")
+  ignore_errors: true
+  failed_when: false
+
+- name: Refresh Ansible facts after NVMe firmware reboot
+  setup:
+  when:
+    - micron_nvme_firmware_update is defined
+    - micron_nvme_firmware_update.stdout is search("UPDATED:")
+  ignore_errors: true
+  failed_when: false
+
+- name: Verify Micron NVMe firmware after update
+  shell: |
+    set +e
+
+    for dev in /dev/nvme[0-9]; do
+      [ -e "$dev" ] || continue
+      echo
+      echo "===== $dev ====="
+      nvme id-ctrl "$dev" | egrep "sn|mn|fr|subnqn"
+      nvme fw-log "$dev"
+    done
+
+    exit 0
+  args:
+    executable: /bin/bash
+  register: micron_nvme_firmware_verify
+  changed_when: false
+  ignore_errors: true
+  failed_when: false
+
+- name: Show Micron NVMe firmware verification
+  debug:
+    var: micron_nvme_firmware_verify.stdout_lines
+  ignore_errors: true
+  failed_when: false
index 164be3209c9ce02ddf2818cd44094c480bb71129..52fbadce4166691c991c9bb0fdcb4553d285f2c8 100644 (file)
@@ -59,6 +59,10 @@ packages:
   # for test-crash.sh
   - gdb
   - iozone
+  # for nvme firmware updates
+  - nvme-cli
+  - curl
+
 
   # centos stream additions start here
   - lvm2
index 8c253880e9f9267830960d534b4cfc139b4c1d9f..7b39549cb932a68e1b4f8a4b1190cadebdf8b57d 100644 (file)
@@ -44,6 +44,10 @@ packages:
   - lvm2
   - python3-pip
   - NetworkManager-initscripts-updown
+  # for nvme firmware updates
+  - nvme-cli
+  - curl
+
 
 ceph_dependency_packages_to_remove:
   - boost-random
index ccf2f00dfe817c2e331d3ce231ca7c63ece0e3b2..c0be7e850a0f3d29adc679101cc76bec5b2b3181 100644 (file)
@@ -89,6 +89,9 @@ packages:
   - bzip2
   - bind-utils
   - iozone
+  # for nvme firmware updates
+  - nvme-cli
+  - curl
 
 epel_packages:
   - dbench
index 5dfdcbaea2b778bf65941b4e5e5c908fadcd136b..38824310430e22aef75289be117bc587d6a1d551 100644 (file)
@@ -67,6 +67,10 @@ packages:
   # for test-crash.sh
   - gdb
   - iozone
+  # for nvme firmware updates
+  - nvme-cli
+  - curl
+
 
 epel_packages:
   - dbench
index 36ee10aa1fe08cafd9729dfe9a2561908f8afcd5..5732de5f25eea19f7a1edbddf4b174832c1e89d0 100644 (file)
@@ -77,6 +77,9 @@ common_packages:
   - software-properties-common
   # for https://twitter.com/letsencrypt/status/1443621997288767491
   - libgnutls30
+  # for nvme firmware updates
+  - nvme-cli
+  - curl
 
 non_aarch64_common_packages:
   - smbios-utils