コード例 #1
0
ファイル: payload.py プロジェクト: steffen-maier/anaconda
    def base_repo(self):
        """Get the identifier of the current base repo or None."""
        # is any locking needed here?
        repo_names = [constants.BASE_REPO_NAME] + constants.DEFAULT_REPOS
        with self._repos_lock:
            if self.source_type == SOURCE_TYPE_CDN:
                if is_module_available(SUBSCRIPTION):
                    subscription_proxy = SUBSCRIPTION.get_proxy()
                    if subscription_proxy.IsSubscriptionAttached:
                        # If CDN is used as the installation source and we have
                        # a subscription attached then any of the enabled repos
                        # should be fine as the base repo.
                        # If CDN is used but subscription has not been attached
                        # there will be no redhat.repo file to parse and we
                        # don't need to do anything.
                        for repo in self._base.repos.iter_enabled():
                            return repo.id
                else:
                    log.error("CDN install source set but Subscription module is not available")
            else:
                for repo in self._base.repos.iter_enabled():
                    if repo.id in repo_names:
                        return repo.id

        return None
コード例 #2
0
def unregister(progress_callback=None, error_callback=None):
    """Try to unregister the installation environment.

    NOTE: Unregistering also removes any attached subscriptions

    :param progress_callback: progress callback function, takes one argument, subscription phase
    :type progress_callback: callable(subscription_phase)
    :param error_callback: error callback function, takes one argument, the error message
    :type error_callback: callable(error_message)
    """

    # assign dummy callback functions if none were provided by caller
    if progress_callback is None:
        progress_callback = dummy_progress_callback
    if error_callback is None:
        error_callback = dummy_error_callback

    # connect to the Subscription DBus module
    subscription_proxy = SUBSCRIPTION.get_proxy()

    if subscription_proxy.IsRegistered:
        log.debug("subscription thread: unregistering the system")
        # Make sure to set RHSM config options to be in sync
        # with the current subscription request in the unlikely
        # case of someone doing a valid change in the subscription
        # request since we registered.
        task_path = subscription_proxy.SetRHSMConfigWithTask()
        task_proxy = SUBSCRIPTION.get_proxy(task_path)
        task.sync_run_task(task_proxy)
        progress_callback(SubscriptionPhase.UNREGISTER)
        task_path = subscription_proxy.UnregisterWithTask()
        task_proxy = SUBSCRIPTION.get_proxy(task_path)
        try:
            task.sync_run_task(task_proxy)
        except UnregistrationError as e:
            log.debug("subscription thread: unregistration failed: %s", e)
            error_callback(str(e))
            return
        log.debug("Subscription GUI: unregistration succeeded")
        progress_callback(SubscriptionPhase.DONE)
    else:
        log.warning("subscription thread: not registered, so can't unregister")
        progress_callback(SubscriptionPhase.DONE)
        return
コード例 #3
0
ファイル: payload.py プロジェクト: sandrobonazzola/anaconda
    def _is_cdn_set_up(self):
        """Is the CDN source set up?"""
        if not self.source_type == SOURCE_TYPE_CDN:
            return False

        if not is_module_available(SUBSCRIPTION):
            return False

        subscription_proxy = SUBSCRIPTION.get_proxy()
        return subscription_proxy.IsSubscriptionAttached
コード例 #4
0
ファイル: subscription.py プロジェクト: zhoupeng/anaconda
def is_cdn_registration_required(payload):
    """Check if Red Hat CDN registration is required.

    :param payload: the payload object
    """
    if not check_cdn_is_installation_source(payload):
        return False

    if not is_module_available(SUBSCRIPTION):
        return False

    subscription_proxy = SUBSCRIPTION.get_proxy()
    return not subscription_proxy.IsSubscriptionAttached
コード例 #5
0
ファイル: subscription.py プロジェクト: zhoupeng/anaconda
def username_password_sufficient(subscription_request=None):
    """Report if sufficient credentials are set for username & password registration attempt.

    :param subscription_request: an subscription request, if None a fresh subscription request
                                 will be fetched from the Subscription module over DBus
    :type subscription_request: SubscriptionRequest instance
    :return: True if sufficient, False otherwise
    :rtype: bool
    """
    if subscription_request is None:
        subscription_proxy = SUBSCRIPTION.get_proxy()
        subscription_request_struct = subscription_proxy.SubscriptionRequest
        subscription_request = SubscriptionRequest.from_structure(
            subscription_request_struct)
    username_set = bool(subscription_request.account_username)
    password_set = subscription_request.account_password.type in SECRET_SET_TYPES
    return username_set and password_set
コード例 #6
0
ファイル: subscription.py プロジェクト: zhoupeng/anaconda
def org_keys_sufficient(subscription_request=None):
    """Report if sufficient credentials are set for org & keys registration attempt.

    :param subscription_request: an subscription request, if None a fresh subscription request
                                 will be fetched from the Subscription module over DBus
    :type subscription_request: SubscriptionRequest instance
    :return: True if sufficient, False otherwise
    :rtype: bool
    """
    if subscription_request is None:
        subscription_proxy = SUBSCRIPTION.get_proxy()
        subscription_request_struct = subscription_proxy.SubscriptionRequest
        subscription_request = SubscriptionRequest.from_structure(
            subscription_request_struct)
    organization_set = bool(subscription_request.organization)
    key_set = subscription_request.activation_keys.type in SECRET_SET_TYPES
    return organization_set and key_set
コード例 #7
0
    def status(self):
        if self._error_msgs:
            return _("Error checking software selection")

        cdn_source = check_cdn_is_installation_source(self.payload)

        subscribed = False
        if is_module_available(SUBSCRIPTION):
            subscription_proxy = SUBSCRIPTION.get_proxy()
            subscribed = subscription_proxy.IsSubscriptionAttached

        if cdn_source and not subscribed:
            return _("Red Hat CDN requires registration.")

        if not self.ready:
            return _("Installation source not set up")

        if not self.txid_valid:
            return _("Source changed - please verify")

        # kickstart installation
        if flags.automatedInstall:
            if self._kickstarted:
                # %packages section is present in kickstart but environment is not set
                if not self._selection.environment:
                    return _("Custom software selected")
                # environment is set to an invalid value
                elif not self.is_environment_valid(
                        self._selection.environment):
                    return _("Invalid environment specified in kickstart")
            # we have no packages section in the kickstart and no environment has been set
            elif not self._selection.environment:
                return _("Please confirm software selection")

        if not flags.automatedInstall:
            if not self._selection.environment:
                # No environment yet set
                return _("Please confirm software selection")
            elif not self.is_environment_valid(self._selection.environment):
                # selected environment is not valid, this can happen when a valid environment
                # is selected (by default, manually or from kickstart) and then the installation
                # source is switched to one where the selected environment is no longer valid
                return _("Selected environment is not valid")

        return self.payload.environment_description(
            self._selection.environment)[0]
コード例 #8
0
    def _apply_system_purpose_data(self):
        """Apply system purpose data to the installation environment.

        Apply system purpose data to the installation environment, provided that:
        - system purpose data has not yet been applied to the system
        or
        - current system purpose data is different from the data last applied to the system

        Due to that we keep a copy of the last applied system purpose data so that we can
        check for difference.

        If the last applied data is the same as current system purpose data, nothing is done.
        """
        if self._last_applied_system_purpose_data != self.system_purpose_data:
            log.debug("Subscription GUI: applying system purpose data to installation environment")
            task_path = self._subscription_module.SetSystemPurposeWithTask()
            task_proxy = SUBSCRIPTION.get_proxy(task_path)
            sync_run_task(task_proxy)
            self._last_applied_system_purpose_data = self.system_purpose_data
コード例 #9
0
ファイル: subscription.py プロジェクト: smclay/anaconda
    def __init__(self, *args):
        super().__init__(*args)

        # connect to the Subscription DBus module API
        self._subscription_module = SUBSCRIPTION.get_proxy()

        # connect to the Network DBus module API
        self._network_module = NETWORK.get_proxy()

        # get initial data from the Subscription module
        self._subscription_request = self._get_subscription_request()
        self._system_purpose_data = self._get_system_purpose_data()
        # Keep a copy of system purpose data that has been last applied to
        # the installation environment.
        # That way we can check if the main copy of the system purposed data
        # changed since it was applied (for example due to user input)
        # and needs to be reapplied.
        # By default this variable is None and will only be set to a
        # SystemPurposeData instance when first system purpose data is
        # applied to the installation environment.
        self._last_applied_system_purpose_data = None

        self._authentication_method = AuthenticationMethod.USERNAME_PASSWORD

        self._registration_error = ""
        self._registration_phase = None
        self._registration_controls_enabled = True

        # Red Hat Insights should be enabled by default for non-kickstart installs.
        #
        # For kickstart installations we will use the value from the module, which
        # False by default & can be set to True via the rhsm kickstart command.
        if not flags.automatedInstall:
            self._subscription_module.SetInsightsEnabled(True)

        # previous visit network connectivity tracking
        self._network_connected_previously = False

        # overriden source tracking
        self._overridden_source_type = None

        self._spoke_initialized = False
