pldm: pldm-scripts: Ignore persistent objects

Changes related to b/465550214 now expose the CX8 firmware versions as
DBus objects under /xyz/openbmc_project/software/CX8_[0-3]. These
objects are incorrectly identified by pldm_update_fw.sh as zombie
bundles from a previous update, and it attempts to remove them even
though they have no Delete method and should be persistent.

This change adjusts the script to to ignore any persistent software
object that does not have a Delete method.

Tested: https://paste.googleplex.com/5339989215936512
Fusion-Link: fusion2,n/a
Platforms-Affected: platform31
Google-Bug-Id: 495924038
Change-Id: I8dc11ecc93cd282045288e7899c287d76215fde8
diff --git a/recipes-google/pldmd/pldm-scripts/pldm_update_fw.sh b/recipes-google/pldmd/pldm-scripts/pldm_update_fw.sh
index 14ffc7a..8e660f9 100644
--- a/recipes-google/pldmd/pldm-scripts/pldm_update_fw.sh
+++ b/recipes-google/pldmd/pldm-scripts/pldm_update_fw.sh
@@ -85,12 +85,17 @@
     fi
 
     # Remove any existing, unactivated software objects.
-    echo "Searching for and removing remaining software objects..."
+    echo "Searching for remaining software objects..."
     local -a remaining_objects
-    # Use readarray with process substitution to safely capture busctl output,
-    # handling potential newlines in object paths.
+    # Query ObjectMapper for objects under the software path that implement Object.Delete.
+    # Filter to only PLDM bus ojects.
     readarray -t remaining_objects < <( \
-      busctl tree --list "${PLDM_BUS}" | grep -F "${SOFTWARE_PATH_PREFIX}"
+      busctl call xyz.openbmc_project.ObjectMapper \
+        /xyz/openbmc_project/object_mapper \
+        xyz.openbmc_project.ObjectMapper \
+        GetSubTree sias \
+        "${SOFTWARE_PATH_PREFIX}" 0 1 "xyz.openbmc_project.Object.Delete" \
+        -j | jq -r --arg BUS "$PLDM_BUS" '.data[0] | to_entries[] | select(.value | has($BUS)) | .key' 2>/dev/null
     )
 
     if (( ${#remaining_objects[@]} > 0 )); then
@@ -139,9 +144,17 @@
       sleep "${delay}"
       total_wait_s=$((total_wait_s + delay)) # Track total time elapsed
 
-      # Get the newly created object path. We assume only one new object.
+      # Get the newly created object path.
+      # Filter for objects that actually have the Activation interface to avoid picking up persistent objects.
       software_object=$(
-        busctl tree --list "${PLDM_BUS}" | grep -F "${SOFTWARE_PATH_PREFIX}"
+        busctl tree --list "${PLDM_BUS}" | grep -F "${SOFTWARE_PATH_PREFIX}" |
+               while read -r obj; do
+          if busctl introspect "${PLDM_BUS}" "$obj" 2>/dev/null |
+                    grep -q "xyz.openbmc_project.Software.Activation"; then
+             echo "$obj"
+             break
+          fi
+        done | head -n 1
       )
 
       if [[ -n "${software_object}" ]]; then
@@ -234,8 +247,11 @@
     echo "------------------------------------"
 
     echo "--- Clean up ${software_object} ---"
-    busctl call "${PLDM_BUS}" "${software_object}" \
-      xyz.openbmc_project.Object.Delete Delete
+    # Ensure it has the Delete interface before cleaning up, just in case
+    if busctl introspect "${PLDM_BUS}" "${software_object}" 2>/dev/null |
+              grep -q "xyz.openbmc_project.Object.Delete"; then
+       busctl call "${PLDM_BUS}" "${software_object}" xyz.openbmc_project.Object.Delete Delete
+    fi
 
     if [[ "${activation_success}" == true ]]; then
       echo "SUCCESS: PLDM firmware update for ${fw_bundle_path} completed successfully."