EVOLUTION-NINJA
Edit File: subscription-manager.py
from __future__ import print_function, division, absolute_import # # Copyright (c) 2010 Red Hat, Inc. # # Authors: Jeff Ortel <jortel@redhat.com> # # This software is licensed to you under the GNU General Public License, # version 2 (GPLv2). There is NO WARRANTY for this software, express or # implied, including the implied warranties of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 # along with this software; if not, see # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. # # Red Hat trademarks are not licensed under GPLv2. No permission is # granted to use or replicate Red Hat trademarks that are incorporated # in this software or its documentation. # import os from yum.plugins import TYPE_CORE from subscription_manager import injection as inj from subscription_manager.action_client import ProfileActionClient from subscription_manager.repolib import RepoActionInvoker from subscription_manager.entcertlib import EntCertActionInvoker from rhsmlib.facts.hwprobe import ClassicCheck from subscription_manager.certlib import Locker from subscription_manager.utils import chroot, is_simple_content_access from subscription_manager.injectioninit import init_dep_injection from subscription_manager import logutil from rhsm import config requires_api_version = '2.5' plugin_type = (TYPE_CORE,) # TODO: translate strings expired_warning = """ *** WARNING *** The subscription for following product(s) has expired: %s You no longer have access to the repositories that provide these products. It is important that you apply an active \ subscription in order to resume access to security and other critical updates. If you don't have other active \ subscriptions, you can renew the expired subscription. """ not_registered_warning = """ This system is not registered with an entitlement server. You can use subscription-manager to register. """ no_subs_warning = """ This system is registered with an entitlement server, but is not receiving updates. You can use subscription-manager \ to assign subscriptions. """ no_subs_container_warning = """ This system is not receiving updates. You can use subscription-manager on the host to register and assign subscriptions. """ # If running from the yum plugin, we want to avoid blocking # yum forever on locks created by other rhsm processes. We try # to acquire the lock before potentially updating redhat.repo, but # if we can't, the plugin will fail back to not updating it. # So this class provides a Locker uses the default ACTION_LOCK, # but if it would have to wait for it, it decides to do nothing # instead. class YumRepoLocker(Locker): def __init__(self, conduit): super(YumRepoLocker, self).__init__() self.conduit = conduit def run(self, action): # lock.acquire will return False if it would block # NOTE: acquire can return None, True, or False # with different meanings. non_blocking = self.lock.acquire(blocking=False) if non_blocking is False: # Could try to grab the pid for the log message, but it's a bit of a race. self.conduit.info(3, "Another process has the cert lock. We will not attempt to update certs or repos.") return 0 try: return action() finally: self.lock.release() def update(conduit, cache_only): """ Update entitlement certificates """ if os.getuid() != 0: conduit.info(3, 'Not root, Subscription Management repositories not updated') return conduit.info(3, 'Updating Subscription Management repositories.') identity = inj.require(inj.IDENTITY) if not identity.is_valid(): conduit.info(3, "Unable to read consumer identity") # In containers we have no identity, but we may have entitlements inherited # from the host, which need to generate a redhat.repo. if config.in_container(): conduit.info(3, "Subscription Manager is operating in container mode.") if not cache_only and not config.in_container(): cert_action_invoker = EntCertActionInvoker(locker=YumRepoLocker(conduit=conduit)) cert_action_invoker.update() repo_action_invoker = RepoActionInvoker(cache_only=cache_only, locker=YumRepoLocker(conduit=conduit)) repo_action_invoker.update() def warn_expired_entitlements(conduit): """ When some entitlement is expired, then display warning message about it """ ent_dir = inj.require(inj.ENT_DIR) products = set() for cert in ent_dir.list_expired(): for product in cert.products: m = ' - %s' % product.name products.add(m) if products: msg = expired_warning % '\n'.join(sorted(products)) conduit.info(2, msg) def warn_or_usage_message(conduit): """ Display warning message, when the system is not registered (no consumer cert) or then is no entitlement cert """ if os.getuid() != 0: return if ClassicCheck().is_registered_with_classic(): return msg = "" try: identity = inj.require(inj.IDENTITY) ent_dir = inj.require(inj.ENT_DIR) # Don't warn people to register if we see entitlements, but no identity: if not identity.is_valid() and len(ent_dir.list_valid()) == 0: msg = not_registered_warning elif len(ent_dir.list_valid()) == 0 and not is_simple_content_access(identity=identity): msg = no_subs_warning if config.in_container() and len(ent_dir.list_valid()) == 0: msg = no_subs_container_warning finally: if msg: conduit.info(2, msg) def init_hook(conduit): """ Hook for disabling system repositories (repositories which are not mangaged by subscription-manager will NOT be used) """ disable_system_repos = conduit.confBool('main', 'disable_system_repos', default=False) if disable_system_repos: disable_count = 0 repo_storage = conduit.getRepos() for repo in repo_storage.repos.values(): if os.path.basename(repo.repofile) != "redhat.repo" and repo.enabled is True: conduit.info(2, 'Disabling system repository "%s" in file "%s"' % (repo.id, repo.repofile)) repo_storage.disableRepo(repo.id) disable_count += 1 conduit.info(2, 'subscription-manager plugin disabled "%d" system repositories with respect of configuration in /etc/yum/pluginconf.d/subscription-manager.conf' % (disable_count)) def config_hook(conduit): """ This is the first hook of this yum plugin that is triggered by yum. So we do initialization of all stuff that is necessary by other hooks :param conduit: Reference on conduit object used by yum plugin API :return: None """ logutil.init_logger_for_yum() init_dep_injection() if hasattr(conduit, 'registerPackageName'): conduit.registerPackageName("subscription-manager") def postconfig_hook(conduit): """ Try to display some warning messages, when it is necessary. :param conduit: Reference on conduit object used by yum plugin API :return: None """ # If a tool (it's, e.g., Mock) manages a chroot via 'yum --installroot', # we must update entitlements in that directory. # Note: conduit.getConf() is available in postconfig_hook chroot(conduit.getConf().installroot) cfg = config.initConfig() cache_only = not bool(cfg.get_int('rhsm', 'full_refresh_on_yum')) if hasattr(conduit, 'registerPackageName'): conduit.registerPackageName("subscription-manager") # It is save to display following warning messages for all yum commands, because following functions # does not communicate with candlepin server. See: https://bugzilla.redhat.com/show_bug.cgi?id=1621275 try: update(conduit, cache_only) warn_or_usage_message(conduit) warn_expired_entitlements(conduit) except Exception as e: conduit.error(2, str(e)) def posttrans_hook(conduit): """ Upload package profile after transactions if run as a yum plugin (BZ 1742208) :param conduit: :return: None """ cfg = config.initConfig() if '1' == cfg.get('rhsm', 'package_profile_on_trans'): conduit.info(3, "Updating package profile") package_profile_client = ProfileActionClient() package_profile_client.update() else: # do nothing return