コード例 #10
0
def _prepare_configuration(payload, ksdata):
    """Configure the installed system."""

    configuration_queue = TaskQueue("Configuration queue")
    # connect progress reporting
    configuration_queue.queue_started.connect(
        lambda x: progress_message(x.status_message))
    configuration_queue.task_completed.connect(lambda x: progress_step(x.name))

    # add installation tasks for the Subscription DBus module
    if is_module_available(SUBSCRIPTION):
        # we only run the tasks if the Subscription module is available
        subscription_config = TaskQueue("Subscription configuration",
                                        N_("Configuring Red Hat subscription"))
        subscription_proxy = SUBSCRIPTION.get_proxy()
        subscription_dbus_tasks = subscription_proxy.InstallWithTasks()
        subscription_config.append_dbus_tasks(SUBSCRIPTION,
                                              subscription_dbus_tasks)
        configuration_queue.append(subscription_config)

    # schedule the execute methods of ksdata that require an installed system to be present
    os_config = TaskQueue("Installed system configuration",
                          N_("Configuring installed system"))

    # add installation tasks for the Security DBus module
    security_proxy = SECURITY.get_proxy()
    security_dbus_tasks = security_proxy.InstallWithTasks()
    os_config.append_dbus_tasks(SECURITY, security_dbus_tasks)

    # add installation tasks for the Timezone DBus module
    # run these tasks before tasks of the Services module
    if is_module_available(TIMEZONE):
        timezone_proxy = TIMEZONE.get_proxy()
        timezone_dbus_tasks = timezone_proxy.InstallWithTasks()
        os_config.append_dbus_tasks(TIMEZONE, timezone_dbus_tasks)

    # add installation tasks for the Services DBus module
    services_proxy = SERVICES.get_proxy()
    services_dbus_tasks = services_proxy.InstallWithTasks()
    os_config.append_dbus_tasks(SERVICES, services_dbus_tasks)

    # add installation tasks for the Localization DBus module
    if is_module_available(LOCALIZATION):
        localization_proxy = LOCALIZATION.get_proxy()
        localization_dbus_tasks = localization_proxy.InstallWithTasks()
        os_config.append_dbus_tasks(LOCALIZATION, localization_dbus_tasks)

    # add the Firewall configuration task
    if conf.target.can_configure_network:
        firewall_proxy = NETWORK.get_proxy(FIREWALL)
        firewall_dbus_task = firewall_proxy.InstallWithTask()
        os_config.append_dbus_tasks(NETWORK, [firewall_dbus_task])

    configuration_queue.append(os_config)

    # schedule network configuration (if required)
    if conf.target.can_configure_network and conf.system.provides_network_config:
        overwrite = payload.type in PAYLOAD_LIVE_TYPES
        network_config = TaskQueue("Network configuration",
                                   N_("Writing network configuration"))
        network_config.append(
            Task("Network configuration", network.write_configuration,
                 (overwrite, )))
        configuration_queue.append(network_config)

    # add installation tasks for the Users DBus module
    if is_module_available(USERS):
        user_config = TaskQueue("User creation", N_("Creating users"))
        users_proxy = USERS.get_proxy()
        users_dbus_tasks = users_proxy.InstallWithTasks()
        user_config.append_dbus_tasks(USERS, users_dbus_tasks)
        configuration_queue.append(user_config)

    # Anaconda addon configuration
    addon_config = TaskQueue("Anaconda addon configuration",
                             N_("Configuring addons"))

    # there is no longer a User class & addons should no longer need it
    # FIXME: drop user class parameter from the API & all known addons
    addon_config.append(
        Task("Configure Anaconda addons", ksdata.addons.execute,
             (None, ksdata, None, payload)))

    boss_proxy = BOSS.get_proxy()
    addon_config.append_dbus_tasks(BOSS, [boss_proxy.InstallSystemWithTask()])

    configuration_queue.append(addon_config)

    # Initramfs generation
    generate_initramfs = TaskQueue("Initramfs generation",
                                   N_("Generating initramfs"))
    bootloader_proxy = STORAGE.get_proxy(BOOTLOADER)

    def run_generate_initramfs():
        tasks = bootloader_proxy.GenerateInitramfsWithTasks(
            payload.type, payload.kernel_version_list)

        for task in tasks:
            sync_run_task(STORAGE.get_proxy(task))

    generate_initramfs.append(
        Task("Generate initramfs", run_generate_initramfs))
    configuration_queue.append(generate_initramfs)

    # Configure FIPS.
    configuration_queue.append_dbus_tasks(
        SECURITY, [security_proxy.ConfigureFIPSWithTask()])

    # realm join
    # - this can run only after network is configured in the target system chroot
    configuration_queue.append_dbus_tasks(SECURITY,
                                          [security_proxy.JoinRealmWithTask()])

    post_scripts = TaskQueue("Post installation scripts",
                             N_("Running post-installation scripts"))
    post_scripts.append(
        Task("Run post installation scripts", runPostScripts,
             (ksdata.scripts, )))
    configuration_queue.append(post_scripts)

    # setup kexec reboot if requested
    if flags.flags.kexec:
        kexec_setup = TaskQueue("Kexec setup", N_("Setting up kexec"))
        kexec_setup.append(Task("Setup kexec", setup_kexec))
        configuration_queue.append(kexec_setup)

    # write anaconda related configs & kickstarts
    write_configs = TaskQueue("Write configs and kickstarts",
                              N_("Storing configuration files and kickstarts"))

    # Write the kickstart file to the installed system (or, copy the input
    # kickstart file over if one exists).
    if flags.flags.nosave_output_ks:
        # don't write the kickstart file to the installed system if this has
        # been disabled by the nosave option
        log.warning(
            "Writing of the output kickstart to installed system has been disabled"
            " by the nosave option.")
    else:
        # write anaconda related configs & kickstarts
        write_configs.append(Task("Store kickstarts", _writeKS, (ksdata, )))

    # only add write_configs to the main queue if we actually store some kickstarts/configs
    if write_configs.task_count:
        configuration_queue.append(write_configs)

    return configuration_queue
