mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Add list_repo_pkgs to win_pkg module
This commit is contained in:
parent
adf62acf9c
commit
dd2c86d844
4 changed files with 166 additions and 6 deletions
3
changelog/67171.fixed.md
Normal file
3
changelog/67171.fixed.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
Fix a stacktrace on Windows with pkg.installed and test=True. The
|
||||||
|
`pkg.list_repo_pkgs` function does not exist on Windows. This uses the
|
||||||
|
`pkg.list_available` function instead for Windows.
|
|
@ -45,6 +45,7 @@ import re
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
from fnmatch import fnmatch
|
||||||
from functools import cmp_to_key
|
from functools import cmp_to_key
|
||||||
|
|
||||||
import salt.fileserver
|
import salt.fileserver
|
||||||
|
@ -275,6 +276,11 @@ def list_available(*names, **kwargs):
|
||||||
return_dict_always (bool):
|
return_dict_always (bool):
|
||||||
Default ``False`` dict when a single package name is queried.
|
Default ``False`` dict when a single package name is queried.
|
||||||
|
|
||||||
|
reverse_sort (bool):
|
||||||
|
Sort the versions for latest to oldest
|
||||||
|
|
||||||
|
.. versionadded:: 3007.2
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: The package name with its available versions
|
dict: The package name with its available versions
|
||||||
|
|
||||||
|
@ -298,12 +304,15 @@ def list_available(*names, **kwargs):
|
||||||
return_dict_always = salt.utils.data.is_true(
|
return_dict_always = salt.utils.data.is_true(
|
||||||
kwargs.get("return_dict_always", False)
|
kwargs.get("return_dict_always", False)
|
||||||
)
|
)
|
||||||
|
reverse_sort = salt.utils.data.is_true(kwargs.get("reverse_sort", False))
|
||||||
if len(names) == 1 and not return_dict_always:
|
if len(names) == 1 and not return_dict_always:
|
||||||
pkginfo = _get_package_info(names[0], saltenv=saltenv)
|
pkginfo = _get_package_info(names[0], saltenv=saltenv)
|
||||||
if not pkginfo:
|
if not pkginfo:
|
||||||
return ""
|
return ""
|
||||||
versions = sorted(
|
versions = sorted(
|
||||||
list(pkginfo.keys()), key=cmp_to_key(_reverse_cmp_pkg_versions)
|
list(pkginfo.keys()),
|
||||||
|
key=cmp_to_key(_reverse_cmp_pkg_versions),
|
||||||
|
reverse=reverse_sort,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
versions = {}
|
versions = {}
|
||||||
|
@ -314,11 +323,70 @@ def list_available(*names, **kwargs):
|
||||||
verlist = sorted(
|
verlist = sorted(
|
||||||
list(pkginfo.keys()) if pkginfo else [],
|
list(pkginfo.keys()) if pkginfo else [],
|
||||||
key=cmp_to_key(_reverse_cmp_pkg_versions),
|
key=cmp_to_key(_reverse_cmp_pkg_versions),
|
||||||
|
reverse=reverse_sort,
|
||||||
)
|
)
|
||||||
versions[name] = verlist
|
versions[name] = verlist
|
||||||
return versions
|
return versions
|
||||||
|
|
||||||
|
|
||||||
|
def list_repo_pkgs(*args, saltenv="base", **kwargs):
|
||||||
|
"""
|
||||||
|
.. versionadded:: 3007.2
|
||||||
|
|
||||||
|
This function was added to match a similar function in Linux. It will
|
||||||
|
return all available packages. Optionally, package names (and name globs)
|
||||||
|
can be passed and the results will be filtered to packages matching those
|
||||||
|
names.
|
||||||
|
|
||||||
|
This function can be helpful in discovering the version or repo to specify
|
||||||
|
in a :mod:`pkg.installed <salt.states.pkg.installed>` state.
|
||||||
|
|
||||||
|
The return data will be a dictionary mapping package names to a list of
|
||||||
|
version numbers, ordered from newest to oldest. For example:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
{
|
||||||
|
'bash': ['4.3-14ubuntu1.1',
|
||||||
|
'4.3-14ubuntu1'],
|
||||||
|
'nginx': ['1.10.0-0ubuntu0.16.04.4',
|
||||||
|
'1.9.15-0ubuntu1']
|
||||||
|
}
|
||||||
|
|
||||||
|
CLI Examples:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt '*' pkg.list_repo_pkgs
|
||||||
|
salt '*' pkg.list_repo_pkgs foo bar baz
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Get all the repo data
|
||||||
|
pkgs = get_repo_data(saltenv=saltenv).get("repo", {})
|
||||||
|
|
||||||
|
# Generate a list of packages and their available versions
|
||||||
|
repo_pkgs = {}
|
||||||
|
for pkg in pkgs:
|
||||||
|
repo_pkgs.update({pkg: list(pkgs[pkg].keys())})
|
||||||
|
|
||||||
|
# If no args passed, just return everything
|
||||||
|
if not args:
|
||||||
|
return repo_pkgs
|
||||||
|
|
||||||
|
# Loop through the args and return info for each specified package
|
||||||
|
ret = {}
|
||||||
|
for arg in args:
|
||||||
|
for pkg in repo_pkgs:
|
||||||
|
if fnmatch(pkg, arg):
|
||||||
|
ret.update({pkg: repo_pkgs[pkg]})
|
||||||
|
|
||||||
|
# If ret is empty, return everything
|
||||||
|
if not ret:
|
||||||
|
ret = repo_pkgs
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def version(*names, **kwargs):
|
def version(*names, **kwargs):
|
||||||
"""
|
"""
|
||||||
Returns a string representing the package version or an empty string if not
|
Returns a string representing the package version or an empty string if not
|
||||||
|
|
|
@ -13,9 +13,26 @@ def pkg_def_contents(state_tree):
|
||||||
my-software:
|
my-software:
|
||||||
'1.0.1':
|
'1.0.1':
|
||||||
full_name: 'My Software'
|
full_name: 'My Software'
|
||||||
installer: 'C:\files\mysoftware.msi'
|
installer: 'C:\files\mysoftware101.msi'
|
||||||
install_flags: '/qn /norestart'
|
install_flags: '/qn /norestart'
|
||||||
uninstaller: 'C:\files\mysoftware.msi'
|
uninstaller: 'C:\files\mysoftware101.msi'
|
||||||
|
uninstall_flags: '/qn /norestart'
|
||||||
|
msiexec: True
|
||||||
|
reboot: False
|
||||||
|
'1.0.2':
|
||||||
|
full_name: 'My Software'
|
||||||
|
installer: 'C:\files\mysoftware102.msi'
|
||||||
|
install_flags: '/qn /norestart'
|
||||||
|
uninstaller: 'C:\files\mysoftware102.msi'
|
||||||
|
uninstall_flags: '/qn /norestart'
|
||||||
|
msiexec: True
|
||||||
|
reboot: False
|
||||||
|
your-software:
|
||||||
|
'1.0.0':
|
||||||
|
full_name: 'Your Software'
|
||||||
|
installer: 'C:\files\yoursoftware101.msi'
|
||||||
|
install_flags: '/qn /norestart'
|
||||||
|
uninstaller: 'C:\files\yoursoftware101.msi'
|
||||||
uninstall_flags: '/qn /norestart'
|
uninstall_flags: '/qn /norestart'
|
||||||
msiexec: True
|
msiexec: True
|
||||||
reboot: False
|
reboot: False
|
||||||
|
@ -27,9 +44,47 @@ def pkg(modules):
|
||||||
yield modules.pkg
|
yield modules.pkg
|
||||||
|
|
||||||
|
|
||||||
def test_refresh_db(pkg, pkg_def_contents, state_tree, minion_opts):
|
@pytest.fixture(scope="function")
|
||||||
|
def repo(pkg, state_tree, pkg_def_contents):
|
||||||
assert len(pkg.get_package_info("my-software")) == 0
|
assert len(pkg.get_package_info("my-software")) == 0
|
||||||
repo_dir = state_tree / "winrepo_ng"
|
repo_dir = state_tree / "winrepo_ng"
|
||||||
with pytest.helpers.temp_file("my-software.sls", pkg_def_contents, repo_dir):
|
with pytest.helpers.temp_file("my-software.sls", pkg_def_contents, repo_dir):
|
||||||
pkg.refresh_db()
|
pkg.refresh_db()
|
||||||
assert len(pkg.get_package_info("my-software")) == 1
|
|
||||||
|
|
||||||
|
def test_refresh_db(pkg, repo):
|
||||||
|
assert len(pkg.get_package_info("my-software")) == 2
|
||||||
|
assert len(pkg.get_package_info("your-software")) == 1
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"as_dict, reverse, expected",
|
||||||
|
[
|
||||||
|
(False, False, ["1.0.1", "1.0.2"]),
|
||||||
|
(False, True, ["1.0.2", "1.0.1"]),
|
||||||
|
(True, False, {"my-software": ["1.0.1", "1.0.2"]}),
|
||||||
|
(True, True, {"my-software": ["1.0.2", "1.0.1"]}),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_list_available(pkg, repo, as_dict, reverse, expected):
|
||||||
|
result = pkg.list_available(
|
||||||
|
"my-software", return_dict_always=as_dict, reverse_sort=reverse
|
||||||
|
)
|
||||||
|
assert result == expected
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"pkg_name, expected",
|
||||||
|
[
|
||||||
|
("my-software", {"my-software": ["1.0.1", "1.0.2"]}),
|
||||||
|
("my-soft*", {"my-software": ["1.0.1", "1.0.2"]}),
|
||||||
|
("your-software", {"your-software": ["1.0.0"]}),
|
||||||
|
(None, {"my-software": ["1.0.1", "1.0.2"], "your-software": ["1.0.0"]}),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_list_repo_pkgs(pkg, repo, pkg_name, expected):
|
||||||
|
if pkg_name is None:
|
||||||
|
result = pkg.list_repo_pkgs()
|
||||||
|
else:
|
||||||
|
result = pkg.list_repo_pkgs(pkg_name)
|
||||||
|
assert result == expected
|
||||||
|
|
|
@ -58,7 +58,7 @@ def refresh_keys(grains, modules):
|
||||||
def PKG_TARGETS(grains):
|
def PKG_TARGETS(grains):
|
||||||
_PKG_TARGETS = ["figlet", "sl"]
|
_PKG_TARGETS = ["figlet", "sl"]
|
||||||
if grains["os"] == "Windows":
|
if grains["os"] == "Windows":
|
||||||
_PKG_TARGETS = ["npp_x64", "winrar"]
|
_PKG_TARGETS = ["npp_x64", "putty"]
|
||||||
elif grains["os"] == "Amazon":
|
elif grains["os"] == "Amazon":
|
||||||
if grains["osfinger"] == "Amazon Linux-2023":
|
if grains["osfinger"] == "Amazon Linux-2023":
|
||||||
_PKG_TARGETS = ["lynx", "gnuplot-minimal"]
|
_PKG_TARGETS = ["lynx", "gnuplot-minimal"]
|
||||||
|
@ -225,6 +225,29 @@ def install_7zip(modules):
|
||||||
assert "22.01.00.0" not in versions
|
assert "22.01.00.0" not in versions
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="module")
|
||||||
|
def pkg_def_contents(state_tree):
|
||||||
|
return r"""
|
||||||
|
my-software:
|
||||||
|
'1.0.1':
|
||||||
|
full_name: 'My Software'
|
||||||
|
installer: 'C:\files\mysoftware101.msi'
|
||||||
|
install_flags: '/qn /norestart'
|
||||||
|
uninstaller: 'C:\files\mysoftware101.msi'
|
||||||
|
uninstall_flags: '/qn /norestart'
|
||||||
|
msiexec: True
|
||||||
|
reboot: False
|
||||||
|
'1.0.2':
|
||||||
|
full_name: 'My Software'
|
||||||
|
installer: 'C:\files\mysoftware102.msi'
|
||||||
|
install_flags: '/qn /norestart'
|
||||||
|
uninstaller: 'C:\files\mysoftware102.msi'
|
||||||
|
uninstall_flags: '/qn /norestart'
|
||||||
|
msiexec: True
|
||||||
|
reboot: False
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.requires_salt_modules("pkg.version")
|
@pytest.mark.requires_salt_modules("pkg.version")
|
||||||
@pytest.mark.requires_salt_states("pkg.installed", "pkg.removed")
|
@pytest.mark.requires_salt_states("pkg.installed", "pkg.removed")
|
||||||
@pytest.mark.slow_test
|
@pytest.mark.slow_test
|
||||||
|
@ -1126,3 +1149,14 @@ def test_pkg_removed_with_version_multiple(install_7zip, modules, states):
|
||||||
assert ret.result is True
|
assert ret.result is True
|
||||||
current = modules.pkg.version("7zip")
|
current = modules.pkg.version("7zip")
|
||||||
assert "22.01.00.0" in current
|
assert "22.01.00.0" in current
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skip_unless_on_windows()
|
||||||
|
def test_pkg_latest_test_true(states, modules, state_tree, pkg_def_contents):
|
||||||
|
repo_dir = state_tree / "winrepo_ng"
|
||||||
|
with pytest.helpers.temp_file("my-software.sls", pkg_def_contents, repo_dir):
|
||||||
|
modules.pkg.refresh_db()
|
||||||
|
assert len(modules.pkg.get_package_info("my-software")) == 2
|
||||||
|
result = states.pkg.latest("my-software", test=True)
|
||||||
|
expected = {"my-software": {"new": "1.0.2", "old": ""}}
|
||||||
|
assert result.changes == expected
|
||||||
|
|
Loading…
Add table
Reference in a new issue