Last active
January 15, 2024 14:44
-
-
Save r0x0d/0b0b1e741006daaab479502f6580e0b5 to your computer and use it in GitHub Desktop.
extending the action framework
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/convert2rhel/actions/__init__.py b/convert2rhel/actions/__init__.py | |
index ce8c06f..1ae7375 100644 | |
--- a/convert2rhel/actions/__init__.py | |
+++ b/convert2rhel/actions/__init__.py | |
@@ -691,7 +691,7 @@ def resolve_action_order(potential_actions, previously_resolved_actions=None): | |
) | |
-def run_actions(): | |
+def run_pre_actions(): | |
""" | |
Run all of the pre-ponr Actions. | |
@@ -719,23 +719,68 @@ def run_actions(): | |
# Run the Actions in system_checks and all subsequent Stages. | |
results = system_checks.run() | |
- # Format results as a dictionary: | |
- # { | |
- # "$Action_id": { | |
- # "messages": [ | |
- # { | |
- # "level": int, | |
- # "id": "$id", | |
- # "message": "" or "$message" | |
- # }, | |
- # ] | |
- # "result": { | |
- # "level": int, | |
- # "id": "$id", | |
- # "message": "" or "$message" | |
- # }, | |
- # }, | |
- # } | |
+ return parse_action_results(results) | |
+ | |
+ | |
+def run_post_actions(): | |
+ """ | |
+ Run all of the post-ponr Actions. | |
+ | |
+ This function runs the Actions that occur before the Point of no Return. | |
+ """ | |
+ # Stages are created in the opposite order that they are run in so that | |
+ # each Stage can know about the Stage that comes after it (via the | |
+ # next_stage parameter). | |
+ # | |
+ # When we call check_dependencies() or run() on the first Stage | |
+ # (system_checks), it will operate on the first Stage and then recursively | |
+ # call check_dependencies() or run() on the next_stage. | |
+ post_ponr_final_changes = Stage("post_ponr_final_changes", "Final modifications to the system") | |
+ post_ponr_conversion = Stage("post_ponr_conversion", "Starting Conversion", next_stage=post_ponr_final_changes) | |
+ | |
+ try: | |
+ # Check dependencies are satisfied for system_checks and all subsequent | |
+ # Stages. | |
+ post_ponr_conversion.check_dependencies() | |
+ except DependencyError as e: | |
+ # We want to fail early if dependencies are not properly set. This | |
+ # way we should fail in testing before release. | |
+ logger.critical("Some dependencies were set on Actions but not present in convert2rhel: %s" % e) | |
+ | |
+ # Run the Actions in system_checks and all subsequent Stages. | |
+ results = post_ponr_conversion.run() | |
+ | |
+ return parse_action_results(results) | |
+ | |
+ | |
+def parse_action_results(results): | |
+ """ | |
+ Parse and format action results | |
+ | |
+ .. note:: | |
+ The formatted dictionary result is-as following: | |
+ { | |
+ "$Action_id": { | |
+ "messages": [ | |
+ { | |
+ "level": int, | |
+ "id": "$id", | |
+ "message": "" or "$message" | |
+ }, | |
+ ] | |
+ "result": { | |
+ "level": int, | |
+ "id": "$id", | |
+ "message": "" or "$message" | |
+ }, | |
+ }, | |
+ } | |
+ | |
+ :param results: Unformatted results given by the actions | |
+ :type results: dict | |
+ :return: Formatted dictionary with the results | |
+ :rtype: dict[str, dict[str, list | dict]] | |
+ """ | |
formatted_results = {} | |
for action in itertools.chain(*results): | |
msgs = [msg.to_dict() for msg in action.messages] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/convert2rhel/actions/report.py b/convert2rhel/actions/report.py | |
index 29f4c14..9b94aec 100644 | |
--- a/convert2rhel/actions/report.py | |
+++ b/convert2rhel/actions/report.py | |
@@ -149,7 +149,7 @@ def get_combined_results_and_message(results): | |
return combined_results_and_message | |
-def summary(results, include_all_reports=False, disable_colors=False): | |
+def summary(results, post_conversion, include_all_reports=False, disable_colors=False): | |
"""Output a summary regarding the actions execution. | |
This summary is intended to be used to inform the user about the results | |
@@ -213,7 +213,11 @@ def summary(results, include_all_reports=False, disable_colors=False): | |
highest ones. | |
:type include_all_reports: bool | |
""" | |
- logger.task("Pre-conversion analysis report") | |
+ if post_conversion: | |
+ logger.task("Post-conversion report") | |
+ else: | |
+ logger.task("Pre-conversion analysis report") | |
+ | |
report = [] | |
combined_results_and_message = get_combined_results_and_message(results) | |
@@ -247,7 +251,10 @@ def summary(results, include_all_reports=False, disable_colors=False): | |
# If there is no other message sent to the user, then we just give a | |
# happy message to them. | |
if not combined_results_and_message: | |
- report.append("No problems detected during the analysis!") | |
+ if post_conversion: | |
+ report.append("No problems detected during the conversion!") | |
+ else: | |
+ report.append("No problems detected during the analysis!") | |
logger.info("%s\n" % "\n".join(report)) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/convert2rhel/main.py b/convert2rhel/main.py | |
index b4358ce..8262be7 100644 | |
--- a/convert2rhel/main.py | |
+++ b/convert2rhel/main.py | |
@@ -97,6 +97,7 @@ def main_locked(): | |
"""Perform all steps for the entire conversion process.""" | |
pre_conversion_results = None | |
+ post_conversion_results = None | |
process_phase = ConversionPhase.POST_CLI | |
try: | |
perform_boilerplate() | |
@@ -109,25 +110,13 @@ def main_locked(): | |
# actions.run_actions() (either from a bug or from the user hitting | |
# Ctrl-C) | |
process_phase = ConversionPhase.PRE_PONR_CHANGES | |
- pre_conversion_results = actions.run_actions() | |
+ pre_conversion_results = actions.run_pre_actions() | |
if toolopts.tool_opts.activity == "analysis": | |
process_phase = ConversionPhase.ANALYZE_EXIT | |
raise _AnalyzeExit() | |
- pre_conversion_failures = actions.find_actions_of_severity( | |
- pre_conversion_results, "SKIP", level_for_raw_action_data | |
- ) | |
- if pre_conversion_failures: | |
- # The report will be handled in the error handler, after rollback. | |
- loggerinst.critical("Conversion failed.") | |
- | |
- # Print the assessment just before we ask the user whether to continue past the PONR | |
- report.summary( | |
- pre_conversion_results, | |
- include_all_reports=False, | |
- disable_colors=logger_module.should_disable_color_output(), | |
- ) | |
+ _analyze_actions_results(pre_conversion_results) | |
loggerinst.warning("********************************************************") | |
loggerinst.warning("The tool allows rollback of any action until this point.") | |
@@ -139,20 +128,28 @@ def main_locked(): | |
loggerinst.warning("********************************************************") | |
utils.ask_to_continue() | |
- process_phase = ConversionPhase.POST_PONR_CHANGES | |
- post_ponr_changes() | |
+ # TODO(r0x0d): Remove this once we have all functions in | |
+ # `py:post_ponr_changes` migrated to actions. | |
+ if "CONVERT2RHEL_EXPERIMENTAL_POST_PONR_ACTIONS" in os.environ: | |
+ process_phase = ConversionPhase.POST_PONR_CHANGES | |
+ post_conversion_results = actions.run_post_actions() | |
+ | |
+ _analyze_actions_results(post_conversion_results) | |
+ else: | |
+ post_ponr_changes() | |
+ | |
loggerinst.info("\nConversion successful!\n") | |
# restart system if required | |
utils.restart_system() | |
- | |
except _AnalyzeExit: | |
breadcrumbs.breadcrumbs.finish_collection(success=True) | |
rollback_changes() | |
report.summary( | |
- pre_conversion_results, | |
+ results=pre_conversion_results, | |
+ post_conversion=process_phase == ConversionPhase.POST_PONR_CHANGES, | |
include_all_reports=True, | |
disable_colors=logger_module.should_disable_color_output(), | |
) | |
@@ -160,21 +157,57 @@ def main_locked(): | |
except exceptions.CriticalError as err: | |
loggerinst.critical_no_exit(err.diagnosis) | |
- return _handle_main_exceptions(process_phase, pre_conversion_results) | |
+ results = _pick_conversion_results(process_phase, pre_conversion_results, post_conversion_results) | |
+ return _handle_main_exceptions(process_phase, results) | |
except (Exception, SystemExit, KeyboardInterrupt) as err: | |
- return _handle_main_exceptions(process_phase, pre_conversion_results) | |
+ results = _pick_conversion_results(process_phase, pre_conversion_results, post_conversion_results) | |
+ return _handle_main_exceptions(process_phase, results) | |
finally: | |
+ # TODO(r0x0d): Maybe we should merge both pre_conversion_results and post_conversion_results? | |
+ | |
# Write the assessment to a file as json data so that other tools can | |
# parse and act upon it. | |
- if pre_conversion_results: | |
- actions.report.summary_as_json(pre_conversion_results) | |
- actions.report.summary_as_txt(pre_conversion_results) | |
+ results = _pick_conversion_results(process_phase, pre_conversion_results, post_conversion_results) | |
+ if results: | |
+ actions.report.summary_as_json(results) | |
+ actions.report.summary_as_txt(results) | |
return 0 | |
+# TODO(r0x0d): Better function name | |
+def _analyze_actions_results(results): | |
+ """Analyze the action results for failures | |
+ | |
+ :param results: The action results from the framework | |
+ :type results: dict | |
+ """ | |
+ failures = actions.find_actions_of_severity(results, "SKIP", level_for_raw_action_data) | |
+ if failures: | |
+ # The report will be handled in the error handler, after rollback. | |
+ loggerinst.critical("Conversion failed.") | |
+ | |
+ # Print the assessment just before we ask the user whether to continue past the PONR | |
+ report.summary( | |
+ results=results, | |
+ include_all_reports=False, | |
+ disable_colors=logger_module.should_disable_color_output(), | |
+ ) | |
+ | |
+# TODO(r0x0d): Better function name | |
+def _pick_conversion_results(process_phase, pre_conversion, post_conversion): | |
+ """Utilitary function to define which action results to use | |
+ | |
+ Maybe not be necessary (or even correct), but it is the best approximation | |
+ idea for now. | |
+ """ | |
+ if process_phase == ConversionPhase.PRE_PONR_CHANGES: | |
+ return pre_conversion | |
+ | |
+ return post_conversion | |
+ | |
def _handle_main_exceptions(process_phase, pre_conversion_results=None): | |
"""Common steps to handle graceful exit due to several different Exception types.""" | |
breadcrumbs.breadcrumbs.finish_collection() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment