Exemple #1
0
def replace_non_rhel_installed_kernel(version):
    """Replace the installed non-RHEL kernel with RHEL kernel with same
    version.
    """
    loggerinst = logging.getLogger(__name__)
    loggerinst.warning("The convert2rhel is going to force-replace the only"
                       " kernel installed, which has the same NEVRA as the"
                       " only available RHEL kernel. If anything goes wrong"
                       " with such replacement, the system will become"
                       " unbootable. If you want the convert2rhel to install"
                       " the RHEL kernel in a safer manner, you can install a"
                       " different version of kernel first and then run"
                       " convert2rhel again.")
    utils.ask_to_continue()

    pkg = "kernel-%s" % version

    ret_code = utils.download_pkg(
        pkg=pkg, dest=utils.TMP_DIR, disablerepo=tool_opts.disablerepo,
        enablerepo=tool_opts.enablerepo)
    if ret_code != 0:
        return

    loggerinst.info("Replacing %s %s with RHEL kernel with the same NEVRA ... " % (system_info.name, pkg))
    output, ret_code = utils.run_subprocess(
        'rpm -i --force --replacepkgs %s*' % os.path.join(utils.TMP_DIR, pkg),
        print_output=False)
    if ret_code != 0:
        loggerinst.critical("Unable to replace kernel package: %s" % output)
        return

    loggerinst.info("\nRHEL %s installed.\n" % pkg)
Exemple #2
0
def remove_original_subscription_manager():
    loggerinst.info(
        "Removing installed subscription-manager/katello-ca-consumer packages."
    )
    # python3-subscription-manager-rhsm, dnf-plugin-subscription-manager, subscription-manager-rhsm-certificates, etc.
    submgr_pkgs = pkghandler.get_installed_pkg_objects(
        "*subscription-manager*")
    # Satellite-server related package
    submgr_pkgs += pkghandler.get_installed_pkg_objects("katello-ca-consumer*")
    if not submgr_pkgs:
        loggerinst.info(
            "No packages related to subscription-manager installed.")
        return
    loggerinst.info(
        "Upon continuing, we will uninstall the following subscription-manager/katello-ca-consumer packages:\n"
    )
    pkghandler.print_pkg_info(submgr_pkgs)
    utils.ask_to_continue()
    submgr_pkg_names = [pkg.name for pkg in submgr_pkgs]

    if system_info.id == "centos" and system_info.version.major == 8 and system_info.version.minor == 5:
        if _SUBMGR_PKG_REMOVED_IN_CL_85 in submgr_pkg_names:
            # The package listed in _SUBMGR_PKG_REMOVED_IN_CL_85 has been
            # removed from CentOS Linux 8.5 and causes conversion to fail if
            # it's installed on that system because it's not possible to back it up.
            # https://bugzilla.redhat.com/show_bug.cgi?id=2046292
            backup.remove_pkgs([_SUBMGR_PKG_REMOVED_IN_CL_85],
                               backup=False,
                               critical=False)
            submgr_pkg_names.remove(_SUBMGR_PKG_REMOVED_IN_CL_85)

    # Remove any oter subscription-manager packages present on the system
    backup.remove_pkgs(submgr_pkg_names, critical=False)
Exemple #3
0
def clear_versionlock():
    """A package can be locked to a specific version using a YUM/DNF versionlock plugin. Then, even if a newer version
    of a package is available, yum or dnf won't update it. That may cause a problem during the conversion as other
    RHEL packages may depend on a different version than is locked. That's why we clear all the locks to prevent a
    system conversion failure.
    DNF has been designed to be backwards compatible with YUM. So the file in which the version locks are defined for
    YUM works correctly even with DNF thanks to symlinks created by DNF.
    """
    loggerinst = logging.getLogger(__name__)

    if os.path.isfile(_VERSIONLOCK_FILE_PATH
                      ) and os.path.getsize(_VERSIONLOCK_FILE_PATH) > 0:
        loggerinst.warn(
            "YUM/DNF versionlock plugin is in use. It may cause the conversion to fail."
        )
        loggerinst.info(
            "Upon continuing, we will clear all package version locks.")
        utils.ask_to_continue()

        versionlock_file.backup()

        loggerinst.info("Clearing package versions locks...")
        call_yum_cmd("versionlock clear", print_output=False)
    else:
        loggerinst.info("Usage of YUM/DNF versionlock plugin not detected.")
