Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package salt for openSUSE:Factory checked in at 2025-02-25 16:41:02 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/salt (Old) and /work/SRC/openSUSE:Factory/.salt.new.1873 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "salt" Tue Feb 25 16:41:02 2025 rev:167 rq:1248212 version:3006.0 Changes: -------- --- /work/SRC/openSUSE:Factory/salt/salt.changes 2025-02-18 19:08:45.283617126 +0100 +++ /work/SRC/openSUSE:Factory/.salt.new.1873/salt.changes 2025-02-25 16:41:48.636428996 +0100 @@ -1,0 +2,38 @@ +Mon Feb 24 16:17:55 UTC 2025 - Pablo Suárez Hernández <[email protected]> + +- Fix issue of using update-alternatives with alts + +------------------------------------------------------------------- +Fri Feb 21 12:46:01 UTC 2025 - Pablo Suárez Hernández <[email protected]> + +- Fix virt_query outputter and add support for block devices +- Make _auth calls visible with master stats +- Repair mount.fstab_present always returning pending changes +- Set virtual grain in Podman systemd container +- Fix crash due wrong client reference on `SaltMakoTemplateLookup` +- Enhace batch async and fix some detected issues + +- Added: + * repair-virt_query-outputter-655.patch + * make-_auth-calls-visible-with-master-stats-696.patch + * repair-fstab_present-test-mode-702.patch + * set-virtual-grain-in-podman-systemd-container-703.patch + * fixed-file-client-private-attribute-reference-on-sal.patch + * backport-batch-async-fixes-and-improvements-701.patch + +------------------------------------------------------------------- +Wed Feb 19 16:06:43 UTC 2025 - Pablo Suárez Hernández <[email protected]> + +- Enhacement of Salt packaging + * Use update-alternatives for all salt scripts + * Use flexible dependencies for the subpackages + * Make salt-minion to require flavored zypp-plugin + * Make zyppnotify to use update-alternatives + * Drop unused yumnotify plugin + * Add dependency to python3-dnf-plugins-core for RHEL based +- Fix tests failures after "repo.saltproject.io" deprecation + +- Added: + * fix-tests-failures-after-repo.saltproject.io-depreca.patch + +------------------------------------------------------------------- New: ---- backport-batch-async-fixes-and-improvements-701.patch fix-tests-failures-after-repo.saltproject.io-depreca.patch fixed-file-client-private-attribute-reference-on-sal.patch make-_auth-calls-visible-with-master-stats-696.patch repair-fstab_present-test-mode-702.patch repair-virt_query-outputter-655.patch set-virtual-grain-in-podman-systemd-container-703.patch BETA DEBUG BEGIN: New: * fixed-file-client-private-attribute-reference-on-sal.patch * backport-batch-async-fixes-and-improvements-701.patch New:- Added: * fix-tests-failures-after-repo.saltproject.io-depreca.patch New: * set-virtual-grain-in-podman-systemd-container-703.patch * fixed-file-client-private-attribute-reference-on-sal.patch * backport-batch-async-fixes-and-improvements-701.patch New: * repair-virt_query-outputter-655.patch * make-_auth-calls-visible-with-master-stats-696.patch * repair-fstab_present-test-mode-702.patch New: * make-_auth-calls-visible-with-master-stats-696.patch * repair-fstab_present-test-mode-702.patch * set-virtual-grain-in-podman-systemd-container-703.patch New:- Added: * repair-virt_query-outputter-655.patch * make-_auth-calls-visible-with-master-stats-696.patch New: * repair-fstab_present-test-mode-702.patch * set-virtual-grain-in-podman-systemd-container-703.patch * fixed-file-client-private-attribute-reference-on-sal.patch BETA DEBUG END: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ salt.spec ++++++ --- /var/tmp/diff_new_pack.Yswh2k/_old 2025-02-25 16:41:51.160534449 +0100 +++ /var/tmp/diff_new_pack.Yswh2k/_new 2025-02-25 16:41:51.164534617 +0100 @@ -34,7 +34,7 @@ %define psuffix %{nil} %endif -%if 0%{?suse_version} > 1210 || 0%{?rhel} >= 7 || 0%{?fedora} >=28 +%if 0%{?suse_version} > 1210 || 0%{?rhel} >= 7 || 0%{?fedora} >= 28 %bcond_without systemd %else %bcond_with systemd @@ -58,6 +58,7 @@ %{?sle15allpythons} %define skip_python2 1 %if 0%{?rhel} == 8 || (0%{?suse_version} == 1500 && 0%{?sle_version} < 150400) +%define singlespec_compat 1 %define __python3_bin_suffix 3.6 %if 0%{?rhel} == 8 %define __python3 /usr/libexec/platform-python @@ -77,7 +78,6 @@ args = args:gsub("$python", python_bin)\ print(rpm.expand(args .. "\\n"))\ } -%define _nosinglespec 1 %endif Name: salt%{psuffix} Version: 3006.0 @@ -509,6 +509,21 @@ Patch152: update-for-deprecation-of-hex-in-pygit2-1.15.0-and-a.patch # PATCH-FIX_UPSTREAM: https://github.com/saltstack/salt/pull/67186 Patch153: fix-failed-to-stat-root-.gitconfig-issue-on-gitfs-bs.patch +# PATCH-FIX_UPSTREAM: https://github.com/saltstack/salt/commit/58f448405b7f46505b2047ecda72abb42b6df9d1 +# PATCH-FIX_UPSTREAM: https://github.com/saltstack/salt/commit/79d4ff772a162b5b8e602e3437c13b90a25bc190 +Patch154: fix-tests-failures-after-repo.saltproject.io-depreca.patch +# PATCH-FIX_UPSTREAM: https://github.com/saltstack/salt/pull/60269 +Patch155: backport-batch-async-fixes-and-improvements-701.patch +# PATCH-FIX_UPSTREAM: https://github.com/saltstack/salt/commit/560ab52ccf94c7974d5a418dfbba7409e0493066 +Patch156: fixed-file-client-private-attribute-reference-on-sal.patch +# PATCH-FIX_UPSTREAM: https://github.com/saltstack/salt/pull/67734 +Patch157: set-virtual-grain-in-podman-systemd-container-703.patch +# PATCH-FIX_UPSTREAM: https://github.com/saltstack/salt/pull/67066 +Patch158: repair-fstab_present-test-mode-702.patch +# PATCH-FIX_UPSTREAM: https://github.com/saltstack/salt/pull/67746 +Patch159: make-_auth-calls-visible-with-master-stats-696.patch +# PATCH-FIX_UPSTREAM: https://github.com/saltstack/salt/pull/65843 +Patch160: repair-virt_query-outputter-655.patch ### IMPORTANT: The line below is used as a snippet marker. Do not touch it. ### SALT PATCHES LIST END @@ -576,10 +591,6 @@ BuildRequires: zsh %endif -%if 0%{?rhel} || 0%{?fedora} -BuildRequires: yum -%endif - %define python_subpackage_only 1 %python_subpackages @@ -593,7 +604,7 @@ %if "%{flavor}" != "testsuite" -%if 0%{?_nosinglespec} +%if 0%{?singlespec_compat} %package -n python3-salt %else %package -n python-salt @@ -650,7 +661,7 @@ %if 0%{?rhel} == 8 Requires: platform-python %else -%if 0%{?_nosinglespec} +%if 0%{?singlespec_compat} Requires: %{python_module base} %else Requires: python-base @@ -674,16 +685,13 @@ Requires: python3-markupsafe Requires: python3-msgpack > 0.3 Requires: python3-zmq >= 2.2.0 -Requires: yum -%if 0%{?rhel} == 8 || 0%{?fedora} >= 30 +%if 0%{?rhel} >= 8 || 0%{?fedora} >= 30 Requires: dnf -%endif -%if 0%{?rhel} == 6 -Requires: yum-plugin-security +Requires: python3-dnf-plugins-core %endif %else # SUSE -%if 0%{?_nosinglespec} +%if 0%{?singlespec_compat} Requires: %{python_module Jinja2} Requires: %{python_module MarkupSafe} Requires: %{python_module msgpack-python > 0.3} @@ -705,7 +713,7 @@ Requires: python-pyzmq >= 2.2.0 %endif %endif # end of RHEL / SUSE specific section -%if 0%{?_nosinglespec} +%if 0%{?singlespec_compat} Recommends: %{python_module jmespath} Requires: %{python_module PyYAML} Requires: %{python_module psutil} @@ -744,17 +752,20 @@ # %if 0%{?suse_version} # python-xml is part of python-base in all rhel versions -%if 0%{?_nosinglespec} +%if 0%{?singlespec_compat} Requires: %{python_module xml} +Requires: %{python_module zypp-plugin} Suggests: %{python_module Mako} Recommends: %{python_module netaddr} Recommends: %{python_module pyinotify} %else Requires: python-xml +Requires: python-zypp-plugin Suggests: python-Mako Recommends: python-netaddr Recommends: python-pyinotify %endif +Requires(pre): libzypp(plugin:system) >= 0 %endif # Required by Salt modules @@ -764,7 +775,7 @@ Recommends: man Recommends: python3-passlib -%if 0%{?_nosinglespec} +%if 0%{?singlespec_compat} Provides: bundled(%{python_module tornado}) = 4.5.3 %else Provides: bundled(python-tornado) = 4.5.3 @@ -772,7 +783,7 @@ Provides: %{name}-call = %{version}-%{release} -%if 0%{?_nosinglespec} +%if 0%{?singlespec_compat} %description -n python3-salt %else %description -n python-salt @@ -785,7 +796,11 @@ Requires: %{name} = %{version}-%{release} Requires: %{name}-master = %{version}-%{release} %if 0%{?suse_version} +%if 0%{?sle_version} >= 150400 +Requires: %{python_module CherryPy >= 3.2.2 if %python-salt} +%else Requires: python3-CherryPy >= 3.2.2 +%endif %else Requires: python3-cherrypy >= 3.2.2 %endif @@ -798,11 +813,19 @@ Group: System/Management Requires: %{name} = %{version}-%{release} Requires: %{name}-master = %{version}-%{release} -Requires: python3-apache-libcloud %if 0%{?suse_version} +%if 0%{?sle_version} >= 150400 +Requires: %{python_module apache-libcloud if %python-salt} +Recommends: %{python_module botocore if %python-salt} +Recommends: %{python_module netaddr if %python-salt} +%else +Requires: python3-apache-libcloud Recommends: python3-botocore Recommends: python3-netaddr %endif +%else +Requires: python3-apache-libcloud +%endif %description cloud public cloud VM management system @@ -824,8 +847,12 @@ Group: System/Management Requires: %{name} = %{version}-%{release} %if 0%{?suse_version} +%if 0%{?sle_version} >= 150400 +Recommends: %{python_module pygit2 >= 0.20.3 if %python-salt} +%else Recommends: python3-pygit2 >= 0.20.3 %endif +%endif %ifarch %{ix86} x86_64 %if 0%{?suse_version} %if 0%{?suse_version} > 1110 @@ -852,10 +879,6 @@ %if 0%{?suse_version} > 1500 || 0%{?sle_version} > 150000 Requires: (%{name}-transactional-update = %{version}-%{release} if read-only-root-fs) %endif -%if 0%{?suse_version} -Requires: python3-zypp-plugin -Requires(pre): libzypp(plugin:system) >= 0 -%endif %if %{with systemd} %{?systemd_requires} @@ -980,8 +1003,8 @@ %if "%{flavor}" == "testsuite" -%if 0%{?_nosinglespec} -%package -n %{python_module salt-testsuite} +%if 0%{?singlespec_compat} +%package -n python3-salt-testsuite %else %package -n python-salt-testsuite %endif @@ -995,7 +1018,7 @@ BuildRequires: %{python_module setuptools} Requires: salt = %{version} -%if 0%{?_nosinglespec} +%if 0%{?singlespec_compat} Recommends: %{python_module CherryPy} Requires: %{python_module Genshi} Requires: %{python_module Mako} @@ -1042,7 +1065,7 @@ Obsoletes: %{name}-tests -%if 0%{?_nosinglespec} +%if 0%{?singlespec_compat} %description -n python3-salt-testsuite %else %description -n python-salt-testsuite @@ -1161,11 +1184,9 @@ %if 0%{?suse_version} install -Dd -m 0750 %{buildroot}%{_prefix}/lib/zypp/plugins/commit %{__install} scripts/suse/zypper/plugins/commit/zyppnotify %{buildroot}%{_prefix}/lib/zypp/plugins/commit/zyppnotify -sed -i '1s=^#!/usr/bin/\(python\|env python\)[0-9.]*=#!/usr/bin/python3=' %{buildroot}%{_prefix}/lib/zypp/plugins/commit/zyppnotify %endif -# Install Yum plugins only on RH machines -%if 0%{?fedora} || 0%{?rhel} +# Install DNF plugin only on RH machines %if 0%{?fedora} >= 22 || 0%{?rhel} >= 8 install -Dd %{buildroot}%{python3_sitelib}/dnf-plugins install -Dd %{buildroot}%{python3_sitelib}/dnf-plugins/__pycache__ @@ -1174,14 +1195,6 @@ %{__install} scripts/suse/dnf/plugins/dnfnotify.conf %{buildroot}%{_sysconfdir}/dnf/plugins %{__python3} -m compileall -d %{python3_sitelib}/dnf-plugins %{buildroot}%{python3_sitelib}/dnf-plugins/dnfnotify.py %{__python3} -O -m compileall -d %{python3_sitelib}/dnf-plugins %{buildroot}%{python3_sitelib}/dnf-plugins/dnfnotify.py -%else -install -Dd %{buildroot}%{_prefix}/share/yum-plugins -install -Dd %{buildroot}%{_sysconfdir}/yum/pluginconf.d -%{__install} scripts/suse/yum/plugins/yumnotify.py %{buildroot}%{_prefix}/share/yum-plugins -%{__install} scripts/suse/yum/plugins/yumnotify.conf %{buildroot}%{_sysconfdir}/yum/pluginconf.d -%{__python} -m compileall -d %{_prefix}/share/yum-plugins %{buildroot}%{_prefix}/share/yum-plugins/yumnotify.py -%{__python} -O -m compileall -d %{_prefix}/share/yum-plugins %{buildroot}%{_prefix}/share/yum-plugins/yumnotify.py -%endif %endif ## install init and systemd scripts @@ -1252,6 +1265,17 @@ %if 0%{?_alternatives} %python_clone -a %{buildroot}%{_bindir}/salt-call +%python_clone -a %{buildroot}%{_bindir}/salt-support +%python_clone -a %{buildroot}%{_bindir}/spm +install -Dd -m 0750 %{buildroot}%{_exec_prefix}/libexec/salt +for SALT_SCRIPT in salt salt-api salt-cloud salt-cp salt-key salt-master salt-minion salt-proxy salt-run salt-ssh salt-syndic; do + mv "%{buildroot}%{_bindir}/${SALT_SCRIPT}" "%{buildroot}%{_exec_prefix}/libexec/salt/" +%python_clone -a %{buildroot}%{_exec_prefix}/libexec/salt/${SALT_SCRIPT} + ln -s "%{_exec_prefix}/libexec/salt/${SALT_SCRIPT}" "%{buildroot}%{_bindir}/${SALT_SCRIPT}" +done +mv "%{buildroot}%{_prefix}/lib/zypp/plugins/commit/zyppnotify" "%{buildroot}%{_exec_prefix}/libexec/salt/" +%python_clone -a %{buildroot}%{_exec_prefix}/libexec/salt/zyppnotify +ln -s "%{_exec_prefix}/libexec/salt/zyppnotify" "%{buildroot}%{_prefix}/lib/zypp/plugins/commit/zyppnotify" %endif %endif @@ -1274,10 +1298,6 @@ if [[ -d "$S_PHOME/.ssh" ]]; then mv $S_PHOME/.ssh $S_HOME fi -%if 0%{?_alternatives} -[ -h %{_bindir}/salt-call ] || rm -f %{_bindir}/salt-call -%python_libalternatives_reset_alternative salt-call -%endif %post %if %{with systemd} @@ -1486,17 +1506,49 @@ %if 0%{?_alternatives} %pre -n python-salt -[ -h %{_bindir}/salt-call ] || rm -f %{_bindir}/salt-call -%python_libalternatives_reset_alternative salt-call +for SALT_SCRIPT in salt-call salt-support spm; do + [ -h "%{_bindir}/${SALT_SCRIPT}" ] || rm -f "%{_bindir}/${SALT_SCRIPT}" + if [ "$1" -gt 0 ] && [ -f /usr/sbin/update-alternatives ]; then + update-alternatives --quiet --remove "${SALT_SCRIPT}" "%{_bindir}/${SALT_SCRIPT}-%{python_bin_suffix}" + fi +done +for SALT_SCRIPT in salt salt-api salt-cloud salt-cp salt-key salt-master salt-minion salt-proxy salt-run salt-ssh salt-syndic zyppnotify; do + [ -h "%{_exec_prefix}/libexec/salt/${SALT_SCRIPT}" ] || rm -f "%{_exec_prefix}/libexec/salt/${SALT_SCRIPT}" + if [ "$1" -gt 0 ] && [ -f /usr/sbin/update-alternatives ]; then + update-alternatives --quiet --remove "${SALT_SCRIPT}" "%{_exec_prefix}/libexec/salt/${SALT_SCRIPT}-%{python_bin_suffix}" + fi +done +%if ! %{with libalternatives} %post -n python-salt -%python_install_alternative salt-call +if [ -f /usr/sbin/update-alternatives ]; then + for SALT_SCRIPT in salt-call salt-support spm; do + update-alternatives --quiet --install "%{_bindir}/${SALT_SCRIPT}" "${SALT_SCRIPT}" \ + "%{_bindir}/${SALT_SCRIPT}-%{python_bin_suffix}" %{python_version_nodots} + done + for SALT_SCRIPT in salt salt-api salt-cloud salt-cp salt-key salt-master salt-minion salt-proxy salt-run salt-ssh salt-syndic zyppnotify; do + update-alternatives --quiet --install "%{_exec_prefix}/libexec/salt/${SALT_SCRIPT}" "${SALT_SCRIPT}" \ + "%{_exec_prefix}/libexec/salt/${SALT_SCRIPT}-%{python_bin_suffix}" %{python_version_nodots} + done +fi %postun -n python-salt -%python_uninstall_alternative salt-call +if [ -f /usr/sbin/update-alternatives ]; then + for SALT_SCRIPT in salt-call salt-support spm; do + if [ ! -e "%{_bindir}/${SALT_SCRIPT}-%{python_bin_suffix}" ]; then + update-alternatives --quiet --remove "${SALT_SCRIPT}" "%{_bindir}/${SALT_SCRIPT}-%{python_bin_suffix}" + fi + done + for SALT_SCRIPT in salt salt-api salt-cloud salt-cp salt-key salt-master salt-minion salt-proxy salt-run salt-ssh salt-syndic zyppnotify; do + if [ ! -e "%{_exec_prefix}/libexec/salt/${SALT_SCRIPT}-%{python_bin_suffix}" ]; then + update-alternatives --quiet --remove "${SALT_SCRIPT}" "%{_exec_prefix}/libexec/salt/${SALT_SCRIPT}-%{python_bin_suffix}" + fi + done +fi +%endif %endif -%if 0%{?_nosinglespec} +%if 0%{?singlespec_compat} %posttrans -n %{python_module salt} %else %posttrans -n python-salt @@ -1559,16 +1611,11 @@ %{_prefix}/lib/zypp/plugins/commit/zyppnotify %endif -# Install Yum plugins only on RH machines -%if 0%{?fedora} || 0%{?rhel} +# Install DNF plugin only on RH machines %if 0%{?fedora} >= 22 || 0%{?rhel} >= 8 %{python3_sitelib}/dnf-plugins/dnfnotify.py %{python3_sitelib}/dnf-plugins/__pycache__/dnfnotify.* %{_sysconfdir}/dnf/plugins/dnfnotify.conf -%else -%{_prefix}/share/yum-plugins/yumnotify.* -%{_sysconfdir}/yum/pluginconf.d/yumnotify.conf -%endif %endif %if %{with systemd} @@ -1651,7 +1698,24 @@ %defattr(-,root,root,-) %if 0%{?_alternatives} %python_alternative %{_bindir}/salt-call +%python_alternative %{_bindir}/salt-support +%python_alternative %{_bindir}/spm +%dir %{_exec_prefix}/libexec +%dir %attr(0755, root, root) %{_exec_prefix}/libexec/salt +%python_alternative %{_exec_prefix}/libexec/salt/salt +%python_alternative %{_exec_prefix}/libexec/salt/salt-api +%python_alternative %{_exec_prefix}/libexec/salt/salt-cloud +%python_alternative %{_exec_prefix}/libexec/salt/salt-cp +%python_alternative %{_exec_prefix}/libexec/salt/salt-key +%python_alternative %{_exec_prefix}/libexec/salt/salt-master +%python_alternative %{_exec_prefix}/libexec/salt/salt-minion +%python_alternative %{_exec_prefix}/libexec/salt/salt-proxy +%python_alternative %{_exec_prefix}/libexec/salt/salt-run +%python_alternative %{_exec_prefix}/libexec/salt/salt-ssh +%python_alternative %{_exec_prefix}/libexec/salt/salt-syndic +%python_alternative %{_exec_prefix}/libexec/salt/zyppnotify %endif + %dir %{python_sitelib}/salt %dir %{python_sitelib}/salt-*.egg-info %{python_sitelib}/salt/* ++++++ _lastrevision ++++++ --- /var/tmp/diff_new_pack.Yswh2k/_old 2025-02-25 16:41:51.264538794 +0100 +++ /var/tmp/diff_new_pack.Yswh2k/_new 2025-02-25 16:41:51.268538962 +0100 @@ -1,3 +1,3 @@ -a9b3f5bf8fd572965c589d95a7f99d36f7f37b62 +4e81748d5e88d323e700a458ca0e9680acc81927 (No newline at EOF) ++++++ backport-batch-async-fixes-and-improvements-701.patch ++++++ >From 4fe7231fa99de8edc848367386f1a6a5192a0f58 Mon Sep 17 00:00:00 2001 From: Victor Zhestkov <[email protected]> Date: Fri, 21 Feb 2025 11:15:42 +0100 Subject: [PATCH] Backport batch async fixes and improvements (#701) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Backport batch async fixes and improvements Co-authored-by: Pablo Suárez Hernández <[email protected]> * Align batch_async tests --------- Co-authored-by: Pablo Suárez Hernández <[email protected]> --- salt/cli/batch_async.py | 60 ++++++++++++++++----- tests/pytests/unit/cli/test_batch_async.py | 63 ++++++++-------------- 2 files changed, 69 insertions(+), 54 deletions(-) diff --git a/salt/cli/batch_async.py b/salt/cli/batch_async.py index 5d49993faa..92215d0e04 100644 --- a/salt/cli/batch_async.py +++ b/salt/cli/batch_async.py @@ -35,7 +35,7 @@ def batch_async_required(opts, minions, extra): Check opts to identify if batch async is required for the operation. """ if not isinstance(minions, list): - False + return False batch_async_opts = opts.get("batch_async", {}) batch_async_threshold = ( batch_async_opts.get("threshold", 1) @@ -179,6 +179,7 @@ class SharedEventsChannel: self._used_by.discard(subscriber_id) def destroy_unused(self): + log.trace("SharedEventsChannel.destroy_unused called") if self._used_by: return False self.master_event.remove_event_handler(self.__handle_event) @@ -267,6 +268,7 @@ class BatchAsync: self.ended = False self.event = self.events_channel.master_event self.scheduled = False + self._start_batch_on_timeout = None def __set_event_handler(self): self.events_channel.subscribe( @@ -278,6 +280,8 @@ class BatchAsync: @salt.ext.tornado.gen.coroutine def __event_handler(self, tag, data, op): + # IMPORTANT: This function must run fast and not wait for any other task, + # otherwise it would cause events to be stuck. if not self.event: return try: @@ -285,7 +289,9 @@ class BatchAsync: if op == "ping_return": self.minions.add(minion) if self.targeted_minions == self.minions: - yield self.start_batch() + # call start_batch and do not wait for timeout as we received + # the responses from all the targets + self.io_loop.add_callback(self.start_batch) elif op == "find_job_return": if data.get("return", None): self.find_job_returned.add(minion) @@ -293,7 +299,8 @@ class BatchAsync: if minion in self.active: self.active.remove(minion) self.done_minions.add(minion) - yield self.schedule_next() + if not self.active: + self.io_loop.add_callback(self.schedule_next) except Exception as ex: # pylint: disable=W0703 log.error( "Exception occured while processing event: %s: %s", @@ -333,7 +340,7 @@ class BatchAsync: ) if timedout_minions: - yield self.schedule_next() + self.io_loop.add_callback(self.schedule_next) if self.event and running: self.find_job_returned = self.find_job_returned.difference(running) @@ -344,6 +351,9 @@ class BatchAsync: """ Find if the job was finished on the minions """ + log.trace( + "[%s] BatchAsync.find_job called for minions: %s", self.batch_jid, minions + ) if not self.event: return not_done = minions.difference(self.done_minions).difference( @@ -386,6 +396,7 @@ class BatchAsync: if not self.event: return self.__set_event_handler() + # call test.ping for all the targets in async way ping_return = yield self.events_channel.local_client.run_job_async( self.opts["tgt"], "test.ping", @@ -398,19 +409,24 @@ class BatchAsync: listen=False, **self.eauth, ) + # ping_return contains actual targeted minions and no actual responses + # from the minions as it's async and intended to populate targeted_minions set self.targeted_minions = set(ping_return["minions"]) - # start batching even if not all minions respond to ping - yield salt.ext.tornado.gen.sleep( - self.batch_presence_ping_timeout or self.opts["gather_job_timeout"] + # schedule start_batch to perform even if not all the minions responded + # self.__event_handler can push start_batch in case if all targets responded + self._start_batch_on_timeout = self.io_loop.call_later( + self.batch_presence_ping_timeout or self.opts["gather_job_timeout"], + self.start_batch, ) - if self.event: - yield self.start_batch() @salt.ext.tornado.gen.coroutine def start_batch(self): """ Fire `salt/batch/*/start` and continue batch with `run_next` """ + if self._start_batch_on_timeout is not None: + self.io_loop.remove_timeout(self._start_batch_on_timeout) + self._start_batch_on_timeout = None if self.initialized: return self.batch_size = get_bnum(self.opts, self.minions, True) @@ -431,6 +447,7 @@ class BatchAsync: """ End the batch and call safe closing """ + log.trace("[%s] BatchAsync.end_batch called", self.batch_jid) left = self.minions.symmetric_difference( self.done_minions.union(self.timedout_minions) ) @@ -452,10 +469,11 @@ class BatchAsync: # release to the IOLoop to allow the event to be published # before closing batch async execution - yield salt.ext.tornado.gen.sleep(1) + yield salt.ext.tornado.gen.sleep(0.03) self.close_safe() def close_safe(self): + log.trace("[%s] BatchAsync.close_safe called", self.batch_jid) if self.events_channel is not None: self.events_channel.unsubscribe(None, None, id(self)) self.events_channel.unuse(id(self)) @@ -465,11 +483,22 @@ class BatchAsync: @salt.ext.tornado.gen.coroutine def schedule_next(self): + log.trace("[%s] BatchAsync.schedule_next called", self.batch_jid) if self.scheduled: + log.trace( + "[%s] BatchAsync.schedule_next -> Batch already scheduled, nothing to do.", + self.batch_jid, + ) return self.scheduled = True - # call later so that we maybe gather more returns - yield salt.ext.tornado.gen.sleep(self.batch_delay) + if self._get_next(): + # call later so that we maybe gather more returns + log.trace( + "[%s] BatchAsync.schedule_next delaying batch %s second(s).", + self.batch_jid, + self.batch_delay, + ) + yield salt.ext.tornado.gen.sleep(self.batch_delay) if self.event: yield self.run_next() @@ -480,6 +509,11 @@ class BatchAsync: """ self.scheduled = False next_batch = self._get_next() + log.trace( + "[%s] BatchAsync.run_next called. Next Batch -> %s", + self.batch_jid, + next_batch, + ) if not next_batch: yield self.end_batch() return @@ -504,7 +538,7 @@ class BatchAsync: yield salt.ext.tornado.gen.sleep(self.opts["timeout"]) # The batch can be done already at this point, which means no self.event - if self.event: + if self.event and self.active.intersection(next_batch): yield self.find_job(set(next_batch)) except Exception as ex: # pylint: disable=W0703 log.error( diff --git a/tests/pytests/unit/cli/test_batch_async.py b/tests/pytests/unit/cli/test_batch_async.py index bc871aba54..be8de692e6 100644 --- a/tests/pytests/unit/cli/test_batch_async.py +++ b/tests/pytests/unit/cli/test_batch_async.py @@ -85,11 +85,17 @@ def test_batch_start_on_batch_presence_ping_timeout(batch): future.set_result({}) with patch.object(batch, "events_channel", MagicMock()), patch( "salt.ext.tornado.gen.sleep", return_value=future - ), patch.object(batch, "start_batch", return_value=future) as start_batch_mock: + ), patch.object(batch, "io_loop", MagicMock()), patch.object( + batch, "start_batch", return_value=future + ) as start_batch_mock: batch.events_channel.local_client.run_job_async.return_value = future_ret ret = batch.start() - # assert start_batch is called - start_batch_mock.assert_called_once() + # start_batch is scheduled to be called later + assert batch.io_loop.call_later.call_args[0] == ( + batch.batch_presence_ping_timeout, + batch.start_batch, + ) + assert batch._start_batch_on_timeout is not None # assert test.ping called assert batch.events_channel.local_client.run_job_async.call_args[0] == ( "*", @@ -109,16 +115,21 @@ def test_batch_start_on_gather_job_timeout(batch): batch.batch_presence_ping_timeout = None with patch.object(batch, "events_channel", MagicMock()), patch( "salt.ext.tornado.gen.sleep", return_value=future + ), patch.object(batch, "io_loop", MagicMock()), patch.object( + batch, "start_batch", return_value=future ), patch.object( batch, "start_batch", return_value=future ) as start_batch_mock, patch.object( batch, "batch_presence_ping_timeout", None ): batch.events_channel.local_client.run_job_async.return_value = future_ret - # ret = batch_async.start(batch) ret = batch.start() - # assert start_batch is called - start_batch_mock.assert_called_once() + # start_batch is scheduled to be called later + assert batch.io_loop.call_later.call_args[0] == ( + batch.opts["gather_job_timeout"], + batch.start_batch, + ) + assert batch._start_batch_on_timeout is not None def test_batch_fire_start_event(batch): @@ -271,34 +282,10 @@ def test_batch__event_handler_ping_return(batch): assert batch.done_minions == set() -def test_batch__event_handler_call_start_batch_when_all_pings_return(batch): - batch.targeted_minions = {"foo"} - future = salt.ext.tornado.gen.Future() - future.set_result({}) - with patch.object(batch, "start_batch", return_value=future) as start_batch_mock: - batch.start() - batch._BatchAsync__event_handler( - "salt/job/1234/ret/foo", {"id": "foo"}, "ping_return" - ) - start_batch_mock.assert_called_once() - - -def test_batch__event_handler_not_call_start_batch_when_not_all_pings_return(batch): - batch.targeted_minions = {"foo", "bar"} - future = salt.ext.tornado.gen.Future() - future.set_result({}) - with patch.object(batch, "start_batch", return_value=future) as start_batch_mock: - batch.start() - batch._BatchAsync__event_handler( - "salt/job/1234/ret/foo", {"id": "foo"}, "ping_return" - ) - start_batch_mock.assert_not_called() - - def test_batch__event_handler_batch_run_return(batch): future = salt.ext.tornado.gen.Future() future.set_result({}) - with patch.object( + with patch.object(batch, "io_loop", MagicMock()), patch.object( batch, "schedule_next", return_value=future ) as schedule_next_mock: batch.start() @@ -308,7 +295,7 @@ def test_batch__event_handler_batch_run_return(batch): ) assert batch.active == set() assert batch.done_minions == {"foo"} - schedule_next_mock.assert_called_once() + batch.io_loop.add_callback.call_args[0] == (batch.schedule_next) def test_batch__event_handler_find_job_return(batch): @@ -322,9 +309,7 @@ def test_batch__event_handler_find_job_return(batch): def test_batch_run_next_end_batch_when_no_next(batch): future = salt.ext.tornado.gen.Future() future.set_result({}) - with patch.object( - batch, "_get_next", return_value={} - ), patch.object( + with patch.object(batch, "_get_next", return_value={}), patch.object( batch, "end_batch", return_value=future ) as end_batch_mock: batch.run_next() @@ -337,9 +322,7 @@ def test_batch_find_job(batch): batch.minions = {"foo", "bar"} with patch("salt.ext.tornado.gen.sleep", return_value=future), patch.object( batch, "check_find_job", return_value=future - ) as check_find_job_mock, patch.object( - batch, "jid_gen", return_value="1236" - ): + ) as check_find_job_mock, patch.object(batch, "jid_gen", return_value="1236"): batch.events_channel.local_client.run_job_async.return_value = future batch.find_job({"foo", "bar"}) assert check_find_job_mock.call_args[0] == ( @@ -355,9 +338,7 @@ def test_batch_find_job_with_done_minions(batch): batch.minions = {"foo", "bar"} with patch("salt.ext.tornado.gen.sleep", return_value=future), patch.object( batch, "check_find_job", return_value=future - ) as check_find_job_mock, patch.object( - batch, "jid_gen", return_value="1236" - ): + ) as check_find_job_mock, patch.object(batch, "jid_gen", return_value="1236"): batch.events_channel.local_client.run_job_async.return_value = future batch.find_job({"foo", "bar"}) assert check_find_job_mock.call_args[0] == ( -- 2.48.1 ++++++ fix-tests-failures-after-repo.saltproject.io-depreca.patch ++++++ >From a630c6a707a1d5227b4a1fa8f0f751fefd3ef47f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?= <[email protected]> Date: Wed, 19 Feb 2025 13:56:01 +0000 Subject: [PATCH] Fix tests failures after "repo.saltproject.io" deprecation (#704) * Use broadcom.com instead of repo.saltproject.io for test_cp * Change repo.saltproject.io to new url --------- Co-authored-by: Daniel A. Wozniak <[email protected]> Co-authored-by: twangboy <[email protected]> --- README.rst | 4 +- doc/_themes/saltstack2/layout.html | 15 +-- doc/conf.py | 12 +- doc/ref/configuration/delta_proxy.rst | 6 +- doc/topics/cloud/windows.rst | 2 +- pkg/tests/support/helpers.py | 115 ++++++++++++------ salt/modules/saltutil.py | 4 +- salt/runners/manage.py | 5 +- salt/states/pkgrepo.py | 6 +- tests/integration/modules/test_cp.py | 41 ++++--- tests/pytests/functional/modules/test_pkg.py | 8 +- .../functional/states/pkgrepo/test_debian.py | 6 +- .../integration/netapi/test_ssh_client.py | 3 +- tests/support/win_installer.py | 1 + 14 files changed, 135 insertions(+), 93 deletions(-) diff --git a/README.rst b/README.rst index f5121f1a74..77806aa14a 100644 --- a/README.rst +++ b/README.rst @@ -93,7 +93,9 @@ for more information. To download and install Salt, see: * `The Salt install guide <https://docs.saltproject.io/salt/install-guide/en/latest/index.html>`_ -* `Salt Project repository <https://repo.saltproject.io/>`_ +* `Salt Project repository <https://packages.broadcom.com/artifactory/saltproject-generic/>`_ +* `Salt Project debian repository <https://packages.broadcom.com/artifactory/saltproject-deb/>`_ +* `Salt Project redhat repository <https://packages.broadcom.com/artifactory/saltproject-rpm/>`_ Technical support diff --git a/doc/_themes/saltstack2/layout.html b/doc/_themes/saltstack2/layout.html index 04bff89e1f..83918a7fb3 100644 --- a/doc/_themes/saltstack2/layout.html +++ b/doc/_themes/saltstack2/layout.html @@ -157,16 +157,11 @@ <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="navbarCollapse"> <ul class="nav navbar-nav"> - <li><a href="/en/latest/">Overview</a></li> - <li><a href="https://docs.saltproject.io/salt/user-guide/en/latest/">Salt User Guide</a></li> - <li><a href="/en/latest/contents.html">Documentation</a></li> - <li><a href="https://repo.saltproject.io">Downloads</a></li> - <li><a href="/en/latest/topics/development/">Develop</a></li> - <!--<li><a href="/en/2016.3/faq/">FAQ</a></li> - <li><a href="/en/2016.3/samples/">Code Samples</a></li>--> - <!-- <li><a href="https://repo.saltproject.io" target="_blank">Downloads</a></li>--> - <!--<li><a href="http://saltstack.com/training" target="_blank">Training</a></li> - <li><a href="http://saltstack.com/support" target="_blank">Support</a></li>--> + <li><a href="/en/latest/">Overview</a></li> + <li><a href="https://docs.saltproject.io/salt/user-guide/en/latest/">Salt User Guide</a></li> + <li><a href="/en/latest/contents.html">Documentation</a></li> + <li><a href="https://packages.broadcom.com/artifactory/saltproject-generic/">Downloads</a></li> + <li><a href="/en/latest/topics/development/">Develop</a></li> </ul> </div> </div> diff --git a/doc/conf.py b/doc/conf.py index 653d912c20..24420d402e 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -178,17 +178,17 @@ rst_prolog = """\ .. |windownload| raw:: html <p>Python3 x86: <a - href="https://repo.saltproject.io/windows/Salt-Minion-{release}-Py3-x86-Setup.exe"><strong>Salt-Minion-{release}-x86-Setup.exe</strong></a> - | <a href="https://repo.saltproject.io/windows/Salt-Minion-{release}-Py3-x86-Setup.exe.md5"><strong>md5</strong></a></p> + href="https://packages.broadcom.com/artifactory/saltproject-generic/windows/{release}/Salt-Minion-{release}-Py3-x86-Setup.exe"><strong>Salt-Minion-{release}-x86-Setup.exe</strong></a> + | <a href="https://packages.broadcom.com/artifactory/saltproject-generic/windows/{release}/Salt-Minion-{release}-Py3-x86-Setup.exe.md5"><strong>md5</strong></a></p> <p>Python3 AMD64: <a - href="https://repo.saltproject.io/windows/Salt-Minion-{release}-Py3-AMD64-Setup.exe"><strong>Salt-Minion-{release}-AMD64-Setup.exe</strong></a> - | <a href="https://repo.saltproject.io/windows/Salt-Minion-{release}-Py3-AMD64-Setup.exe.md5"><strong>md5</strong></a></p> + href="https://packages.broadcom.com/artifactory/saltproject-generic/windows/{release}/Salt-Minion-{release}-Py3-AMD64-Setup.exe"><strong>Salt-Minion-{release}-AMD64-Setup.exe</strong></a> + | <a href="https://packages.broadcom.com/artifactory/saltproject-generic/windows/{release}/Salt-Minion-{release}-Py3-AMD64-Setup.exe.md5"><strong>md5</strong></a></p> .. |osxdownloadpy3| raw:: html - <p>x86_64: <a href="https://repo.saltproject.io/osx/salt-{release}-py3-x86_64.pkg"><strong>salt-{release}-py3-x86_64.pkg</strong></a> - | <a href="https://repo.saltproject.io/osx/salt-{release}-py3-x86_64.pkg.md5"><strong>md5</strong></a></p> + <p>x86_64: <a href="https://packages.broadcom.com/artifactory/saltproject-generic/macos/{release}/salt-{release}-py3-x86_64.pkg"><strong>salt-{release}-py3-x86_64.pkg</strong></a> + | <a href="https://packages.broadcom.com/artifactory/saltproject-generic/macos/{release}/salt-{release}-py3-x86_64.pkg.md5"><strong>md5</strong></a></p> """.format( release=stripped_release diff --git a/doc/ref/configuration/delta_proxy.rst b/doc/ref/configuration/delta_proxy.rst index be1831da39..bce5f821c9 100644 --- a/doc/ref/configuration/delta_proxy.rst +++ b/doc/ref/configuration/delta_proxy.rst @@ -146,10 +146,8 @@ Before installing the delta proxy minion, ensure that: Install or upgrade Salt ----------------------- Ensure your Salt masters are running at least Salt version 3004. For instructions -on installing or upgrading Salt, see `repo.saltproject.io -<http://repo.saltproject.io/>`_. For RedHat systems, see `Install or Upgrade Salt -<https://enterprise.saltproject.io/en/latest/docs/install-salt.html>`_. - +on installing or upgrading Salt, see the `Salt install guide +<https://docs.saltproject.io/salt/install-guide>`_. .. _delta-proxy-install: diff --git a/doc/topics/cloud/windows.rst b/doc/topics/cloud/windows.rst index 9dfdde6db5..79d6665a5a 100644 --- a/doc/topics/cloud/windows.rst +++ b/doc/topics/cloud/windows.rst @@ -62,7 +62,7 @@ from saltstack.com: * `SaltStack Download Area`__ -.. __: https://repo.saltproject.io/windows/ +.. __: https://packages.broadcom.com/artifactory/saltproject-generic/windows/ .. _new-pywinrm: diff --git a/pkg/tests/support/helpers.py b/pkg/tests/support/helpers.py index 90abf8b88e..ce23f699b6 100644 --- a/pkg/tests/support/helpers.py +++ b/pkg/tests/support/helpers.py @@ -636,8 +636,7 @@ class SaltPkgInstall: def install_previous(self): """ - Install previous version. This is used for - upgrade tests. + Install previous version. This is used for upgrade tests. """ major_ver = self.major minor_ver = self.minor @@ -648,16 +647,12 @@ class SaltPkgInstall: distro_name = self.distro_name if distro_name == "centos" or distro_name == "fedora": distro_name = "redhat" - root_url = "salt/py3/" - if self.classic: - root_url = "py3/" + root_url = "https://packages.broadcom.com/artifactory" if self.distro_name in ["redhat", "centos", "amazon", "fedora", "vmware"]: for fp in pathlib.Path("/etc", "yum.repos.d").glob("epel*"): fp.unlink() - gpg_key = "SALTSTACK-GPG-KEY.pub" - if self.distro_version == "9": - gpg_key = "SALTSTACK-GPG-KEY2.pub" + if platform.is_aarch64(): arch = "aarch64" else: @@ -694,46 +689,86 @@ class SaltPkgInstall: arch = "arm64" else: arch = "amd64" + pathlib.Path("/etc/apt/keyrings").mkdir(parents=True, exist_ok=True) + gpg_full_path = "/etc/apt/keyrings/salt-archive-keyring.gpg" + + # download the gpg pub key download_file( - f"https://repo.saltproject.io/{root_url}{distro_name}/{self.distro_version}/{arch}/{major_ver}/salt-archive-keyring.gpg", - "/etc/apt/keyrings/salt-archive-keyring.gpg", + f"{root_url}/api/security/keypair/SaltProjectKey/public", + f"{gpg_full_path}", ) - with open( + with salt.utils.files.fopen( pathlib.Path("/etc", "apt", "sources.list.d", "salt.list"), "w" ) as fp: fp.write( - f"deb [signed-by=/etc/apt/keyrings/salt-archive-keyring.gpg arch={arch}] " - f"https://repo.saltproject.io/{root_url}{distro_name}/{self.distro_version}/{arch}/{major_ver} {self.distro_codename} main" + f"deb [signed-by={gpg_full_path} arch={arch}] " + f"{root_url}/saltproject-deb/ {self.distro_codename} main" ) - ret = self.proc.run(self.pkg_mngr, "update") - self._check_retcode(ret) - ret = self.proc.run( - self.pkg_mngr, - "install", - *self.salt_pkgs, - "-y", - ) self._check_retcode(ret) + + cmd = [self.pkg_mngr, "install", *self.salt_pkgs, "-y"] + + if downgrade: + pref_file = pathlib.Path("/etc", "apt", "preferences.d", "salt.pref") + pref_file.parent.mkdir(exist_ok=True) + # TODO: There's probably something I should put in here to say what version + # TODO: But maybe that's done elsewhere, hopefully in self.salt_pkgs + pref_file.write_text( + textwrap.dedent( + f"""\ + Package: salt* + Pin: origin "{root_url}/saltproject-deb" + Pin-Priority: 1001 + """ + ), + encoding="utf-8", + ) + cmd.append("--allow-downgrades") + env = os.environ.copy() + env["DEBIAN_FRONTEND"] = "noninteractive" + extra_args = [ + "-o", + "DPkg::Options::=--force-confdef", + "-o", + "DPkg::Options::=--force-confold", + ] + self.proc.run(self.pkg_mngr, "update", *extra_args, env=env) + + cmd.extend(extra_args) + + ret = self.proc.run(*cmd, env=env) + # Pre-relenv packages down get downgraded to cleanly programmatically + # They work manually, and the install tests after downgrades will catch problems with the install + # Let's not check the returncode if this is the case + if not ( + downgrade + and packaging.version.parse(self.prev_version) + < packaging.version.parse("3006.0") + ): + self._check_retcode(ret) + if downgrade: + pref_file.unlink() self.stop_services() elif platform.is_windows(): self.onedir = True self.installer_pkg = True self.bin_dir = self.install_dir / "bin" - self.run_root = self.bin_dir / f"salt.exe" - self.ssm_bin = self.bin_dir / "ssm.exe" - if self.file_ext == "msi": - self.ssm_bin = self.install_dir / "ssm.exe" + self.run_root = self.bin_dir / "salt.exe" + self.ssm_bin = self.install_dir / "ssm.exe" - if not self.classic: - win_pkg = f"salt-{full_version}-windows-amd64.{self.file_ext}" - win_pkg_url = f"https://repo.saltproject.io/salt/py3/windows/{full_version}/{win_pkg}" + if self.file_ext == "exe": + win_pkg = ( + f"Salt-Minion-{self.prev_version}-Py3-AMD64-Setup.{self.file_ext}" + ) + elif self.file_ext == "msi": + win_pkg = f"Salt-Minion-{self.prev_version}-Py3-AMD64.{self.file_ext}" else: - if self.file_ext == "msi": - win_pkg = f"Salt-Minion-{min_ver}-1-Py3-AMD64.{self.file_ext}" - elif self.file_ext == "exe": - win_pkg = f"Salt-Minion-{min_ver}-1-Py3-AMD64-Setup.{self.file_ext}" - win_pkg_url = f"https://repo.saltproject.io/windows/{win_pkg}" + log.debug(f"Unknown windows file extension: {self.file_ext}") + + win_pkg_url = ( + f"{root_url}/saltproject-generic/windows/{major_ver}/{win_pkg}" + ) pkg_path = pathlib.Path(r"C:\TEMP", win_pkg) pkg_path.parent.mkdir(exist_ok=True) ret = requests.get(win_pkg_url) @@ -763,12 +798,16 @@ class SaltPkgInstall: self._install_system_service() elif platform.is_darwin(): - if self.classic: - mac_pkg = f"salt-{min_ver}.{minor_ver}-1-py3-x86_64.pkg" - mac_pkg_url = f"https://repo.saltproject.io/osx/{mac_pkg}" + if relenv and platform.is_aarch64(): + arch = "arm64" + elif platform.is_aarch64() and self.classic: + arch = "arm64" else: - mac_pkg = f"salt-{min_ver}.{minor_ver}-1-macos-x86_64.pkg" - mac_pkg_url = f"https://repo.saltproject.io/salt/py3/macos/{major_ver}.{minor_ver}-1/{mac_pkg}" + arch = "x86_64" + + mac_pkg = f"salt-{self.prev_version}-py3-{arch}.pkg" + mac_pkg_url = f"{root_url}/saltproject-generic/macos/{major_ver}/{mac_pkg}" + mac_pkg_path = f"/tmp/{mac_pkg}" if not os.path.exists(mac_pkg_path): download_file( diff --git a/salt/modules/saltutil.py b/salt/modules/saltutil.py index a692c3f34d..320b9c34fa 100644 --- a/salt/modules/saltutil.py +++ b/salt/modules/saltutil.py @@ -128,8 +128,8 @@ def _sync(form, saltenv=None, extmod_whitelist=None, extmod_blacklist=None): def update(version=None): """ Update the salt minion from the URL defined in opts['update_url'] - VMware, Inc provides the latest builds here: - update_url: https://repo.saltproject.io/windows/ + Broadcom, Inc provides the latest builds here: + update_url: https://packages.broadcom.com/artifactory/saltproject-generic/windows/ Be aware that as of 2014-8-11 there's a bug in esky such that only the latest version available in the update_url can be downloaded and installed. diff --git a/salt/runners/manage.py b/salt/runners/manage.py index 9dc67ed728..81197ca41f 100644 --- a/salt/runners/manage.py +++ b/salt/runners/manage.py @@ -772,7 +772,7 @@ def bootstrap_psexec( installer_url URL of minion installer executable. Defaults to the latest version from - https://repo.saltproject.io/windows/ + https://packages.broadcom.com/artifactory/saltproject-generic/windows/ username Optional user name for login on remote computer. @@ -790,6 +790,9 @@ def bootstrap_psexec( salt-run manage.bootstrap_psexec hosts='host1,host2' installer_url='http://exampledomain/salt-installer.exe' """ + # TODO: Need to make this gets the latest version from the new repo location + # TODO: Similar to tests/support/win_installer.py + # TODO: Maybe need to move that ^^^^ to a salt util if not installer_url: base_url = "https://repo.saltproject.io/windows/" source = urllib.request.urlopen(base_url).read() diff --git a/salt/states/pkgrepo.py b/salt/states/pkgrepo.py index f041644287..4ef5fd9c2f 100644 --- a/salt/states/pkgrepo.py +++ b/salt/states/pkgrepo.py @@ -99,17 +99,17 @@ Using ``aptkey: False`` with ``key_url`` example: .. code-block:: yaml - deb [signed-by=/etc/apt/keyrings/salt-archive-keyring.gpg arch=amd64] https://repo.saltproject.io/py3/ubuntu/18.04/amd64/latest bionic main: + deb [signed-by=/etc/apt/keyrings/salt-archive-keyring.gpg arch=amd64] https://packages.broadcom.com/artifactory/saltproject-deb/ bionic main: pkgrepo.managed: - file: /etc/apt/sources.list.d/salt.list - - key_url: https://repo.saltproject.io/py3/ubuntu/18.04/amd64/latest/salt-archive-keyring.gpg + - key_url: https://packages.broadcom.com/artifactory/api/security/keypair/SaltProjectKey/public - aptkey: False Using ``aptkey: False`` with ``keyserver`` and ``keyid``: .. code-block:: yaml - deb [signed-by=/etc/apt/keyrings/salt-archive-keyring.gpg arch=amd64] https://repo.saltproject.io/py3/ubuntu/18.04/amd64/latest bionic main: + deb [signed-by=/etc/apt/keyrings/salt-archive-keyring.gpg arch=amd64] https://packages.broadcom.com/artifactory/saltproject-deb/ bionic main: pkgrepo.managed: - file: /etc/apt/sources.list.d/salt.list - keyserver: keyserver.ubuntu.com diff --git a/tests/integration/modules/test_cp.py b/tests/integration/modules/test_cp.py index cd3e4c2f5a..d417f90ddc 100644 --- a/tests/integration/modules/test_cp.py +++ b/tests/integration/modules/test_cp.py @@ -231,12 +231,15 @@ class CPModuleTest(ModuleCase): """ cp.get_url with https:// source given """ - self.run_function("cp.get_url", ["https://repo.saltproject.io/index.html", tgt]) + self.run_function( + "cp.get_url", + ["https://packages.broadcom.com/artifactory/saltproject-generic/", tgt], + ) with salt.utils.files.fopen(tgt, "r") as instructions: data = salt.utils.stringutils.to_unicode(instructions.read()) - self.assertIn("Salt Project", data) - self.assertIn("Package", data) - self.assertIn("Repo", data) + self.assertIn("Index of saltproject", data) + self.assertIn("onedir", data) + self.assertIn("Artifactory Online Server", data) self.assertNotIn("AYBABTU", data) @pytest.mark.slow_test @@ -245,14 +248,15 @@ class CPModuleTest(ModuleCase): cp.get_url with https:// source given and destination omitted. """ ret = self.run_function( - "cp.get_url", ["https://repo.saltproject.io/index.html"] + "cp.get_url", + ["https://packages.broadcom.com/artifactory/saltproject-generic/"], ) with salt.utils.files.fopen(ret, "r") as instructions: data = salt.utils.stringutils.to_unicode(instructions.read()) - self.assertIn("Salt Project", data) - self.assertIn("Package", data) - self.assertIn("Repo", data) + self.assertIn("Index of saltproject", data) + self.assertIn("onedir", data) + self.assertIn("Artifactory Online Server", data) self.assertNotIn("AYBABTU", data) @pytest.mark.slow_test @@ -266,16 +270,19 @@ class CPModuleTest(ModuleCase): tgt = None while time.time() - start <= timeout: ret = self.run_function( - "cp.get_url", ["https://repo.saltproject.io/index.html", tgt] + "cp.get_url", + ["https://packages.broadcom.com/artifactory/saltproject-generic/", tgt], ) if ret.find("HTTP 599") == -1: break time.sleep(sleep) if ret.find("HTTP 599") != -1: - raise Exception("https://repo.saltproject.io/index.html returned 599 error") - self.assertIn("Salt Project", ret) - self.assertIn("Package", ret) - self.assertIn("Repo", ret) + raise Exception( + "https://packages.broadcom.com/artifactory/saltproject-generic/ returned 599 error" + ) + self.assertIn("Index of saltproject", ret) + self.assertIn("onedir", ret) + self.assertIn("Artifactory Online Server", ret) self.assertNotIn("AYBABTU", ret) @pytest.mark.slow_test @@ -344,11 +351,11 @@ class CPModuleTest(ModuleCase): """ cp.get_file_str with https:// source given """ - src = "https://repo.saltproject.io/index.html" + src = "https://packages.broadcom.com/artifactory/saltproject-generic/" ret = self.run_function("cp.get_file_str", [src]) - self.assertIn("Salt Project", ret) - self.assertIn("Package", ret) - self.assertIn("Repo", ret) + self.assertIn("Index of saltproject", ret) + self.assertIn("onedir", ret) + self.assertIn("Artifactory Online Server", ret) self.assertNotIn("AYBABTU", ret) @pytest.mark.slow_test diff --git a/tests/pytests/functional/modules/test_pkg.py b/tests/pytests/functional/modules/test_pkg.py index 82d0801965..addb3da3d1 100644 --- a/tests/pytests/functional/modules/test_pkg.py +++ b/tests/pytests/functional/modules/test_pkg.py @@ -130,12 +130,8 @@ def test_mod_del_repo(grains, modules, refresh_db): elif grains["os_family"] == "RedHat": repo = "saltstack" name = "SaltStack repo for RHEL/CentOS {}".format(grains["osmajorrelease"]) - baseurl = "https://repo.saltproject.io/py3/redhat/{}/x86_64/latest/".format( - grains["osmajorrelease"] - ) - gpgkey = "https://repo.saltproject.io/py3/redhat/{}/x86_64/latest/SALTSTACK-GPG-KEY.pub".format( - grains["osmajorrelease"] - ) + baseurl = "https://packages.broadcom.com/artifactory/saltproject-rpm/" + gpgkey = "https://packages.broadcom.com/artifactory/api/security/keypair/SaltProjectKey/public" gpgcheck = 1 enabled = 1 ret = modules.pkg.mod_repo( diff --git a/tests/pytests/functional/states/pkgrepo/test_debian.py b/tests/pytests/functional/states/pkgrepo/test_debian.py index 7bda100b63..307fcb5819 100644 --- a/tests/pytests/functional/states/pkgrepo/test_debian.py +++ b/tests/pytests/functional/states/pkgrepo/test_debian.py @@ -616,8 +616,8 @@ class Repo: @alt_repo.default def _default_alt_repo(self): """ - Use an alternative repo, packages do not - exist for the OS on repo.saltproject.io + Use an alternative repo, packages do not exist for the OS on + packages.broadcom.com """ if ( self.grains["osfullname"] == "Ubuntu" @@ -777,7 +777,7 @@ def test_adding_repo_file_signedby_alt_file(pkgrepo, states, repo): assert repo.repo_content in ret.comment key_file = repo.key_file.parent / "salt-alt-key.gpg" - repo_content = "deb [arch=amd64 signed-by={}] https://repo.saltproject.io/py3/debian/10/amd64/latest buster main".format( + repo_content = "deb [arch=amd64 signed-by={}] https://packages.broadcom.com/artifactory/saltproject-deb/ buster main".format( str(key_file) ) ret = states.pkgrepo.managed( diff --git a/tests/pytests/integration/netapi/test_ssh_client.py b/tests/pytests/integration/netapi/test_ssh_client.py index 457c151c94..7dd540d9b9 100644 --- a/tests/pytests/integration/netapi/test_ssh_client.py +++ b/tests/pytests/integration/netapi/test_ssh_client.py @@ -149,7 +149,8 @@ def test_shell_inject_ssh_priv( """ # ZDI-CAN-11143 path = tmp_path / "test-11143" - tgts = ["repo.saltproject.io", "www.zerodayinitiative.com"] + tgts = ["packages.broadcom.com", "www.zerodayinitiative.com"] + ret = None for tgt in tgts: low = { "roster": "cache", diff --git a/tests/support/win_installer.py b/tests/support/win_installer.py index 6a2f387dc8..d67105e8a0 100644 --- a/tests/support/win_installer.py +++ b/tests/support/win_installer.py @@ -10,6 +10,7 @@ """ import hashlib +from html.parser import HTMLParser import requests -- 2.48.1 ++++++ fixed-file-client-private-attribute-reference-on-sal.patch ++++++ >From 1772da828f40e36d2a9eceb7055a1fa1a2257830 Mon Sep 17 00:00:00 2001 From: Georg <[email protected]> Date: Fri, 21 Feb 2025 10:23:38 +0000 Subject: [PATCH] Fixed file client private attribute reference on `SaltMakoTemplateLookup` (#694) Fixes #64280 Signed-off-by: Pedro Algarvio <[email protected]> (cherry picked from commit 560ab52ccf94c7974d5a418dfbba7409e0493066) Co-authored-by: Pedro Algarvio <[email protected]> --- changelog/64280.fixed.md | 1 + salt/utils/mako.py | 6 ++++-- tests/pytests/unit/utils/test_mako.py | 28 +++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 changelog/64280.fixed.md create mode 100644 tests/pytests/unit/utils/test_mako.py diff --git a/changelog/64280.fixed.md b/changelog/64280.fixed.md new file mode 100644 index 0000000000..5a9b905dd0 --- /dev/null +++ b/changelog/64280.fixed.md @@ -0,0 +1 @@ +Fixed file client private attribute reference on `SaltMakoTemplateLookup` diff --git a/salt/utils/mako.py b/salt/utils/mako.py index 037d5d86de..4397ae8cc7 100644 --- a/salt/utils/mako.py +++ b/salt/utils/mako.py @@ -99,8 +99,10 @@ if HAS_MAKO: ) def destroy(self): - if self.client: + if self._file_client: + file_client = self._file_client + self._file_client = None try: - self.client.destroy() + file_client.destroy() except AttributeError: pass diff --git a/tests/pytests/unit/utils/test_mako.py b/tests/pytests/unit/utils/test_mako.py new file mode 100644 index 0000000000..952cf44652 --- /dev/null +++ b/tests/pytests/unit/utils/test_mako.py @@ -0,0 +1,28 @@ +import pytest + +from tests.support.mock import Mock, call, patch + +pytest.importorskip("mako") + +# This import needs to be after the above importorskip so that no ImportError +# is raised if Mako is not installed +from salt.utils.mako import SaltMakoTemplateLookup + + +def test_mako_template_lookup(minion_opts): + """ + The shudown method can be called without raising an exception when the + file_client does not have a destroy method + """ + # Test SaltCacheLoader creating and destroying the file client created + file_client = Mock() + with patch("salt.fileclient.get_file_client", return_value=file_client): + loader = SaltMakoTemplateLookup(minion_opts) + assert loader._file_client is None + assert loader.file_client() is file_client + assert loader._file_client is file_client + try: + loader.destroy() + except AttributeError: + pytest.fail("Regression when calling SaltMakoTemplateLookup.destroy()") + assert file_client.mock_calls == [call.destroy()] -- 2.48.1 ++++++ make-_auth-calls-visible-with-master-stats-696.patch ++++++ >From 32099b97c2fa549cb050d3ae618b5200c07328c8 Mon Sep 17 00:00:00 2001 From: Victor Zhestkov <[email protected]> Date: Fri, 21 Feb 2025 11:59:00 +0100 Subject: [PATCH] Make `_auth` calls visible with master stats (#696) * Put _auth calls to the master stats * Add _auth master stats tests * test small fix --- salt/channel/server.py | 9 ++++-- salt/master.py | 5 ++++ tests/pytests/unit/channel/__init__.py | 0 tests/pytests/unit/channel/test_server.py | 34 +++++++++++++++++++++++ tests/pytests/unit/test_master.py | 25 +++++++++++++++++ 5 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 tests/pytests/unit/channel/__init__.py create mode 100644 tests/pytests/unit/channel/test_server.py diff --git a/salt/channel/server.py b/salt/channel/server.py index f1b6f701a9..59da3a2dc2 100644 --- a/salt/channel/server.py +++ b/salt/channel/server.py @@ -9,6 +9,7 @@ import hashlib import logging import os import shutil +import time import salt.crypt import salt.ext.tornado.gen @@ -149,9 +150,11 @@ class ReqServerChannel: # intercept the "_auth" commands, since the main daemon shouldn't know # anything about our key auth if payload["enc"] == "clear" and payload.get("load", {}).get("cmd") == "_auth": - raise salt.ext.tornado.gen.Return( - self._auth(payload["load"], sign_messages) - ) + start = time.time() + ret = self._auth(payload["load"], sign_messages) + if self.opts.get("master_stats", False): + yield self.payload_handler({"cmd": "_auth", "_start": start}) + raise salt.ext.tornado.gen.Return(ret) nonce = None if version > 1: diff --git a/salt/master.py b/salt/master.py index 49cfb68860..c0cd9a366b 100644 --- a/salt/master.py +++ b/salt/master.py @@ -1036,6 +1036,11 @@ class MWorker(salt.utils.process.SignalHandlingProcess): :param dict payload: The payload route to the appropriate handler """ + if payload.get("cmd") == "_auth": + if self.opts["master_stats"]: + self.stats["_auth"]["runs"] += 1 + self._post_stats(payload["_start"], "_auth") + return key = payload["enc"] load = payload["load"] if key == "aes": diff --git a/tests/pytests/unit/channel/__init__.py b/tests/pytests/unit/channel/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/pytests/unit/channel/test_server.py b/tests/pytests/unit/channel/test_server.py new file mode 100644 index 0000000000..3fa5d94bea --- /dev/null +++ b/tests/pytests/unit/channel/test_server.py @@ -0,0 +1,34 @@ +import time + +import pytest + +import salt.channel.server as server +import salt.ext.tornado.gen +from tests.support.mock import MagicMock, patch + + +def test__auth_cmd_stats_passing(): + req_server_channel = server.ReqServerChannel({"master_stats": True}, None) + + fake_ret = {"enc": "clear", "load": b"FAKELOAD"} + + def _auth_mock(*_, **__): + time.sleep(0.03) + return fake_ret + + future = salt.ext.tornado.gen.Future() + future.set_result({}) + + with patch.object(req_server_channel, "_auth", _auth_mock): + req_server_channel.payload_handler = MagicMock(return_value=future) + req_server_channel.handle_message( + {"enc": "clear", "load": {"cmd": "_auth", "id": "minion"}} + ) + cur_time = time.time() + req_server_channel.payload_handler.assert_called_once() + assert req_server_channel.payload_handler.call_args[0][0]["cmd"] == "_auth" + auth_call_duration = ( + cur_time - req_server_channel.payload_handler.call_args[0][0]["_start"] + ) + assert auth_call_duration >= 0.03 + assert auth_call_duration < 0.05 diff --git a/tests/pytests/unit/test_master.py b/tests/pytests/unit/test_master.py index 679229066d..7fccb24d73 100644 --- a/tests/pytests/unit/test_master.py +++ b/tests/pytests/unit/test_master.py @@ -282,3 +282,28 @@ def test_syndic_return_cache_dir_creation_traversal(encrypted_requests): ) assert not (cachedir / "syndics").exists() assert not (cachedir / "mamajama").exists() + + +def test_collect__auth_to_master_stats(): + """ + Check if master stats is collecting _auth calls while not calling neither _handle_aes nor _handle_clear + """ + opts = { + "master_stats": True, + "master_stats_event_iter": 10, + } + req_channel_mock = MagicMock() + mworker = salt.master.MWorker(opts, {}, {}, [req_channel_mock]) + with patch.object(mworker, "_handle_aes") as handle_aes_mock, patch.object( + mworker, "_handle_clear" + ) as handle_clear_mock: + mworker._handle_payload({"cmd": "_auth", "_start": time.time() - 0.02}) + assert mworker.stats["_auth"]["runs"] == 1 + assert mworker.stats["_auth"]["mean"] >= 0.02 + assert mworker.stats["_auth"]["mean"] < 0.04 + mworker._handle_payload({"cmd": "_auth", "_start": time.time() - 0.02}) + assert mworker.stats["_auth"]["runs"] == 2 + assert mworker.stats["_auth"]["mean"] >= 0.02 + assert mworker.stats["_auth"]["mean"] < 0.04 + handle_aes_mock.assert_not_called() + handle_clear_mock.assert_not_called() -- 2.48.1 ++++++ repair-fstab_present-test-mode-702.patch ++++++ >From 73d18711314738796e802a6d929f4b609cee1f67 Mon Sep 17 00:00:00 2001 From: Georg <[email protected]> Date: Fri, 21 Feb 2025 10:26:25 +0000 Subject: [PATCH] Repair fstab_present test mode (#702) Return no pending changes if the configuration already matches. Signed-off-by: Georg Pfuetzenreuter <[email protected]> (cherry picked from commit fc7ed2b53152ab255d7763f200e8d28d526c5e52) --- changelog/67065.fixed.md | 1 + salt/states/mount.py | 1 + tests/pytests/unit/states/test_mount.py | 6 +++--- 3 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 changelog/67065.fixed.md diff --git a/changelog/67065.fixed.md b/changelog/67065.fixed.md new file mode 100644 index 0000000000..7b210dc297 --- /dev/null +++ b/changelog/67065.fixed.md @@ -0,0 +1 @@ +Repaired mount.fstab_present always returning pending changes diff --git a/salt/states/mount.py b/salt/states/mount.py index 36b9a16b5d..97dddbe3b0 100644 --- a/salt/states/mount.py +++ b/salt/states/mount.py @@ -1228,6 +1228,7 @@ def fstab_present( if out == "present": msg = "{} entry is already in {}." ret["comment"].append(msg.format(fs_file, config)) + ret["result"] = True elif out == "new": msg = "{} entry will be written in {}." ret["comment"].append(msg.format(fs_file, config)) diff --git a/tests/pytests/unit/states/test_mount.py b/tests/pytests/unit/states/test_mount.py index 5e4d5274e8..382fe6d0e8 100644 --- a/tests/pytests/unit/states/test_mount.py +++ b/tests/pytests/unit/states/test_mount.py @@ -701,7 +701,7 @@ def test_fstab_present_macos_test_present(): """ ret = { "name": "/dev/sda1", - "result": None, + "result": True, "changes": {}, "comment": ["/home entry is already in /etc/auto_salt."], } @@ -730,7 +730,7 @@ def test_fstab_present_aix_test_present(): """ ret = { "name": "/dev/sda1", - "result": None, + "result": True, "changes": {}, "comment": ["/home entry is already in /etc/filesystems."], } @@ -761,7 +761,7 @@ def test_fstab_present_test_present(): """ ret = { "name": "/dev/sda1", - "result": None, + "result": True, "changes": {}, "comment": ["/home entry is already in /etc/fstab."], } -- 2.48.1 ++++++ repair-virt_query-outputter-655.patch ++++++ >From 325506774381cc8edadee9b2f43fd6733d4f9edb Mon Sep 17 00:00:00 2001 From: Georg <[email protected]> Date: Fri, 21 Feb 2025 12:40:45 +0000 Subject: [PATCH] Repair virt_query outputter (#655) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Repair virt_query outputter Existing code was not functional. Only return if a dictionary is passed and reference the correct data. Signed-off-by: Georg Pfuetzenreuter <[email protected]> (cherry picked from commit e3c365ad8f385121aa878950e13892d986d79656) * Facilitate block devices in virt_query outputter Disk data in Libvirt VMs does not contain a disk size if the disk references a block device. Skip the field for such disks instead of failing with a key error. Signed-off-by: Georg Pfuetzenreuter <[email protected]> (cherry picked from commit ed73abd44117ad745e9c91f2b33caf04402b117c) * Add unit tests for virt_query outputter --------- Co-authored-by: Pablo Suárez Hernández <[email protected]> --- changelog/65841.fixed.md | 1 + salt/output/virt_query.py | 64 +++---- tests/pytests/unit/output/test_virt_query.py | 176 +++++++++++++++++++ 3 files changed, 210 insertions(+), 31 deletions(-) create mode 100644 changelog/65841.fixed.md create mode 100644 tests/pytests/unit/output/test_virt_query.py diff --git a/changelog/65841.fixed.md b/changelog/65841.fixed.md new file mode 100644 index 0000000000..7fb6336ea1 --- /dev/null +++ b/changelog/65841.fixed.md @@ -0,0 +1 @@ +Restore functionality of virt_query outputter and add support for block devices. diff --git a/salt/output/virt_query.py b/salt/output/virt_query.py index d20e6357e6..0f989fedfa 100644 --- a/salt/output/virt_query.py +++ b/salt/output/virt_query.py @@ -12,35 +12,37 @@ def output(data, **kwargs): # pylint: disable=unused-argument Display output for the salt-run virt.query function """ out = "" - for id_ in data["data"]: - out += "{}\n".format(id_) - for vm_ in data["data"][id_]["vm_info"]: - out += " {}\n".format(vm_) - vm_data = data[id_]["vm_info"][vm_] - if "cpu" in vm_data: - out += " CPU: {}\n".format(vm_data["cpu"]) - if "mem" in vm_data: - out += " Memory: {}\n".format(vm_data["mem"]) - if "state" in vm_data: - out += " State: {}\n".format(vm_data["state"]) - if "graphics" in vm_data: - if vm_data["graphics"].get("type", "") == "vnc": - out += " Graphics: vnc - {}:{}\n".format( - id_, vm_data["graphics"]["port"] - ) - if "disks" in vm_data: - for disk, d_data in vm_data["disks"].items(): - out += " Disk - {}:\n".format(disk) - out += " Size: {}\n".format(d_data["disk size"]) - out += " File: {}\n".format(d_data["file"]) - out += " File Format: {}\n".format(d_data["file format"]) - if "nics" in vm_data: - for mac in vm_data["nics"]: - out += " Nic - {}:\n".format(mac) - out += " Source: {}\n".format( - vm_data["nics"][mac]["source"][ - next(iter(vm_data["nics"][mac]["source"].keys())) - ] - ) - out += " Type: {}\n".format(vm_data["nics"][mac]["type"]) + if isinstance(data, dict) and "event" in data: + for id_ in data["event"]["data"]: + out += "{}\n".format(id_) + for vm_ in data["event"]["data"][id_]["vm_info"]: + out += " {}\n".format(vm_) + vm_data = data["event"]["data"][id_]["vm_info"][vm_] + if "cpu" in vm_data: + out += " CPU: {}\n".format(vm_data["cpu"]) + if "mem" in vm_data: + out += " Memory: {}\n".format(vm_data["mem"]) + if "state" in vm_data: + out += " State: {}\n".format(vm_data["state"]) + if "graphics" in vm_data: + if vm_data["graphics"].get("type", "") == "vnc": + out += " Graphics: vnc - {}:{}\n".format( + id_, vm_data["graphics"]["port"] + ) + if "disks" in vm_data: + for disk, d_data in vm_data["disks"].items(): + out += " Disk - {}:\n".format(disk) + if "disk size" in d_data: + out += " Size: {}\n".format(d_data["disk size"]) + out += " File: {}\n".format(d_data["file"]) + out += " File Format: {}\n".format(d_data["file format"]) + if "nics" in vm_data: + for mac in vm_data["nics"]: + out += " NIC - {}:\n".format(mac) + out += " Source: {}\n".format( + vm_data["nics"][mac]["source"][ + next(iter(vm_data["nics"][mac]["source"].keys())) + ] + ) + out += " Type: {}\n".format(vm_data["nics"][mac]["type"]) return out diff --git a/tests/pytests/unit/output/test_virt_query.py b/tests/pytests/unit/output/test_virt_query.py new file mode 100644 index 0000000000..3f8814ee26 --- /dev/null +++ b/tests/pytests/unit/output/test_virt_query.py @@ -0,0 +1,176 @@ +""" +unittests for virt_query outputter +""" + +import pytest + +import salt.output.virt_query as virt_query +from tests.support.mock import patch + + [email protected] +def configure_loader_modules(): + return {virt_query: {}} + + [email protected] +def data(): + return { + "suffix": "progress", + "event": { + "data": { + "mysystem": { + "freecpu": 14, + "freemem": 29566.0, + "node_info": { + "cpucores": 8, + "cpumhz": 1089, + "cpumodel": "x86_64", + "cpus": 16, + "cputhreads": 2, + "numanodes": 1, + "phymemory": 30846, + "sockets": 1, + }, + "vm_info": { + "vm1": { + "cpu": 2, + "cputime": 1214270000000, + "disks": { + "vda": { + "file": "default/vm1-main-disk", + "type": "disk", + "file format": "qcow2", + "virtual size": 214748364800, + "disk size": 1831731200, + "backing file": { + "file": "/var/lib/libvirt/images/sles15sp4o", + "file format": "qcow2", + }, + }, + "hdd": { + "file": "default/vm1-cloudinit-disk", + "type": "cdrom", + "file format": "raw", + "virtual size": 374784, + "disk size": 376832, + }, + }, + "graphics": { + "autoport": "yes", + "keymap": "None", + "listen": "0.0.0.0", + "port": "5900", + "type": "spice", + }, + "nics": { + "aa:bb:cc:dd:ee:ff": { + "type": "network", + "mac": "aa:bb:cc:dd:ee:ff", + "source": {"network": "default"}, + "model": "virtio", + "address": { + "type": "pci", + "domain": "0x0000", + "bus": "0x00", + "slot": "0x03", + "function": "0x0", + }, + } + }, + "uuid": "yyyyyy", + "loader": {"path": "None"}, + "on_crash": "destroy", + "on_reboot": "restart", + "on_poweroff": "destroy", + "maxMem": 1048576, + "mem": 1048576, + "state": "running", + }, + "uyuni-proxy": { + "cpu": 2, + "cputime": 0, + "disks": { + "vda": { + "file": "default/uyuni-proxy-main-disk", + "type": "disk", + "file format": "qcow2", + "virtual size": 214748364800, + "disk size": 4491255808, + "backing file": { + "file": "/var/lib/libvirt/images/leapmicro55o", + "file format": "qcow2", + }, + } + }, + "graphics": { + "autoport": "yes", + "keymap": "None", + "listen": "0.0.0.0", + "port": "None", + "type": "spice", + }, + "nics": { + "aa:bb:cc:dd:ee:aa": { + "type": "network", + "mac": "aa:bb:cc:dd:ee:aa", + "source": {"network": "default"}, + "model": "virtio", + "address": { + "type": "pci", + "domain": "0x0000", + "bus": "0x00", + "slot": "0x03", + "function": "0x0", + }, + } + }, + "uuid": "xxxxx", + "loader": {"path": "None"}, + "on_crash": "destroy", + "on_reboot": "restart", + "on_poweroff": "destroy", + "maxMem": 2097152, + "mem": 2097152, + "state": "shutdown", + }, + }, + } + }, + "outputter": "virt_query", + "_stamp": "2025-02-21T11:28:04.406561", + }, + } + + +def test_default_output(data): + ret = virt_query.output(data) + expected = """mysystem + vm1 + CPU: 2 + Memory: 1048576 + State: running + Disk - vda: + Size: 1831731200 + File: default/vm1-main-disk + File Format: qcow2 + Disk - hdd: + Size: 376832 + File: default/vm1-cloudinit-disk + File Format: raw + NIC - aa:bb:cc:dd:ee:ff: + Source: default + Type: network + uyuni-proxy + CPU: 2 + Memory: 2097152 + State: shutdown + Disk - vda: + Size: 4491255808 + File: default/uyuni-proxy-main-disk + File Format: qcow2 + NIC - aa:bb:cc:dd:ee:aa: + Source: default + Type: network +""" + assert expected == ret -- 2.48.1 ++++++ set-virtual-grain-in-podman-systemd-container-703.patch ++++++ >From dde665763bd2f043022f9601dd25d0ca8aa716be Mon Sep 17 00:00:00 2001 From: Georg <[email protected]> Date: Fri, 21 Feb 2025 10:24:51 +0000 Subject: [PATCH] Set virtual grain in Podman systemd container (#703) Correctly handle the systemd-detect-virt output to identify a Podman container running systemd as what it is instead of as a physical machine. Signed-off-by: Georg Pfuetzenreuter <[email protected]> (cherry picked from commit cf504a06859fb4a4fe9b8ebdd76380697f1f0c25) --- changelog/67733.fixed.md | 1 + salt/grains/core.py | 4 ++++ tests/pytests/unit/grains/test_core.py | 31 ++++++++++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 changelog/67733.fixed.md diff --git a/changelog/67733.fixed.md b/changelog/67733.fixed.md new file mode 100644 index 0000000000..242f65ec76 --- /dev/null +++ b/changelog/67733.fixed.md @@ -0,0 +1 @@ +Set correct virtual grain in systemd based Podman containers diff --git a/salt/grains/core.py b/salt/grains/core.py index 84d5b179dd..ceb142a7b8 100644 --- a/salt/grains/core.py +++ b/salt/grains/core.py @@ -911,6 +911,10 @@ def _virtual(osdata): grains["virtual"] = "container" grains["virtual_subtype"] = "LXC" break + elif "podman" in output: + grains["virtual"] = "container" + grains["virtual_subtype"] = "Podman" + break elif "amazon" in output: grains["virtual"] = "Nitro" grains["virtual_subtype"] = "Amazon EC2" diff --git a/tests/pytests/unit/grains/test_core.py b/tests/pytests/unit/grains/test_core.py index 3d2beaa2c9..072287248f 100644 --- a/tests/pytests/unit/grains/test_core.py +++ b/tests/pytests/unit/grains/test_core.py @@ -1752,6 +1752,37 @@ def test_lxc_virtual_with_virt_what(): assert ret["virtual_subtype"] == "LXC" [email protected]_on_windows +def test_podman_virtual_with_systemd_detect_virt(): + """ + Test if virtual grains are parsed correctly in Podman using systemd-detect-virt. + """ + + def _which_side_effect(path): + if path == "systemd-detect-virt": + return "/usr/bin/systemd-detect-virt" + return None + + with patch.object( + salt.utils.platform, "is_windows", MagicMock(return_value=False) + ), patch.object( + salt.utils.path, + "which", + MagicMock(return_value=True, side_effect=_which_side_effect), + ), patch.dict( + core.__salt__, + { + "cmd.run_all": MagicMock( + return_value={"pid": 78, "retcode": 0, "stderr": "", "stdout": "podman"} + ) + }, + ): + osdata = {"kernel": "test"} + ret = core._virtual(osdata) + assert ret["virtual"] == "container" + assert ret["virtual_subtype"] == "Podman" + + @pytest.mark.skip_on_windows def test_container_inside_virtual_machine(): """ -- 2.48.1
