-
Notifications
You must be signed in to change notification settings - Fork 192
[psud] Refactor PSU object retrieval to improve exception handling #659
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
sonic-psud/scripts/psud
Outdated
| if platform_chassis is not None: | ||
| try: | ||
| return platform_chassis.get_psu(psu_index - 1) | ||
| except NotImplementedError: # TODO: Is NotImplementedError sufficient? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Log a warning for this exception and return None, Also add a general exception to make the code robust.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
sonic-psud/scripts/psud
Outdated
| def _wrapper_get_psu_presence(psu_index): | ||
| if platform_chassis is not None: | ||
| psu = _wrapper_get_psu(psu_index) | ||
| if not psu: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if psu returned is None here, add exception here to log error and returning false.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
sonic-psud/scripts/psud
Outdated
| try: | ||
| return platform_chassis.get_psu(psu_index - 1) | ||
| except NotImplementedError as e: | ||
| logger.log_warning("get_psu() not implemented by platform chassis: {}".format(str(e))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this something that needs to be logged? Also in its current form, you'll get two conflicting logs. Say you run the wrapper to get presence, this get_psu wrapper will log "get_psu() not implemented by platform chassis: {}" and return none, but now that its none the get_presence will print "Failed to get PSU {} object from platform chassis".
This also seems to deviate from the prior behavior where if the platform_chassis doesn't have the get_psu, it will fallback to the platform_psuutil case. Is it possible that some vendors have not implemented this get_psu on the platform_chassis and still rely on this fallback?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your pointing out.
sonic-psud/scripts/psud
Outdated
| psu = _wrapper_get_psu(psu_index) | ||
| if not psu: | ||
| logger.log_error("Failed to get PSU {} object from platform chassis".format(psu_index)) | ||
| return '' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
imo this should be a case where it returns the PSU_INFO_KEY_TEMPLATE, not an empty string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
/azpw run |
|
/AzurePipelines run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Signed-off-by: Lin Jin <[email protected]>
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Signed-off-by: Lin Jin <[email protected]>
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Signed-off-by: Lin Jin <[email protected]>
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Signed-off-by: Lin Jin <[email protected]>
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Signed-off-by: Lin Jin <[email protected]>
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
sonic-psud/scripts/psud
Outdated
| except Exception as e: | ||
| self.log_error("Failed to load psuutil: %s" % (str(e)), True) | ||
| sys.exit(PSUUTIL_LOAD_ERROR) | ||
| self.log_warning("Failed to load psuutil: %s" % (str(e)), True) |
Copilot
AI
Oct 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The log_warning method is being called with a second parameter True, but logger methods typically don't take a boolean parameter for console output. This could cause runtime errors if the logger doesn't support this parameter pattern.
| self.log_warning("Failed to load psuutil: %s" % (str(e)), True) | |
| self.log_warning("Failed to load psuutil: %s" % (str(e))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
Signed-off-by: Lin Jin <[email protected]>
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| def _wrapper_get_psu_presence(psu_index): | ||
| def _wrapper_get_psu(logger, psu_index): | ||
| """ | ||
| Get PSU object from platform chassis |
Copilot
AI
Oct 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docstring is missing the logger parameter description. Add ':param logger: Logger instance for error/warning messages' to document the logger parameter.
| Get PSU object from platform chassis | |
| Get PSU object from platform chassis | |
| :param logger: Logger instance for error/warning messages |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@LinJin23 Pls fix this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
sonic-psud/scripts/psud
Outdated
| self.log_error("Failed to load psuutil: %s" % (str(e)), True) | ||
| sys.exit(PSUUTIL_LOAD_ERROR) | ||
| self.log_warning("Failed to load psuutil: %s" % (str(e))) | ||
| # Don't expect the PSUD to exit just because psuutil is not available |
Copilot
AI
Oct 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a grammatical error in the comment. It should be 'Don't expect PSUD to exit' instead of 'Don't expect the PSUD to exit'.
| # Don't expect the PSUD to exit just because psuutil is not available | |
| # Don't expect PSUD to exit just because psuutil is not available |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line has been removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| return platform_psuutil.get_num_psus() | ||
| if platform_psuutil is not None: | ||
| return platform_psuutil.get_num_psus() | ||
| return 0 |
Copilot
AI
Oct 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function should maintain consistent fallback behavior. When platform_psuutil is None, returning 0 may not accurately represent the actual number of PSUs on the system. Consider returning a default value that makes sense for the platform or raising an appropriate exception.
| return 0 | |
| raise RuntimeError("Unable to determine number of PSUs: neither platform_chassis nor platform_psuutil is available") |
sonic-psud/scripts/psud
Outdated
| except NotImplementedError: | ||
| pass | ||
| if platform_psuutil is not None: | ||
| return platform_psuutil.get_psu_presence(psu_index) |
Copilot
AI
Oct 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fallback logic should handle potential exceptions from platform_psuutil.get_psu_presence(). Consider wrapping this call in a try-except block to prevent unhandled exceptions from propagating up.
| return platform_psuutil.get_psu_presence(psu_index) | |
| try: | |
| return platform_psuutil.get_psu_presence(psu_index) | |
| except Exception as e: | |
| if logger: | |
| logger.log_error("Exception in platform_psuutil.get_psu_presence({}): {}".format(psu_index, str(e))) | |
| return False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please wrap around this exception and log a warning message if it is not implemented.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
sonic-psud/scripts/psud
Outdated
| except NotImplementedError: | ||
| pass | ||
| if platform_psuutil is not None: | ||
| return platform_psuutil.get_psu_status(psu_index) |
Copilot
AI
Oct 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fallback logic should handle potential exceptions from platform_psuutil.get_psu_status(). Consider wrapping this call in a try-except block to prevent unhandled exceptions from propagating up.
| return platform_psuutil.get_psu_status(psu_index) | |
| try: | |
| return platform_psuutil.get_psu_status(psu_index) | |
| except Exception as e: | |
| if logger: | |
| logger.log_error("Exception in platform_psuutil.get_psu_status({}): {}".format(psu_index, str(e))) | |
| return False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add this exception
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done, and at the suggested line 152, I changed log_error to log_warning.
| def _wrapper_get_psu_presence(psu_index): | ||
| def _wrapper_get_psu(logger, psu_index): | ||
| """ | ||
| Get PSU object from platform chassis |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@LinJin23 Pls fix this.
sonic-psud/scripts/psud
Outdated
| except NotImplementedError as e: | ||
| if logger: | ||
| logger.log_warning("get_psu() not implemented by platform chassis: {}".format(str(e))) | ||
| return None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"return None" at line 121 is sufficient and line 116 and 120 is redundant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
| return platform_chassis.get_psu(psu_index - 1) | ||
| except NotImplementedError as e: | ||
| if logger: | ||
| logger.log_warning("get_psu() not implemented by platform chassis: {}".format(str(e))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
notice is not available, so you can leave this as warning for now.
sonic-psud/scripts/psud
Outdated
| except NotImplementedError: | ||
| pass | ||
| if platform_psuutil is not None: | ||
| return platform_psuutil.get_psu_presence(psu_index) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please wrap around this exception and log a warning message if it is not implemented.
sonic-psud/scripts/psud
Outdated
| except NotImplementedError: | ||
| pass | ||
| if platform_psuutil is not None: | ||
| return platform_psuutil.get_psu_status(psu_index) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add this exception
| return platform_psuutil.get_num_psus() | ||
| if platform_psuutil is not None: | ||
| return platform_psuutil.get_num_psus() | ||
| return 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a warning log something like, if we have to return 0
if logger:
logger.log_warning("No PSU provider available; assuming 0 PSUs")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
sonic-psud/scripts/psud
Outdated
| return None | ||
| except Exception as e: | ||
| if logger: | ||
| logger.log_warning("Failed to get PSU {} from platform chassis: {}".format(psu_index, str(e))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be an error type log
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
Signed-off-by: Lin Jin <[email protected]>
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
…dling Signed-off-by: Lin Jin <[email protected]>
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| try: | ||
| return psu.get_name() | ||
| except NotImplementedError: | ||
| pass |
Copilot
AI
Oct 23, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment explaining the IndexError exception handling was removed. This comment provided valuable context about why the exception is caught and should be preserved: 'some functionality is expectent on returning an expected key even if the psu object itself does not exist'.
| pass | |
| pass | |
| # some functionality is expectent on returning an expected key even if the psu object itself does not exist |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
sonic-psud/scripts/psud
Outdated
| platform_psuutil = self.load_platform_util(PLATFORM_SPECIFIC_MODULE_NAME, PLATFORM_SPECIFIC_CLASS_NAME) | ||
| except Exception as e: | ||
| self.log_error("Failed to load psuutil: %s" % (str(e)), True) | ||
| self.log_warning("Failed to load psuutil: %s" % (str(e))) |
Copilot
AI
Oct 23, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logging a warning message before calling sys.exit() is contradictory. If the process is going to exit with an error code (PSUUTIL_LOAD_ERROR), this should remain as log_error(). Alternatively, if platform_psuutil being unavailable is truly non-fatal as the PR description suggests, the sys.exit() call should be removed.
| self.log_warning("Failed to load psuutil: %s" % (str(e))) | |
| self.log_error("Failed to load psuutil: %s" % (str(e))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done, revert to original logic
Signed-off-by: Lin Jin <[email protected]>
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| Get PSU object from platform chassis | ||
| :param logger: Logger instance for error/warning messages | ||
| :param psu_index: PSU index (1-based) | ||
| :return: PSU object if available, None otherwise |
Copilot
AI
Oct 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docstring should clarify that logger can be None and that when None is passed, errors/warnings won't be logged. This is an important behavior detail for callers of this function.
| Get PSU object from platform chassis | |
| :param logger: Logger instance for error/warning messages | |
| :param psu_index: PSU index (1-based) | |
| :return: PSU object if available, None otherwise | |
| Get PSU object from platform chassis. | |
| :param logger: Logger instance for error/warning messages. Can be None; if None is passed, errors and warnings will not be logged. | |
| :param psu_index: PSU index (1-based) | |
| :return: PSU object if available, None otherwise | |
| Note: | |
| If logger is None, errors and warnings encountered during execution will not be logged. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
Signed-off-by: Lin Jin <[email protected]>
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
Description
This PR refactors the PSU object retrieval logic in psud by extracting the
platform_chassis.get_psu()call into a dedicated wrapper function_wrapper_get_psu(). In addition, the process no longer exits when platform_psuutil is unavailable. The change improves exception handling consistency and code maintainability by centralizing PSU object retrieval logic.Motivation and Context
The original code had duplicate
platform_chassis.get_psu(psu_index - 1)calls scattered across multiple wrapper functions, making it difficult to maintain consistent exception handling and increasing code duplication.How Has This Been Tested?
Unit tests were extended to test the PSU exception handling features and tested in physical platform.
Additional Information (Optional)