Exemple #4
0
def remove_blacklisted_pkgs():
    """Certain packages need to be removed before the system conversion,
    depending on the system to be converted. At least removing <os>-release
    package is a must.
    """
    loggerinst = logging.getLogger(__name__)
    installed_blacklisted_pkgs = []
    loggerinst.info("Searching for the following blacklisted packages:\n")
    for blacklisted_pkg in system_info.pkg_blacklist:
        temp = '.' * (50 - len(blacklisted_pkg) - 2)
        pkg_objects = get_installed_pkg_objects(blacklisted_pkg)
        installed_blacklisted_pkgs.extend(pkg_objects)
        loggerinst.info("%s %s %s" %
                        (blacklisted_pkg, temp, str(len(pkg_objects))))

    if not installed_blacklisted_pkgs:
        loggerinst.info("\nNothing to do.")
        return
    loggerinst.info("\n")
    loggerinst.warning("The following packages will be removed...")
    loggerinst.info("\n")
    print_pkg_info(installed_blacklisted_pkgs)
    utils.ask_to_continue()
    utils.remove_pkgs(
        [get_pkg_nvra(pkg) for pkg in installed_blacklisted_pkgs])
    return
Exemple #5
0
def replace_non_rhel_installed_kernel(version):
    """Replace the installed non-RHEL kernel with RHEL kernel with same version."""
    loggerinst.warning("The convert2rhel is going to force-replace the only"
                       " kernel installed, which has the same NEVRA as the"
                       " only available RHEL kernel. If anything goes wrong"
                       " with such replacement, the system will become"
                       " unbootable. If you want the convert2rhel to install"
                       " the RHEL kernel in a safer manner, you can install a"
                       " different version of kernel first and then run"
                       " convert2rhel again.")
    utils.ask_to_continue()

    pkg = "kernel-%s" % version

    # For downloading the RHEL kernel we need to use the RHEL repositories. Those are available either through the
    # attached subscription (submgr_enabled_repos) or through custom repositories (tool_opts.enablerepo).
    repos_to_enable = system_info.submgr_enabled_repos if not tool_opts.disable_submgr else tool_opts.enablerepo
    path = utils.download_pkg(
        pkg=pkg, dest=utils.TMP_DIR, disable_repos=tool_opts.disablerepo,
        enable_repos=repos_to_enable)
    if not path:
        loggerinst.critical("Unable to download the RHEL kernel package.")

    loggerinst.info("Replacing %s %s with RHEL kernel with the same NEVRA ... " % (system_info.name, pkg))
    output, ret_code = utils.run_subprocess(
        # The --nodeps is needed as some kernels depend on system-release (alias for redhat-release) and that package
        # is not installed at this stage.
        'rpm -i --force --nodeps --replacepkgs %s*' % os.path.join(utils.TMP_DIR, pkg),
        print_output=False)
    if ret_code != 0:
        loggerinst.critical("Unable to replace the kernel package: %s" % output)

    loggerinst.info("\nRHEL %s installed.\n" % pkg)
Exemple #6
0
def package_analysis():
    """Go through the installed packages, report which packages are missing
    in RHEL repos and return in which RHEL repos the rest can be found.
    """
    loggerinst = logging.getLogger(__name__)

    repo_data_files = get_repo_data_files()
    if repo_data_files:
        loggerinst.info("Reading offline snapshot of RHEL repositories"
                        " for %s variant" % tool_opts.variant)
        loggerinst.info("\n".join(repo_data_files) + "\n")
        rhel_repos_content = read_repo_files(repo_data_files)
        repos_needed = match_repo_pkgs_to_installed(rhel_repos_content)
        loggerinst.info("Repositories needed: %s" % "\n".join(repos_needed) +
                        "\n")
        loggerinst.info("Listing non-%s and non-Red Hat packages ... " %
                        system_info.name)
    else:
        loggerinst.debug("Offline snapshot of RHEL repositories not found.")
        repos_needed = [system_info.default_repository_id]
    third_party_pkgs = pkghandler.get_third_party_pkgs()
    if third_party_pkgs:
        loggerinst.warning("Only packages signed by %s are to be"
                           " reinstalled. Red Hat support won't be provided"
                           " for the following third party packages:\n" %
                           system_info.name)
        pkghandler.print_pkg_info(third_party_pkgs)
        utils.ask_to_continue()
    else:
        loggerinst.info("No third party packages installed.")
    return repos_needed
