Source code for pykickstart.commands.repo

#
# Chris Lumens <clumens@redhat.com>
#
# Copyright 2007, 2008, 2009 Red Hat, Inc.
#
# This copyrighted material is made available to anyone wishing to use, modify,
# copy, or redistribute it subject to the terms and conditions of the GNU
# General Public License v.2.  This program is distributed in the hope that it
# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  Any Red Hat
# trademarks that are incorporated in the source code or documentation are not
# subject to the GNU General Public License and may only be used or replicated
# with the express permission of Red Hat, Inc.
#
from textwrap import dedent
from pykickstart.version import versionToLongString, F40
from pykickstart.version import FC6, F8, F11, F13, F14, F15, F21, F27, F30, F33
from pykickstart.base import BaseData, KickstartCommand
from pykickstart.errors import KickstartError, KickstartParseError, KickstartParseWarning
from pykickstart.options import KSOptionParser, commaSplit, ksboolean

import warnings
from pykickstart.i18n import _

[docs] class FC6_RepoData(BaseData): removedKeywords = BaseData.removedKeywords removedAttrs = BaseData.removedAttrs def __init__(self, *args, **kwargs): BaseData.__init__(self, *args, **kwargs) self.baseurl = kwargs.get("baseurl", "") self.mirrorlist = kwargs.get("mirrorlist", None) self.name = kwargs.get("name", "") def __eq__(self, y): if not y: return False return self.name == y.name def __ne__(self, y): return not self == y def _getArgsAsStr(self): retval = "" if self.baseurl: retval += "--baseurl=%s" % self.baseurl elif self.mirrorlist: retval += "--mirrorlist=%s" % self.mirrorlist return retval def __str__(self): retval = BaseData.__str__(self) retval += "repo --name=\"%s\" %s\n" % (self.name, self._getArgsAsStr()) return retval
[docs] class F8_RepoData(FC6_RepoData): removedKeywords = FC6_RepoData.removedKeywords removedAttrs = FC6_RepoData.removedAttrs def __init__(self, *args, **kwargs): FC6_RepoData.__init__(self, *args, **kwargs) self.cost = kwargs.get("cost", None) self.includepkgs = kwargs.get("includepkgs", []) self.excludepkgs = kwargs.get("excludepkgs", []) def _getArgsAsStr(self): retval = FC6_RepoData._getArgsAsStr(self) if self.cost: retval += " --cost=%s" % self.cost if self.includepkgs: retval += " --includepkgs=\"%s\"" % ",".join(self.includepkgs) if self.excludepkgs: retval += " --excludepkgs=\"%s\"" % ",".join(self.excludepkgs) return retval
[docs] class F11_RepoData(F8_RepoData): removedKeywords = F8_RepoData.removedKeywords removedAttrs = F8_RepoData.removedAttrs def __init__(self, *args, **kwargs): F8_RepoData.__init__(self, *args, **kwargs) self.ignoregroups = kwargs.get("ignoregroups", None) def _getArgsAsStr(self): retval = F8_RepoData._getArgsAsStr(self) if self.ignoregroups: retval += " --ignoregroups=true" return retval
[docs] class F13_RepoData(F11_RepoData): removedKeywords = F11_RepoData.removedKeywords removedAttrs = F11_RepoData.removedAttrs def __init__(self, *args, **kwargs): F11_RepoData.__init__(self, *args, **kwargs) self.proxy = kwargs.get("proxy", "") def _getArgsAsStr(self): retval = F11_RepoData._getArgsAsStr(self) if self.proxy: retval += " --proxy=\"%s\"" % self.proxy return retval
[docs] class F14_RepoData(F13_RepoData): removedKeywords = F13_RepoData.removedKeywords removedAttrs = F13_RepoData.removedAttrs def __init__(self, *args, **kwargs): F13_RepoData.__init__(self, *args, **kwargs) self.noverifyssl = kwargs.get("noverifyssl", False) def _getArgsAsStr(self): retval = F13_RepoData._getArgsAsStr(self) if self.noverifyssl: retval += " --noverifyssl" return retval
[docs] class RHEL6_RepoData(F14_RepoData): pass
[docs] class F15_RepoData(F14_RepoData): pass
[docs] class F21_RepoData(F15_RepoData): removedKeywords = F15_RepoData.removedKeywords removedAttrs = F15_RepoData.removedAttrs def __init__(self, *args, **kwargs): F15_RepoData.__init__(self, *args, **kwargs) self.install = kwargs.get("install", False) def _getArgsAsStr(self): retval = F15_RepoData._getArgsAsStr(self) if self.install: retval += " --install" return retval
[docs] class F27_RepoData(F21_RepoData): removedKeywords = F21_RepoData.removedKeywords removedAttrs = F21_RepoData.removedAttrs def __init__(self, *args, **kwargs): F21_RepoData.__init__(self, *args, **kwargs) self.metalink = kwargs.get("metalink", False) def _getArgsAsStr(self): retval = F21_RepoData._getArgsAsStr(self) if self.metalink: retval += " --metalink=%s" % self.metalink return retval
[docs] class F30_RepoData(F27_RepoData): removedKeywords = F27_RepoData.removedKeywords removedAttrs = F27_RepoData.removedAttrs def __init__(self, *args, **kwargs): F27_RepoData.__init__(self, *args, **kwargs) self.sslcacert = kwargs.get("sslcacert", None) self.sslclientcert = kwargs.get("sslclientcert", None) self.sslclientkey = kwargs.get("sslclientkey", None) def _getArgsAsStr(self): retval = F27_RepoData._getArgsAsStr(self) if self.sslcacert: retval += " --sslcacert=\"%s\"" % self.sslcacert if self.sslclientcert: retval += " --sslclientcert=\"%s\"" % self.sslclientcert if self.sslclientkey: retval += " --sslclientkey=\"%s\"" % self.sslclientkey return retval
[docs] class RHEL7_RepoData(F21_RepoData): pass
[docs] class RHEL8_RepoData(F30_RepoData): pass
[docs] class FC6_Repo(KickstartCommand): removedKeywords = KickstartCommand.removedKeywords removedAttrs = KickstartCommand.removedAttrs urlRequired = True def __init__(self, writePriority=0, *args, **kwargs): KickstartCommand.__init__(self, writePriority, *args, **kwargs) self.op = self._getParser() self.repoList = kwargs.get("repoList", []) self.exclusive_required_options = [("mirrorlist", "--mirrorlist"), ("baseurl", "--baseurl")] def __str__(self): retval = "" for repo in self.repoList: retval += repo.__str__() return retval def _getParser(self): op = KSOptionParser(prog="repo", description=""" Configures additional yum repositories that may be used as sources for package installation. Multiple repo lines may be specified. By default, anaconda has a configured set of repos taken from /etc/anaconda.repos.d plus a special Installation Repo in the case of a media install. The exact set of repos in this directory changes from release to release and cannot be listed here. There will likely always be a repo named "updates". Note: If you want to enable one of the repos in /etc/anaconda.repos.d that is disabled by default (like "updates"), you should use --name= but none of the other options. anaconda will look for a repo by this name automatically. Providing a baseurl or mirrorlist URL will result in anaconda attempting to add another repo by the same name, which will cause a conflicting repo error.""", version=FC6) op.add_argument("--name", required=True, version=FC6, help=""" The repo id. This option is required. The RepoId must not contain spaces (do not confuse with the optional name used by yum). If a repo has a name that conflicts with a previously added one, the new repo will be ignored. Because anaconda has a populated list of repos when it starts, this means that users cannot create new repos that override these names. Please check /etc/anaconda.repos.d from the operating system you wish to install to see what names are not available.""") op.add_argument("--baseurl", version=FC6, help=""" The URL for the repository. The variables that may be used in yum repo config files are not supported here. You may use one of either this option or ``--mirrorlist``, not both. If an NFS repository is specified, it should be of the form ``nfs://host:/path/to/repo``. Note that there is a colon after the host. Anaconda passes everything after "nfs:// " directly to the mount command instead of parsing URLs according to RFC 2224. Variable substitution is done for $releasever and $basearch in the url.""") op.add_argument("--mirrorlist", version=FC6, help=""" The URL pointing at a list of mirrors for the repository. The variables that may be used in yum repo config files are not supported here. You may use one of either this option or ``--baseurl``, not both. Variable substitution is done for $releasever and $basearch in the url.""") return op
[docs] def parse(self, args): ns = self.op.parse_args(args=args, lineno=self.lineno) # Check that just one of exclusive required options is specified used_options = [opt for attr, opt in self.exclusive_required_options if getattr(ns, attr, None)] if self.urlRequired and not used_options: mapping = {"options_list": ", ".join((opt for attr, opt in self.exclusive_required_options))} raise KickstartParseError(_("One of -%(options_list)s options must be specified for repo command.") % mapping, lineno=self.lineno) if len(used_options) > 1: mapping = {"options_list": ", ".join((opt for opt in used_options))} raise KickstartParseError(_("Only one of %(options_list)s options may be specified for repo command.") % mapping, lineno=self.lineno) rd = self.dataClass() # pylint: disable=not-callable self.set_to_obj(ns, rd) rd.lineno = self.lineno # Check for duplicates in the data list. if rd in self.dataList(): warnings.warn(_("A repo with the name %s has already been defined.") % rd.name, KickstartParseWarning) return rd
[docs] def dataList(self): return self.repoList
@property def dataClass(self): return self.handler.RepoData
[docs] class F8_Repo(FC6_Repo): removedKeywords = FC6_Repo.removedKeywords removedAttrs = FC6_Repo.removedAttrs def __str__(self): retval = "" for repo in self.repoList: retval += repo.__str__() return retval def _getParser(self): op = FC6_Repo._getParser(self) op.add_argument("--cost", type=int, version=F8, help=""" An integer value to assign a cost to this repository. If multiple repositories provide the same packages, this number will be used to prioritize which repository will be used before another. Repositories with a lower cost take priority over repositories with higher cost. """) op.add_argument("--excludepkgs", type=commaSplit, version=F8, help=""" A comma-separated list of package names and globs that must not be fetched from this repository. This is useful if multiple repositories provide the same package and you want to make sure it is not fetched from a particular repository during installation.""") op.add_argument("--includepkgs", type=commaSplit, version=F8, help=""" A comma-separated list of package names and globs that can be pulled from this repository. Any other packages provided by the repository not on this list will be ignored. This is useful if you want to install just a single package or set of packages from a repository while including all other packages the repository provides.""") return op
[docs] def methodToRepo(self): if not self.handler.method.url: raise KickstartError(_("Method must be a url to be added to the repo list."), lineno=self.handler.method.lineno) reponame = "ks-method-url" repourl = self.handler.method.url rd = self.handler.RepoData(name=reponame, baseurl=repourl) return rd
[docs] class F11_Repo(F8_Repo): removedKeywords = F8_Repo.removedKeywords removedAttrs = F8_Repo.removedAttrs def _getParser(self): op = F8_Repo._getParser(self) op.add_argument("--ignoregroups", type=ksboolean, version=F11, help=""" This option is used when composing installation trees and has no effect on the installation process itself. It tells the compose tools to not look at the package group information when mirroring trees so as to avoid mirroring large amounts of unnecessary data.""") return op
[docs] class F13_Repo(F11_Repo): removedKeywords = F11_Repo.removedKeywords removedAttrs = F11_Repo.removedAttrs def _getParser(self): op = F11_Repo._getParser(self) op.add_argument("--proxy", version=F13, help=""" Specify an HTTP/HTTPS/FTP proxy to use just for this repository. This setting does not affect any other repositories, nor how the install.img is fetched on HTTP installs. The various parts of the argument act like you would expect. The syntax is:: ``--proxy=[protocol://][username[:password]@]host[:port]`` """) return op
[docs] class F14_Repo(F13_Repo): removedKeywords = F13_Repo.removedKeywords removedAttrs = F13_Repo.removedAttrs def _getParser(self): op = F13_Repo._getParser(self) op.add_argument("--noverifyssl", action="store_true", version=F14, default=False, help=""" For a https repo do not check the server's certificate with what well-known CA validate and do not check the server's hostname matches the certificate's domain name. """) return op
[docs] class RHEL6_Repo(F14_Repo): pass
[docs] class F15_Repo(F14_Repo): removedKeywords = F14_Repo.removedKeywords removedAttrs = F14_Repo.removedAttrs urlRequired = False def _getParser(self): op = F14_Repo._getParser(self) for action in op._actions: for option in ['--baseurl', '--mirrorlist']: if option in action.option_strings: action.help += dedent(""" .. versionchanged:: %s ``--mirrorlist`` and ``--baseurl`` are not required anymore! """ % versionToLongString(F15)) return op
[docs] class F21_Repo(F15_Repo): removedKeywords = F15_Repo.removedKeywords removedAttrs = F15_Repo.removedAttrs def _getParser(self): op = F15_Repo._getParser(self) op.add_argument("--install", action="store_true", version=F21, default=False, help=""" Install this repository to the target system so that it can be used after reboot.""") return op
[docs] class F27_Repo(F21_Repo): removedKeywords = F21_Repo.removedKeywords removedAttrs = F21_Repo.removedAttrs def __init__(self, *args, **kwargs): F21_Repo.__init__(self, *args, **kwargs) self.exclusive_required_options.append(("metalink", "--metalink")) def _getParser(self): op = F21_Repo._getParser(self) op.add_argument("--metalink", version=F27, help=""" The URL pointing at a metalink for the repository. The variables that may be used in yum repo config files are not supported here. You may use only one of the ``--baseurl``, ``--mirrorlist``, or ``--metalink`` options. Variable substitution is done for $releasever and $basearch in the url.""") for action in op._actions: for option in ['--baseurl', '--mirrorlist']: if option in action.option_strings: action.help += dedent(""" .. versionchanged:: %s ``Another mutually exclusive option --metalink`` was added. """ % versionToLongString(F27)) return op
[docs] class F30_Repo(F27_Repo): removedKeywords = F27_Repo.removedKeywords removedAttrs = F27_Repo.removedAttrs def _getParser(self): op = F27_Repo._getParser(self) op.add_argument("--sslcacert", version=F30, help=""" Path to the file holding one or more SSL certificates to verify the repository host with. **Note** Usage of this parameter is discouraged. It is designed for a specific image building tool use and there are plans for a replacement.""") op.add_argument("--sslclientcert", version=F30, help=""" Path to the SSL client certificate (PEM file) which should be used to connect to the repository. **Note** Usage of this parameter is discouraged. It is designed for a specific image building tool use and there are plans for a replacement.""") op.add_argument("--sslclientkey", version=F30, help=""" Path to the private key file associated with the client certificate given with --sslclientcert. **Note** Usage of this parameter is discouraged. It is designed for a specific image building tool use and there are plans for a replacement.""") return op
[docs] class F33_Repo(F30_Repo): removedKeywords = F30_Repo.removedKeywords removedAttrs = F30_Repo.removedAttrs def _getParser(self): op = F30_Repo._getParser(self) op.add_argument("--ignoregroups", type=ksboolean, deprecated=F33) return op
[docs] class RHEL7_Repo(F21_Repo): pass
[docs] class RHEL8_Repo(F30_Repo): pass
[docs] class F40_Repo(F33_Repo): removedKeywords = F33_Repo.removedKeywords + ["ignoregroups"] removedAttrs = F33_Repo.removedAttrs + ["ignoregroups"] def _getParser(self): op = F33_Repo._getParser(self) op.remove_argument("--ignoregroups", version=F40) return op