From ef9db76e53a6cf6b2608c63a752ecd9af48be279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Schr=C3=B6ter?= Date: Tue, 10 Sep 2024 11:32:45 +0200 Subject: [PATCH] Sync from SUSE:ALP:Source:Standard:1.0 venv-salt-minion revision f61f79cdd12f077f8b28689cc3413ed1 --- _lastrevision | 2 +- ...ize-new-rich-rules-before-comparing-.patch | 180 ++++++++++++ ...sage-and-exclude-some-tests-to-run-w.patch | 243 ++++++++++++++++ ...user.list_groups-omits-remote-groups.patch | 265 ++++++++++++++++++ ...e-small-tests-fixes-enhancements-661.patch | 152 ++++++++++ ...ust-test-expectation-to-prevent-fail.patch | 28 ++ venv-salt-minion.changes | 40 +++ venv-salt-minion.spec | 10 + 8 files changed, 919 insertions(+), 1 deletion(-) create mode 100644 firewalld-normalize-new-rich-rules-before-comparing-.patch create mode 100644 fix-status.diskusage-and-exclude-some-tests-to-run-w.patch create mode 100644 fix-user.list_groups-omits-remote-groups.patch create mode 100644 some-more-small-tests-fixes-enhancements-661.patch create mode 100644 test_vultrpy-adjust-test-expectation-to-prevent-fail.patch diff --git a/_lastrevision b/_lastrevision index 091c36c..310f131 100644 --- a/_lastrevision +++ b/_lastrevision @@ -1 +1 @@ -1eb7b9e2177458d1bd4b32462af85ea0e3f7b072 \ No newline at end of file +597049dd3d38cffb3d6e555ded591bc36ed09a58 \ No newline at end of file diff --git a/firewalld-normalize-new-rich-rules-before-comparing-.patch b/firewalld-normalize-new-rich-rules-before-comparing-.patch new file mode 100644 index 0000000..7e6c9a6 --- /dev/null +++ b/firewalld-normalize-new-rich-rules-before-comparing-.patch @@ -0,0 +1,180 @@ +From 522b2331e6584758aeaefbf2d41f0c18cd1113d9 Mon Sep 17 00:00:00 2001 +From: Marek Czernek +Date: Tue, 23 Jul 2024 13:01:27 +0200 +Subject: [PATCH] firewalld: normalize new rich rules before comparing + to old (bsc#1222684) (#648) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +* Normalize new rich rules before comparing to old + +Firewallcmd rich rule output quotes each +assigned part of the rich rule, for example: +rule family="ipv4" source port port="161" ... +The firewalld module must first normalize +the user defined rich rules to match the +firewallcmd output before comparison to +ensure idempotency. + +* Add changelog entry + +* Enhance documentation for normalization function + +* Add unit tests to cover rich rules normalization + +--------- + +Co-authored-by: Pablo Suárez Hernández +--- + changelog/61235.fixed.md | 1 + + salt/states/firewalld.py | 38 +++++++++++- + tests/pytests/unit/states/test_firewalld.py | 64 +++++++++++++++++++++ + 3 files changed, 102 insertions(+), 1 deletion(-) + create mode 100644 changelog/61235.fixed.md + create mode 100644 tests/pytests/unit/states/test_firewalld.py + +diff --git a/changelog/61235.fixed.md b/changelog/61235.fixed.md +new file mode 100644 +index 00000000000..7ae9bb40800 +--- /dev/null ++++ b/changelog/61235.fixed.md +@@ -0,0 +1 @@ ++- firewalld: normalize new rich rules before comparing to old ones +diff --git a/salt/states/firewalld.py b/salt/states/firewalld.py +index 534b9dd62df..9ce0bfc61a8 100644 +--- a/salt/states/firewalld.py ++++ b/salt/states/firewalld.py +@@ -204,7 +204,6 @@ def present( + rich_rules=None, + prune_rich_rules=False, + ): +- + """ + Ensure a zone has specific attributes. + +@@ -378,6 +377,42 @@ def service(name, ports=None, protocols=None): + return ret + + ++def _normalize_rich_rules(rich_rules): ++ """ ++ Make sure rich rules are normalized and attributes ++ are quoted with double quotes so it matches the output ++ from firewall-cmd ++ ++ Example: ++ ++ rule family="ipv4" source address="192.168.0.0/16" port port=22 protocol=tcp accept ++ rule family="ipv4" source address="192.168.0.0/16" port port='22' protocol=tcp accept ++ rule family='ipv4' source address='192.168.0.0/16' port port='22' protocol=tcp accept ++ ++ normalized to: ++ ++ rule family="ipv4" source address="192.168.0.0/16" port port="22" protocol="tcp" accept ++ """ ++ normalized_rules = [] ++ for rich_rule in rich_rules: ++ normalized_rule = "" ++ for cmd in rich_rule.split(" "): ++ cmd_components = cmd.split("=", 1) ++ if len(cmd_components) == 2: ++ assigned_component = cmd_components[1] ++ if not assigned_component.startswith( ++ '"' ++ ) and not assigned_component.endswith('"'): ++ if assigned_component.startswith( ++ "'" ++ ) and assigned_component.endswith("'"): ++ assigned_component = assigned_component[1:-1] ++ cmd_components[1] = f'"{assigned_component}"' ++ normalized_rule = f"{normalized_rule} {'='.join(cmd_components)}" ++ normalized_rules.append(normalized_rule.lstrip()) ++ return normalized_rules ++ ++ + def _present( + name, + block_icmp=None, +@@ -761,6 +796,7 @@ def _present( + + if rich_rules or prune_rich_rules: + rich_rules = rich_rules or [] ++ rich_rules = _normalize_rich_rules(rich_rules) + try: + _current_rich_rules = __salt__["firewalld.get_rich_rules"]( + name, permanent=True +diff --git a/tests/pytests/unit/states/test_firewalld.py b/tests/pytests/unit/states/test_firewalld.py +new file mode 100644 +index 00000000000..0cbc59633bf +--- /dev/null ++++ b/tests/pytests/unit/states/test_firewalld.py +@@ -0,0 +1,64 @@ ++""" ++ :codeauthor: Hristo Voyvodov ++""" ++ ++import pytest ++ ++import salt.states.firewalld as firewalld ++from tests.support.mock import MagicMock, patch ++ ++ ++@pytest.fixture ++def configure_loader_modules(): ++ return {firewalld: {"__opts__": {"test": False}}} ++ ++ ++@pytest.mark.parametrize( ++ "rich_rule", ++ [ ++ ( ++ [ ++ 'rule family="ipv4" source address="192.168.0.0/16" port port=22 protocol=tcp accept' ++ ] ++ ), ++ ( ++ [ ++ 'rule family="ipv4" source address="192.168.0.0/16" port port=\'22\' protocol=tcp accept' ++ ] ++ ), ++ ( ++ [ ++ "rule family='ipv4' source address='192.168.0.0/16' port port='22' protocol=tcp accept" ++ ] ++ ), ++ ], ++) ++def test_present_rich_rules_normalized(rich_rule): ++ firewalld_reload_rules = MagicMock(return_value={}) ++ firewalld_rich_rules = [ ++ 'rule family="ipv4" source address="192.168.0.0/16" port port="22" protocol="tcp" accept', ++ ] ++ ++ firewalld_get_zones = MagicMock( ++ return_value=[ ++ "block", ++ "public", ++ ] ++ ) ++ firewalld_get_masquerade = MagicMock(return_value=False) ++ firewalld_get_rich_rules = MagicMock(return_value=firewalld_rich_rules) ++ ++ __salt__ = { ++ "firewalld.reload_rules": firewalld_reload_rules, ++ "firewalld.get_zones": firewalld_get_zones, ++ "firewalld.get_masquerade": firewalld_get_masquerade, ++ "firewalld.get_rich_rules": firewalld_get_rich_rules, ++ } ++ with patch.dict(firewalld.__dict__, {"__salt__": __salt__}): ++ ret = firewalld.present("public", rich_rules=rich_rule) ++ assert ret == { ++ "changes": {}, ++ "result": True, ++ "comment": "'public' is already in the desired state.", ++ "name": "public", ++ } +-- +2.45.2 + + diff --git a/fix-status.diskusage-and-exclude-some-tests-to-run-w.patch b/fix-status.diskusage-and-exclude-some-tests-to-run-w.patch new file mode 100644 index 0000000..a772be8 --- /dev/null +++ b/fix-status.diskusage-and-exclude-some-tests-to-run-w.patch @@ -0,0 +1,243 @@ +From 4555f215614c2f2d5c4b5c376264df9b3f23a55b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?= + +Date: Tue, 18 Jun 2024 15:55:31 +0100 +Subject: [PATCH] Fix "status.diskusage" and exclude some tests to run + when testing Salt Bundle (#659) + +* Show warning instead of crashing when stats cannot be fetched + +* Skip tests that are not compatible with Salt Bundle + +* test_syndic_eauth: do not produce error if docker service is not running + +* test_cmdmod: assert properly in case of DeprecationsWarnings + +* Include path as part of output in case of errors + +Co-authored-by: Marek Czernek + +--------- + +Co-authored-by: Marek Czernek +--- + salt/modules/status.py | 14 +++++++++----- + tests/integration/modules/test_pip.py | 5 +++++ + tests/integration/ssh/test_state.py | 5 +++++ + tests/pytests/functional/modules/test_pip.py | 4 ++++ + .../functional/modules/test_virtualenv_mod.py | 5 +++++ + tests/pytests/functional/states/test_pip_state.py | 4 ++++ + tests/pytests/integration/cli/test_syndic_eauth.py | 3 +++ + tests/pytests/integration/modules/test_cmdmod.py | 4 +++- + .../pytests/integration/netapi/test_ssh_client.py | 6 ++++++ + tests/pytests/integration/ssh/conftest.py | 9 +++++++++ + tests/unit/utils/test_thin.py | 4 ++++ + 11 files changed, 57 insertions(+), 6 deletions(-) + create mode 100644 tests/pytests/integration/ssh/conftest.py + +diff --git a/salt/modules/status.py b/salt/modules/status.py +index 33e5d7b8df5..8d6241a9dce 100644 +--- a/salt/modules/status.py ++++ b/salt/modules/status.py +@@ -1053,11 +1053,15 @@ def diskusage(*args): + ret = {} + for path in selected: + if os.path.exists(path): +- fsstats = os.statvfs(path) +- blksz = fsstats.f_bsize +- available = fsstats.f_bavail * blksz +- total = fsstats.f_blocks * blksz +- ret[path] = {"available": available, "total": total} ++ try: ++ fsstats = os.statvfs(path) ++ blksz = fsstats.f_bsize ++ available = fsstats.f_bavail * blksz ++ total = fsstats.f_blocks * blksz ++ ret[path] = {"available": available, "total": total} ++ except OSError as exc: ++ log.warning("Cannot get stats from '{}': {}".format(path, exc)) ++ ret[path] = {"available": None, "total": None} + return ret + + +diff --git a/tests/integration/modules/test_pip.py b/tests/integration/modules/test_pip.py +index d57e9cd2aea..85045dec90b 100644 +--- a/tests/integration/modules/test_pip.py ++++ b/tests/integration/modules/test_pip.py +@@ -2,6 +2,7 @@ import os + import pprint + import re + import shutil ++import sys + import tempfile + + import pytest +@@ -16,6 +17,10 @@ from tests.support.runtests import RUNTIME_VARS + + + @pytest.mark.skip_if_binaries_missing(*KNOWN_BINARY_NAMES, check_all=False) ++@pytest.mark.skipif( ++ "venv-salt-minion" in sys.executable, ++ reason="Skipping for Salt Bundle (tests are not compatible)", ++) + @pytest.mark.windows_whitelisted + class PipModuleTest(ModuleCase): + def setUp(self): +diff --git a/tests/integration/ssh/test_state.py b/tests/integration/ssh/test_state.py +index 69245454e85..daa478b45be 100644 +--- a/tests/integration/ssh/test_state.py ++++ b/tests/integration/ssh/test_state.py +@@ -2,6 +2,7 @@ import glob + import logging + import os + import shutil ++import sys + import threading + import time + +@@ -18,6 +19,10 @@ log = logging.getLogger(__name__) + + + @pytest.mark.slow_test ++@pytest.mark.skipif( ++ "venv-salt-minion" in sys.executable, ++ reason="Skipping for Salt Bundle (tests are not compatible)", ++) + class SSHStateTest(SSHCase): + """ + testing the state system with salt-ssh +diff --git a/tests/pytests/functional/modules/test_pip.py b/tests/pytests/functional/modules/test_pip.py +index e04baa7c43f..1f0104e3e6d 100644 +--- a/tests/pytests/functional/modules/test_pip.py ++++ b/tests/pytests/functional/modules/test_pip.py +@@ -23,6 +23,10 @@ from tests.support.helpers import VirtualEnv + @pytest.mark.requires_network + @pytest.mark.slow_test + @pytest.mark.skip_if_binaries_missing("virtualenv", reason="Needs virtualenv binary") ++@pytest.mark.skipif( ++ "venv-salt-minion" in sys.executable, ++ reason="Skipping for Salt Bundle (tests are not compatible)", ++) + def test_list_available_packages(modules, pip_version, tmp_path): + with VirtualEnv(venv_dir=tmp_path, pip_requirement=pip_version) as virtualenv: + virtualenv.install("-U", pip_version) +diff --git a/tests/pytests/functional/modules/test_virtualenv_mod.py b/tests/pytests/functional/modules/test_virtualenv_mod.py +index 2b6abf91e23..69e1866c6e3 100644 +--- a/tests/pytests/functional/modules/test_virtualenv_mod.py ++++ b/tests/pytests/functional/modules/test_virtualenv_mod.py +@@ -1,4 +1,5 @@ + import shutil ++import sys + + import pytest + +@@ -68,6 +69,10 @@ def test_clear(virtualenv, venv_dir, modules): + bool(salt.utils.path.which("transactional-update")), + reason="Skipping on transactional systems", + ) ++@pytest.mark.skipif( ++ "venv-salt-minion" in sys.executable, ++ reason="Skipping for Salt Bundle (tests are not compatible)", ++) + def test_virtualenv_ver(virtualenv, venv_dir): + ret = virtualenv.create(str(venv_dir)) + assert ret +diff --git a/tests/pytests/functional/states/test_pip_state.py b/tests/pytests/functional/states/test_pip_state.py +index 1f2080f1f86..28c1f9fd1f3 100644 +--- a/tests/pytests/functional/states/test_pip_state.py ++++ b/tests/pytests/functional/states/test_pip_state.py +@@ -84,6 +84,10 @@ def create_virtualenv(modules): + bool(salt.utils.path.which("transactional-update")), + reason="Skipping on transactional systems", + ) ++@pytest.mark.skipif( ++ "venv-salt-minion" in sys.executable, ++ reason="Skipping for Salt Bundle (tests are not compatible)", ++) + def test_pip_installed_removed(modules, states): + """ + Tests installed and removed states +diff --git a/tests/pytests/integration/cli/test_syndic_eauth.py b/tests/pytests/integration/cli/test_syndic_eauth.py +index dde4c25bc91..f2d36c13abb 100644 +--- a/tests/pytests/integration/cli/test_syndic_eauth.py ++++ b/tests/pytests/integration/cli/test_syndic_eauth.py +@@ -68,6 +68,9 @@ def syndic_network(): + try: + network = client.networks.create(name="syndic_test_net", ipam=ipam_config) + yield network.name ++ except Exception as e: ++ # Docker failed, it's gonna be an environment issue, let's just skip ++ pytest.skip(f"Docker failed with error {e}") + finally: + if network is not None: + network.remove() +diff --git a/tests/pytests/integration/modules/test_cmdmod.py b/tests/pytests/integration/modules/test_cmdmod.py +index d0b993ddbcf..20a6f808933 100644 +--- a/tests/pytests/integration/modules/test_cmdmod.py ++++ b/tests/pytests/integration/modules/test_cmdmod.py +@@ -75,7 +75,9 @@ def test_blacklist_glob(salt_call_cli): + ) + + assert ( +- ret.stderr.rstrip() ++ ret.stderr.rstrip().split("\n")[ ++ -1 ++ ] # Taking only the last line in case of DeprecationWarnings + == "Error running 'cmd.run': The shell command \"bad_command --foo\" is not permitted" + ) + +diff --git a/tests/pytests/integration/netapi/test_ssh_client.py b/tests/pytests/integration/netapi/test_ssh_client.py +index 42db6d0eacd..457c151c94f 100644 +--- a/tests/pytests/integration/netapi/test_ssh_client.py ++++ b/tests/pytests/integration/netapi/test_ssh_client.py +@@ -1,3 +1,5 @@ ++import sys ++ + import pytest + + import salt.netapi +@@ -8,6 +10,10 @@ from tests.support.mock import patch + pytestmark = [ + pytest.mark.slow_test, + pytest.mark.requires_sshd_server, ++ pytest.mark.skipif( ++ "venv-salt-minion" in sys.executable, ++ reason="Skipping for Salt Bundle (tests are not compatible)", ++ ), + ] + + +diff --git a/tests/pytests/integration/ssh/conftest.py b/tests/pytests/integration/ssh/conftest.py +new file mode 100644 +index 00000000000..ba6e5f2773a +--- /dev/null ++++ b/tests/pytests/integration/ssh/conftest.py +@@ -0,0 +1,9 @@ ++import sys ++ ++import pytest ++ ++ ++@pytest.fixture(scope="package", autouse=True) ++def _auto_skip_on_salt_bundle(): ++ if "venv-salt-minion" in sys.executable: ++ pytest.skip("Skipping for Salt Bundle (tests are not compatible)") +diff --git a/tests/unit/utils/test_thin.py b/tests/unit/utils/test_thin.py +index c4e9c3b3bef..b31199976c8 100644 +--- a/tests/unit/utils/test_thin.py ++++ b/tests/unit/utils/test_thin.py +@@ -1383,6 +1383,10 @@ class SSHThinTestCase(TestCase): + "virtualenv", reason="Needs virtualenv binary" + ) + @pytest.mark.skip_on_windows(reason="salt-ssh does not deploy to/from windows") ++ @pytest.mark.skipif( ++ "venv-salt-minion" in sys.executable, ++ reason="Skipping for Salt Bundle (tests are not compatible)", ++ ) + def test_thin_dir(self): + """ + Test the thin dir to make sure salt-call can run +-- +2.44.0 + + diff --git a/fix-user.list_groups-omits-remote-groups.patch b/fix-user.list_groups-omits-remote-groups.patch new file mode 100644 index 0000000..91fe344 --- /dev/null +++ b/fix-user.list_groups-omits-remote-groups.patch @@ -0,0 +1,265 @@ +From 70509ff67d4eb734c88032913134092257a0d35b Mon Sep 17 00:00:00 2001 +From: Flex Liu +Date: Tue, 2 Jul 2024 15:25:30 +0800 +Subject: [PATCH] Fix user.list_groups omits remote groups + +* fixes saltstack/salt#64953 user.list_groups omits remote groups + +* fixes saltstack/salt#65029 support for pysss can be removed + +* add changlog entries + +* add tests for _getgrall and local vs remote group handling + +* add negative tests for _getgrall + +* root can still read the file and tests run as root + +* remove permission check as its probably an unreachable edge case + +--------- + +Co-authored-by: nicholasmhughes +--- + changelog/64888.fixed.md | 1 + + changelog/64953.fixed.md | 1 + + changelog/65029.removed.md | 1 + + salt/auth/pam.py | 9 --- + salt/utils/user.py | 73 ++++++++++++------- + .../functional/utils/user/test__getgrall.py | 44 +++++++++++ + tests/pytests/unit/utils/test_user.py | 29 ++++++++ + 7 files changed, 122 insertions(+), 36 deletions(-) + create mode 100644 changelog/64888.fixed.md + create mode 100644 changelog/64953.fixed.md + create mode 100644 changelog/65029.removed.md + create mode 100644 tests/pytests/functional/utils/user/test__getgrall.py + create mode 100644 tests/pytests/unit/utils/test_user.py + +diff --git a/changelog/64888.fixed.md b/changelog/64888.fixed.md +new file mode 100644 +index 0000000000..08b2efd042 +--- /dev/null ++++ b/changelog/64888.fixed.md +@@ -0,0 +1 @@ ++Fixed grp.getgrall() in utils/user.py causing performance issues +diff --git a/changelog/64953.fixed.md b/changelog/64953.fixed.md +new file mode 100644 +index 0000000000..f0b1ed46f1 +--- /dev/null ++++ b/changelog/64953.fixed.md +@@ -0,0 +1 @@ ++Fix user.list_groups omits remote groups via sssd, etc. +diff --git a/changelog/65029.removed.md b/changelog/65029.removed.md +new file mode 100644 +index 0000000000..d09f10b4ba +--- /dev/null ++++ b/changelog/65029.removed.md +@@ -0,0 +1 @@ ++Tech Debt - support for pysss removed due to functionality addition in Python 3.3 +diff --git a/salt/auth/pam.py b/salt/auth/pam.py +index f0397c1062..12af29bbdb 100644 +--- a/salt/auth/pam.py ++++ b/salt/auth/pam.py +@@ -24,15 +24,6 @@ authenticated against. This defaults to `login` + + The Python interface to PAM does not support authenticating as ``root``. + +-.. note:: Using PAM groups with SSSD groups on python2. +- +- To use sssd with the PAM eauth module and groups the `pysss` module is +- needed. On RedHat/CentOS this is `python-sss`. +- +- This should not be needed with python >= 3.3, because the `os` modules has the +- `getgrouplist` function. +- +- + .. note:: This module executes itself in a subprocess in order to user the system python + and pam libraries. We do this to avoid openssl version conflicts when + running under a salt onedir build. +diff --git a/salt/utils/user.py b/salt/utils/user.py +index 2f1ca65cf9..3588b3804a 100644 +--- a/salt/utils/user.py ++++ b/salt/utils/user.py +@@ -31,13 +31,6 @@ try: + except ImportError: + HAS_GRP = False + +-try: +- import pysss +- +- HAS_PYSSS = True +-except ImportError: +- HAS_PYSSS = False +- + try: + import salt.utils.win_functions + +@@ -289,30 +282,35 @@ def get_group_list(user, include_default=True): + return [] + group_names = None + ugroups = set() +- if hasattr(os, "getgrouplist"): +- # Try os.getgrouplist, available in python >= 3.3 +- log.trace("Trying os.getgrouplist for '%s'", user) +- try: +- user_group_list = os.getgrouplist(user, pwd.getpwnam(user).pw_gid) +- group_names = [ +- _group.gr_name +- for _group in grp.getgrall() +- if _group.gr_gid in user_group_list +- ] +- except Exception: # pylint: disable=broad-except +- pass +- elif HAS_PYSSS: +- # Try pysss.getgrouplist +- log.trace("Trying pysss.getgrouplist for '%s'", user) +- try: +- group_names = list(pysss.getgrouplist(user)) +- except Exception: # pylint: disable=broad-except +- pass ++ # Try os.getgrouplist, available in python >= 3.3 ++ log.trace("Trying os.getgrouplist for '%s'", user) ++ try: ++ user_group_list = sorted(os.getgrouplist(user, pwd.getpwnam(user).pw_gid)) ++ local_grall = _getgrall() ++ local_gids = sorted(lgrp.gr_gid for lgrp in local_grall) ++ max_idx = -1 ++ local_max = local_gids[max_idx] ++ while local_max >= 65000: ++ max_idx -= 1 ++ local_max = local_gids[max_idx] ++ user_group_list_local = [lgrp for lgrp in user_group_list if lgrp <= local_max] ++ user_group_list_remote = [rgrp for rgrp in user_group_list if rgrp > local_max] ++ local_group_names = [ ++ _group.gr_name ++ for _group in local_grall ++ if _group.gr_gid in user_group_list_local ++ ] ++ remote_group_names = [ ++ grp.getgrgid(group_id).gr_name for group_id in user_group_list_remote ++ ] ++ group_names = local_group_names + remote_group_names ++ except Exception: # pylint: disable=broad-except ++ pass + + if group_names is None: + # Fall back to generic code + # Include the user's default group to match behavior of +- # os.getgrouplist() and pysss.getgrouplist() ++ # os.getgrouplist() + log.trace("Trying generic group list for '%s'", user) + group_names = [g.gr_name for g in grp.getgrall() if user in g.gr_mem] + try: +@@ -389,3 +387,24 @@ def get_gid(group=None): + return grp.getgrnam(group).gr_gid + except KeyError: + return None ++ ++ ++def _getgrall(root=None): ++ """ ++ Alternative implemetantion for getgrall, that uses only /etc/group ++ """ ++ ret = [] ++ root = "/" if not root else root ++ etc_group = os.path.join(root, "etc/group") ++ with salt.utils.files.fopen(etc_group) as fp_: ++ for line in fp_: ++ line = salt.utils.stringutils.to_unicode(line) ++ comps = line.strip().split(":") ++ # Generate a getgrall compatible output ++ comps[2] = int(comps[2]) ++ if comps[3]: ++ comps[3] = [mem.strip() for mem in comps[3].split(",")] ++ else: ++ comps[3] = [] ++ ret.append(grp.struct_group(comps)) ++ return ret +diff --git a/tests/pytests/functional/utils/user/test__getgrall.py b/tests/pytests/functional/utils/user/test__getgrall.py +new file mode 100644 +index 0000000000..db994019e6 +--- /dev/null ++++ b/tests/pytests/functional/utils/user/test__getgrall.py +@@ -0,0 +1,44 @@ ++from textwrap import dedent ++ ++import pytest ++ ++pytest.importorskip("grp") ++ ++import grp ++ ++import salt.utils.user ++ ++ ++@pytest.fixture(scope="function") ++def etc_group(tmp_path): ++ etcgrp = tmp_path / "etc" / "group" ++ etcgrp.parent.mkdir() ++ etcgrp.write_text( ++ dedent( ++ """games:x:50: ++ docker:x:959:debian,salt ++ salt:x:1000:""" ++ ) ++ ) ++ return etcgrp ++ ++ ++def test__getgrall(etc_group): ++ group_lines = [ ++ ["games", "x", 50, []], ++ ["docker", "x", 959, ["debian", "salt"]], ++ ["salt", "x", 1000, []], ++ ] ++ expected_grall = [grp.struct_group(comps) for comps in group_lines] ++ ++ grall = salt.utils.user._getgrall(root=str(etc_group.parent.parent)) ++ ++ assert grall == expected_grall ++ ++ ++def test__getgrall_bad_format(etc_group): ++ with etc_group.open("a") as _fp: ++ _fp.write("\n# some comment here\n") ++ ++ with pytest.raises(IndexError): ++ salt.utils.user._getgrall(root=str(etc_group.parent.parent)) +diff --git a/tests/pytests/unit/utils/test_user.py b/tests/pytests/unit/utils/test_user.py +new file mode 100644 +index 0000000000..17c6b1551f +--- /dev/null ++++ b/tests/pytests/unit/utils/test_user.py +@@ -0,0 +1,29 @@ ++from types import SimpleNamespace ++ ++import pytest ++ ++from tests.support.mock import MagicMock, patch ++ ++pytest.importorskip("grp") ++ ++import grp ++ ++import salt.utils.user ++ ++ ++def test_get_group_list(): ++ getpwname = SimpleNamespace(pw_gid=1000) ++ getgrgid = MagicMock(side_effect=[SimpleNamespace(gr_name="remote")]) ++ group_lines = [ ++ ["games", "x", 50, []], ++ ["salt", "x", 1000, []], ++ ] ++ getgrall = [grp.struct_group(comps) for comps in group_lines] ++ with patch("os.getgrouplist", MagicMock(return_value=[50, 1000, 12000])), patch( ++ "pwd.getpwnam", MagicMock(return_value=getpwname) ++ ), patch("salt.utils.user._getgrall", MagicMock(return_value=getgrall)), patch( ++ "grp.getgrgid", getgrgid ++ ): ++ group_list = salt.utils.user.get_group_list("salt") ++ assert group_list == ["games", "remote", "salt"] ++ getgrgid.assert_called_once() +-- +2.35.3 + diff --git a/some-more-small-tests-fixes-enhancements-661.patch b/some-more-small-tests-fixes-enhancements-661.patch new file mode 100644 index 0000000..a402bc2 --- /dev/null +++ b/some-more-small-tests-fixes-enhancements-661.patch @@ -0,0 +1,152 @@ +From e4333e2000b3ee92c1df7f9af57133706b48ca66 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?= + +Date: Mon, 8 Jul 2024 16:58:28 +0100 +Subject: [PATCH] Some more small tests fixes/enhancements (#661) + +* test_system: prevent errors when systemd-timesyncd service is masked + +* test_custom_module: disable tests when running on Salt Bundle + +* Fix debian 12 package tests + +* pam: use sys.executable in case /usr/bin/python3 does not exist + +* pam: add unit test to ensure sys.executable is used + +* Use proper method to calculate the path to Python interpreter + +--------- + +Co-authored-by: Megan Wilhite +--- + salt/auth/pam.py | 19 ++++++++++++++++++- + tests/integration/cli/test_custom_module.py | 6 ++++++ + .../pytests/functional/modules/test_system.py | 4 +++- + .../functional/states/pkgrepo/test_debian.py | 4 ++++ + tests/pytests/unit/auth/test_pam.py | 19 +++++++++++++++++++ + 5 files changed, 50 insertions(+), 2 deletions(-) + +diff --git a/salt/auth/pam.py b/salt/auth/pam.py +index 12af29bbdb8..25e080861b7 100644 +--- a/salt/auth/pam.py ++++ b/salt/auth/pam.py +@@ -223,12 +223,29 @@ def authenticate(username, password): + + ``password``: the password in plain text + """ ++ ++ def __find_pyexe(): ++ """ ++ Provides the path to the Python interpreter to use. ++ ++ First option: the system's Python 3 interpreter ++ If not found, it fallback to use the running Python interpreter (sys.executable) ++ ++ This can be overwritten via "auth.pam.python" configuration parameter. ++ """ ++ if __opts__.get("auth.pam.python"): ++ return __opts__.get("auth.pam.python") ++ elif os.path.exists("/usr/bin/python3"): ++ return "/usr/bin/python3" ++ else: ++ return sys.executable ++ + env = os.environ.copy() + env["SALT_PAM_USERNAME"] = username + env["SALT_PAM_PASSWORD"] = password + env["SALT_PAM_SERVICE"] = __opts__.get("auth.pam.service", "login") + env["SALT_PAM_ENCODING"] = __salt_system_encoding__ +- pyexe = pathlib.Path(__opts__.get("auth.pam.python", "/usr/bin/python3")).resolve() ++ pyexe = pathlib.Path(__find_pyexe()).resolve() + pyfile = pathlib.Path(__file__).resolve() + if not pyexe.exists(): + log.error("Error 'auth.pam.python' config value does not exist: %s", pyexe) +diff --git a/tests/integration/cli/test_custom_module.py b/tests/integration/cli/test_custom_module.py +index 6c048e30cd2..a4863b584f8 100644 +--- a/tests/integration/cli/test_custom_module.py ++++ b/tests/integration/cli/test_custom_module.py +@@ -29,12 +29,18 @@ + olleh + """ + ++import sys ++ + import pytest + + from tests.support.case import SSHCase + + + @pytest.mark.skip_on_windows ++@pytest.mark.skipif( ++ "venv-salt-minion" in sys.executable, ++ reason="Skipping for Salt Bundle (tests are not compatible)", ++) + class SSHCustomModuleTest(SSHCase): + """ + Test sls with custom module functionality using ssh +diff --git a/tests/pytests/functional/modules/test_system.py b/tests/pytests/functional/modules/test_system.py +index 3b669c46afd..2cd03a3a3e4 100644 +--- a/tests/pytests/functional/modules/test_system.py ++++ b/tests/pytests/functional/modules/test_system.py +@@ -61,7 +61,9 @@ def setup_teardown_vars(file, service, system): + _machine_info = False + + try: +- _systemd_timesyncd_available_ = service.available("systemd-timesyncd") ++ _systemd_timesyncd_available_ = service.available( ++ "systemd-timesyncd" ++ ) and not service.masked("systemd-timesyncd") + if _systemd_timesyncd_available_: + res = service.stop("systemd-timesyncd") + assert res +diff --git a/tests/pytests/functional/states/pkgrepo/test_debian.py b/tests/pytests/functional/states/pkgrepo/test_debian.py +index d025643aa4c..87716706d5e 100644 +--- a/tests/pytests/functional/states/pkgrepo/test_debian.py ++++ b/tests/pytests/functional/states/pkgrepo/test_debian.py +@@ -622,6 +622,10 @@ class Repo: + if ( + self.grains["osfullname"] == "Ubuntu" + and self.grains["osrelease"] == "22.04" ++ or "Debian" in self.grains["osfullname"] ++ and self.grains["osrelease"] == "12" ++ # only need to use alt repo until ++ # we release Debian 12 salt packages + ): + return True + return False +diff --git a/tests/pytests/unit/auth/test_pam.py b/tests/pytests/unit/auth/test_pam.py +index 22c7f438d63..35f599e3d17 100644 +--- a/tests/pytests/unit/auth/test_pam.py ++++ b/tests/pytests/unit/auth/test_pam.py +@@ -1,3 +1,5 @@ ++import tempfile ++ + import pytest + + import salt.auth.pam +@@ -45,3 +47,20 @@ def test_if_pam_acct_mgmt_returns_zero_authenticate_should_be_true(mock_pam): + ) + is True + ) ++ ++ ++def test_if_sys_executable_is_used_to_call_pam_auth(mock_pam): ++ class Ret: ++ returncode = 0 ++ ++ with patch( ++ "salt.auth.pam.subprocess.run", return_value=Ret ++ ) as run_mock, tempfile.NamedTemporaryFile() as f, patch( ++ "salt.auth.pam.sys.executable", f.name ++ ), patch( ++ "os.path.exists", return_value=False ++ ): ++ assert salt.auth.pam.auth( ++ username="fnord", password="fnord", service="login", encoding="utf-8" ++ ) ++ assert f.name in run_mock.call_args_list[0][0][0] +-- +2.45.2 + + diff --git a/test_vultrpy-adjust-test-expectation-to-prevent-fail.patch b/test_vultrpy-adjust-test-expectation-to-prevent-fail.patch new file mode 100644 index 0000000..f0e1ba7 --- /dev/null +++ b/test_vultrpy-adjust-test-expectation-to-prevent-fail.patch @@ -0,0 +1,28 @@ +From e24c5dbc8c48ce46d3a87cd527677b980c29124d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?= + +Date: Tue, 9 Jul 2024 12:19:36 +0100 +Subject: [PATCH] test_vultrpy: adjust test expectation to prevent + failure (#666) + +--- + tests/integration/cloud/clouds/test_vultrpy.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/integration/cloud/clouds/test_vultrpy.py b/tests/integration/cloud/clouds/test_vultrpy.py +index a25b4502dae..719d7291410 100644 +--- a/tests/integration/cloud/clouds/test_vultrpy.py ++++ b/tests/integration/cloud/clouds/test_vultrpy.py +@@ -19,7 +19,7 @@ class VultrTest(CloudTest): + """ + image_list = self.run_cloud("--list-images {}".format(self.PROVIDER)) + +- self.assertIn("Debian 10 x64 (buster)", [i.strip() for i in image_list]) ++ self.assertIn("Debian 12 x64 (bookworm)", [i.strip() for i in image_list]) + + def test_list_locations(self): + """ +-- +2.45.2 + + diff --git a/venv-salt-minion.changes b/venv-salt-minion.changes index b4d7845..c8ad564 100644 --- a/venv-salt-minion.changes +++ b/venv-salt-minion.changes @@ -1,3 +1,43 @@ +------------------------------------------------------------------- +Wed Jul 24 10:13:27 UTC 2024 - Pablo Suárez Hernández + +- Fix rich rule comparison in firewalld module (bsc#1222684) + +- Added: + * firewalld-normalize-new-rich-rules-before-comparing-.patch + +------------------------------------------------------------------- +Tue Jul 9 11:24:07 UTC 2024 - Pablo Suárez Hernández + +- test_vultrpy: adjust test expectation to prevent failure after Debian 10 EOL + +- Added: + * test_vultrpy-adjust-test-expectation-to-prevent-fail.patch + +------------------------------------------------------------------- +Mon Jul 8 16:03:27 UTC 2024 - Pablo Suárez Hernández + +- Make auth.pam more robust with Salt Bundle and fix tests + +- Added: + * some-more-small-tests-fixes-enhancements-661.patch + +------------------------------------------------------------------- +Wed Jul 3 10:45:24 UTC 2024 - Flex Liu + +- Fix performance of user.list_groups with many remote groups + +- Added: + * fix-user.list_groups-omits-remote-groups.patch + +------------------------------------------------------------------- +Tue Jun 18 15:01:28 UTC 2024 - Pablo Suárez Hernández + +- Fix "status.diskusage" function and exclude some tests for Salt Bundle + +- Added: + * fix-status.diskusage-and-exclude-some-tests-to-run-w.patch + ------------------------------------------------------------------- Wed Jun 12 08:47:03 UTC 2024 - Pablo Suárez Hernández diff --git a/venv-salt-minion.spec b/venv-salt-minion.spec index 506e9f1..dd720c8 100644 --- a/venv-salt-minion.spec +++ b/venv-salt-minion.spec @@ -405,6 +405,16 @@ Patch119: several-fixes-for-tests-to-avoid-errors-and-failures.patch Patch120: provide-systemd-timer-unit.patch # PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/66630 Patch121: skip-certain-tests-if-necessary-and-mark-some-flaky-.patch +# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/66647 +Patch122: fix-status.diskusage-and-exclude-some-tests-to-run-w.patch +# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/65077 +Patch123: fix-user.list_groups-omits-remote-groups.patch +# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/66695 +Patch124: some-more-small-tests-fixes-enhancements-661.patch +# PATCH-FIX_OPENSUSE: https://github.com/openSUSE/salt/pull/666 +Patch125: test_vultrpy-adjust-test-expectation-to-prevent-fail.patch +# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/66698 +Patch126: firewalld-normalize-new-rich-rules-before-comparing-.patch ### IMPORTANT: The line below is used as a snippet marker. Do not touch it. ### SALT PATCHES LIST END