コード例 #11
0
ファイル: payload.py プロジェクト: steffen-maier/anaconda
    def update_base_repo(self, fallback=True, checkmount=True):
        """Update the base repository from the DBus source."""
        log.info("Configuring the base repo")
        self._reset_configuration()

        disabled_treeinfo_repo_names = self._cleanup_old_treeinfo_repositories()

        # Find the source and its type.
        source_proxy = self.get_source_proxy()
        source_type = source_proxy.Type

        # Change the default source to CDROM if there is a valid install media.
        # FIXME: Set up the default source earlier.
        if checkmount and self._is_source_default() and find_optical_install_media():
            source_type = SOURCE_TYPE_CDROM
            source_proxy = create_source(source_type)
            set_source(self.proxy, source_proxy)

        # Set up the source.
        set_up_sources(self.proxy)

        # Read in all the repos from the installation environment, make a note of which
        # are enabled, and then disable them all.  If the user gave us a method, we want
        # to use that instead of the default repos.
        self._base.read_all_repos()

        # Enable or disable updates.
        self.set_updates_enabled(self._updates_enabled)

        # Repo files are always loaded from the system.
        # When reloaded their state needs to be synchronized with the user configuration.
        # So we disable them now and enable them later if required.
        enabled = []
        with self._repos_lock:
            for repo in self._base.repos.iter_enabled():
                enabled.append(repo.id)
                repo.disable()

        # Add a new repo.
        if source_type not in SOURCE_REPO_FILE_TYPES:
            # Get the repo configuration of the first source.
            data = RepoConfigurationData.from_structure(
                self.proxy.GetRepoConfigurations()[0]
            )

            log.debug("Using the repo configuration: %s", data)

            # Get the URL.
            install_tree_url = data.url if data.type == URL_TYPE_BASEURL else ""
            mirrorlist = data.url if data.type == URL_TYPE_MIRRORLIST else ""
            metalink = data.url if data.type == URL_TYPE_METALINK else ""

            # Fallback to the installation root.
            base_repo_url = install_tree_url

            try:
                self._refresh_install_tree(data)
                self._base.conf.releasever = self._get_release_version(install_tree_url)
                base_repo_url = self._get_base_repo_location(install_tree_url)
                log.debug("releasever from %s is %s", base_repo_url, self._base.conf.releasever)

                self._load_treeinfo_repositories(base_repo_url, disabled_treeinfo_repo_names, data)
            except configparser.MissingSectionHeaderError as e:
                log.error("couldn't set releasever from base repo (%s): %s", source_type, e)

            try:
                base_ksrepo = self.data.RepoData(
                    name=constants.BASE_REPO_NAME,
                    baseurl=base_repo_url,
                    mirrorlist=mirrorlist,
                    metalink=metalink,
                    noverifyssl=not data.ssl_verification_enabled,
                    proxy=data.proxy,
                    sslcacert=data.ssl_configuration.ca_cert_path,
                    sslclientcert=data.ssl_configuration.client_cert_path,
                    sslclientkey=data.ssl_configuration.client_key_path
                )
                self._add_repo_to_dnf(base_ksrepo)
                self._fetch_md(base_ksrepo.name)
            except (MetadataError, PayloadError) as e:
                log.error("base repo (%s/%s) not valid -- removing it",
                          source_type, base_repo_url)
                log.error("reason for repo removal: %s", e)
                with self._repos_lock:
                    self._base.repos.pop(constants.BASE_REPO_NAME, None)
                if not fallback:
                    with self._repos_lock:
                        for repo in self._base.repos.iter_enabled():
                            self._disable_repo(repo.id)
                    return

                # Fallback to the default source
                #
                # This is at the moment CDN on RHEL
                # and closest mirror everywhere else.
                tear_down_sources(self.proxy)

                source_type = conf.payload.default_source
                source_proxy = create_source(source_type)
                set_source(self.proxy, source_proxy)

                set_up_sources(self.proxy)

        # We need to check this again separately in case REPO_FILES were set above.
        if source_type in SOURCE_REPO_FILE_TYPES:

            # If this is a kickstart install, just return now as we normally do not
            # want to read the on media repo files in such a case. On the other hand,
            # the local repo files are a valid use case if the system is subscribed
            # and the CDN is selected as the installation source.
            if self.source_type == SOURCE_TYPE_CDN and is_module_available(SUBSCRIPTION):
                # only check if the Subscription module is available & CDN is the
                # installation source
                subscription_proxy = SUBSCRIPTION.get_proxy()
                load_cdn_repos = subscription_proxy.IsSubscriptionAttached
            else:
                # if the Subscription module is not available, we simply can't use
                # the CDN repos, making our decision here simple
                load_cdn_repos = False
            if flags.automatedInstall and not load_cdn_repos:
                return

            # Otherwise, fall back to the default repos that we disabled above
            with self._repos_lock:
                for (id_, repo) in self._base.repos.items():
                    if id_ in enabled:
                        log.debug("repo %s: fall back enabled from default repos", id_)
                        repo.enable()

        for repo in self.addons:
            ksrepo = self.get_addon_repo(repo)

            if ksrepo.is_harddrive_based():
                ksrepo.baseurl = self._setup_harddrive_addon_repo(ksrepo)

            log.debug("repo %s: mirrorlist %s, baseurl %s, metalink %s",
                      ksrepo.name, ksrepo.mirrorlist, ksrepo.baseurl, ksrepo.metalink)
            # one of these must be set to create new repo
            if not (ksrepo.mirrorlist or ksrepo.baseurl or ksrepo.metalink or
                    ksrepo.name in self._base.repos):
                raise PayloadSetupError("Repository %s has no mirror, baseurl or "
                                        "metalink set and is not one of "
                                        "the pre-defined repositories" %
                                        ksrepo.name)

            self._add_repo_to_dnf(ksrepo)

        with self._repos_lock:

            # disable unnecessary repos
            for repo in self._base.repos.iter_enabled():
                id_ = repo.id
                if 'source' in id_ or 'debuginfo' in id_:
                    self._disable_repo(id_)
                elif constants.isFinal and 'rawhide' in id_:
                    self._disable_repo(id_)

            # fetch md for enabled repos
            enabled_repos = self._enabled_repos
            for repo_name in self.addons:
                if repo_name in enabled_repos:
                    self._fetch_md(repo_name)
