SHA256
1
0
forked from pool/salt
salt/allow-vendor-change-option-with-zypper.patch
Alexander Graul 2686359b2c Accepting request 1084999 from home:agraul:branches:systemsmanagement:saltstack
- Update to Salt release version 3006.0 (jsc#PED-3139)
  * See release notes: https://docs.saltproject.io/en/latest/topics/releases/3006.0.html
- Add python3-looseversion as new dependency for salt
- Add python3-packaging as new dependency for salt
- Drop conflictive patch dicarded from upstream
- Fix SLS rendering error when Jinja macros are used
- Fix version detection and avoid building and testing failures
- Added:
  * fix-version-detection-and-avoid-building-and-testing.patch
  * make-sure-the-file-client-is-destroyed-upon-used.patch
- Modified:
  * 3005.1-implement-zypper-removeptf-573.patch
  * activate-all-beacons-sources-config-pillar-grains.patch
  * add-custom-suse-capabilities-as-grains.patch
  * add-environment-variable-to-know-if-yum-is-invoked-f.patch
  * add-migrated-state-and-gpg-key-management-functions-.patch
  * add-publish_batch-to-clearfuncs-exposed-methods.patch
  * add-salt-ssh-support-with-venv-salt-minion-3004-493.patch
  * add-sleep-on-exception-handling-on-minion-connection.patch
  * add-standalone-configuration-file-for-enabling-packa.patch
  * add-support-for-gpgautoimport-539.patch
  * allow-vendor-change-option-with-zypper.patch
  * async-batch-implementation.patch
  * avoid-excessive-syslogging-by-watchdog-cronjob-58.patch
  * bsc-1176024-fix-file-directory-user-and-group-owners.patch
  * change-the-delimeters-to-prevent-possible-tracebacks.patch
  * control-the-collection-of-lvm-grains-via-config.patch
  * debian-info_installed-compatibility-50453.patch
  * dnfnotify-pkgset-plugin-implementation-3002.2-450.patch
  * do-not-load-pip-state-if-there-is-no-3rd-party-depen.patch
  * don-t-use-shell-sbin-nologin-in-requisites.patch
  * drop-serial-from-event.unpack-in-cli.batch_async.patch
  * early-feature-support-config.patch
  * enable-passing-a-unix_socket-for-mysql-returners-bsc.patch
  * enhance-openscap-module-add-xccdf_eval-call-386.patch
  * fix-bsc-1065792.patch
  * fix-for-suse-expanded-support-detection.patch
  * fix-issue-2068-test.patch
  * fix-missing-minion-returns-in-batch-mode-360.patch
  * fix-ownership-of-salt-thin-directory-when-using-the-.patch
  * fix-regression-with-depending-client.ssh-on-psutil-b.patch
  * fix-salt-ssh-opts-poisoning-bsc-1197637-3004-501.patch
  * fix-salt.utils.stringutils.to_str-calls-to-make-it-w.patch
  * fix-the-regression-for-yumnotify-plugin-456.patch
  * fix-traceback.print_exc-calls-for-test_pip_state-432.patch
  * fixes-for-python-3.10-502.patch
  * include-aliases-in-the-fqdns-grains.patch
  * info_installed-works-without-status-attr-now.patch
  * let-salt-ssh-use-platform-python-binary-in-rhel8-191.patch
  * make-aptpkg.list_repos-compatible-on-enabled-disable.patch
  * make-setup.py-script-to-not-require-setuptools-9.1.patch
  * pass-the-context-to-pillar-ext-modules.patch
  * prevent-affection-of-ssh.opts-with-lazyloader-bsc-11.patch
  * prevent-pkg-plugins-errors-on-missing-cookie-path-bs.patch
  * prevent-shell-injection-via-pre_flight_script_args-4.patch
  * read-repo-info-without-using-interpolation-bsc-11356.patch
  * restore-default-behaviour-of-pkg-list-return.patch
  * return-the-expected-powerpc-os-arch-bsc-1117995.patch
  * revert-fixing-a-use-case-when-multiple-inotify-beaco.patch
  * run-salt-api-as-user-salt-bsc-1064520.patch
  * run-salt-master-as-dedicated-salt-user.patch
  * save-log-to-logfile-with-docker.build.patch
  * skip-package-names-without-colon-bsc-1208691-578.patch
  * switch-firewalld-state-to-use-change_interface.patch
  * temporary-fix-extend-the-whitelist-of-allowed-comman.patch
  * update-target-fix-for-salt-ssh-to-process-targets-li.patch
  * use-adler32-algorithm-to-compute-string-checksums.patch
  * use-rlock-to-avoid-deadlocks-in-salt-ssh.patch
  * use-salt-bundle-in-dockermod.patch
  * x509-fixes-111.patch
  * zypperpkg-ignore-retcode-104-for-search-bsc-1176697-.patch
- Removed:
  * add-amazon-ec2-detection-for-virtual-grains-bsc-1195.patch
  * add-support-for-name-pkgs-and-diff_attr-parameters-t.patch
  * align-amazon-ec2-nitro-grains-with-upstream-pr-bsc-1.patch
  * allow-entrypoint-compatibility-for-importlib-metadat.patch
  * clarify-pkg.installed-pkg_verify-documentation.patch
  * detect-module.run-syntax.patch
  * fix-salt.states.file.managed-for-follow_symlinks-tru.patch
  * fix-state.apply-in-test-mode-with-file-state-module-.patch
  * fix-test_ipc-unit-tests.patch
  * fixes-pkg.version_cmp-on-openeuler-systems-and-a-few.patch
  * fopen-workaround-bad-buffering-for-binary-mode-563.patch
  * ignore-erros-on-reading-license-files-with-dpkg_lowp.patch
  * ignore-extend-declarations-from-excluded-sls-files.patch
  * ignore-non-utf8-characters-while-reading-files-with-.patch
  * include-stdout-in-error-message-for-zypperpkg-559.patch
  * make-pass-renderer-configurable-other-fixes-532.patch
  * make-sure-saltcacheloader-use-correct-fileclient-519.patch
  * normalize-package-names-once-with-pkg.installed-remo.patch
  * retry-if-rpm-lock-is-temporarily-unavailable-547.patch
  * set-default-target-for-pip-from-venv_pip_target-envi.patch
  * state.apply-don-t-check-for-cached-pillar-errors.patch
  * state.orchestrate_single-does-not-pass-pillar-none-4.patch

OBS-URL: https://build.opensuse.org/request/show/1084999
OBS-URL: https://build.opensuse.org/package/show/systemsmanagement:saltstack/salt?expand=0&rev=210
2023-05-05 09:15:58 +00:00

842 lines
34 KiB
Diff

From a36d6524e530eca32966f46597c88dbfd4b90e78 Mon Sep 17 00:00:00 2001
From: Martin Seidl <mseidl@suse.de>
Date: Tue, 27 Oct 2020 16:12:29 +0100
Subject: [PATCH] Allow vendor change option with zypper
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Fix novendorchange option (#284)
* Fixed novendorchange handling in zypperpkg
* refactor handling of novendorchange and fix tests
add patch support for allow vendor change option with zypper
Revert "add patch support for allow vendor change option with zypper"
This reverts commit cee4cc182b4740c912861c712dea7bc44eb70ffb.
Allow vendor change option with zypper (#313)
* add patch support for allow vendor change option with zypper
* adjust unit tests vendor change refactor, dropping cli arg
* Fix pr issues
Co-authored-by: Pablo Suárez Hernández <psuarezhernandez@suse.com>
* Fix unit test for allow vendor change on upgrade
* Add unit test with unsupported zypper version
Co-authored-by: Pablo Suárez Hernández <psuarezhernandez@suse.com>
Move vendor change logic to zypper class (#355)
* move vendor change logic to zypper class
* fix thing in zypperkg
* refactor unit tests
* Fix for syntax error
* Fix mocking issue in unit test
* fix issues with pr
* Fix for zypperpkg unit test after refactor of vendorchangeflags
Co-authored-by: Pablo Suárez Hernández <psuarezhernandez@suse.com>
* fix docs for vendor change options
* Fix doc strings, and clean up tests
Co-authored-by: Jochen Breuer <jbreuer@suse.de>
Co-authored-by: Pablo Suárez Hernández <psuarezhernandez@suse.com>
---
salt/modules/zypperpkg.py | 105 ++++--
tests/unit/modules/test_zypperpkg.py | 532 ++++++++++++++++++++++++++-
2 files changed, 612 insertions(+), 25 deletions(-)
diff --git a/salt/modules/zypperpkg.py b/salt/modules/zypperpkg.py
index 4bb10f445a..2da470bea3 100644
--- a/salt/modules/zypperpkg.py
+++ b/salt/modules/zypperpkg.py
@@ -36,6 +36,8 @@ import salt.utils.stringutils
import salt.utils.systemd
import salt.utils.versions
from salt.exceptions import CommandExecutionError, MinionError, SaltInvocationError
+
+# pylint: disable=import-error,redefined-builtin,no-name-in-module
from salt.utils.versions import LooseVersion
if salt.utils.files.is_fcntl_available():
@@ -140,6 +142,13 @@ class _Zypper:
self.__systemd_scope = False
self.__root = None
+ # Dist upgrade vendor change support (SLE12+)
+ self.dup_avc = False
+ # Install/Patch/Upgrade vendor change support (SLE15+)
+ self.inst_avc = False
+ # Flag if allow vendor change should be allowed
+ self.avc = False
+
# Call status
self.__called = False
@@ -184,6 +193,8 @@ class _Zypper:
self.__no_raise = True
elif item == "refreshable":
self.__refresh = True
+ elif item == "allow_vendor_change":
+ return self.__allow_vendor_change
elif item == "call":
return self.__call
else:
@@ -224,6 +235,33 @@ class _Zypper:
def pid(self):
return self.__call_result.get("pid", "")
+ def __allow_vendor_change(self, allowvendorchange, novendorchange):
+ if allowvendorchange or not novendorchange:
+ self.refresh_zypper_flags()
+ if self.dup_avc or self.inst_avc:
+ log.info("Enabling vendor change")
+ self.avc = True
+ else:
+ log.warning(
+ "Enabling/Disabling vendor changes is not supported on this Zypper version"
+ )
+ return self
+
+ def refresh_zypper_flags(self):
+ try:
+ zypp_version = version("zypper")
+ # zypper version 1.11.34 in SLE12 update supports vendor change for only dist upgrade
+ if version_cmp(zypp_version, "1.11.34") >= 0:
+ # zypper version supports vendor change for dist upgrade
+ self.dup_avc = True
+ # zypper version 1.14.8 in SLE15 update supports vendor change in install/patch/upgrading
+ if version_cmp(zypp_version, "1.14.8") >= 0:
+ self.inst_avc = True
+ else:
+ log.error("Failed to compare Zypper version")
+ except Exception as ex:
+ log.error("Unable to get Zypper version: {}".format(ex))
+
def _is_error(self):
"""
Is this is an error code?
@@ -362,6 +400,15 @@ class _Zypper:
if self.__systemd_scope:
cmd.extend(["systemd-run", "--scope"])
cmd.extend(self.__cmd)
+
+ if self.avc:
+ for i in ["install", "upgrade", "dist-upgrade"]:
+ if i in cmd:
+ if i == "install" and self.inst_avc:
+ cmd.insert(cmd.index(i) + 1, "--allow-vendor-change")
+ elif i in ["upgrade", "dist-upgrade"] and self.dup_avc:
+ cmd.insert(cmd.index(i) + 1, "--allow-vendor-change")
+
log.debug("Calling Zypper: %s", " ".join(cmd))
self.__call_result = __salt__["cmd.run_all"](cmd, **kwargs)
if self._check_result():
@@ -1490,6 +1537,8 @@ def install(
no_recommends=False,
root=None,
inclusion_detection=False,
+ novendorchange=True,
+ allowvendorchange=False,
**kwargs
):
"""
@@ -1537,6 +1586,13 @@ def install(
skip_verify
Skip the GPG verification check (e.g., ``--no-gpg-checks``)
+ novendorchange
+ DEPRECATED(use allowvendorchange): If set to True, do not allow vendor changes. Default: True
+
+ allowvendorchange
+ If set to True, vendor change is allowed. Default: False
+ If both allowvendorchange and novendorchange are passed, only allowvendorchange is used.
+
version
Can be either a version number, or the combination of a comparison
operator (<, >, <=, >=, =) and a version number (ex. '>1.2.3-4').
@@ -1702,6 +1758,7 @@ def install(
cmd_install.append(
kwargs.get("resolve_capabilities") and "--capability" or "--name"
)
+ # Install / patching / upgrade with vendor change support is only in SLE 15+ opensuse Leap 15+
if not refresh:
cmd_install.insert(0, "--no-refresh")
@@ -1738,6 +1795,7 @@ def install(
systemd_scope=systemd_scope,
root=root,
)
+ .allow_vendor_change(allowvendorchange, novendorchange)
.call(*cmd)
.splitlines()
):
@@ -1750,7 +1808,9 @@ def install(
while downgrades:
cmd = cmd_install + ["--force"] + downgrades[:500]
downgrades = downgrades[500:]
- __zypper__(no_repo_failure=ignore_repo_failure, root=root).call(*cmd)
+ __zypper__(no_repo_failure=ignore_repo_failure, root=root).allow_vendor_change(
+ allowvendorchange, novendorchange
+ ).call(*cmd)
_clean_cache()
new = (
@@ -1783,7 +1843,8 @@ def upgrade(
dryrun=False,
dist_upgrade=False,
fromrepo=None,
- novendorchange=False,
+ novendorchange=True,
+ allowvendorchange=False,
skip_verify=False,
no_recommends=False,
root=None,
@@ -1844,7 +1905,11 @@ def upgrade(
Specify a list of package repositories to upgrade from. Default: None
novendorchange
- If set to True, no allow vendor changes. Default: False
+ DEPRECATED(use allowvendorchange): If set to True, do not allow vendor changes. Default: True
+
+ allowvendorchange
+ If set to True, vendor change is allowed. Default: False
+ If both allowvendorchange and novendorchange are passed, only allowvendorchange is used.
skip_verify
Skip the GPG verification check (e.g., ``--no-gpg-checks``)
@@ -1927,28 +1992,18 @@ def upgrade(
cmd_update.extend(["--from" if dist_upgrade else "--repo", repo])
log.info("Targeting repos: %s", fromrepo)
- if dist_upgrade:
- if novendorchange:
- # TODO: Grains validation should be moved to Zypper class
- if __grains__["osrelease_info"][0] > 11:
- cmd_update.append("--no-allow-vendor-change")
- log.info("Disabling vendor changes")
- else:
- log.warning(
- "Disabling vendor changes is not supported on this Zypper version"
- )
+ if no_recommends:
+ cmd_update.append("--no-recommends")
+ log.info("Disabling recommendations")
- if no_recommends:
- cmd_update.append("--no-recommends")
- log.info("Disabling recommendations")
+ if dryrun:
+ # Creates a solver test case for debugging.
+ log.info("Executing debugsolver and performing a dry-run dist-upgrade")
+ __zypper__(systemd_scope=_systemd_scope(), root=root).allow_vendor_change(
+ allowvendorchange, novendorchange
+ ).noraise.call(*cmd_update + ["--debug-solver"])
- if dryrun:
- # Creates a solver test case for debugging.
- log.info("Executing debugsolver and performing a dry-run dist-upgrade")
- __zypper__(systemd_scope=_systemd_scope(), root=root).noraise.call(
- *cmd_update + ["--debug-solver"]
- )
- else:
+ if not dist_upgrade:
if name or pkgs:
try:
(pkg_params, _) = __salt__["pkg_resource.parse_targets"](
@@ -1962,7 +2017,9 @@ def upgrade(
old = list_pkgs(root=root, attr=diff_attr)
- __zypper__(systemd_scope=_systemd_scope(), root=root).noraise.call(*cmd_update)
+ __zypper__(systemd_scope=_systemd_scope(), root=root).allow_vendor_change(
+ allowvendorchange, novendorchange
+ ).noraise.call(*cmd_update)
_clean_cache()
new = list_pkgs(root=root, attr=diff_attr)
ret = salt.utils.data.compare_dicts(old, new)
diff --git a/tests/unit/modules/test_zypperpkg.py b/tests/unit/modules/test_zypperpkg.py
index 5e4c967520..e85c93da3b 100644
--- a/tests/unit/modules/test_zypperpkg.py
+++ b/tests/unit/modules/test_zypperpkg.py
@@ -137,6 +137,7 @@ class ZypperTestCase(TestCase, LoaderModuleMockMixin):
stdout_xml_snippet = '<?xml version="1.0"?><test foo="bar"/>'
sniffer = RunSniffer(stdout=stdout_xml_snippet)
+ zypper.__zypper__._reset()
with patch.dict("salt.modules.zypperpkg.__salt__", {"cmd.run_all": sniffer}):
self.assertEqual(zypper.__zypper__.call("foo"), stdout_xml_snippet)
self.assertEqual(len(sniffer.calls), 1)
@@ -628,13 +629,495 @@ class ZypperTestCase(TestCase, LoaderModuleMockMixin):
{"vim": "7.4.326-2.62", "fakepkg": ""},
)
+ def test_upgrade_without_vendor_change(self):
+ """
+ Dist-upgrade without vendor change option.
+ """
+ with patch(
+ "salt.modules.zypperpkg.refresh_db", MagicMock(return_value=True)
+ ), patch(
+ "salt.modules.zypperpkg._systemd_scope", MagicMock(return_value=False)
+ ):
+ with patch(
+ "salt.modules.zypperpkg.__zypper__.noraise.call", MagicMock()
+ ) as zypper_mock:
+ with patch(
+ "salt.modules.zypperpkg.list_pkgs",
+ MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.2"}]),
+ ):
+ ret = zypper.upgrade(dist_upgrade=True)
+ self.assertDictEqual(ret, {"vim": {"old": "1.1", "new": "1.2"}})
+ zypper_mock.assert_any_call(
+ "dist-upgrade", "--auto-agree-with-licenses",
+ )
+
+ def test_refresh_zypper_flags(self):
+ zypper.__zypper__._reset()
+ with patch(
+ "salt.modules.zypperpkg.version", MagicMock(return_value="0.5")
+ ), patch.dict(
+ zypper.__salt__, {"lowpkg.version_cmp": MagicMock(side_effect=[-1, -1])}
+ ):
+ zypper.__zypper__.refresh_zypper_flags()
+ assert zypper.__zypper__.inst_avc == False
+ assert zypper.__zypper__.dup_avc == False
+ with patch(
+ "salt.modules.zypperpkg.version", MagicMock(return_value="1.11.34")
+ ), patch.dict(
+ zypper.__salt__, {"lowpkg.version_cmp": MagicMock(side_effect=[0, -1])}
+ ):
+ zypper.__zypper__.refresh_zypper_flags()
+ assert zypper.__zypper__.inst_avc == False
+ assert zypper.__zypper__.dup_avc == True
+ with patch(
+ "salt.modules.zypperpkg.version", MagicMock(return_value="1.14.8")
+ ), patch.dict(
+ zypper.__salt__, {"lowpkg.version_cmp": MagicMock(side_effect=[0, 0])}
+ ):
+ zypper.__zypper__.refresh_zypper_flags()
+ assert zypper.__zypper__.inst_avc == True
+ assert zypper.__zypper__.dup_avc == True
+
+ @patch("salt.modules.zypperpkg.__zypper__.refresh_zypper_flags", MagicMock())
+ def test_allow_vendor_change_function(self):
+ zypper.__zypper__._reset()
+ zypper.__zypper__.inst_avc = True
+ zypper.__zypper__.dup_avc = True
+ zypper.__zypper__.avc = False
+ zypper.__zypper__.allow_vendor_change(False, False)
+ assert zypper.__zypper__.avc == True
+ zypper.__zypper__.avc = False
+ zypper.__zypper__.allow_vendor_change(True, False)
+ assert zypper.__zypper__.avc == True
+ zypper.__zypper__.avc = False
+ zypper.__zypper__.allow_vendor_change(False, True)
+ assert zypper.__zypper__.avc == False
+ zypper.__zypper__.avc = False
+ zypper.__zypper__.allow_vendor_change(True, True)
+ assert zypper.__zypper__.avc == True
+
+ zypper.__zypper__._reset()
+ zypper.__zypper__.inst_avc = False
+ zypper.__zypper__.dup_avc = True
+ zypper.__zypper__.avc = False
+ zypper.__zypper__.allow_vendor_change(False, False)
+ assert zypper.__zypper__.avc == True
+ zypper.__zypper__.avc = False
+ zypper.__zypper__.allow_vendor_change(True, False)
+ assert zypper.__zypper__.avc == True
+ zypper.__zypper__.avc = False
+ zypper.__zypper__.allow_vendor_change(False, True)
+ assert zypper.__zypper__.avc == False
+ zypper.__zypper__.avc = False
+ zypper.__zypper__.allow_vendor_change(True, True)
+ assert zypper.__zypper__.avc == True
+
+ zypper.__zypper__._reset()
+ zypper.__zypper__.inst_avc = False
+ zypper.__zypper__.dup_avc = False
+ zypper.__zypper__.avc = False
+ zypper.__zypper__.allow_vendor_change(False, False)
+ assert zypper.__zypper__.avc == False
+ zypper.__zypper__.avc = False
+ zypper.__zypper__.allow_vendor_change(True, False)
+ assert zypper.__zypper__.avc == False
+ zypper.__zypper__.avc = False
+ zypper.__zypper__.allow_vendor_change(False, True)
+ assert zypper.__zypper__.avc == False
+ zypper.__zypper__.avc = False
+ zypper.__zypper__.allow_vendor_change(True, True)
+ assert zypper.__zypper__.avc == False
+
+ @patch(
+ "salt.utils.environment.get_module_environment",
+ MagicMock(return_value={"SALT_RUNNING": "1"}),
+ )
+ def test_zypper_call_dist_upgrade_with_avc_true(self):
+ cmd_run_mock = MagicMock(return_value={"retcode": 0, "stdout": None})
+ zypper.__zypper__._reset()
+ with patch.dict(zypper.__salt__, {"cmd.run_all": cmd_run_mock}), patch(
+ "salt.modules.zypperpkg.__zypper__.refresh_zypper_flags", MagicMock()
+ ), patch("salt.modules.zypperpkg.__zypper__._reset", MagicMock()):
+ zypper.__zypper__.dup_avc = True
+ zypper.__zypper__.avc = True
+ zypper.__zypper__.call("dist-upgrade")
+ cmd_run_mock.assert_any_call(
+ [
+ "zypper",
+ "--non-interactive",
+ "--no-refresh",
+ "dist-upgrade",
+ "--allow-vendor-change",
+ ],
+ output_loglevel="trace",
+ python_shell=False,
+ env={"SALT_RUNNING": "1"},
+ )
+
+ @patch(
+ "salt.utils.environment.get_module_environment",
+ MagicMock(return_value={"SALT_RUNNING": "1"}),
+ )
+ def test_zypper_call_dist_upgrade_with_avc_false(self):
+ cmd_run_mock = MagicMock(return_value={"retcode": 0, "stdout": None})
+ zypper.__zypper__._reset()
+ with patch.dict(zypper.__salt__, {"cmd.run_all": cmd_run_mock}), patch(
+ "salt.modules.zypperpkg.__zypper__.refresh_zypper_flags", MagicMock()
+ ), patch("salt.modules.zypperpkg.__zypper__._reset", MagicMock()):
+ zypper.__zypper__.dup_avc = False
+ zypper.__zypper__.avc = False
+ zypper.__zypper__.call("dist-upgrade")
+ cmd_run_mock.assert_any_call(
+ ["zypper", "--non-interactive", "--no-refresh", "dist-upgrade",],
+ output_loglevel="trace",
+ python_shell=False,
+ env={"SALT_RUNNING": "1"},
+ )
+
+ @patch(
+ "salt.utils.environment.get_module_environment",
+ MagicMock(return_value={"SALT_RUNNING": "1"}),
+ )
+ def test_zypper_call_install_with_avc_true(self):
+ cmd_run_mock = MagicMock(return_value={"retcode": 0, "stdout": None})
+ zypper.__zypper__._reset()
+ with patch.dict(zypper.__salt__, {"cmd.run_all": cmd_run_mock}), patch(
+ "salt.modules.zypperpkg.__zypper__.refresh_zypper_flags", MagicMock()
+ ), patch("salt.modules.zypperpkg.__zypper__._reset", MagicMock()):
+ zypper.__zypper__.inst_avc = True
+ zypper.__zypper__.avc = True
+ zypper.__zypper__.call("install")
+ cmd_run_mock.assert_any_call(
+ [
+ "zypper",
+ "--non-interactive",
+ "--no-refresh",
+ "install",
+ "--allow-vendor-change",
+ ],
+ output_loglevel="trace",
+ python_shell=False,
+ env={"SALT_RUNNING": "1"},
+ )
+
+ @patch(
+ "salt.utils.environment.get_module_environment",
+ MagicMock(return_value={"SALT_RUNNING": "1"}),
+ )
+ def test_zypper_call_install_with_avc_false(self):
+ cmd_run_mock = MagicMock(return_value={"retcode": 0, "stdout": None})
+ zypper.__zypper__._reset()
+ with patch.dict(zypper.__salt__, {"cmd.run_all": cmd_run_mock}), patch(
+ "salt.modules.zypperpkg.__zypper__.refresh_zypper_flags", MagicMock()
+ ), patch("salt.modules.zypperpkg.__zypper__._reset", MagicMock()):
+ zypper.__zypper__.inst_avc = False
+ zypper.__zypper__.dup_avc = True
+ zypper.__zypper__.avc = True
+ zypper.__zypper__.call("install")
+ cmd_run_mock.assert_any_call(
+ ["zypper", "--non-interactive", "--no-refresh", "install",],
+ output_loglevel="trace",
+ python_shell=False,
+ env={"SALT_RUNNING": "1"},
+ )
+
+ def test_upgrade_with_novendorchange_true(self):
+ """
+ Dist-upgrade without vendor change option.
+ """
+ zypper.__zypper__._reset()
+ with patch(
+ "salt.modules.zypperpkg.refresh_db", MagicMock(return_value=True)
+ ), patch(
+ "salt.modules.zypperpkg.__zypper__.refresh_zypper_flags", MagicMock()
+ ) as refresh_flags_mock, patch(
+ "salt.modules.zypperpkg._systemd_scope", MagicMock(return_value=False)
+ ):
+ with patch(
+ "salt.modules.zypperpkg.__zypper__.noraise.call", MagicMock()
+ ) as zypper_mock:
+ with patch(
+ "salt.modules.zypperpkg.list_pkgs",
+ MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.2"}]),
+ ):
+ ret = zypper.upgrade(dist_upgrade=True, novendorchange=True)
+ refresh_flags_mock.assert_not_called()
+ zypper_mock.assert_any_call(
+ "dist-upgrade", "--auto-agree-with-licenses",
+ )
+
+ def test_upgrade_with_novendorchange_false(self):
+ """
+ Perform dist-upgrade with novendorchange set to False.
+ """
+ zypper.__zypper__._reset()
+ with patch(
+ "salt.modules.zypperpkg.refresh_db", MagicMock(return_value=True)
+ ), patch(
+ "salt.modules.zypperpkg.__zypper__.refresh_zypper_flags", MagicMock()
+ ), patch(
+ "salt.modules.zypperpkg._systemd_scope", MagicMock(return_value=False)
+ ):
+ with patch(
+ "salt.modules.zypperpkg.__zypper__.noraise.call", MagicMock()
+ ) as zypper_mock:
+ with patch(
+ "salt.modules.zypperpkg.list_pkgs",
+ MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.1"}]),
+ ):
+ zypper.__zypper__.inst_avc = True
+ zypper.__zypper__.dup_avc = True
+ with patch.dict(
+ zypper.__salt__,
+ {
+ "pkg_resource.version": MagicMock(return_value="1.15"),
+ "lowpkg.version_cmp": MagicMock(return_value=1),
+ },
+ ):
+ ret = zypper.upgrade(
+ dist_upgrade=True,
+ dryrun=True,
+ fromrepo=["Dummy", "Dummy2"],
+ novendorchange=False,
+ )
+ assert zypper.__zypper__.avc == True
+
+ def test_upgrade_with_allowvendorchange_true(self):
+ """
+ Perform dist-upgrade with allowvendorchange set to True.
+ """
+ zypper.__zypper__._reset()
+ with patch(
+ "salt.modules.zypperpkg.refresh_db", MagicMock(return_value=True)
+ ), patch(
+ "salt.modules.zypperpkg.__zypper__.refresh_zypper_flags", MagicMock()
+ ), patch(
+ "salt.modules.zypperpkg._systemd_scope", MagicMock(return_value=False)
+ ):
+ with patch(
+ "salt.modules.zypperpkg.__zypper__.noraise.call", MagicMock()
+ ) as zypper_mock:
+ with patch(
+ "salt.modules.zypperpkg.list_pkgs",
+ MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.1"}]),
+ ):
+ with patch.dict(
+ zypper.__salt__,
+ {
+ "pkg_resource.version": MagicMock(return_value="1.15"),
+ "lowpkg.version_cmp": MagicMock(return_value=1),
+ },
+ ):
+
+ zypper.__zypper__.inst_avc = True
+ zypper.__zypper__.dup_avc = True
+ ret = zypper.upgrade(
+ dist_upgrade=True,
+ dryrun=True,
+ fromrepo=["Dummy", "Dummy2"],
+ allowvendorchange=True,
+ )
+ assert zypper.__zypper__.avc == True
+
+ def test_upgrade_with_allowvendorchange_false(self):
+ """
+ Perform dist-upgrade with allowvendorchange set to False.
+ """
+ zypper.__zypper__._reset()
+ with patch(
+ "salt.modules.zypperpkg.refresh_db", MagicMock(return_value=True)
+ ), patch(
+ "salt.modules.zypperpkg.__zypper__.refresh_zypper_flags", MagicMock()
+ ), patch(
+ "salt.modules.zypperpkg._systemd_scope", MagicMock(return_value=False)
+ ):
+ with patch(
+ "salt.modules.zypperpkg.__zypper__.noraise.call", MagicMock()
+ ) as zypper_mock:
+ with patch(
+ "salt.modules.zypperpkg.list_pkgs",
+ MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.1"}]),
+ ):
+ with patch.dict(
+ zypper.__salt__,
+ {
+ "pkg_resource.version": MagicMock(return_value="1.15"),
+ "lowpkg.version_cmp": MagicMock(return_value=1),
+ },
+ ):
+
+ zypper.__zypper__.inst_avc = True
+ zypper.__zypper__.dup_avc = True
+ ret = zypper.upgrade(
+ dist_upgrade=True,
+ dryrun=True,
+ fromrepo=["Dummy", "Dummy2"],
+ allowvendorchange=False,
+ )
+ assert zypper.__zypper__.avc == False
+
+ def test_upgrade_old_zypper(self):
+ zypper.__zypper__._reset()
+ with patch(
+ "salt.modules.zypperpkg.refresh_db", MagicMock(return_value=True)
+ ), patch(
+ "salt.modules.zypperpkg.__zypper__.refresh_zypper_flags", MagicMock()
+ ) as refresh_flags_mock, patch(
+ "salt.modules.zypperpkg._systemd_scope", MagicMock(return_value=False)
+ ):
+ with patch(
+ "salt.modules.zypperpkg.__zypper__.noraise.call", MagicMock()
+ ) as zypper_mock:
+ with patch(
+ "salt.modules.zypperpkg.list_pkgs",
+ MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.1"}]),
+ ):
+ with patch.dict(
+ zypper.__salt__,
+ {
+ "pkg_resource.version": MagicMock(return_value="1.11"),
+ "lowpkg.version_cmp": MagicMock(return_value=-1),
+ },
+ ):
+ zypper.__zypper__.inst_avc = False
+ zypper.__zypper__.dup_avc = False
+ ret = zypper.upgrade(
+ dist_upgrade=True,
+ dryrun=True,
+ fromrepo=["Dummy", "Dummy2"],
+ novendorchange=False,
+ )
+ zypper.__zypper__.avc = False
+
+ def test_upgrade_success(self):
+ """
+ Test system upgrade and dist-upgrade success.
+
+ :return:
+ """
+ with patch(
+ "salt.modules.zypperpkg.refresh_db", MagicMock(return_value=True)
+ ), patch(
+ "salt.modules.zypperpkg._systemd_scope", MagicMock(return_value=False)
+ ):
+ with patch(
+ "salt.modules.zypperpkg.__zypper__.noraise.call", MagicMock()
+ ) as zypper_mock:
+ with patch(
+ "salt.modules.zypperpkg.list_pkgs",
+ MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.2"}]),
+ ):
+ ret = zypper.upgrade()
+ self.assertDictEqual(ret, {"vim": {"old": "1.1", "new": "1.2"}})
+ zypper_mock.assert_any_call("update", "--auto-agree-with-licenses")
+
+ with patch(
+ "salt.modules.zypperpkg.list_pkgs",
+ MagicMock(
+ side_effect=[
+ {"kernel-default": "1.1"},
+ {"kernel-default": "1.1,1.2"},
+ ]
+ ),
+ ):
+ ret = zypper.upgrade()
+ self.assertDictEqual(
+ ret, {"kernel-default": {"old": "1.1", "new": "1.1,1.2"}}
+ )
+ zypper_mock.assert_any_call("update", "--auto-agree-with-licenses")
+
+ with patch(
+ "salt.modules.zypperpkg.list_pkgs",
+ MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.1,1.2"}]),
+ ):
+ ret = zypper.upgrade()
+ self.assertDictEqual(ret, {"vim": {"old": "1.1", "new": "1.1,1.2"}})
+ zypper_mock.assert_any_call("update", "--auto-agree-with-licenses")
+
+ with patch(
+ "salt.modules.zypperpkg.list_pkgs",
+ MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.1"}]),
+ ):
+ ret = zypper.upgrade(dist_upgrade=True, dryrun=True)
+ zypper_mock.assert_any_call(
+ "dist-upgrade", "--auto-agree-with-licenses", "--dry-run"
+ )
+ zypper_mock.assert_any_call(
+ "dist-upgrade",
+ "--auto-agree-with-licenses",
+ "--dry-run",
+ "--debug-solver",
+ )
+
+ with patch(
+ "salt.modules.zypperpkg.list_pkgs",
+ MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.1"}]),
+ ):
+ ret = zypper.upgrade(
+ dist_upgrade=False, fromrepo=["Dummy", "Dummy2"], dryrun=False
+ )
+ zypper_mock.assert_any_call(
+ "update",
+ "--auto-agree-with-licenses",
+ "--repo",
+ "Dummy",
+ "--repo",
+ "Dummy2",
+ )
+
+ with patch(
+ "salt.modules.zypperpkg.list_pkgs",
+ MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.1"}]),
+ ):
+ ret = zypper.upgrade(
+ dist_upgrade=True,
+ dryrun=True,
+ fromrepo=["Dummy", "Dummy2"],
+ novendorchange=True,
+ )
+ zypper_mock.assert_any_call(
+ "dist-upgrade",
+ "--auto-agree-with-licenses",
+ "--dry-run",
+ "--from",
+ "Dummy",
+ "--from",
+ "Dummy2",
+ )
+ zypper_mock.assert_any_call(
+ "dist-upgrade",
+ "--auto-agree-with-licenses",
+ "--dry-run",
+ "--from",
+ "Dummy",
+ "--from",
+ "Dummy2",
+ "--debug-solver",
+ )
+
+ with patch(
+ "salt.modules.zypperpkg.list_pkgs",
+ MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.1"}]),
+ ):
+ ret = zypper.upgrade(
+ dist_upgrade=False, fromrepo=["Dummy", "Dummy2"], dryrun=False
+ )
+ zypper_mock.assert_any_call(
+ "update",
+ "--auto-agree-with-licenses",
+ "--repo",
+ "Dummy",
+ "--repo",
+ "Dummy2",
+ )
+
def test_upgrade_kernel(self):
"""
Test kernel package upgrade success.
:return:
"""
- with patch.dict(zypper.__grains__, {"osrelease_info": [12, 1]}), patch(
+ with patch(
"salt.modules.zypperpkg.refresh_db", MagicMock(return_value=True)
), patch(
"salt.modules.zypperpkg._systemd_scope", MagicMock(return_value=False)
@@ -672,6 +1155,53 @@ class ZypperTestCase(TestCase, LoaderModuleMockMixin):
},
)
+ def test_upgrade_failure(self):
+ """
+ Test system upgrade failure.
+
+ :return:
+ """
+ zypper_out = """
+Loading repository data...
+Reading installed packages...
+Computing distribution upgrade...
+Use 'zypper repos' to get the list of defined repositories.
+Repository 'DUMMY' not found by its alias, number, or URI.
+"""
+
+ class FailingZypperDummy:
+ def __init__(self):
+ self.stdout = zypper_out
+ self.stderr = ""
+ self.pid = 1234
+ self.exit_code = 555
+ self.noraise = MagicMock()
+ self.allow_vendor_change = self
+ self.SUCCESS_EXIT_CODES = [0]
+
+ def __call__(self, *args, **kwargs):
+ return self
+
+ with patch(
+ "salt.modules.zypperpkg.__zypper__", FailingZypperDummy()
+ ) as zypper_mock, patch(
+ "salt.modules.zypperpkg.refresh_db", MagicMock(return_value=True)
+ ), patch(
+ "salt.modules.zypperpkg._systemd_scope", MagicMock(return_value=False)
+ ):
+ zypper_mock.noraise.call = MagicMock()
+ with patch(
+ "salt.modules.zypperpkg.list_pkgs",
+ MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.1"}]),
+ ):
+ with self.assertRaises(CommandExecutionError) as cmd_exc:
+ ret = zypper.upgrade(dist_upgrade=True, fromrepo=["DUMMY"])
+ self.assertEqual(cmd_exc.exception.info["changes"], {})
+ self.assertEqual(cmd_exc.exception.info["result"]["stdout"], zypper_out)
+ zypper_mock.noraise.call.assert_called_with(
+ "dist-upgrade", "--auto-agree-with-licenses", "--from", "DUMMY",
+ )
+
def test_upgrade_available(self):
"""
Test whether or not an upgrade is available for a given package.
--
2.39.2