Exemple #1
0
class TestMigrationConfig(object):
    @patch.object(Defaults, 'get_migration_config_file')
    @patch.object(Defaults, 'get_system_migration_custom_config_file')
    def setup(self, mock_get_system_migration_config_custom_file,
              mock_get_migration_config_file):
        mock_get_migration_config_file.return_value = \
            '../data/migration-config.yml'
        mock_get_system_migration_config_custom_file.return_value = \
            '../data/custom-migration-config.yml'
        self.config = MigrationConfig()

    def test_get_migration_product(self):
        assert self.config.get_migration_product() == 'SLES/15/x86_64'

    def test_get_preserve_udev_rules_list(self):
        assert self.config.get_preserve_udev_rules_list() == [
            '/etc/udev/rules.d/a.rules', '/etc/udev/rules.d/b.rules'
        ]

    @patch('suse_migration_services.logger.log.error')
    def test_get_migration_product_targets(self, mock_error):
        self.config.config_data = {'not_migration_product': 'another_info'}

        with raises(DistMigrationProductNotFoundException):
            self.config.get_migration_product()
            assert mock_error.called

    @patch.object(MigrationConfig, '_write_config_file')
    @patch('suse_migration_services.logger.log.info')
    def test_update_migration_config_file(
        self,
        mock_info,
        mock_write_config_file,
    ):
        self.config.update_migration_config_file()
        assert self.config.get_migration_product() == 'SLES/15.1/x86_64'
        assert self.config.is_debug_requested() is True
        assert mock_info.called

    def test_is_zypper_migration_plugin_requested(self):
        assert self.config.is_zypper_migration_plugin_requested() is True

    def test_is_debug_requested(self):
        assert self.config.is_debug_requested() is False

    @patch('yaml.dump')
    def test_write_config_file(self, mock_yaml_dump):
        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
            self.config._write_config_file()
            mock_open.assert_called_once_with(
                self.config.migration_config_file, 'w')
            mock_yaml_dump.assert_called_once_with(self.config.config_data,
                                                   file_handle,
                                                   default_flow_style=False)
Exemple #2
0
def main():
    """
    DistMigration run zypper based migration

    Call zypper migration plugin and migrate the system.
    The output of the call is logged on the system to migrate
    """
    root_path = Defaults.get_system_root_path()

    try:
        log.info('Running migrate service')
        migration_config = MigrationConfig()
        if migration_config.is_zypper_migration_plugin_requested():
            bash_command = ' '.join([
                'zypper', 'migration', '--non-interactive',
                '--gpg-auto-import-keys', '--no-selfupdate',
                '--auto-agree-with-licenses', '--allow-vendor-change',
                '--strict-errors-dist-migration', '--replacefiles',
                '--product',
                migration_config.get_migration_product(), '--root', root_path,
                '&>>',
                Defaults.get_migration_log_file()
            ])
            Command.run(['bash', '-c', bash_command])
        else:
            bash_command = ' '.join([
                'zypper', '--non-interactive', '--gpg-auto-import-keys',
                '--root', root_path, 'dup', '--auto-agree-with-licenses',
                '--allow-vendor-change', '--replacefiles', '&>>',
                Defaults.get_migration_log_file()
            ])
            zypper_call = Command.run(['bash', '-c', bash_command],
                                      raise_on_error=False)
            if zypper_has_failed(zypper_call.returncode):
                raise DistMigrationCommandException(
                    '{0} failed with: {1}: {2}'.format(bash_command,
                                                       zypper_call.output,
                                                       zypper_call.error))
    except Exception as issue:
        etc_issue_path = os.sep.join([root_path, 'etc/issue'])
        log_path_migrated_system = os.sep + os.path.relpath(
            Defaults.get_migration_log_file(), root_path)
        with open(etc_issue_path, 'w') as issue_file:
            issue_file.write(
                'Migration has failed, for further details see {0}'.format(
                    log_path_migrated_system))
        log.error('migrate service failed with {0}'.format(issue))
        raise DistMigrationZypperException(
            'Migration failed with {0}'.format(issue))