Exemple #7
0
def warn_on_unsupported_options():
    if any(x in sys.argv[1:] for x in ["--variant", "-v"]):
        loggerinst.warning(
            "The -v|--variant option is not supported anymore and has no effect.\n"
            "See help (convert2rhel -h) for more information."
        )
        utils.ask_to_continue()
Exemple #8
0
def unregister_from_rhn_classic():
    loggerinst = logging.getLogger(__name__)
    if os.path.isfile(_RHN_REGISTRATION_FILE):
        loggerinst.warning("The use of RHN Classic is not allowed during the conversion.\n"
                           "The convert2rhel is going to unregister from RHN Classic.\n"
                           "See https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/installation_guide/unregister-rhn for details.")
        utils.ask_to_continue()
        rhn_reg_file.remove()
    else:
        loggerinst.info("RHN Classic not detected.")
def remove_original_subscription_manager():
    loggerinst.info("Removing non-RHEL subscription-manager packages.")
    # python3-subscription-manager-rhsm, dnf-plugin-subscription-manager, subscription-manager-rhsm-certificates, etc.
    submgr_pkgs = pkghandler.get_installed_pkgs_w_different_fingerprint(
        system_info.fingerprints_rhel, "*subscription-manager*")
    if not submgr_pkgs:
        loggerinst.info("No packages related to subscription-manager installed.")
        return
    loggerinst.info("Upon continuing, we will uninstall the following subscription-manager pkgs:\n")
    pkghandler.print_pkg_info(submgr_pkgs)
    utils.ask_to_continue()
    submgr_pkg_names = [pkg.name for pkg in submgr_pkgs]
    utils.remove_pkgs(submgr_pkg_names, critical=False)
Exemple #10
0
def list_third_party_pkgs():
    """List packages not packaged by the original OS vendor or Red Hat and warn that these are not going
    to be converted.
    """
    third_party_pkgs = get_third_party_pkgs()
    if third_party_pkgs:
        loggerinst.warning("Only packages signed by %s are to be"
                           " reinstalled. Red Hat support won't be provided"
                           " for the following third party packages:\n" %
                           system_info.name)
        print_pkg_info(third_party_pkgs)
        utils.ask_to_continue()
    else:
        loggerinst.info("No third party packages installed.")
Exemple #11
0
def user_to_accept_eula():
    """Request user to accept EULA license agreement. This is required
    otherwise the conversion process stops and fails with error.
    """
    loggerinst = logging.getLogger(__name__)

    eula_filename = "GLOBAL_EULA_RHEL"
    eula_filepath = os.path.join(utils.data_dir, eula_filename)
    eula_text = utils.get_file_content(eula_filepath)
    if eula_text:
        loggerinst.info(eula_text)
        loggerinst.warning("By continuing you accept this EULA.")
        utils.ask_to_continue()
    else:
        loggerinst.critical('EULA file not found.')
    return
Exemple #12
0
def warn_about_nonavail_pkgs(pkgs):
    """Print out information about availability of the installed packages as
    related to RHEL repositories.
    """
    loggerinst = logging.getLogger(__name__)
    if pkgs["removed"]:
        loggerinst.warning("The following packages were not found in the"
                           " offline snapshot of RHEL repositories. \nIt may"
                           " be that the snapshot is either not up-to-date or"
                           " does not cover special RHEL repos that hold these"
                           " packages. \nBut possibly these packages will not"
                           " be replaced by the Red Hat-signed ones and"
                           " therefore not supported by Red Hat:\n")
        loggerinst.info("\n".join(pkgs["removed"]))
        loggerinst.info("\n")
        utils.ask_to_continue()
