diff --git a/src/subscription_manager/repofile.py b/src/subscription_manager/repofile.py index cc9880349..cb05b57fb 100644 --- a/src/subscription_manager/repofile.py +++ b/src/subscription_manager/repofile.py @@ -23,6 +23,7 @@ import re import string import sys +from importlib import util as importlib_util try: from debian.deb822 import Deb822 @@ -31,6 +32,11 @@ except ImportError: HAS_DEB822 = False +if importlib_util.find_spec("zypp_plugin") is not None: + HAS_ZYPP = True +else: + HAS_ZYPP = False + from subscription_manager import utils from subscription_manager.certdirectory import Path import configparser @@ -562,15 +568,17 @@ def section(self, section: str) -> "Repo": return Repo(section, self.items(section)) -class ZypperRepoFile(YumRepoFile): - """ - Class for manipulation of repo file on systems using Zypper (SuSE, OpenSuse). - """ +if HAS_ZYPP: - ZYPP_RHSM_PLUGIN_CONFIG_FILE = "/etc/rhsm/zypper.conf" - PATH = "etc/rhsm/zypper.repos.d" - NAME = "redhat.repo" - REPOFILE_HEADER = """# + class ZypperRepoFile(YumRepoFile): + """ + Class for manipulation of repo file on systems using Zypper (SuSE, OpenSuse). + """ + + ZYPP_RHSM_PLUGIN_CONFIG_FILE = "/etc/rhsm/zypper.conf" + PATH = "etc/rhsm/zypper.repos.d" + NAME = "redhat.repo" + REPOFILE_HEADER = """# # Certificate-Based Repositories # Managed by (rhsm) subscription-manager # @@ -582,120 +590,124 @@ class ZypperRepoFile(YumRepoFile): # """ - def __init__(self, path: Optional[str] = None, name: Optional[str] = None): - super(ZypperRepoFile, self).__init__(path, name) - self.gpgcheck: bool = False - self.repo_gpgcheck: bool = False - self.autorefresh: bool = False - # According to - # https://github.com/openSUSE/libzypp/blob/67f55b474d67f77c1868955da8542a7acfa70a9f/zypp/media/MediaManager.h#L394 - # the following values are valid: "yes", "no", "host", "peer" - self.gpgkey_ssl_verify: Optional[str] = None - self.repo_ssl_verify: Optional[str] = None - - def read_zypp_conf(self): - """ - Read configuration file for zypper plugin - :return: None - """ - zypp_cfg = configparser.ConfigParser() - zypp_cfg.read(self.ZYPP_RHSM_PLUGIN_CONFIG_FILE) - if zypp_cfg.has_option("rhsm-plugin", "gpgcheck"): - self.gpgcheck = zypp_cfg.getboolean("rhsm-plugin", "gpgcheck") - if zypp_cfg.has_option("rhsm-plugin", "repo_gpgcheck"): - self.repo_gpgcheck = zypp_cfg.getboolean("rhsm-plugin", "repo_gpgcheck") - if zypp_cfg.has_option("rhsm-plugin", "autorefresh"): - self.autorefresh = zypp_cfg.getboolean("rhsm-plugin", "autorefresh") - if zypp_cfg.has_option("rhsm-plugin", "gpgkey-ssl-verify"): - self.gpgkey_ssl_verify = zypp_cfg.get("rhsm-plugin", "gpgkey-ssl-verify") - if zypp_cfg.has_option("rhsm-plugin", "repo-ssl-verify"): - self.repo_ssl_verify = zypp_cfg.get("rhsm-plugin", "repo-ssl-verify") - - def fix_content(self, content: "Content") -> str: - self.read_zypp_conf() - zypper_cont = content.copy() - sslverify = zypper_cont["sslverify"] - sslcacert = zypper_cont["sslcacert"] - sslclientkey = zypper_cont["sslclientkey"] - sslclientcert = zypper_cont["sslclientcert"] - proxy = zypper_cont["proxy"] - proxy_username = zypper_cont["proxy_username"] - proxy_password = zypper_cont["proxy_password"] - - del zypper_cont["sslverify"] - del zypper_cont["sslcacert"] - del zypper_cont["sslclientkey"] - del zypper_cont["sslclientcert"] - del zypper_cont["proxy"] - del zypper_cont["proxy_username"] - del zypper_cont["proxy_password"] - # NOTE looks like metadata_expire and ui_repoid_vars are ignored by zypper - - # clean up data for zypper - if zypper_cont["gpgkey"] in ["https://", "http://"]: - del zypper_cont["gpgkey"] - - # make sure gpg key download doesn't fail because of private certs - if zypper_cont["gpgkey"] and self.gpgkey_ssl_verify: - zypper_cont["gpgkey"] += "?ssl_verify=%s" % self.gpgkey_ssl_verify - - # See BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1764265 - if self.gpgcheck is False: - zypper_cont["gpgcheck"] = "0" - - # See BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1858231 - if self.repo_gpgcheck is True: - zypper_cont["repo_gpgcheck"] = "1" - else: - zypper_cont["repo_gpgcheck"] = "0" - - # See BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1797386 - if self.autorefresh is True: - zypper_cont["autorefresh"] = "1" - else: - zypper_cont["autorefresh"] = "0" - - baseurl = zypper_cont["baseurl"] - parsed = urlparse(baseurl) - zypper_query_args: Dict[str, str] = parse_qs(parsed.query) + def __init__(self, path: Optional[str] = None, name: Optional[str] = None): + super(ZypperRepoFile, self).__init__(path, name) + self.gpgcheck: bool = False + self.repo_gpgcheck: bool = False + self.autorefresh: bool = False + # According to + # https://github.com/openSUSE/libzypp/blob/67f55b474d67f77c1868955da8542a7acfa70a9f/zypp/media/MediaManager.h#L394 + # the following values are valid: "yes", "no", "host", "peer" + self.gpgkey_ssl_verify: Optional[str] = None + self.repo_ssl_verify: Optional[str] = None + + def read_zypp_conf(self): + """ + Read configuration file for zypper plugin + :return: None + """ + zypp_cfg = configparser.ConfigParser() + zypp_cfg.read(self.ZYPP_RHSM_PLUGIN_CONFIG_FILE) + if zypp_cfg.has_option("rhsm-plugin", "gpgcheck"): + self.gpgcheck = zypp_cfg.getboolean("rhsm-plugin", "gpgcheck") + if zypp_cfg.has_option("rhsm-plugin", "repo_gpgcheck"): + self.repo_gpgcheck = zypp_cfg.getboolean("rhsm-plugin", "repo_gpgcheck") + if zypp_cfg.has_option("rhsm-plugin", "autorefresh"): + self.autorefresh = zypp_cfg.getboolean("rhsm-plugin", "autorefresh") + if zypp_cfg.has_option("rhsm-plugin", "gpgkey-ssl-verify"): + self.gpgkey_ssl_verify = zypp_cfg.get("rhsm-plugin", "gpgkey-ssl-verify") + if zypp_cfg.has_option("rhsm-plugin", "repo-ssl-verify"): + self.repo_ssl_verify = zypp_cfg.get("rhsm-plugin", "repo-ssl-verify") + + def fix_content(self, content: "Content") -> str: + self.read_zypp_conf() + zypper_cont = content.copy() + sslverify = zypper_cont["sslverify"] + sslcacert = zypper_cont["sslcacert"] + sslclientkey = zypper_cont["sslclientkey"] + sslclientcert = zypper_cont["sslclientcert"] + proxy = zypper_cont["proxy"] + proxy_username = zypper_cont["proxy_username"] + proxy_password = zypper_cont["proxy_password"] + + del zypper_cont["sslverify"] + del zypper_cont["sslcacert"] + del zypper_cont["sslclientkey"] + del zypper_cont["sslclientcert"] + del zypper_cont["proxy"] + del zypper_cont["proxy_username"] + del zypper_cont["proxy_password"] + # NOTE looks like metadata_expire and ui_repoid_vars are ignored by zypper + + # clean up data for zypper + if zypper_cont["gpgkey"] in ["https://", "http://"]: + del zypper_cont["gpgkey"] + + # make sure gpg key download doesn't fail because of private certs + if zypper_cont["gpgkey"] and self.gpgkey_ssl_verify: + zypper_cont["gpgkey"] += "?ssl_verify=%s" % self.gpgkey_ssl_verify + + # See BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1764265 + if self.gpgcheck is False: + zypper_cont["gpgcheck"] = "0" + + # See BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1858231 + if self.repo_gpgcheck is True: + zypper_cont["repo_gpgcheck"] = "1" + else: + zypper_cont["repo_gpgcheck"] = "0" - if sslverify and sslverify in ["1"]: - if self.repo_ssl_verify: - zypper_query_args["ssl_verify"] = self.repo_ssl_verify + # See BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1797386 + if self.autorefresh is True: + zypper_cont["autorefresh"] = "1" else: - zypper_query_args["ssl_verify"] = "host" - - if sslcacert: - zypper_query_args["ssl_capath"] = os.path.dirname(sslcacert) - if sslclientkey: - zypper_query_args["ssl_clientkey"] = sslclientkey - if sslclientcert: - zypper_query_args["ssl_clientcert"] = sslclientcert - if proxy: - zypper_query_args["proxy"] = proxy - if proxy_username: - zypper_query_args["proxyuser"] = proxy_username - if proxy_password: - zypper_query_args["proxypass"] = proxy_password - zypper_query = urlencode(zypper_query_args) - - new_url = urlunparse( - (parsed.scheme, parsed.netloc, parsed.path, parsed.params, zypper_query, parsed.fragment) - ) - zypper_cont["baseurl"] = new_url - - return zypper_cont - - # We need to overwrite this, to avoid name clashes with yum's server_val_repo_file - @classmethod - def server_value_repo_file(cls) -> "ZypperRepoFile": - return cls("var/lib/rhsm/repo_server_val/", "zypper_{}".format(cls.NAME)) + zypper_cont["autorefresh"] = "0" + + baseurl = zypper_cont["baseurl"] + parsed = urlparse(baseurl) + zypper_query_args: Dict[str, str] = parse_qs(parsed.query) + + if sslverify and sslverify in ["1"]: + if self.repo_ssl_verify: + zypper_query_args["ssl_verify"] = self.repo_ssl_verify + else: + zypper_query_args["ssl_verify"] = "host" + + if sslcacert: + zypper_query_args["ssl_capath"] = os.path.dirname(sslcacert) + if sslclientkey: + zypper_query_args["ssl_clientkey"] = sslclientkey + if sslclientcert: + zypper_query_args["ssl_clientcert"] = sslclientcert + if proxy: + zypper_query_args["proxy"] = proxy + if proxy_username: + zypper_query_args["proxyuser"] = proxy_username + if proxy_password: + zypper_query_args["proxypass"] = proxy_password + zypper_query = urlencode(zypper_query_args) + + new_url = urlunparse( + (parsed.scheme, parsed.netloc, parsed.path, parsed.params, zypper_query, parsed.fragment) + ) + zypper_cont["baseurl"] = new_url + + return zypper_cont + + # We need to overwrite this, to avoid name clashes with yum's server_val_repo_file + @classmethod + def server_value_repo_file(cls) -> "ZypperRepoFile": + return cls("var/lib/rhsm/repo_server_val/", "zypper_{}".format(cls.NAME)) def init_repo_file_classes() -> List[Tuple[type(RepoFileBase), str]]: - repo_file_classes: List[type(RepoFileBase)] = [YumRepoFile, ZypperRepoFile] + repo_file_classes: List[type(RepoFileBase)] = [] if HAS_DEB822: repo_file_classes.append(AptRepoFile) + elif HAS_ZYPP: + repo_file_classes.append(ZypperRepoFile) + else: + repo_file_classes.append(YumRepoFile) _repo_files: List[Tuple[type(RepoFileBase), type(RepoFileBase)]] = [ (RepoFile, RepoFile.server_value_repo_file) for RepoFile in repo_file_classes if RepoFile.installed() ] diff --git a/src/subscription_manager/repolib.py b/src/subscription_manager/repolib.py index 4e7c016b4..3e37ca4bd 100644 --- a/src/subscription_manager/repolib.py +++ b/src/subscription_manager/repolib.py @@ -23,13 +23,19 @@ from subscription_manager import model from subscription_manager.model import ent_cert from subscription_manager.repofile import Repo, manage_repos_enabled, get_repo_file_classes -from subscription_manager.repofile import YumRepoFile +from subscription_manager.repofile import YumRepoFile, RepoFileBase +from subscription_manager.repofile import HAS_DEB822, HAS_ZYPP from subscription_manager.utils import get_supported_resources import rhsm.config import configparser from rhsmlib.facts.hwprobe import HardwareCollector +if HAS_DEB822: + from rhsm.repofile import AptRepoFile +if HAS_ZYPP: + from rhsm.repofile import ZypperRepoFile + # FIXME: local imports from subscription_manager.certlib import ActionReport, BaseActionInvoker @@ -217,12 +223,12 @@ def get_repos(self, apply_overrides: bool = True) -> Set[Repo]: current = set() # Add the current repo data - yum_repo_file = YumRepoFile() - yum_repo_file.read() + repo_file = self.get_system_repo_file() + repo_file.read() server_value_repo_file = YumRepoFile("var/lib/rhsm/repo_server_val/") server_value_repo_file.read() for repo in repos: - existing = yum_repo_file.section(repo.id) + existing = repo_file.section(repo.id) server_value_repo = server_value_repo_file.section(repo.id) # we need a repo in the server val file to match any in # the main repo definition file @@ -237,9 +243,18 @@ def get_repos(self, apply_overrides: bool = True) -> Set[Repo]: return current + def get_system_repo_file(self) -> "RepoFileBase": + if HAS_DEB822: + repo = AptRepoFile() + elif HAS_ZYPP: + repo = ZypperRepoFile() + else: + repo = YumRepoFile() + return repo + def get_repo_file(self) -> str: - yum_repo_file = YumRepoFile() - return yum_repo_file.path + repo_file = self.get_system_repo_file() + return repo_file.path @classmethod def delete_repo_file(cls) -> None: