Skip to content

Commit

Permalink
fix: handle rollback phases in messages
Browse files Browse the repository at this point in the history
We didn't know what phase we were on before going into rollback. With
this change it now keeps a (soft) linear history where each phase points
to the previous one
  • Loading branch information
Venefilyn committed Oct 10, 2024
1 parent 3ac4d76 commit dff0124
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 9 deletions.
24 changes: 15 additions & 9 deletions convert2rhel/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@
from convert2rhel import logger as logger_module
from convert2rhel import pkghandler, pkgmanager, subscription, systeminfo, utils
from convert2rhel.actions import level_for_raw_action_data, report
from convert2rhel.phase import ConversionPhases
from convert2rhel.phase import ConversionPhase, ConversionPhases # noqa: F401 ignoring due to type comments
from convert2rhel.toolopts import tool_opts


loggerinst = logger_module.root_logger.getChild(__name__)


Expand Down Expand Up @@ -197,16 +196,16 @@ def main_locked():
except _InhibitorsFound as err:
loggerinst.critical_no_exit(str(err))
results = _pick_conversion_results(pre_conversion_results, post_conversion_results)
_handle_main_exceptions(results)
_handle_main_exceptions(current_phase=ConversionPhases.current_phase, results=results)

return _handle_inhibitors_found_exception()
except exceptions.CriticalError as err:
loggerinst.critical_no_exit(err.diagnosis)
results = _pick_conversion_results(pre_conversion_results, post_conversion_results)
return _handle_main_exceptions(results)
return _handle_main_exceptions(current_phase=ConversionPhases.current_phase, results=results)
except (Exception, SystemExit, KeyboardInterrupt):
results = _pick_conversion_results(pre_conversion_results, post_conversion_results)
return _handle_main_exceptions(results)
return _handle_main_exceptions(current_phase=ConversionPhases.current_phase, results=results)
finally:
if not backup.backup_control.rollback_failed:
# Write the assessment to a file as json data so that other tools can
Expand Down Expand Up @@ -254,17 +253,24 @@ def _pick_conversion_results(pre_conversion, post_conversion):
return pre_conversion


def _handle_main_exceptions(results=None):
def _handle_main_exceptions(current_phase, results=None): # type: (ConversionPhase|None, dict|None) -> int
"""Common steps to handle graceful exit due to several different Exception types."""
breadcrumbs.breadcrumbs.finish_collection()

no_changes_msg = "No changes were made to the system."
utils.log_traceback(tool_opts.debug)

if ConversionPhases.is_current([ConversionPhases.POST_CLI, ConversionPhases.PREPARE]):
execution_phase = current_phase # type: ConversionPhase|None

if current_phase and current_phase == ConversionPhases.ROLLBACK:
# Rollback is an indication of what we are doing, but here we want to know what we were doing before the
# rollback so that we can make assertions. Hence fetching the previous stage
execution_phase = current_phase.last_stage

Check warning on line 268 in convert2rhel/main.py

View check run for this annotation

Codecov / codecov/patch

convert2rhel/main.py#L268

Added line #L268 was not covered by tests

if execution_phase in [ConversionPhases.POST_CLI, ConversionPhases.PREPARE]:
loggerinst.info(no_changes_msg)
return ConversionExitCodes.FAILURE
elif ConversionPhases.is_current(ConversionPhases.PRE_PONR_CHANGES):
elif execution_phase == ConversionPhases.PRE_PONR_CHANGES:
# Update RHSM custom facts only when this returns False. Otherwise,
# sub-man get uninstalled and the data is removed from the RHSM server.
if not subscription.should_subscribe():
Expand All @@ -275,7 +281,7 @@ def _handle_main_exceptions(results=None):
pre_conversion_results=results,
include_all_reports=True,
)
elif ConversionPhases.is_current(ConversionPhases.POST_PONR_CHANGES):
elif execution_phase == ConversionPhases.POST_PONR_CHANGES:
# After the process of subscription is done and the mass update of
# packages is started convert2rhel will not be able to guarantee a
# system rollback without user intervention. If a proper rollback
Expand Down
5 changes: 5 additions & 0 deletions convert2rhel/phase.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class ConversionPhase:
def __init__(self, name, log_name=None): # type: (str, str|None) -> None
self.name = name
self.log_name = log_name
self.last_stage = None # type: ConversionPhase|None

def __str__(self):
return self.log_name if self.log_name else self.name

Check warning on line 30 in convert2rhel/phase.py

View check run for this annotation

Codecov / codecov/patch

convert2rhel/phase.py#L30

Added line #L30 was not covered by tests
Expand Down Expand Up @@ -69,6 +70,7 @@ def has(cls, key): # type: (str) -> bool

@classmethod
def set_current(cls, phase): # type: (str|ConversionPhase|None) -> None
previous_phase = cls.current_phase
if phase is None:
cls.current_phase = None

Check warning on line 75 in convert2rhel/phase.py

View check run for this annotation

Codecov / codecov/patch

convert2rhel/phase.py#L75

Added line #L75 was not covered by tests
elif isinstance(phase, str) and cls.has(phase):
Expand All @@ -78,6 +80,9 @@ def set_current(cls, phase): # type: (str|ConversionPhase|None) -> None
else:
raise NotImplementedError("The {} phase is not implemented in the {} class".format(phase, cls.__name__))

Check warning on line 81 in convert2rhel/phase.py

View check run for this annotation

Codecov / codecov/patch

convert2rhel/phase.py#L81

Added line #L81 was not covered by tests

if cls.current_phase:
cls.current_phase.last_stage = previous_phase

@classmethod
def is_current(cls, phase): # type: (str|ConversionPhase|list[str|ConversionPhase]) -> bool
if isinstance(phase, str):
Expand Down

0 comments on commit dff0124

Please sign in to comment.