Exemple #13
0
def check_package_updates():
    """Ensure that the system packages installed are up-to-date."""
    logger.task("Prepare: Checking if the installed packages are up-to-date")

    if system_info.id == "oracle" and system_info.corresponds_to_rhel_eus_release(
    ):
        logger.info(
            "Skipping the check because there are no publicly available %s %d.%d repositories available."
            % (system_info.name, system_info.version.major,
               system_info.version.minor))
        return

    reposdir = get_hardcoded_repofiles_dir()

    if reposdir and not system_info.has_internet_access:
        logger.warning(
            "Skipping the check as no internet connection has been detected.")
        return

    try:
        packages_to_update = get_total_packages_to_update(reposdir=reposdir)
    except pkgmanager.RepoError as e:
        # As both yum and dnf have the same error class (RepoError), to identify any problems when interacting with the
        # repositories, we use this to catch exceptions when verifying if there is any packages to update on the system.
        # Beware that the `RepoError` exception is based on the `pkgmanager` module and the message sent to the output
        # can differ depending if the code is running in RHEL7 (yum) or RHEL8 (dnf).
        logger.warning(
            "There was an error while checking whether the installed packages are up-to-date. Having updated system is "
            "an important prerequisite for a successful conversion. Consider stopping the conversion to "
            "verify that manually.")
        logger.warning(str(e))
        ask_to_continue()
        return

    if len(packages_to_update) > 0:
        repos_message = ("on the enabled system repos" if not reposdir else
                         "on repositories defined in the %s folder" % reposdir)
        logger.warning(
            "The system has %s packages not updated based %s.\n"
            "List of packages to update: %s.\n\n"
            "Not updating the packages may cause the conversion to fail.\n"
            "Consider stopping the conversion and update the packages before re-running convert2rhel."
            % (len(packages_to_update), repos_message,
               " ".join(packages_to_update)))
        ask_to_continue()
    else:
        logger.info("System is up-to-date.")
def check_needed_repos_availability(repo_ids_needed):
    """Check whether all the RHEL repositories needed for the system
    conversion are available through subscription-manager.
    """
    loggerinst.info("Verifying needed RHEL repositories are available ... ")
    avail_repos = get_avail_repos()
    loggerinst.info("Repositories available through RHSM:\n%s" %
                    "\n".join(avail_repos) + "\n")

    all_repos_avail = True
    for repo_id in repo_ids_needed:
        if repo_id not in avail_repos:
            # TODO: List the packages that would be left untouched
            loggerinst.warning("%s repository is not available - some packages"
                               " may not be replaced and thus not supported."
                               % repo_id)
            utils.ask_to_continue()
            all_repos_avail = False
    if all_repos_avail:
        loggerinst.info("Needed RHEL repos are available.")
Exemple #15
0
def remove_pkgs_with_confirm(pkgs, backup=True):
    """
    Remove selected packages with a breakdown and user confirmation prompt.
    """
    pkgs_to_remove = []
    for pkg in pkgs:
        temp = '.' * (50 - len(pkg) - 2)
        pkg_objects = get_installed_pkgs_w_different_fingerprint(system_info.fingerprints_rhel, pkg)
        pkgs_to_remove.extend(pkg_objects)
        loggerinst.info("%s %s %s" %
                        (pkg, temp, str(len(pkg_objects))))

    if not pkgs_to_remove:
        loggerinst.info("\nNothing to do.")
        return
    loggerinst.info("\n")
    loggerinst.warning("The following packages will be removed...")
    print_pkg_info(pkgs_to_remove)
    utils.ask_to_continue()
    utils.remove_pkgs([get_pkg_nvra(pkg) for pkg in pkgs_to_remove], backup=backup)
    loggerinst.debug("Successfully removed %s packages" % str(len(pkgs_to_remove)))
Exemple #16
0
def check_needed_repos_availability(repo_ids_needed):
    """Check whether all the RHEL repositories needed for the system
    conversion are available through the provided subscription.
    """
    loggerinst = logging.getLogger(__name__)
    loggerinst.info("Verifying required repositories are available ... ")
    if tool_opts.disable_submgr:
        avail_repos = get_avail_repos()
    else:
        avail_repos = subscription.get_avail_repos()

    loggerinst.info("repos available:\n%s" % "\n".join(avail_repos) + "\n")
    all_repos_avail = True
    for repo_id in repo_ids_needed:
        if repo_id not in avail_repos:
            # TODO: List the packages that would be left untouched
            loggerinst.warning("%s repository is not available - some packages"
                               " may not be replaced and thus not supported." %
                               repo_id)
            utils.ask_to_continue()
            all_repos_avail = False
    if all_repos_avail:
        loggerinst.info("Needed repos are available.")
