mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Add COPR support to states.pkgrepo (#57259)
This commit is contained in:
parent
1c64b8a841
commit
59c9983105
4 changed files with 160 additions and 18 deletions
1
changelog/57258.added
Normal file
1
changelog/57258.added
Normal file
|
@ -0,0 +1 @@
|
|||
Added COPR option to states.pkgrepo
|
|
@ -107,6 +107,12 @@ def _strip_headers(output, *args):
|
|||
return ret
|
||||
|
||||
|
||||
def _get_copr_repo(copr):
|
||||
copr = copr.split(":", 1)[1]
|
||||
copr = copr.split("/", 1)
|
||||
return "copr:copr.fedorainfracloud.org:{}:{}".format(copr[0], copr[1])
|
||||
|
||||
|
||||
def _get_hold(line, pattern=__HOLD_PATTERN, full=True):
|
||||
"""
|
||||
Resolve a package name from a line containing the hold expression. If the
|
||||
|
@ -2720,7 +2726,7 @@ def list_repos(basedir=None, **kwargs):
|
|||
return repos
|
||||
|
||||
|
||||
def get_repo(name, basedir=None, **kwargs): # pylint: disable=W0613
|
||||
def get_repo(repo, basedir=None, **kwargs): # pylint: disable=W0613
|
||||
"""
|
||||
Display a repo from <basedir> (default basedir: all dirs in ``reposdir``
|
||||
yum option).
|
||||
|
@ -2735,16 +2741,19 @@ def get_repo(name, basedir=None, **kwargs): # pylint: disable=W0613
|
|||
"""
|
||||
repos = list_repos(basedir)
|
||||
|
||||
if repo.startswith("copr:"):
|
||||
repo = _get_copr_repo(repo)
|
||||
|
||||
# Find out what file the repo lives in
|
||||
repofile = ""
|
||||
for repo in repos:
|
||||
if repo == name:
|
||||
repofile = repos[repo]["file"]
|
||||
for list_repo in repos:
|
||||
if list_repo == repo:
|
||||
repofile = repos[list_repo]["file"]
|
||||
|
||||
if repofile:
|
||||
# Return just one repo
|
||||
filerepos = _parse_repo_file(repofile)[1]
|
||||
return filerepos[name]
|
||||
return filerepos[repo]
|
||||
return {}
|
||||
|
||||
|
||||
|
@ -2764,6 +2773,10 @@ def del_repo(repo, basedir=None, **kwargs): # pylint: disable=W0613
|
|||
salt '*' pkg.del_repo myrepo basedir=/path/to/dir
|
||||
salt '*' pkg.del_repo myrepo basedir=/path/to/dir,/path/to/another/dir
|
||||
"""
|
||||
|
||||
if repo.startswith("copr:"):
|
||||
repo = _get_copr_repo(repo)
|
||||
|
||||
# this is so we know which dirs are searched for our error messages below
|
||||
basedirs = _normalize_basedir(basedir)
|
||||
repos = list_repos(basedirs)
|
||||
|
@ -2856,6 +2869,12 @@ def mod_repo(repo, basedir=None, **kwargs):
|
|||
"Only one of 'mirrorlist' and 'baseurl' can be specified"
|
||||
)
|
||||
|
||||
use_copr = False
|
||||
if repo.startswith("copr:"):
|
||||
copr_name = repo.split(":", 1)[1]
|
||||
repo = _get_copr_repo(repo)
|
||||
use_copr = True
|
||||
|
||||
# Build a list of keys to be deleted
|
||||
todelete = []
|
||||
# list() of keys because the dict could be shrinking in the for loop.
|
||||
|
@ -2897,20 +2916,47 @@ def mod_repo(repo, basedir=None, **kwargs):
|
|||
"of the following basedir directories exist: {0}".format(basedirs)
|
||||
)
|
||||
|
||||
repofile = "{0}/{1}.repo".format(newdir, repo)
|
||||
if use_copr:
|
||||
# Is copr plugin installed?
|
||||
copr_plugin_name = ""
|
||||
if _yum() == "dnf":
|
||||
copr_plugin_name = "dnf-plugins-core"
|
||||
else:
|
||||
copr_plugin_name = "yum-plugin-copr"
|
||||
|
||||
if "name" not in repo_opts:
|
||||
raise SaltInvocationError(
|
||||
"The repo does not exist and needs to be created, but a name "
|
||||
"was not given"
|
||||
)
|
||||
if not __salt__["pkg_resource.version"](copr_plugin_name):
|
||||
raise SaltInvocationError(
|
||||
"{} must be installed to use COPR".format(copr_plugin_name)
|
||||
)
|
||||
|
||||
if "baseurl" not in repo_opts and "mirrorlist" not in repo_opts:
|
||||
raise SaltInvocationError(
|
||||
"The repo does not exist and needs to be created, but either "
|
||||
"a baseurl or a mirrorlist needs to be given"
|
||||
)
|
||||
filerepos[repo] = {}
|
||||
# Enable COPR
|
||||
out = _call_yum(["copr", "enable", copr_name, "-y"])
|
||||
if out["retcode"]:
|
||||
raise CommandExecutionError(
|
||||
"Unable to add COPR '{0}'. '{1}' exited with "
|
||||
"status {2!s}: '{3}' ".format(
|
||||
copr_name, _yum(), out["retcode"], out["stderr"]
|
||||
)
|
||||
)
|
||||
# Repo has been added, update repos list
|
||||
repos = list_repos(basedirs)
|
||||
repofile = repos[repo]["file"]
|
||||
header, filerepos = _parse_repo_file(repofile)
|
||||
else:
|
||||
repofile = "{0}/{1}.repo".format(newdir, repo)
|
||||
|
||||
if "name" not in repo_opts:
|
||||
raise SaltInvocationError(
|
||||
"The repo does not exist and needs to be created, but a name "
|
||||
"was not given"
|
||||
)
|
||||
|
||||
if "baseurl" not in repo_opts and "mirrorlist" not in repo_opts:
|
||||
raise SaltInvocationError(
|
||||
"The repo does not exist and needs to be created, but either "
|
||||
"a baseurl or a mirrorlist needs to be given"
|
||||
)
|
||||
filerepos[repo] = {}
|
||||
else:
|
||||
# The repo does exist, open its file
|
||||
repofile = repos[repo]["file"]
|
||||
|
|
|
@ -83,6 +83,14 @@ package managers are APT, DNF, YUM and Zypper. Here is some example SLS:
|
|||
installed. To check if this package is installed, run ``dpkg -l python-apt``.
|
||||
``python-apt`` will need to be manually installed if it is not present.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
hello-copr:
|
||||
pkgrepo.managed:
|
||||
- copr: mymindstorm/hello
|
||||
pkg.installed:
|
||||
- name: hello
|
||||
|
||||
"""
|
||||
|
||||
# Import Python libs
|
||||
|
@ -111,7 +119,7 @@ def __virtual__():
|
|||
return "pkg.mod_repo" in __salt__
|
||||
|
||||
|
||||
def managed(name, ppa=None, **kwargs):
|
||||
def managed(name, ppa=None, copr=None, **kwargs):
|
||||
"""
|
||||
This state manages software package repositories. Currently, :mod:`yum
|
||||
<salt.modules.yumpkg>`, :mod:`apt <salt.modules.aptpkg>`, and :mod:`zypper
|
||||
|
@ -141,6 +149,12 @@ def managed(name, ppa=None, **kwargs):
|
|||
reverse will be passed as ``enabled``. For example passing
|
||||
``disabled=True`` will assume ``enabled=False``.
|
||||
|
||||
copr
|
||||
Fedora and RedHat based distributions only. Use community packages
|
||||
outside of the main package repository.
|
||||
|
||||
.. versionadded:: 3002
|
||||
|
||||
humanname
|
||||
This is used as the "name" value in the repo file in
|
||||
``/etc/yum.repos.d/`` (or ``/etc/zypp/repos.d`` for SUSE distros).
|
||||
|
@ -369,6 +383,11 @@ def managed(name, ppa=None, **kwargs):
|
|||
)
|
||||
|
||||
elif __grains__["os_family"] in ("RedHat", "Suse"):
|
||||
if __grains__["os_family"] in "RedHat":
|
||||
if copr is not None:
|
||||
repo = ":".join(("copr", copr))
|
||||
kwargs["name"] = name
|
||||
|
||||
if "humanname" in kwargs:
|
||||
kwargs["name"] = kwargs.pop("humanname")
|
||||
if "name" not in kwargs:
|
||||
|
@ -550,6 +569,19 @@ def absent(name, **kwargs):
|
|||
The name of the package repo, as it would be referred to when running
|
||||
the regular package manager commands.
|
||||
|
||||
**FEDORA/REDHAT-SPECIFIC OPTIONS**
|
||||
|
||||
copr
|
||||
Use community packages outside of the main package repository.
|
||||
|
||||
.. versionadded:: 3002
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
hello-copr:
|
||||
pkgrepo.absent:
|
||||
- copr: mymindstorm/hello
|
||||
|
||||
**UBUNTU-SPECIFIC OPTIONS**
|
||||
|
||||
ppa
|
||||
|
@ -596,6 +628,11 @@ def absent(name, **kwargs):
|
|||
if not name.startswith("ppa:"):
|
||||
name = "ppa:" + name
|
||||
|
||||
if "copr" in kwargs and __grains__["os_family"] in "RedHat":
|
||||
name = kwargs.pop("copr")
|
||||
if not name.startswith("copr:"):
|
||||
name = "copr:" + name
|
||||
|
||||
remove_key = any(kwargs.get(x) is not None for x in ("keyid", "keyid_ppa"))
|
||||
if remove_key and "pkg.del_repo_key" not in __salt__:
|
||||
ret["result"] = False
|
||||
|
|
|
@ -266,3 +266,61 @@ class PkgrepoTest(ModuleCase, SaltReturnAssertsMixin):
|
|||
os.remove(fn_)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
@requires_salt_states("pkgrepo.absent", "pkgrepo.managed")
|
||||
@requires_system_grains
|
||||
@slowTest
|
||||
def test_pkgrepo_05_copr_with_comments(self, grains):
|
||||
"""
|
||||
Test copr
|
||||
"""
|
||||
kwargs = {}
|
||||
if grains["os_family"] == "RedHat":
|
||||
if (
|
||||
grains["osfinger"] == "CentOS Linux-7"
|
||||
or grains["osfinger"] == "Amazon Linux-2"
|
||||
):
|
||||
self.skipTest("copr plugin not installed on Centos 7 CI")
|
||||
kwargs = {
|
||||
"name": "hello-copr",
|
||||
"copr": "mymindstorm/hello",
|
||||
"enabled": False,
|
||||
"comments": ["This is a comment"],
|
||||
}
|
||||
else:
|
||||
self.skipTest(
|
||||
"{}/{} test case needed".format(grains["os_family"], grains["os"])
|
||||
)
|
||||
|
||||
try:
|
||||
# Run the state to add the repo
|
||||
ret = self.run_state("pkgrepo.managed", **kwargs)
|
||||
self.assertSaltTrueReturn(ret)
|
||||
|
||||
# Run again with modified comments
|
||||
kwargs["comments"].append("This is another comment")
|
||||
ret = self.run_state("pkgrepo.managed", **kwargs)
|
||||
self.assertSaltTrueReturn(ret)
|
||||
ret = ret[next(iter(ret))]
|
||||
self.assertEqual(
|
||||
ret["changes"],
|
||||
{
|
||||
"comments": {
|
||||
"old": ["This is a comment"],
|
||||
"new": ["This is a comment", "This is another comment"],
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
# Run a third time, no changes should be made
|
||||
ret = self.run_state("pkgrepo.managed", **kwargs)
|
||||
self.assertSaltTrueReturn(ret)
|
||||
ret = ret[next(iter(ret))]
|
||||
self.assertFalse(ret["changes"])
|
||||
self.assertEqual(
|
||||
ret["comment"],
|
||||
"Package repo '{0}' already configured".format(kwargs["name"]),
|
||||
)
|
||||
finally:
|
||||
# Clean up
|
||||
self.run_state("pkgrepo.absent", copr=kwargs["copr"])
|
||||
|
|
Loading…
Add table
Reference in a new issue