Skip to content

Commit

Permalink
Add success indicator flag file
Browse files Browse the repository at this point in the history
Added /var/log/distro_migration.exitcode to be written
by the migrate service. The file contains the exit code
from the zypper process and is used in the migrate tool
to know about the overall state of the migration process.
The migrate tool initializes the flag file with a failed
value.
  • Loading branch information
schaefi committed Oct 20, 2024
1 parent 646dc37 commit fe285f8
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 29 deletions.
4 changes: 4 additions & 0 deletions suse_migration_services/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ def get_migration_config_file():
def get_migration_log_name():
return 'suse-migration'

@staticmethod
def get_migration_exit_code_file():
return '/var/log/distro_migration.exitcode'

@staticmethod
def get_migration_log_file(system_root=True):
migration_log_file = 'var/log/distro_migration.log'
Expand Down
7 changes: 7 additions & 0 deletions suse_migration_services/units/migrate.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def main():
Logger.setup()
log = logging.getLogger(Defaults.get_migration_log_name())
root_path = Defaults.get_system_root_path()
exit_code_file = Defaults.get_migration_exit_code_file()

try:
log.info('Running migrate service')
Expand Down Expand Up @@ -99,6 +100,9 @@ def main():
bash_command, zypper_call.output, zypper_call.error
)
)
# report success(0) return code
with open(exit_code_file, 'w') as exit_code:
exit_code.write('0{}'.format(os.linesep))
except Exception as issue:
etc_issue_path = os.sep.join(
[root_path, 'etc/issue']
Expand All @@ -112,6 +116,9 @@ def main():
log_path_migrated_system
)
)
# report failed(1) return code
with open(exit_code_file, 'w') as exit_code:
exit_code.write('1{}'.format(os.linesep))
log.error('migrate service failed with {0}'.format(issue))
raise DistMigrationZypperException(
'Migration failed with {0}'.format(issue)
Expand Down
112 changes: 83 additions & 29 deletions test/unit/units/migrate_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import io
from unittest.mock import (
patch, Mock, MagicMock
patch, Mock, MagicMock, call
)
from pytest import raises

Expand All @@ -12,11 +12,27 @@
)


@patch('suse_migration_services.logger.Logger.setup')
@patch('suse_migration_services.command.Command.run')
@patch('suse_migration_services.units.migrate.log_env')
@patch('suse_migration_services.units.migrate.update_env')
class TestMigration(object):
@patch.object(Defaults, 'get_migration_config_file')
def setup(self, mock_get_migration_config_file):
mock_get_migration_config_file.return_value = \
'../data/migration-config.yml'
self.migration_config = MigrationConfig()
mock_get_migration_config_file.return_value = \
'../data/migration-config-verbose.yml'
self.migration_config_verbose = MigrationConfig()
mock_get_migration_config_file.return_value = \
'../data/migration-config-zypper-dup.yml'
self.migration_config_dup = MigrationConfig()

@patch.object(Defaults, 'get_migration_config_file')
def setup_method(self, cls, mock_get_migration_config_file):
self.setup()

@patch('suse_migration_services.logger.Logger.setup')
@patch('suse_migration_services.command.Command.run')
@patch('suse_migration_services.units.migrate.log_env')
@patch('suse_migration_services.units.migrate.update_env')
@patch('suse_migration_services.defaults.Defaults.get_system_root_path')
@patch('suse_migration_services.units.migrate.MigrationConfig')
def test_main_zypper_migration_plugin_raises(
Expand All @@ -35,15 +51,24 @@ def test_main_zypper_migration_plugin_raises(
file_handle = mock_open.return_value.__enter__.return_value
with raises(DistMigrationZypperException):
main()
mock_open.assert_called_once_with(
'../data/etc/issue', 'w'
)
file_handle.write.assert_called_once_with(
'Migration has failed, for further details see {0}'.format(
'/var/log/distro_migration.log'
)
)

assert mock_open.call_args_list == [
call('../data/etc/issue', 'w'),
call('/var/log/distro_migration.exitcode', 'w')
]
assert file_handle.write.call_args_list == [
call(
'Migration has failed, for further details see {0}'.format(
'/var/log/distro_migration.log'
)
),
call('1\n')
]

@patch('suse_migration_services.logger.Logger.setup')
@patch('suse_migration_services.command.Command.run')
@patch('suse_migration_services.units.migrate.log_env')
@patch('suse_migration_services.units.migrate.update_env')
@patch('suse_migration_services.defaults.Defaults.get_system_root_path')
@patch('suse_migration_services.units.migrate.MigrationConfig')
def test_main_zypper_dup_raises(
Expand All @@ -61,36 +86,57 @@ def test_main_zypper_dup_raises(
with patch('builtins.open', create=True):
# zypper exit code is 0, all ok
main()

with patch('builtins.open', create=True):
# zypper exit code is 1, error
zypper_call.returncode = 1
with raises(DistMigrationZypperException):
main()

with patch('builtins.open', create=True):
# zypper exit code is 104, error
zypper_call.returncode = 104
with raises(DistMigrationZypperException):
main()

with patch('builtins.open', create=True):
# zypper exit code is 105, error
zypper_call.returncode = 105
with raises(DistMigrationZypperException):
main()

with patch('builtins.open', create=True):
# zypper exit code is 106, error
zypper_call.returncode = 106
with raises(DistMigrationZypperException):
main()

with patch('builtins.open', create=True):
# zypper exit code is 107, all ok
zypper_call.returncode = 107
main()

@patch('suse_migration_services.logger.Logger.setup')
@patch('suse_migration_services.command.Command.run')
@patch('suse_migration_services.units.migrate.log_env')
@patch('suse_migration_services.units.migrate.update_env')
@patch.object(MigrationConfig, 'get_migration_product')
@patch.object(Defaults, 'get_migration_config_file')
@patch('suse_migration_services.units.migrate.MigrationConfig')
def test_main_zypper_migration_plugin(
self, mock_get_migration_config_file, mock_get_system_root_path,
self, mock_MigrationConfig, mock_get_system_root_path,
mock_update_env, mock_log_env, mock_Command_run, mock_logger_setup
):
mock_MigrationConfig.return_value = self.migration_config
mock_get_system_root_path.return_value = 'SLES/15/x86_64'
mock_get_migration_config_file.return_value = \
'../data/migration-config.yml'
main()
with patch('builtins.open', create=True) as mock_open:
mock_open.return_value = MagicMock(spec=io.IOBase)
file_handle = mock_open.return_value.__enter__.return_value
main()

mock_open.assert_called_once_with(
'/var/log/distro_migration.exitcode', 'w'
)
file_handle.write.assert_called_once_with('0\n')
mock_Command_run.assert_called_once_with(
[
'bash', '-c',
Expand All @@ -109,16 +155,20 @@ def test_main_zypper_migration_plugin(
]
)

@patch('suse_migration_services.logger.Logger.setup')
@patch('suse_migration_services.command.Command.run')
@patch('suse_migration_services.units.migrate.log_env')
@patch('suse_migration_services.units.migrate.update_env')
@patch.object(MigrationConfig, 'get_migration_product')
@patch.object(Defaults, 'get_migration_config_file')
@patch('suse_migration_services.units.migrate.MigrationConfig')
def test_main_zypper_migration_plugin_verbose(
self, mock_get_migration_config_file, mock_get_system_root_path,
self, mock_MigrationConfig, mock_get_system_root_path,
mock_update_env, mock_log_env, mock_Command_run, mock_logger_setup
):
mock_MigrationConfig.return_value = self.migration_config_verbose
mock_get_system_root_path.return_value = 'SLES/15/x86_64'
mock_get_migration_config_file.return_value = \
'../data/migration-config-verbose.yml'
main()
with patch('builtins.open', create=True):
main()
mock_Command_run.assert_called_once_with(
[
'bash', '-c',
Expand All @@ -137,17 +187,21 @@ def test_main_zypper_migration_plugin_verbose(
]
)

@patch.object(Defaults, 'get_migration_config_file')
@patch('suse_migration_services.logger.Logger.setup')
@patch('suse_migration_services.command.Command.run')
@patch('suse_migration_services.units.migrate.log_env')
@patch('suse_migration_services.units.migrate.update_env')
@patch('suse_migration_services.units.migrate.MigrationConfig')
def test_main_zypper_dup(
self, mock_get_migration_config_file,
mock_update_env, mock_log_env, mock_Command_run, mock_logger_setup
self, mock_MigrationConfig, mock_update_env,
mock_log_env, mock_Command_run, mock_logger_setup
):
mock_MigrationConfig.return_value = self.migration_config_dup
zypper_call = Mock()
zypper_call.returncode = 0
mock_Command_run.return_value = zypper_call
mock_get_migration_config_file.return_value = \
'../data/migration-config-zypper-dup.yml'
main()
with patch('builtins.open', create=True):
main()
mock_Command_run.assert_called_once_with(
[
'bash', '-c',
Expand Down

0 comments on commit fe285f8

Please sign in to comment.