Exemple #17
0
def main():
    """Perform all steps for the entire conversion process."""
    process_phase = ConversionPhase.INIT
    # initialize logging
    logger.initialize_logger("convert2rhel.log")
    # get module level logger (inherits from root logger)
    loggerinst = logging.getLogger(__name__)

    try:
        # handle command line arguments
        toolopts.CLI()

        process_phase = ConversionPhase.POST_CLI

        # the tool will not run if not executed under the root user
        utils.require_root()

        # license agreement
        loggerinst.task("Prepare: End user license agreement")
        user_to_accept_eula()

        # gather system information
        loggerinst.task("Prepare: Gather system information")
        systeminfo.system_info.resolve_system_info()
        loggerinst.task("Prepare: Determine RHEL variant")
        rhelvariant.determine_rhel_variant()

        # backup system release file before starting conversion process
        loggerinst.task("Prepare: Backup System")
        redhatrelease.system_release_file.backup()
        redhatrelease.yum_conf.backup()

        # begin conversion process
        process_phase = ConversionPhase.PRE_PONR_CHANGES
        pre_ponr_conversion()

        loggerinst.warning("The tool allows rollback of any action until this"
                           " point.")
        loggerinst.warning("By continuing all further changes on the system"
                           " will need to be reverted manually by the user,"
                           " if necessary.")
        utils.ask_to_continue()

        process_phase = ConversionPhase.POST_PONR_CHANGES
        post_ponr_conversion()

        # recommend non-interactive command
        loggerinst.task("Final: Non-interactive mode")
        toolopts.print_non_interactive_opts()

        # restart system if required
        utils.restart_system()

    except (Exception, SystemExit, KeyboardInterrupt), err:
        # Catching the three exception types separately due to python 2.4
        # (RHEL 5) - 2.7 (RHEL 7) compatibility.

        utils.log_traceback(toolopts.tool_opts.debug)

        print("\n")
        if is_help_msg_exit(process_phase, err):
            return 0
        elif process_phase in (ConversionPhase.INIT, ConversionPhase.POST_CLI):
            print("No changes were made to the system.")
        elif process_phase == ConversionPhase.PRE_PONR_CHANGES:
            rollback_changes()
        elif process_phase == ConversionPhase.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 intervation. If a proper rollback
            # solution is necessary it will need to be future implemented here
            # or with the use of other backup tools.
            print("Conversion process interrupted and manual user intervation"
                  " will be necessary.")

        return 1