Exemple #3
0
class TestMigrationConfig(object):
    @patch.object(Defaults, 'get_migration_config_file')
    @patch.object(Defaults, 'get_system_migration_custom_config_file')
    def setup(
        self, mock_get_system_migration_config_custom_file,
        mock_get_migration_config_file
    ):
        mock_get_migration_config_file.return_value = \
            '../data/migration-config.yml'
        mock_get_system_migration_config_custom_file.return_value = \
            '../data/custom-migration-config.yml'
        self.config = MigrationConfig()

    @patch.object(Defaults, 'get_os_release')
    @patch.object(Defaults, 'get_system_root_path')
    def test_get_migration_product_auto_detected(
        self, mock_get_system_root_path, mock_get_os_release
    ):
        os_release_tuple = namedtuple(
            'OSRelease', [
                'name', 'version', 'version_id',
                'pretty_name', 'id', 'id_like', 'ansi_color', 'cpe_name'
            ]
        )
        os_release_result = os_release_tuple(
            name='SLES', version='15-SP1', version_id='15.1',
            pretty_name='SUSE Linux Enterprise Server 15 SP1',
            id='sles', id_like='suse', ansi_color='0;32',
            cpe_name='cpe:/o:suse:sles:15:sp1'
        )
        mock_get_system_root_path.return_value = '../data'
        mock_get_os_release.return_value = os_release_result
        assert self.config.get_migration_product() == 'SLES/15.1/x86_64'

    def test_get_preserve_udev_rules_list(self):
        assert self.config.get_preserve_udev_rules_list() == [
            '/etc/udev/rules.d/a.rules', '/etc/udev/rules.d/b.rules'
        ]

    @patch.object(Defaults, 'get_os_release')
    @patch.object(SUSEBaseProduct, 'get_tag')
    @patch.object(Defaults, 'get_system_root_path')
    def test_get_migration_product_targets(
        self, mock_get_system_root_path,
        mock_get_product_name, mock_get_os_release
    ):
        os_release_tuple = namedtuple(
            'OSRelease', [
                'name', 'version', 'version_id',
                'pretty_name', 'id', 'id_like', 'ansi_color', 'cpe_name'
            ]
        )
        os_release_result = os_release_tuple(
            name='SLES', version='15-SP1', version_id='15.1',
            pretty_name='SUSE Linux Enterprise Server 15 SP1',
            id='sles', id_like='suse', ansi_color='0;32',
            cpe_name='cpe:/o:suse:sles:15:sp1'
        )
        mock_get_system_root_path.return_value = '../data'
        mock_get_os_release.return_value = os_release_result
        mock_get_product_name.side_effect = Exception
        self.config.config_data = {'not_migration_product': 'another_info'}

        with raises(DistMigrationProductNotFoundException):
            self.config.get_migration_product()

    @patch.object(Defaults, 'get_os_release')
    @patch.object(SUSEBaseProduct, 'get_product_name')
    @patch.object(Defaults, 'get_system_root_path')
    @patch.object(MigrationConfig, '_write_config_file')
    def test_update_migration_config_file_no_autodetect(
        self, mock_write_config_file,
        mock_get_system_root_path, mock_get_product_name,
        mock_get_os_release
    ):
        os_release_tuple = namedtuple(
            'OSRelease', [
                'name', 'version', 'version_id',
                'pretty_name', 'id', 'id_like', 'ansi_color', 'cpe_name'
            ]
        )
        os_release_result = os_release_tuple(
            name='SLES', version='15-SP1', version_id='15.1',
            pretty_name='SUSE Linux Enterprise Server 15 SP1',
            id='sles', id_like='suse', ansi_color='0;32',
            cpe_name='cpe:/o:suse:sles:15:sp1'
        )
        mock_get_os_release.return_value = os_release_result
        mock_get_system_root_path.return_value = '../data'
        mock_get_product_name.return_value = None
        self.config.update_migration_config_file()
        assert self.config.get_migration_product() == 'SLES/15.1/x86_64'
        assert self.config.is_debug_requested() is True

    def test_is_zypper_migration_plugin_requested(self):
        assert self.config.is_zypper_migration_plugin_requested() is True

    def test_is_debug_requested(self):
        assert self.config.is_debug_requested() is False

    @patch('yaml.dump')
    def test_write_config_file(self, mock_yaml_dump):
        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
            self.config._write_config_file()
            mock_open.assert_called_once_with(
                self.config.migration_config_file, 'w'
            )
            mock_yaml_dump.assert_called_once_with(
                self.config.config_data, file_handle, default_flow_style=False
            )

    @patch.object(MigrationConfig, '_write_config_file')
    @patch.object(Defaults, 'get_migration_config_file')
    @patch.object(Defaults, 'get_system_migration_custom_config_file')
    def test_update_migration_config_file_empty(
        self, mock_get_system_migration_config_custom_file,
        mock_get_migration_config_file,
        mock_write_config_file,
    ):
        mock_get_migration_config_file.return_value = \
            '../data/migration-config.yml'
        mock_get_system_migration_config_custom_file.return_value = \
            '../data/custom-migration-config-empty.yml'
        self.config = MigrationConfig()
        self.config.update_migration_config_file()

    @patch.object(MigrationConfig, '_write_config_file')
    @patch.object(Defaults, 'get_migration_config_file')
    @patch.object(Defaults, 'get_system_migration_custom_config_file')
    def test_update_migration_config_file_just_comments(
        self, mock_get_system_migration_config_custom_file,
        mock_get_migration_config_file,
        mock_write_config_file,
    ):
        mock_get_migration_config_file.return_value = \
            '../data/migration-config.yml'
        mock_get_system_migration_config_custom_file.return_value = \
            '../data/custom-migration-config-just-comments.yml'
        self.config = MigrationConfig()
        self.config.update_migration_config_file()

    @patch.object(MigrationConfig, '_write_config_file')
    @patch.object(Defaults, 'get_migration_config_file')
    @patch.object(Defaults, 'get_system_migration_custom_config_file')
    def test_update_migration_config_file_slightly_broken(
        self, mock_get_system_migration_config_custom_file,
        mock_get_migration_config_file, mock_write_config_file,
    ):
        mock_get_migration_config_file.return_value = \
            '../data/migration-config.yml'
        mock_get_system_migration_config_custom_file.return_value = \
            '../data/custom-migration-config-corrupt-string.yml'
        self.config = MigrationConfig()
        with raises(DistMigrationConfigDataException):
            self.config.update_migration_config_file()

    @patch.object(MigrationConfig, '_write_config_file')
    @patch.object(Defaults, 'get_migration_config_file')
    @patch.object(Defaults, 'get_system_migration_custom_config_file')
    def test_update_migration_config_file_very_broken(
        self, mock_get_system_migration_config_custom_file,
        mock_get_migration_config_file, mock_write_config_file,
    ):
        mock_get_migration_config_file.return_value = \
            '../data/migration-config.yml'
        mock_get_system_migration_config_custom_file.return_value = \
            '../data/custom-migration-config-corrupt-mess.yml'
        self.config = MigrationConfig()
        with raises(DistMigrationConfigDataException):
            self.config.update_migration_config_file()

    @patch.object(MigrationConfig, '_write_config_file')
    @patch.object(Defaults, 'get_migration_config_file')
    @patch.object(Defaults, 'get_system_migration_custom_config_file')
    def test_update_migration_config_file_violates_schema(
        self, mock_get_system_migration_config_custom_file,
        mock_get_migration_config_file, mock_write_config_file,
    ):
        mock_get_migration_config_file.return_value = \
            '../data/migration-config.yml'
        mock_get_system_migration_config_custom_file.return_value = \
            '../data/custom-migration-config-violates-schema.yml'
        self.config = MigrationConfig()
        with raises(DistMigrationConfigDataException):
            self.config.update_migration_config_file()