コード例 #12
0
ファイル: subscription.py プロジェクト: zhoupeng/anaconda
def unregister(payload,
               overridden_source_type,
               progress_callback=None,
               error_callback=None,
               restart_payload=False):
    """Try to unregister the installation environment.

    NOTE: Unregistering also removes any attached subscriptions and
          if an installation source has been overridden, switches
          back to it.

    :param payload: Anaconda payload instance
    :param overridden_source_type: type of the source that was overridden by the CDN source at
                             registration time (if any)
    :param progress_callback: progress callback function, takes one argument, subscription phase
    :type progress_callback: callable(subscription_phase)
    :param error_callback: error callback function, takes one argument, the error message
    :type error_callback: callable(error_message)
    :param bool restart_payload: should payload restart be attempted if it appears necessary ?

    NOTE: For more information about the restart_payload attribute, see the
          register_and_subscribe() function doc string.
    """

    # assign dummy callback functions if none were provided by caller
    if progress_callback is None:
        progress_callback = dummy_progress_callback
    if error_callback is None:
        error_callback = dummy_error_callback

    # connect to the Subscription DBus module
    subscription_proxy = SUBSCRIPTION.get_proxy()

    if subscription_proxy.IsRegistered:
        log.debug("subscription thread: unregistering the system")
        # Make sure to set RHSM config options to be in sync
        # with the current subscription request in the unlikely
        # case of someone doing a valid change in the subscription
        # request since we registered.
        task_path = subscription_proxy.SetRHSMConfigWithTask()
        task_proxy = SUBSCRIPTION.get_proxy(task_path)
        task.sync_run_task(task_proxy)
        progress_callback(SubscriptionPhase.UNREGISTER)
        task_path = subscription_proxy.UnregisterWithTask()
        task_proxy = SUBSCRIPTION.get_proxy(task_path)
        try:
            task.sync_run_task(task_proxy)
        except UnregistrationError as e:
            log.debug("subscription thread: unregistration failed: %s", e)
            error_callback(str(e))
            return

        # If the CDN overrode an installation source we should revert that
        # on unregistration, provided CDN is the current source.
        source_proxy = payload.get_source_proxy()
        switched_source = False
        if payload.type == PAYLOAD_TYPE_DNF:
            if source_proxy.Type == SOURCE_TYPE_CDN and overridden_source_type:
                log.debug(
                    "subscription thread: rolling back CDN installation source override"
                )
                switch_source(payload, overridden_source_type)
                switched_source = True

            # If requested, also restart the payload if:
            # - installation source switch occured
            # - the current source is CDN, which can no longer be used
            #   after unregistration, so we need to refresh the Source
            #   and Software spokes
            if restart_payload and (source_proxy.Type == SOURCE_TYPE_CDN
                                    or switched_source):
                log.debug(
                    "subscription thread: restarting payload after unregistration"
                )
                _do_payload_restart(payload)

        log.debug("Subscription GUI: unregistration succeeded")
        progress_callback(SubscriptionPhase.DONE)
    else:
        log.warning("subscription thread: not registered, so can't unregister")
        progress_callback(SubscriptionPhase.DONE)
        return