Exemple #18
0
    def _process_cli_options(self):
        """Process command line options used with the tool."""
        loggerinst = logging.getLogger(__name__)
        parsed_opts, _ = self._parser.parse_args()

        global tool_opts  # pylint: disable=C0103
        if parsed_opts.debug:
            tool_opts.debug = True

        if parsed_opts.disable_colors:
            tool_opts.disable_colors = True

        if parsed_opts.no_rpm_va:
            tool_opts.no_rpm_va = True

        if parsed_opts.username:
            tool_opts.username = parsed_opts.username

        if parsed_opts.password:
            tool_opts.password = parsed_opts.password

        if parsed_opts.password_from_file:
            tool_opts.password_file = parsed_opts.password_from_file
            tool_opts.password = utils.get_file_content(
                parsed_opts.password_from_file)

        if parsed_opts.enablerepo:
            tool_opts.enablerepo = parsed_opts.enablerepo
        if parsed_opts.disablerepo:
            tool_opts.disablerepo = parsed_opts.disablerepo
        if parsed_opts.disable_submgr:
            tool_opts.disable_submgr = True
            if not tool_opts.enablerepo:
                loggerinst.critical(
                    "Error: --enablerepo is required if --disable-submgr is passed "
                )
        if not tool_opts.disablerepo:
            # Default to disable every repo except:
            # - the ones passed through --enablerepo
            # - the ones enabled through subscription-manager based on convert2rhel config files
            tool_opts.disablerepo = ["*"]

        if parsed_opts.pool:
            tool_opts.pool = parsed_opts.pool

        if '--variant' in sys.argv[1:]:
            loggerinst.warning(
                "The --variant option is not supported anymore.")
            if parsed_opts.disable_submgr:
                loggerinst.warning(
                    "The system will be converted to the RHEL variant provided by the repositories you"
                    " have enabled through the --enablerepo option.")
            else:
                loggerinst.warning(
                    "The system will be converted to the Server variant of RHEL."
                )
            utils.ask_to_continue()

        if parsed_opts.serverurl:
            if parsed_opts.disable_submgr:
                loggerinst.warn(
                    "Ignoring the --serverurl option. It has no effect when --disable-submgr is used."
                )
            else:
                tool_opts.serverurl = parsed_opts.serverurl

        tool_opts.autoaccept = parsed_opts.y
        tool_opts.auto_attach = parsed_opts.auto_attach
        tool_opts.restart = parsed_opts.restart

        if parsed_opts.activationkey:
            tool_opts.activation_key = parsed_opts.activationkey

        if parsed_opts.org:
            tool_opts.org = parsed_opts.org

        if tool_opts.username and tool_opts.password:
            tool_opts.credentials_thru_cli = True
Exemple #19
0
def main():
    """Perform all steps for the entire conversion process."""

    # handle command line arguments
    toolopts.CLI()

    # the tool will not run if not executed under the root user
    utils.require_root()

    process_phase = ConversionPhase.INIT
    # initialize logging
    logger.initialize_logger("convert2rhel.log")
    # get module level logger (inherits from root logger)

    try:
        process_phase = ConversionPhase.POST_CLI

        # license agreement
        loggerinst.task("Prepare: Show Red Hat software EULA")
        show_eula()

        # gather system information
        loggerinst.task("Prepare: Gather system information")
        systeminfo.system_info.resolve_system_info()

        # check the system prior the conversion (possible inhibit)
        loggerinst.task("Prepare: Initial system checks before conversion")
        checks.perform_pre_checks()

        # backup system release file before starting conversion process
        loggerinst.task("Prepare: Backup System")
        redhatrelease.system_release_file.backup()
        redhatrelease.yum_conf.backup()
        repo.backup_yum_repos()

        loggerinst.task("Prepare: Clear YUM/DNF version locks")
        pkghandler.clear_versionlock()

        # begin conversion process
        process_phase = ConversionPhase.PRE_PONR_CHANGES
        pre_ponr_conversion()

        loggerinst.warning(
            "********************************************************")
        loggerinst.warning(
            "The tool allows rollback of any action until this point.")
        loggerinst.warning("By continuing all further changes on the system"
                           " will need to be reverted manually by the user,"
                           " if necessary.")
        loggerinst.warning(
            "********************************************************")
        utils.ask_to_continue()

        process_phase = ConversionPhase.POST_PONR_CHANGES
        post_ponr_conversion()

        loggerinst.task("Final: rpm files modified by the conversion")
        systeminfo.system_info.modified_rpm_files_diff()

        # recommend non-interactive command
        loggerinst.task("Final: Non-interactive mode")
        toolopts.print_non_interactive_opts()

        # restart system if required
        utils.restart_system()

    except (Exception, SystemExit, KeyboardInterrupt) as err:
        # Catching the three exception types separately due to python 2.4
        # (RHEL 5) - 2.7 (RHEL 7) compatibility.

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

        if is_help_msg_exit(process_phase, err):
            return 0
        elif process_phase == ConversionPhase.INIT:
            print(no_changes_msg)
        elif process_phase == ConversionPhase.POST_CLI:
            loggerinst.info(no_changes_msg)
        elif process_phase == ConversionPhase.PRE_PONR_CHANGES:
            rollback_changes()
        elif process_phase == ConversionPhase.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
            # solution is necessary it will need to be future implemented here
            # or with the use of other backup tools.
            loggerinst.warning(
                "Conversion process interrupted and manual user intervention will be necessary."
            )

        return 1

    return 0