mirror of
https://github.com/saltstack/salt.git
synced 2025-04-16 09:40:20 +00:00
fixes saltstack/salt#63982 aptpkg.latest_version calls apt-cache too much
This commit is contained in:
parent
e4ba3fd7d2
commit
4730bea00b
3 changed files with 68 additions and 20 deletions
1
changelog/63982.fixed.md
Normal file
1
changelog/63982.fixed.md
Normal file
|
@ -0,0 +1 @@
|
|||
Fix aptpkg.latest_version performance, reducing number of times to 'shell out'
|
|
@ -423,6 +423,8 @@ def parse_arch(name):
|
|||
|
||||
def latest_version(*names, **kwargs):
|
||||
"""
|
||||
.. versionchanged:: 3007.0
|
||||
|
||||
Return the latest version of the named package available for upgrade or
|
||||
installation. If more than one package name is specified, a dict of
|
||||
name/version pairs is returned.
|
||||
|
@ -469,38 +471,47 @@ def latest_version(*names, **kwargs):
|
|||
if refresh:
|
||||
refresh_db(cache_valid_time)
|
||||
|
||||
cmd = ["apt-cache", "-q", "policy"]
|
||||
cmd.extend(names)
|
||||
if repo is not None:
|
||||
cmd.extend(repo)
|
||||
out = _call_apt(cmd, scope=False)
|
||||
|
||||
short_names = [nom.split(":", maxsplit=1)[0] for nom in names]
|
||||
|
||||
candidates = {}
|
||||
for line in salt.utils.itertools.split(out["stdout"], "\n"):
|
||||
if line.endswith(":") and line[:-1] in short_names:
|
||||
this_pkg = names[short_names.index(line[:-1])]
|
||||
elif "Candidate" in line:
|
||||
candidate = ""
|
||||
comps = line.split()
|
||||
if len(comps) >= 2:
|
||||
candidate = comps[-1]
|
||||
if candidate.lower() == "(none)":
|
||||
candidate = ""
|
||||
candidates[this_pkg] = candidate
|
||||
|
||||
for name in names:
|
||||
cmd = ["apt-cache", "-q", "policy", name]
|
||||
if repo is not None:
|
||||
cmd.extend(repo)
|
||||
out = _call_apt(cmd, scope=False)
|
||||
|
||||
candidate = ""
|
||||
for line in salt.utils.itertools.split(out["stdout"], "\n"):
|
||||
if "Candidate" in line:
|
||||
comps = line.split()
|
||||
if len(comps) >= 2:
|
||||
candidate = comps[-1]
|
||||
if candidate.lower() == "(none)":
|
||||
candidate = ""
|
||||
break
|
||||
|
||||
installed = pkgs.get(name, [])
|
||||
if not installed:
|
||||
ret[name] = candidate
|
||||
ret[name] = candidates.get(name, "")
|
||||
elif installed and show_installed:
|
||||
ret[name] = candidate
|
||||
elif candidate:
|
||||
ret[name] = candidates.get(name, "")
|
||||
elif candidates.get(name):
|
||||
# If there are no installed versions that are greater than or equal
|
||||
# to the install candidate, then the candidate is an upgrade, so
|
||||
# add it to the return dict
|
||||
if not any(
|
||||
salt.utils.versions.compare(
|
||||
ver1=x, oper=">=", ver2=candidate, cmp_func=version_cmp
|
||||
ver1=x,
|
||||
oper=">=",
|
||||
ver2=candidates.get(name, ""),
|
||||
cmp_func=version_cmp,
|
||||
)
|
||||
for x in installed
|
||||
):
|
||||
ret[name] = candidate
|
||||
ret[name] = candidates.get(name, "")
|
||||
|
||||
# Return a string if only one package name passed
|
||||
if len(names) == 1:
|
||||
|
|
|
@ -1401,3 +1401,39 @@ def test_sourceslist_architectures(repo_line):
|
|||
assert source.architectures == ["amd64", "armel"]
|
||||
else:
|
||||
assert source.architectures == ["amd64"]
|
||||
|
||||
|
||||
def test_latest_version_calls_aptcache_once_per_run():
|
||||
"""
|
||||
Performance Test - don't call apt-cache once for each pkg, call once and parse output
|
||||
"""
|
||||
mock_list_pkgs = MagicMock(return_value={"sudo": "1.8.27-1+deb10u5"})
|
||||
apt_cache_ret = {
|
||||
"stdout": textwrap.dedent(
|
||||
"""sudo:
|
||||
Installed: 1.8.27-1+deb10u5
|
||||
Candidate: 1.8.27-1+deb10u5
|
||||
Version table:
|
||||
*** 1.8.27-1+deb10u5 500
|
||||
500 http://security.debian.org/debian-security buster/updates/main amd64 Packages
|
||||
100 /var/lib/dpkg/status
|
||||
1.8.27-1+deb10u3 500
|
||||
500 http://deb.debian.org/debian buster/main amd64 Packages
|
||||
unzip:
|
||||
Installed: (none)
|
||||
Candidate: 6.0-23+deb10u3
|
||||
Version table:
|
||||
6.0-23+deb10u3 500
|
||||
500 http://security.debian.org/debian-security buster/updates/main amd64 Packages
|
||||
6.0-23+deb10u2 500
|
||||
500 http://deb.debian.org/debian buster/main amd64 Packages
|
||||
"""
|
||||
)
|
||||
}
|
||||
mock_apt_cache = MagicMock(return_value=apt_cache_ret)
|
||||
with patch("salt.modules.aptpkg._call_apt", mock_apt_cache), patch(
|
||||
"salt.modules.aptpkg.list_pkgs", mock_list_pkgs
|
||||
):
|
||||
ret = aptpkg.latest_version("sudo", "unzip", refresh=False)
|
||||
mock_apt_cache.assert_called_once()
|
||||
assert ret == {"sudo": "6.0-23+deb10u3", "unzip": ""}
|
||||
|
|
Loading…
Add table
Reference in a new issue