コード例 #13
0
ファイル: subscription.py プロジェクト: zhoupeng/anaconda
def register_and_subscribe(payload,
                           progress_callback=None,
                           error_callback=None,
                           restart_payload=False):
    """Try to register and subscribe the installation environment.

    :param payload: Anaconda payload instance
    :param progress_callback: progress callback function, takes one argument, subscription phase
    :type progress_callback: callable(subscription_phase)
    :param error_callback: error callback function, takes one argument, the error message
    :type error_callback: callable(error_message)
    :param bool restart_payload: should payload restart be attempted if it appears necessary ?

    NOTE: The restart_payload attribute controls if the subscription helper function should
          attempt to restart the payload thread if it deems it necessary (DVD -> CDN switch,
          registration with CDN source, etc.). If restart_payload is True, it might restart
          the payload. If it is False, it well never try to do that.

          The main usecase of this at the moment is when the subscription helper function
          is invoked during early Anaconda kickstart installation. At this stage the initial
          payload restart has not yet been run and starting it too early could lead to various
          issues. At this stage we don't want the helper function to restart payload, so we keep
          restart_payload at default value (False). Later on during manual user interaction we
          definitely want payload to be restarted as needed (the initial restart long done)
          and so we pass restart_payload=True.
    """

    # assign dummy callback functions if none were provided by caller
    if progress_callback is None:
        progress_callback = dummy_progress_callback
    if error_callback is None:
        error_callback = dummy_error_callback

    # connect to the Subscription DBus module
    subscription_proxy = SUBSCRIPTION.get_proxy()

    # First make sure network connectivity is available
    # by waiting for the connectivity check thread
    # to finish, in case it is running, usually early
    # during Anaconda startup.
    threadMgr.wait(THREAD_WAIT_FOR_CONNECTING_NM)

    # Next we make sure to set RHSM config options
    # to be in sync with the current subscription request.
    task_path = subscription_proxy.SetRHSMConfigWithTask()
    task_proxy = SUBSCRIPTION.get_proxy(task_path)
    task.sync_run_task(task_proxy)

    # Then check if we are not already registered.
    #
    # In some fairly bizarre cases it is apparently
    # possible that registration & attach will succeed,
    # but the attached subscription will be incomplete
    # and/or invalid. These cases will be caught by
    # the subscription token check and marked as failed
    # by Anaconda.
    #
    # It is also possible that registration succeeds,
    # but attach fails.
    #
    # To make recovery and another registration attempt
    # possible, we need to first unregister the already
    # registered system, as a registration attempt on
    # an already registered system would fail.
    if subscription_proxy.IsRegistered:
        log.debug(
            "subscription thread: system already registered, unregistering")
        progress_callback(SubscriptionPhase.UNREGISTER)
        task_path = subscription_proxy.UnregisterWithTask()
        task_proxy = SUBSCRIPTION.get_proxy(task_path)
        try:
            task.sync_run_task(task_proxy)
        except UnregistrationError as e:
            log.debug("subscription thread: unregistration failed: %s", e)
            # Failing to unregister the system is an unrecoverable error,
            # so we end there.
            error_callback(str(e))
            return
        log.debug("Subscription GUI: unregistration succeeded")

    # Try to register.
    #
    # If we got this far the system was either not registered
    # or was unregistered successfully.
    log.debug("subscription thread: attempting to register")
    progress_callback(SubscriptionPhase.REGISTER)
    # check authentication method has been set and credentials seem to be
    # sufficient (though not necessarily valid)
    subscription_request_struct = subscription_proxy.SubscriptionRequest
    subscription_request = SubscriptionRequest.from_structure(
        subscription_request_struct)
    task_path = None
    if subscription_request.type == SUBSCRIPTION_REQUEST_TYPE_USERNAME_PASSWORD:
        if username_password_sufficient():
            task_path = subscription_proxy.RegisterUsernamePasswordWithTask()
    elif subscription_request.type == SUBSCRIPTION_REQUEST_TYPE_ORG_KEY:
        if org_keys_sufficient():
            task_path = subscription_proxy.RegisterOrganizationKeyWithTask()

    if task_path:
        task_proxy = SUBSCRIPTION.get_proxy(task_path)
        try:
            task.sync_run_task(task_proxy)
        except RegistrationError as e:
            log.debug("subscription thread: registration attempt failed: %s",
                      e)
            log.debug(
                "subscription thread: skipping auto attach due to registration error"
            )
            error_callback(str(e))
            return
        log.debug("subscription thread: registration succeeded")
    else:
        log.debug(
            "subscription thread: credentials insufficient, skipping registration attempt"
        )
        error_callback(
            _("Registration failed due to insufficient credentials."))
        return

    # try to attach subscription
    log.debug("subscription thread: attempting to auto attach an entitlement")
    progress_callback(SubscriptionPhase.ATTACH_SUBSCRIPTION)
    task_path = subscription_proxy.AttachSubscriptionWithTask()
    task_proxy = SUBSCRIPTION.get_proxy(task_path)
    try:
        task.sync_run_task(task_proxy)
    except SubscriptionError as e:
        log.debug("subscription thread: failed to attach subscription: %s", e)
        error_callback(str(e))
        return

    # parse attached subscription data
    log.debug("subscription thread: parsing attached subscription data")
    task_path = subscription_proxy.ParseAttachedSubscriptionsWithTask()
    task_proxy = SUBSCRIPTION.get_proxy(task_path)
    task.sync_run_task(task_proxy)

    # check if the current installation source should be overridden by
    # the CDN source we can now use
    # - at the moment this is true only for the CDROM source
    source_proxy = payload.get_source_proxy()
    if payload.type == PAYLOAD_TYPE_DNF:
        if source_proxy.Type in SOURCE_TYPES_OVERRIDEN_BY_CDN:
            log.debug(
                "subscription thread: overriding current installation source by CDN"
            )
            switch_source(payload, SOURCE_TYPE_CDN)
        # If requested, also restart the payload if CDN is the installation source
        # The CDN either already was the installation source or we just switched to it.
        #
        # Make sure to get fresh source proxy as the old one might be stale after
        # a source switch.
        source_proxy = payload.get_source_proxy()
        if restart_payload and source_proxy.Type == SOURCE_TYPE_CDN:
            log.debug(
                "subscription thread: restarting payload after registration")
            _do_payload_restart(payload)

    # and done, report attaching subscription was successful
    log.debug("subscription thread: auto attach succeeded")
    progress_callback(SubscriptionPhase.DONE)
