From 27bf2091135e4e0f2650e325378a69916b795a31 Mon Sep 17 00:00:00 2001
From: Vanou Ishii <ishii.vanou@fujitsu.com>
Date: Sun, 14 May 2023 16:37:53 -0400
Subject: [PATCH] [iRMC] Fix IPMI incompatibility handling error

This patch deals with overlooked situation in patch
d23f72ee501a5bdcc89806eb0ebbba929a36e64d, in which
`irmc_ipmi_succeed` flag is added to deal with iRMC
firmware's IPMI incompatibility introduced at iRMC
firmware version S6 2.00 and later.
That flag is set and updated by `irmc` power_interface
code and rest of iRMC driver code use that flag.

When `ipmitool` is set as power_interface, that flag
is not set nor updated and rest of iRMC driver code
fail to handle IPMI incompatibility correctly.

This patch adds logic to check power_interface to
make iRMC driver properly deal with iRMC firmware's IPMI
incompatibility even when `ipmitool` power_interface
is used.

Change-Id: Id353c4f5260a7c469779b50ad302f442223df5a0
---
 ironic/drivers/modules/irmc/inspect.py         |  3 ++-
 ironic/drivers/modules/irmc/management.py      | 18 ++++++++++++------
 ...ility-patch-situation-c246d2b59b2e8a78.yaml |  8 ++++++++
 3 files changed, 22 insertions(+), 7 deletions(-)
 create mode 100644 releasenotes/notes/fix-overlooked-irmc-ipmi-incompatibility-patch-situation-c246d2b59b2e8a78.yaml

diff --git a/ironic/drivers/modules/irmc/inspect.py b/ironic/drivers/modules/irmc/inspect.py
index 64708ff9b2..3d4f2cb7d4 100644
--- a/ironic/drivers/modules/irmc/inspect.py
+++ b/ironic/drivers/modules/irmc/inspect.py
@@ -197,7 +197,8 @@ def _inspect_hardware(node, existing_traits=None, **kwargs):
         props = irmc.scci.get_essential_properties(
             report, IRMCInspect.ESSENTIAL_PROPERTIES)
         d_info = irmc_common.parse_driver_info(node)
-        if node.driver_internal_info.get('irmc_ipmi_succeed'):
+        if (getattr(node, 'power_interface') == 'ipmitool'
+            or node.driver_internal_info.get('irmc_ipmi_succeed')):
             capabilities = irmc.scci.get_capabilities_properties(
                 d_info,
                 capabilities_props,
diff --git a/ironic/drivers/modules/irmc/management.py b/ironic/drivers/modules/irmc/management.py
index cf146f2cd8..69f9aea7be 100644
--- a/ironic/drivers/modules/irmc/management.py
+++ b/ironic/drivers/modules/irmc/management.py
@@ -226,7 +226,8 @@ class IRMCManagement(ipmitool.IPMIManagement,
         :raises: InvalidParameterValue if required parameters are invalid.
         :raises: MissingParameterValue if a required parameter is missing.
         """
-        if task.node.driver_internal_info.get('irmc_ipmi_succeed'):
+        if (getattr(task.node, 'power_interface') == 'ipmitool'
+            or task.node.driver_internal_info.get('irmc_ipmi_succeed')):
             irmc_common.parse_driver_info(task.node)
             irmc_common.update_ipmi_properties(task)
             super(IRMCManagement, self).validate(task)
@@ -245,7 +246,8 @@ class IRMCManagement(ipmitool.IPMIManagement,
                   in :mod:`ironic.common.boot_devices`.
 
         """
-        if task.node.driver_internal_info.get('irmc_ipmi_succeed'):
+        if (getattr(task.node, 'power_interface') == 'ipmitool'
+            or task.node.driver_internal_info.get('irmc_ipmi_succeed')):
             return super(IRMCManagement, self).get_supported_boot_devices(task)
         else:
             return super(ipmitool.IPMIManagement,
@@ -271,7 +273,8 @@ class IRMCManagement(ipmitool.IPMIManagement,
         :raises: RedfishConnectionError on Redfish operation failure.
         :raises: RedfishError on Redfish operation failure.
         """
-        if task.node.driver_internal_info.get('irmc_ipmi_succeed'):
+        if (getattr(task.node, 'power_interface') == 'ipmitool'
+            or task.node.driver_internal_info.get('irmc_ipmi_succeed')):
             if device not in self.get_supported_boot_devices(task):
                 raise exception.InvalidParameterValue(_(
                     "Invalid boot device %s specified.") % device)
@@ -331,7 +334,8 @@ class IRMCManagement(ipmitool.IPMIManagement,
             :persistent: Whether the boot device will persist to all
                 future boots or not, None if it is unknown.
         """
-        if task.node.driver_internal_info.get('irmc_ipmi_succeed'):
+        if (getattr(task.node, 'power_interface') == 'ipmitool'
+            or task.node.driver_internal_info.get('irmc_ipmi_succeed')):
             return super(IRMCManagement, self).get_boot_device(task)
         else:
             return super(
@@ -426,7 +430,8 @@ class IRMCManagement(ipmitool.IPMIManagement,
         if sensor_method == 'scci':
             return _get_sensors_data(task)
         elif sensor_method == 'ipmitool':
-            if task.node.driver_internal_info.get('irmc_ipmi_succeed'):
+            if (getattr(task.node, 'power_interface') == 'ipmitool'
+                or task.node.driver_internal_info.get('irmc_ipmi_succeed')):
                 return super(IRMCManagement, self).get_sensors_data(task)
             else:
                 raise exception.InvalidParameterValue(_(
@@ -567,7 +572,8 @@ class IRMCManagement(ipmitool.IPMIManagement,
         :returns: String representing the BMC reported Vendor or
                   Manufacturer, otherwise returns None.
         """
-        if task.node.driver_internal_info.get('irmc_ipmi_succeed'):
+        if (getattr(task.node, 'power_interface') == 'ipmitool'
+            or task.node.driver_internal_info.get('irmc_ipmi_succeed')):
             return super(IRMCManagement, self).detect_vendor(task)
         else:
             return super(ipmitool.IPMIManagement, self).detect_vendor(task)
diff --git a/releasenotes/notes/fix-overlooked-irmc-ipmi-incompatibility-patch-situation-c246d2b59b2e8a78.yaml b/releasenotes/notes/fix-overlooked-irmc-ipmi-incompatibility-patch-situation-c246d2b59b2e8a78.yaml
new file mode 100644
index 0000000000..082814707b
--- /dev/null
+++ b/releasenotes/notes/fix-overlooked-irmc-ipmi-incompatibility-patch-situation-c246d2b59b2e8a78.yaml
@@ -0,0 +1,8 @@
+---
+fixes:
+  - |
+    Fixes bug in iRMC driver, where `irmc` power_interface sets and updates
+    `irmc_ipmi_succeed` flag which is used by rest of iRMC driver code to deal
+    with iRMC firmware's IPMI incompatibility but `ipmitool` power_interface
+    doesn't set nor update `irmc_ipmi_succeed` flag and rest of iRMC driver
+    code fail to handle iRMC firmware's IPMI incompatibility correctly.