コード例 #14
0
def register_and_subscribe(payload,
                           progress_callback=None,
                           error_callback=None):
    """Try to register and subscribe the installation environment.

    :param payload: Anaconda payload instance
    :param progress_callback: progress callback function, takes one argument, subscription phase
    :type progress_callback: callable(subscription_phase)
    :param error_callback: error callback function, takes one argument, the error message
    :type error_callback: callable(error_message)
    """

    # assign dummy callback functions if none were provided by caller
    if progress_callback is None:
        progress_callback = dummy_progress_callback
    if error_callback is None:
        error_callback = dummy_error_callback

    # connect to the Subscription DBus module
    subscription_proxy = SUBSCRIPTION.get_proxy()

    # First make sure network connectivity is available
    # by waiting for the connectivity check thread
    # to finish, in case it is running, usually early
    # during Anaconda startup.
    threadMgr.wait(THREAD_WAIT_FOR_CONNECTING_NM)

    # Next we make sure to set RHSM config options
    # to be in sync with the current subscription request.
    task_path = subscription_proxy.SetRHSMConfigWithTask()
    task_proxy = SUBSCRIPTION.get_proxy(task_path)
    task.sync_run_task(task_proxy)

    # Then check if we are not already registered.
    #
    # In some fairly bizarre cases it is apparently
    # possible that registration & attach will succeed,
    # but the attached subscription will be incomplete
    # and/or invalid. These cases will be caught by
    # the subscription token check and marked as failed
    # by Anaconda.
    #
    # It is also possible that registration succeeds,
    # but attach fails.
    #
    # To make recovery and another registration attempt
    # possible, we need to first unregister the already
    # registered system, as a registration attempt on
    # an already registered system would fail.
    if subscription_proxy.IsRegistered:
        log.debug(
            "subscription thread: system already registered, unregistering")
        progress_callback(SubscriptionPhase.UNREGISTER)
        task_path = subscription_proxy.UnregisterWithTask()
        task_proxy = SUBSCRIPTION.get_proxy(task_path)
        try:
            task.sync_run_task(task_proxy)
        except UnregistrationError as e:
            log.debug("subscription thread: unregistration failed: %s", e)
            # Failing to unregister the system is an unrecoverable error,
            # so we end there.
            error_callback(str(e))
            return
        log.debug("Subscription GUI: unregistration succeeded")

    # Try to register.
    #
    # If we got this far the system was either not registered
    # or was unregistered successfully.
    log.debug("subscription thread: attempting to register")
    progress_callback(SubscriptionPhase.REGISTER)
    # check authentication method has been set and credentials seem to be
    # sufficient (though not necessarily valid)
    subscription_request_struct = subscription_proxy.SubscriptionRequest
    subscription_request = SubscriptionRequest.from_structure(
        subscription_request_struct)
    task_path = None
    if subscription_request.type == SUBSCRIPTION_REQUEST_TYPE_USERNAME_PASSWORD:
        if username_password_sufficient():
            task_path = subscription_proxy.RegisterUsernamePasswordWithTask()
    elif subscription_request.type == SUBSCRIPTION_REQUEST_TYPE_ORG_KEY:
        if org_keys_sufficient():
            task_path = subscription_proxy.RegisterOrganizationKeyWithTask()

    if task_path:
        task_proxy = SUBSCRIPTION.get_proxy(task_path)
        try:
            task.sync_run_task(task_proxy)
        except RegistrationError as e:
            log.debug("subscription thread: registration attempt failed: %s",
                      e)
            log.debug(
                "subscription thread: skipping auto attach due to registration error"
            )
            error_callback(str(e))
            return
        log.debug("subscription thread: registration succeeded")
    else:
        log.debug(
            "subscription thread: credentials insufficient, skipping registration attempt"
        )
        error_callback(
            _("Registration failed due to insufficient credentials."))
        return

    # try to attach subscription
    log.debug("subscription thread: attempting to auto attach an entitlement")
    progress_callback(SubscriptionPhase.ATTACH_SUBSCRIPTION)
    task_path = subscription_proxy.AttachSubscriptionWithTask()
    task_proxy = SUBSCRIPTION.get_proxy(task_path)
    try:
        task.sync_run_task(task_proxy)
    except SubscriptionError as e:
        log.debug("subscription thread: failed to attach subscription: %s", e)
        error_callback(str(e))
        return

    # parse attached subscription data
    log.debug("subscription thread: parsing attached subscription data")
    task_path = subscription_proxy.ParseAttachedSubscriptionsWithTask()
    task_proxy = SUBSCRIPTION.get_proxy(task_path)
    task.sync_run_task(task_proxy)

    # report attaching subscription was successful
    log.debug("subscription thread: auto attach succeeded")
    # set CDN as installation source now that we can use it
    log.debug("subscription thread: setting CDN as installation source")
    set_source_cdn(payload)
    # and done
    progress_callback(SubscriptionPhase.DONE)
コード例 #15
0
def unregister(payload,
               overridden_source_type,
               progress_callback=None,
               error_callback=None):
    """Try to unregister the installation environment.

    NOTE: Unregistering also removes any attached subscriptions and
          if an installation source has been overridden, switches
          back to it.

    :param payload: Anaconda payload instance
    :param overridden_source_type: type of the source that was overridden by the CDN source at
                             registration time (if any)
    :param progress_callback: progress callback function, takes one argument, subscription phase
    :type progress_callback: callable(subscription_phase)
    :param error_callback: error callback function, takes one argument, the error message
    :type error_callback: callable(error_message)
    """

    # assign dummy callback functions if none were provided by caller
    if progress_callback is None:
        progress_callback = dummy_progress_callback
    if error_callback is None:
        error_callback = dummy_error_callback

    # connect to the Subscription DBus module
    subscription_proxy = SUBSCRIPTION.get_proxy()

    if subscription_proxy.IsRegistered:
        log.debug("subscription thread: unregistering the system")
        # Make sure to set RHSM config options to be in sync
        # with the current subscription request in the unlikely
        # case of someone doing a valid change in the subscription
        # request since we registered.
        task_path = subscription_proxy.SetRHSMConfigWithTask()
        task_proxy = SUBSCRIPTION.get_proxy(task_path)
        task.sync_run_task(task_proxy)
        progress_callback(SubscriptionPhase.UNREGISTER)
        task_path = subscription_proxy.UnregisterWithTask()
        task_proxy = SUBSCRIPTION.get_proxy(task_path)
        try:
            task.sync_run_task(task_proxy)
        except UnregistrationError as e:
            log.debug("subscription thread: unregistration failed: %s", e)
            error_callback(str(e))
            return

        # If the CDN overrode an installation source we should revert that
        # on unregistration, provided CDN is the current source.
        source_proxy = payload.get_source_proxy()
        should_override = source_proxy.Type == SOURCE_TYPE_CDN and overridden_source_type
        if payload.type == PAYLOAD_TYPE_DNF and should_override:
            log.debug(
                "subscription thread: rolling back installation source override by the CDN"
            )
            switch_source(payload, overridden_source_type)

        log.debug("Subscription GUI: unregistration succeeded")
        progress_callback(SubscriptionPhase.DONE)
    else:
        log.warning("subscription thread: not registered, so can't unregister")
        progress_callback(SubscriptionPhase.DONE)
        return