From a9a09d3ee17a895732c66f1d92f6a15abbaa16b4 Mon Sep 17 00:00:00 2001 From: Maxwell G Date: Mon, 25 Nov 2024 23:02:26 -0600 Subject: [PATCH 01/23] Update to 2.18.0. Fixes rhbz#2282011. --- .gitignore | 2 ++ ansible-core.spec | 23 +++++------------------ python3.13.patch | 48 ----------------------------------------------- sources | 4 ++-- 4 files changed, 9 insertions(+), 68 deletions(-) delete mode 100644 python3.13.patch diff --git a/.gitignore b/.gitignore index 949512f..2da70f1 100644 --- a/.gitignore +++ b/.gitignore @@ -69,3 +69,5 @@ /ansible-documentation-2.16.11.tar.gz /ansible-core-2.16.12.tar.gz /ansible-documentation-2.16.12.tar.gz +/ansible-core-2.18.0.tar.gz +/ansible-documentation-2.18.0.tar.gz diff --git a/ansible-core.spec b/ansible-core.spec index c7683f0..63099d4 100644 --- a/ansible-core.spec +++ b/ansible-core.spec @@ -14,7 +14,7 @@ Name: ansible-core Summary: A radically simple IT automation system -Version: 2.16.12 +Version: 2.18.0 %global uversion %{version_no_tilde %{quote:%nil}} Release: 1%{?dist} # The main license is GPLv3+. Many of the files in lib/ansible/module_utils @@ -25,36 +25,20 @@ License: GPL-3.0-or-later AND BSD-2-Clause AND PSF-2.0 AND MIT AND Apache-2.0 Source0: https://github.com/ansible/ansible/archive/v%{uversion}/%{name}-%{uversion}.tar.gz Source1: https://github.com/ansible/ansible-documentation/archive/v%{uversion}/ansible-documentation-%{uversion}.tar.gz -# ansible-core 2.16 does not support Python 3.13 and upstream does not plan to do so until 2.18 -# This downstream-only patch makes it possible to build 2.16 with Python 3.13 -Patch: python3.13.patch - Url: https://ansible.com BuildArch: noarch # Virtual provides for bundled libraries # Search for `_BUNDLED_METADATA` to find them -# lib/ansible/module_utils/urls.py -# SPDX-License-Identifier: BSD-2-Clause AND PSF-2.0 -Provides: bundled(python3dist(backports-ssl-match-hostname)) = 3.7.0.1 - # lib/ansible/module_utils/distro/* # SPDX-License-Identifier: Apache-2.0 -Provides: bundled(python3dist(distro)) = 1.6.0 +Provides: bundled(python3dist(distro)) = 1.9.0 # lib/ansible/module_utils/six/* # SPDX-License-Identifier: MIT Provides: bundled(python3dist(six)) = 1.16.0 -# lib/ansible/module_utils/compat/selectors.py -# SPDX-License-Identifier: GPL-3.0-or-later -Provides: bundled(python3dist(selectors2)) = 1.1.1 - -# lib/ansible/module_utils/compat/ipaddress.py -# SPDX-License-Identifier: PSF-2.0 -Provides: bundled(python3dist(ipaddress)) = 1.0.22 - Conflicts: ansible <= 2.9.99 # # obsoletes/provides for ansible-base @@ -278,6 +262,9 @@ install -Dpm 0644 licenses/* -t %{buildroot}%{_pkglicensedir} %changelog +* Tue Nov 26 2024 Maxwell G - 2.18.0-1 +- Update to 2.18.0. Fixes rhbz#2282011. + * Fri Oct 11 2024 Maxwell G - 2.16.12-1 - Update to 2.16.12. diff --git a/python3.13.patch b/python3.13.patch deleted file mode 100644 index 80fc84c..0000000 --- a/python3.13.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 54fc9d327d272c3d1d02a9c44d609a027b67105c Mon Sep 17 00:00:00 2001 -From: Karolina Surma -Date: Thu, 23 May 2024 12:38:22 +0200 -Subject: [PATCH] Make it possible to build with Python 3.13 - ---- - test/lib/ansible_test/_data/requirements/ansible-test.txt | 2 +- - test/lib/ansible_test/_internal/coverage_util.py | 2 +- - test/lib/ansible_test/_util/target/common/constants.py | 1 + - 3 files changed, 3 insertions(+), 2 deletions(-) - -diff --git a/test/lib/ansible_test/_data/requirements/ansible-test.txt b/test/lib/ansible_test/_data/requirements/ansible-test.txt -index 17662f0..2b725a9 100644 ---- a/test/lib/ansible_test/_data/requirements/ansible-test.txt -+++ b/test/lib/ansible_test/_data/requirements/ansible-test.txt -@@ -1,5 +1,5 @@ - # The test-constraints sanity test verifies this file, but changes must be made manually to keep it in up-to-date. - virtualenv == 16.7.12 ; python_version < '3' --coverage == 7.3.2 ; python_version >= '3.8' and python_version <= '3.12' -+coverage == 7.3.2 ; python_version >= '3.8' and python_version <= '3.13' - coverage == 6.5.0 ; python_version >= '3.7' and python_version <= '3.7' - coverage == 4.5.4 ; python_version >= '2.6' and python_version <= '3.6' -diff --git a/test/lib/ansible_test/_internal/coverage_util.py b/test/lib/ansible_test/_internal/coverage_util.py -index 3017623..f437110 100644 ---- a/test/lib/ansible_test/_internal/coverage_util.py -+++ b/test/lib/ansible_test/_internal/coverage_util.py -@@ -69,7 +69,7 @@ class CoverageVersion: - - COVERAGE_VERSIONS = ( - # IMPORTANT: Keep this in sync with the ansible-test.txt requirements file. -- CoverageVersion('7.3.2', 7, (3, 8), (3, 12)), -+ CoverageVersion('7.3.2', 7, (3, 8), (3, 13)), - CoverageVersion('6.5.0', 7, (3, 7), (3, 7)), - CoverageVersion('4.5.4', 0, (2, 6), (3, 6)), - ) -diff --git a/test/lib/ansible_test/_util/target/common/constants.py b/test/lib/ansible_test/_util/target/common/constants.py -index 36a5a2c..db81f6b 100644 ---- a/test/lib/ansible_test/_util/target/common/constants.py -+++ b/test/lib/ansible_test/_util/target/common/constants.py -@@ -17,4 +17,5 @@ CONTROLLER_PYTHON_VERSIONS = ( - '3.10', - '3.11', - '3.12', -+ '3.13', - ) --- -2.45.0 - diff --git a/sources b/sources index 06978ba..ca347af 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (ansible-core-2.16.12.tar.gz) = 6048ecc31b23244f0826dd3e46c93d35e667f059a346a3f51a312028c80d333b75066b0a17fe043e53aafa128c78ca3a88dbfa3954c0b8869fe92b2e71134f42 -SHA512 (ansible-documentation-2.16.12.tar.gz) = 466f95af9bcae3b392d737f58d7dfe0fe9c9b27305fea66b6d9fa358c0ef2340bf0b4c24637675bd5aaa950a435dd1d6e04d7b043cd7962a80468a6ed6e38992 +SHA512 (ansible-core-2.18.0.tar.gz) = 3c5c620778ad4120c8f231be88c3e018bc902718ece4b05dce009d40709da7a3d97640155de074432d17aad620a74700a71b87c055d9cfb03a1e4f6d8168b1ef +SHA512 (ansible-documentation-2.18.0.tar.gz) = 66d5fdab8299236b3606a8f335fef6afe02b0172d052a6e3a0fb180f327ba1b0de9743e5797b9160ff8752a27aef71e80793cff9fc8cc42c0c88a1c97944eb4b From 23959358145ff806a31d033321f657a26dd6bf9f Mon Sep 17 00:00:00 2001 From: Maxwell G Date: Tue, 3 Dec 2024 21:41:56 -0600 Subject: [PATCH 02/23] Update to 2.18.1. Fixes rhbz#2330005. --- .gitignore | 2 ++ ansible-core.spec | 5 ++++- sources | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 2da70f1..fbc245c 100644 --- a/.gitignore +++ b/.gitignore @@ -71,3 +71,5 @@ /ansible-documentation-2.16.12.tar.gz /ansible-core-2.18.0.tar.gz /ansible-documentation-2.18.0.tar.gz +/ansible-core-2.18.1.tar.gz +/ansible-documentation-2.18.1.tar.gz diff --git a/ansible-core.spec b/ansible-core.spec index 63099d4..fc31716 100644 --- a/ansible-core.spec +++ b/ansible-core.spec @@ -14,7 +14,7 @@ Name: ansible-core Summary: A radically simple IT automation system -Version: 2.18.0 +Version: 2.18.1 %global uversion %{version_no_tilde %{quote:%nil}} Release: 1%{?dist} # The main license is GPLv3+. Many of the files in lib/ansible/module_utils @@ -262,6 +262,9 @@ install -Dpm 0644 licenses/* -t %{buildroot}%{_pkglicensedir} %changelog +* Wed Dec 04 2024 Maxwell G - 2.18.1-1 +- Update to 2.18.1. Fixes rhbz#2330005. + * Tue Nov 26 2024 Maxwell G - 2.18.0-1 - Update to 2.18.0. Fixes rhbz#2282011. diff --git a/sources b/sources index ca347af..7c3a57a 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (ansible-core-2.18.0.tar.gz) = 3c5c620778ad4120c8f231be88c3e018bc902718ece4b05dce009d40709da7a3d97640155de074432d17aad620a74700a71b87c055d9cfb03a1e4f6d8168b1ef -SHA512 (ansible-documentation-2.18.0.tar.gz) = 66d5fdab8299236b3606a8f335fef6afe02b0172d052a6e3a0fb180f327ba1b0de9743e5797b9160ff8752a27aef71e80793cff9fc8cc42c0c88a1c97944eb4b +SHA512 (ansible-core-2.18.1.tar.gz) = 5358d5f8e9408457c56582a8b9234861bb40f773517408dd66e8f1511a80ffeaaafd4db81cc34ff1bf5ba79e3fb6a3b7fdccc6c5ed8531b41f31b617baecf8ca +SHA512 (ansible-documentation-2.18.1.tar.gz) = 2384beb447ef0ea8ec27331ac8a5f1e0d4247e8ab8a4788c9f8280141d6feb591141a8b7aee60eebf55049d068bcba0128f5edf72d5ef65f8d43ec4e20bae3e3 From 0071dba023d4e8a5f643dffee02f86c141fa30a4 Mon Sep 17 00:00:00 2001 From: Maxwell G Date: Tue, 3 Dec 2024 21:46:50 -0600 Subject: [PATCH 03/23] Reformat specfile --- ansible-core.spec | 57 ++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/ansible-core.spec b/ansible-core.spec index fc31716..708e936 100644 --- a/ansible-core.spec +++ b/ansible-core.spec @@ -12,70 +12,71 @@ # disable the python -s shbang flag as we want to be able to find non system modules %undefine _py3_shebang_s -Name: ansible-core -Summary: A radically simple IT automation system -Version: 2.18.1 +Name: ansible-core +Version: 2.18.1 %global uversion %{version_no_tilde %{quote:%nil}} -Release: 1%{?dist} +Release: 1%{?dist} +Summary: A radically simple IT automation system + # The main license is GPLv3+. Many of the files in lib/ansible/module_utils # are BSD licensed. There are various files scattered throughout the codebase # containing code under different licenses. -License: GPL-3.0-or-later AND BSD-2-Clause AND PSF-2.0 AND MIT AND Apache-2.0 +License: GPL-3.0-or-later AND BSD-2-Clause AND PSF-2.0 AND MIT AND Apache-2.0 +URL: https://ansible.com -Source0: https://github.com/ansible/ansible/archive/v%{uversion}/%{name}-%{uversion}.tar.gz -Source1: https://github.com/ansible/ansible-documentation/archive/v%{uversion}/ansible-documentation-%{uversion}.tar.gz +Source0: https://github.com/ansible/ansible/archive/v%{uversion}/%{name}-%{uversion}.tar.gz +Source1: https://github.com/ansible/ansible-documentation/archive/v%{uversion}/ansible-documentation-%{uversion}.tar.gz -Url: https://ansible.com -BuildArch: noarch +BuildArch: noarch # Virtual provides for bundled libraries # Search for `_BUNDLED_METADATA` to find them # lib/ansible/module_utils/distro/* # SPDX-License-Identifier: Apache-2.0 -Provides: bundled(python3dist(distro)) = 1.9.0 +Provides: bundled(python3dist(distro)) = 1.9.0 # lib/ansible/module_utils/six/* # SPDX-License-Identifier: MIT -Provides: bundled(python3dist(six)) = 1.16.0 +Provides: bundled(python3dist(six)) = 1.16.0 -Conflicts: ansible <= 2.9.99 +Conflicts: ansible <= 2.9.99 # # obsoletes/provides for ansible-base # -Provides: ansible-base = %{version}-%{release} -Obsoletes: ansible-base < 2.10.6-1 +Provides: ansible-base = %{version}-%{release} +Obsoletes: ansible-base < 2.10.6-1 -BuildRequires: make -BuildRequires: python%{python3_pkgversion}-devel +BuildRequires: make +BuildRequires: python%{python3_pkgversion}-devel # This is only used in %%prep to relax the required setuptools version, # which is not necessary in RHEL 10+. # Not using it in RHEL avoids unwanted dependencies. %if %{undefined rhel} -BuildRequires: tomcli >= 0.3.0 +BuildRequires: tomcli >= 0.3.0 %endif # Needed to build manpages from source. -BuildRequires: python%{python3_pkgversion}-docutils +BuildRequires: python%{python3_pkgversion}-docutils %if %{with tests} -BuildRequires: git-core -BuildRequires: glibc-all-langpacks -BuildRequires: python%{python3_pkgversion}-systemd +BuildRequires: git-core +BuildRequires: glibc-all-langpacks +BuildRequires: python%{python3_pkgversion}-systemd %if v"0%{?python3_version}" >= v"3.13" # Use crypt_r on Python 3.13+ # https://github.com/ansible/ansible/issues/82758 # Upstream has removed the dependency on crypt from ansible 2.17+ -BuildRequires: python%{python3_pkgversion}-crypt-r +BuildRequires: python%{python3_pkgversion}-crypt-r %endif %endif %if %{with argcomplete} -Requires: python%{python3_pkgversion}-argcomplete +Requires: python%{python3_pkgversion}-argcomplete %endif %if 0%{?fedora} >= 39 -BuildRequires: python3-libdnf5 -Recommends: python3-libdnf5 +BuildRequires: python3-libdnf5 +Recommends: python3-libdnf5 %endif @@ -91,9 +92,9 @@ are transferred to managed machines automatically.} This is the base part of ansible (the engine). %package doc -Summary: Documentation for Ansible Core -Provides: ansible-base-doc = %{version}-%{release} -Obsoletes: ansible-base-doc < 2.10.6-1 +Summary: Documentation for Ansible Core +Provides: ansible-base-doc = %{version}-%{release} +Obsoletes: ansible-base-doc < 2.10.6-1 %description doc %_description From fe2a4316f38331efad76586717d2a102c8f36e1b Mon Sep 17 00:00:00 2001 From: Maxwell G Date: Tue, 3 Dec 2024 21:57:42 -0600 Subject: [PATCH 04/23] Backport support for automatically installing python3-libdnf5 Resolves: https://bugzilla.redhat.com/2322751 --- ...uto_install_module_deps-option-84292.patch | 348 ++++++++++++++++++ ansible-core.spec | 6 + 2 files changed, 354 insertions(+) create mode 100644 0001-dnf5-apt-add-auto_install_module_deps-option-84292.patch diff --git a/0001-dnf5-apt-add-auto_install_module_deps-option-84292.patch b/0001-dnf5-apt-add-auto_install_module_deps-option-84292.patch new file mode 100644 index 0000000..826e39b --- /dev/null +++ b/0001-dnf5-apt-add-auto_install_module_deps-option-84292.patch @@ -0,0 +1,348 @@ +From e951ca7cc9fa55a626239ed88f3afb7cd67d1fcc Mon Sep 17 00:00:00 2001 +From: Martin Krizek +Date: Thu, 21 Nov 2024 17:06:18 +0100 +Subject: [PATCH] dnf5,apt: add auto_install_module_deps option (#84292) + +* dnf5,apt: add auto_install_module_deps option + +Fixes #84206 + +(cherry picked from commit 2a53b851fee8ebaa07c1341122dd905354659237) +--- + ...4206-dnf5-apt-auto-install-module-deps.yml | 2 + + lib/ansible/modules/apt.py | 90 +++++++++++-------- + lib/ansible/modules/dnf5.py | 52 ++++++++--- + test/integration/targets/apt/tasks/apt.yml | 28 ++++-- + test/integration/targets/dnf5/playbook.yml | 21 ++++- + 5 files changed, 132 insertions(+), 61 deletions(-) + create mode 100644 changelogs/fragments/84206-dnf5-apt-auto-install-module-deps.yml + +diff --git a/changelogs/fragments/84206-dnf5-apt-auto-install-module-deps.yml b/changelogs/fragments/84206-dnf5-apt-auto-install-module-deps.yml +new file mode 100644 +index 0000000000..14d595449c +--- /dev/null ++++ b/changelogs/fragments/84206-dnf5-apt-auto-install-module-deps.yml +@@ -0,0 +1,2 @@ ++minor_changes: ++ - dnf5, apt - add ``auto_install_module_deps`` option (https://github.com/ansible/ansible/issues/84206) +diff --git a/lib/ansible/modules/apt.py b/lib/ansible/modules/apt.py +index 70a2a07cc0..c18bd36fe4 100644 +--- a/lib/ansible/modules/apt.py ++++ b/lib/ansible/modules/apt.py +@@ -17,6 +17,12 @@ description: + - Manages I(apt) packages (such as for Debian/Ubuntu). + version_added: "0.0.2" + options: ++ auto_install_module_deps: ++ description: ++ - Automatically install dependencies required to run this module. ++ type: bool ++ default: yes ++ version_added: 2.19 + name: + description: + - A list of package names, like V(foo), or package specifier with version, like V(foo=1.0) or V(foo>=1.0). +@@ -191,8 +197,7 @@ options: + default: 60 + version_added: "2.12" + requirements: +- - python-apt (python 2) +- - python3-apt (python 3) ++ - python3-apt + - aptitude (before 2.4) + author: "Matthew Williams (@mgwilliams)" + extends_documentation_fragment: action_common_attributes +@@ -214,8 +219,8 @@ notes: + - When used with a C(loop:) each package will be processed individually, it is much more efficient to pass the list directly to the O(name) option. + - When O(default_release) is used, an implicit priority of 990 is used. This is the same behavior as C(apt-get -t). + - When an exact version is specified, an implicit priority of 1001 is used. +- - If the interpreter can't import C(python-apt)/C(python3-apt) the module will check for it in system-owned interpreters as well. +- If the dependency can't be found, the module will attempt to install it. ++ - If the interpreter can't import C(python3-apt) the module will check for it in system-owned interpreters as well. ++ If the dependency can't be found, depending on the value of O(auto_install_module_deps) the module will attempt to install it. + If the dependency is found or installed, the module will be respawned under the correct interpreter. + ''' + +@@ -1233,6 +1238,7 @@ def main(): + allow_downgrade=dict(type='bool', default=False, aliases=['allow-downgrade', 'allow_downgrades', 'allow-downgrades']), + allow_change_held_packages=dict(type='bool', default=False), + lock_timeout=dict(type='int', default=60), ++ auto_install_module_deps=dict(type='bool', default=True), + ), + mutually_exclusive=[['deb', 'package', 'upgrade']], + required_one_of=[['autoremove', 'deb', 'package', 'update_cache', 'upgrade']], +@@ -1268,7 +1274,7 @@ def main(): + if not HAS_PYTHON_APT: + # This interpreter can't see the apt Python library- we'll do the following to try and fix that: + # 1) look in common locations for system-owned interpreters that can see it; if we find one, respawn under it +- # 2) finding none, try to install a matching python-apt package for the current interpreter version; ++ # 2) finding none, try to install a matching python3-apt package for the current interpreter version; + # we limit to the current interpreter version to try and avoid installing a whole other Python just + # for apt support + # 3) if we installed a support package, try to respawn under what we think is the right interpreter (could be +@@ -1294,39 +1300,47 @@ def main(): + + # don't make changes if we're in check_mode + if module.check_mode: +- module.fail_json(msg="%s must be installed to use check mode. " +- "If run normally this module can auto-install it." % apt_pkg_name) +- +- # We skip cache update in auto install the dependency if the +- # user explicitly declared it with update_cache=no. +- if module.params.get('update_cache') is False: +- module.warn("Auto-installing missing dependency without updating cache: %s" % apt_pkg_name) +- else: +- module.warn("Updating cache and auto-installing missing dependency: %s" % apt_pkg_name) +- module.run_command([APT_GET_CMD, 'update'], check_rc=True) +- +- # try to install the apt Python binding +- apt_pkg_cmd = [APT_GET_CMD, 'install', apt_pkg_name, '-y', '-q', dpkg_options] +- +- if install_recommends is False: +- apt_pkg_cmd.extend(["-o", "APT::Install-Recommends=no"]) +- elif install_recommends is True: +- apt_pkg_cmd.extend(["-o", "APT::Install-Recommends=yes"]) +- # install_recommends is None uses the OS default +- +- module.run_command(apt_pkg_cmd, check_rc=True) +- +- # try again to find the bindings in common places +- interpreter = probe_interpreters_for_module(interpreters, 'apt') +- +- if interpreter: +- # found the Python bindings; respawn this module under the interpreter where we found them +- # NB: respawn is somewhat wasteful if it's this interpreter, but simplifies the code +- respawn_module(interpreter) +- # this is the end of the line for this process, it will exit here once the respawned module has completed +- else: +- # we've done all we can do; just tell the user it's busted and get out +- module.fail_json(msg="{0} must be installed and visible from {1}.".format(apt_pkg_name, sys.executable)) ++ module.fail_json( ++ msg=f"{apt_pkg_name} must be installed to use check mode. " ++ "If run normally this module can auto-install it, " ++ "see the auto_install_module_deps option.", ++ ) ++ elif p['auto_install_module_deps']: ++ # We skip cache update in auto install the dependency if the ++ # user explicitly declared it with update_cache=no. ++ if module.params.get('update_cache') is False: ++ module.warn("Auto-installing missing dependency without updating cache: %s" % apt_pkg_name) ++ else: ++ module.warn("Updating cache and auto-installing missing dependency: %s" % apt_pkg_name) ++ module.run_command([APT_GET_CMD, 'update'], check_rc=True) ++ ++ # try to install the apt Python binding ++ apt_pkg_cmd = [APT_GET_CMD, 'install', apt_pkg_name, '-y', '-q', dpkg_options] ++ ++ if install_recommends is False: ++ apt_pkg_cmd.extend(["-o", "APT::Install-Recommends=no"]) ++ elif install_recommends is True: ++ apt_pkg_cmd.extend(["-o", "APT::Install-Recommends=yes"]) ++ # install_recommends is None uses the OS default ++ ++ module.run_command(apt_pkg_cmd, check_rc=True) ++ ++ # try again to find the bindings in common places ++ interpreter = probe_interpreters_for_module(interpreters, 'apt') ++ ++ if interpreter: ++ # found the Python bindings; respawn this module under the interpreter where we found them ++ # NB: respawn is somewhat wasteful if it's this interpreter, but simplifies the code ++ respawn_module(interpreter) ++ # this is the end of the line for this process, it will exit here once the respawned module has completed ++ ++ # we've done all we can do; just tell the user it's busted and get out ++ py_version = sys.version.replace("\n", "") ++ module.fail_json( ++ msg=f"Could not import the {apt_pkg_name} module using {sys.executable} ({py_version}). " ++ f"Ensure {apt_pkg_name} package is installed (either manually or via the auto_install_module_deps option) " ++ f"or that you have specified the correct ansible_python_interpreter. (attempted {interpreters}).", ++ ) + + if p['clean'] is True: + aptclean_stdout, aptclean_stderr, aptclean_diff = aptclean(module) +diff --git a/lib/ansible/modules/dnf5.py b/lib/ansible/modules/dnf5.py +index 0e429d3a43..2eef580933 100644 +--- a/lib/ansible/modules/dnf5.py ++++ b/lib/ansible/modules/dnf5.py +@@ -14,6 +14,12 @@ description: + provides are implemented in M(ansible.builtin.dnf5), please consult specific options for more information." + short_description: Manages packages with the I(dnf5) package manager + options: ++ auto_install_module_deps: ++ description: ++ - Automatically install dependencies required to run this module. ++ type: bool ++ default: yes ++ version_added: 2.19 + name: + description: + - "A package name or package specifier with version, like C(name-1.0). +@@ -246,6 +252,10 @@ attributes: + platforms: rhel + requirements: + - "python3-libdnf5" ++notes: ++ - If the interpreter can't import C(python3-libdnf5) the module will check for it in system-owned interpreters as well. ++ If the dependency can't be found, depending on the value of O(auto_install_module_deps) the module will attempt to install it. ++ If the dependency is found or installed, the module will be respawned under the correct interpreter. + version_added: 2.15 + """ + +@@ -460,6 +470,8 @@ def get_unneeded_pkgs(base): + class Dnf5Module(YumDnf): + def __init__(self, module): + super(Dnf5Module, self).__init__(module) ++ self.auto_install_module_deps = self.module.params["auto_install_module_deps"] ++ + self._ensure_dnf() + + self.pkg_mgr_name = "dnf5" +@@ -509,21 +521,30 @@ class Dnf5Module(YumDnf): + ] + + if not has_respawned(): +- # probe well-known system Python locations for accessible bindings, favoring py3 +- interpreter = probe_interpreters_for_module(system_interpreters, "libdnf5") +- +- if interpreter: +- # respawn under the interpreter where the bindings should be found +- respawn_module(interpreter) +- # end of the line for this module, the process will exit here once the respawned module completes ++ for attempt in (1, 2): ++ # probe well-known system Python locations for accessible bindings ++ interpreter = probe_interpreters_for_module(system_interpreters, "libdnf5") ++ if interpreter: ++ # respawn under the interpreter where the bindings should be found ++ respawn_module(interpreter) ++ # end of the line for this module, the process will exit here once the respawned module completes ++ if attempt == 1: ++ if self.module.check_mode: ++ self.module.fail_json( ++ msg="python3-libdnf5 must be installed to use check mode. " ++ "If run normally this module can auto-install it, " ++ "see the auto_install_module_deps option.", ++ ) ++ elif self.auto_install_module_deps: ++ self.module.run_command(["dnf", "install", "-y", "python3-libdnf5"], check_rc=True) ++ else: ++ break + +- # done all we can do, something is just broken (auto-install isn't useful anymore with respawn, so it was removed) ++ py_version = sys.version.replace("\n", "") + self.module.fail_json( +- msg="Could not import the libdnf5 python module using {0} ({1}). " +- "Please install python3-libdnf5 package or ensure you have specified the " +- "correct ansible_python_interpreter. (attempted {2})".format( +- sys.executable, sys.version.replace("\n", ""), system_interpreters +- ), ++ msg=f"Could not import the libdnf5 python module using {sys.executable} ({py_version}). " ++ "Ensure python3-libdnf5 package is installed (either manually or via the auto_install_module_deps option) " ++ f"or that you have specified the correct ansible_python_interpreter. (attempted {system_interpreters}).", + failures=[], + ) + +@@ -780,6 +801,11 @@ class Dnf5Module(YumDnf): + + + def main(): ++ yumdnf_argument_spec["argument_spec"].update( ++ dict( ++ auto_install_module_deps=dict(type="bool", default=True), ++ ) ++ ) + Dnf5Module(AnsibleModule(**yumdnf_argument_spec)).run() + + +diff --git a/test/integration/targets/apt/tasks/apt.yml b/test/integration/targets/apt/tasks/apt.yml +index 64e00d3ca9..dda5fc1fab 100644 +--- a/test/integration/targets/apt/tasks/apt.yml ++++ b/test/integration/targets/apt/tasks/apt.yml +@@ -8,17 +8,17 @@ + distro_mirror: http://archive.ubuntu.com/ubuntu + when: ansible_distribution == 'Ubuntu' + +-# UNINSTALL 'python-apt' +-# The `apt` module has the smarts to auto-install `python-apt(3)`. To test, we +-# will first uninstall `python-apt`. +-- name: uninstall python-apt with apt ++# UNINSTALL 'python3-apt' ++# The `apt` module has the smarts to auto-install `python3-apt`. To test, we ++# will first uninstall `python3-apt`. ++- name: uninstall python3-apt with apt + apt: +- pkg: [python-apt, python3-apt] ++ pkg: python3-apt + state: absent + purge: yes + register: apt_result + +-# In check mode, auto-install of `python-apt` must fail ++# In check mode, auto-install of `python3-apt` must fail + - name: test fail uninstall hello without required apt deps in check mode + apt: + pkg: hello +@@ -32,13 +32,25 @@ + assert: + that: + - apt_result is failed +- - '"If run normally this module can auto-install it." in apt_result.msg' ++ - '"If run normally this module can auto-install it" in apt_result.msg' + + - name: check with dpkg +- shell: dpkg -s python-apt python3-apt ++ shell: dpkg -s python3-apt + register: dpkg_result + ignore_errors: true + ++- name: Test the auto_install_module_deps option ++ apt: ++ pkg: hello ++ auto_install_module_deps: false ++ register: r ++ ignore_errors: true ++ ++- assert: ++ that: ++ - r is failed ++ - r.msg is contains("Could not import the python3-apt module") ++ + # UNINSTALL 'hello' + # With 'python-apt' uninstalled, the first call to 'apt' should install + # python-apt without updating the cache. +diff --git a/test/integration/targets/dnf5/playbook.yml b/test/integration/targets/dnf5/playbook.yml +index a1024f4b3d..a36c17a202 100644 +--- a/test/integration/targets/dnf5/playbook.yml ++++ b/test/integration/targets/dnf5/playbook.yml +@@ -2,9 +2,26 @@ + tasks: + - block: + - command: "dnf install -y 'dnf-command(copr)'" +- - command: dnf copr enable -y rpmsoftwaremanagement/dnf-nightly +- - command: dnf install -y -x condor python3-libdnf5 ++ - name: Test against dnf5 nightly build to detect any issues early ++ command: dnf copr enable -y rpmsoftwaremanagement/dnf-nightly + ++ - name: Ensure module deps are not installed ++ command: dnf remove -y python3-libdnf5 ++ ++ - name: Test the auto_install_module_deps option ++ dnf5: ++ name: sos ++ auto_install_module_deps: false ++ register: r ++ ignore_errors: true ++ ++ - assert: ++ that: ++ - r is failed ++ - r.msg is contains("Could not import the libdnf5 python module") ++ ++ # Now the first dnf5 task in the dnf role should auto install python3-libdnf5 as ++ # auto_install_module_deps is true by default. + - include_role: + name: dnf + vars: +-- +2.47.0 + diff --git a/ansible-core.spec b/ansible-core.spec index 708e936..cc3cc9d 100644 --- a/ansible-core.spec +++ b/ansible-core.spec @@ -27,6 +27,11 @@ URL: https://ansible.com Source0: https://github.com/ansible/ansible/archive/v%{uversion}/%{name}-%{uversion}.tar.gz Source1: https://github.com/ansible/ansible-documentation/archive/v%{uversion}/ansible-documentation-%{uversion}.tar.gz +# dnf5,apt: add auto_install_module_deps option (#84292) +# https://github.com/ansible/ansible/pull/84292.patch +# https://bugzilla.redhat.com/2322751 +Patch: 0001-dnf5-apt-add-auto_install_module_deps-option-84292.patch + BuildArch: noarch # Virtual provides for bundled libraries @@ -265,6 +270,7 @@ install -Dpm 0644 licenses/* -t %{buildroot}%{_pkglicensedir} %changelog * Wed Dec 04 2024 Maxwell G - 2.18.1-1 - Update to 2.18.1. Fixes rhbz#2330005. +- dnf5 - backport support for automatically installing python3-libdnf5 (rhbz#2322751). * Tue Nov 26 2024 Maxwell G - 2.18.0-1 - Update to 2.18.0. Fixes rhbz#2282011. From 68783103c49c061c733e58afa726905abfb24973 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 16 Jan 2025 11:08:44 +0000 Subject: [PATCH 05/23] Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild --- ansible-core.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ansible-core.spec b/ansible-core.spec index cc3cc9d..70c24c8 100644 --- a/ansible-core.spec +++ b/ansible-core.spec @@ -15,7 +15,7 @@ Name: ansible-core Version: 2.18.1 %global uversion %{version_no_tilde %{quote:%nil}} -Release: 1%{?dist} +Release: 2%{?dist} Summary: A radically simple IT automation system # The main license is GPLv3+. Many of the files in lib/ansible/module_utils @@ -268,6 +268,9 @@ install -Dpm 0644 licenses/* -t %{buildroot}%{_pkglicensedir} %changelog +* Thu Jan 16 2025 Fedora Release Engineering - 2.18.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + * Wed Dec 04 2024 Maxwell G - 2.18.1-1 - Update to 2.18.1. Fixes rhbz#2330005. - dnf5 - backport support for automatically installing python3-libdnf5 (rhbz#2322751). From 4d318e99ccc2e4535dd5bcabba487d37a9aa3b65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Tue, 11 Mar 2025 11:30:02 +0100 Subject: [PATCH 06/23] No longer BuildRequire python3-crypt-r, it is not used --- ansible-core.spec | 7 ------- 1 file changed, 7 deletions(-) diff --git a/ansible-core.spec b/ansible-core.spec index 70c24c8..e86a0fc 100644 --- a/ansible-core.spec +++ b/ansible-core.spec @@ -67,13 +67,6 @@ BuildRequires: python%{python3_pkgversion}-docutils BuildRequires: git-core BuildRequires: glibc-all-langpacks BuildRequires: python%{python3_pkgversion}-systemd - -%if v"0%{?python3_version}" >= v"3.13" -# Use crypt_r on Python 3.13+ -# https://github.com/ansible/ansible/issues/82758 -# Upstream has removed the dependency on crypt from ansible 2.17+ -BuildRequires: python%{python3_pkgversion}-crypt-r -%endif %endif %if %{with argcomplete} From 67ee763e319e06f3aba3ffa6be818e618f20a46f Mon Sep 17 00:00:00 2001 From: Maxwell G Date: Sun, 16 Mar 2025 20:42:31 -0500 Subject: [PATCH 07/23] packit: add rawhide configuration --- .packit.yaml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .packit.yaml diff --git a/.packit.yaml b/.packit.yaml new file mode 100644 index 0000000..3f9979a --- /dev/null +++ b/.packit.yaml @@ -0,0 +1,23 @@ +# See the documentation for more information: +# https://packit.dev/docs/configuration/ + +upstream_project_url: https://github.com/ansible/ansible +upstream_tag_template: v{version} +issue_repository: https://pagure.io/ansible-packit-issues +jobs: + - job: pull_from_upstream + trigger: release + dist_git_branches: + - rawhide + - job: koji_build + trigger: commit + dist_git_branches: + - rawhide + sidetag_group: "ansible" + dependents: + - ansible + # The update for the sidetag group is created in the ansible package. + # - job: bodhi_update + # trigger: commit + # dist_git_branches: + # - rawhide From 1541de53630d1b3d443a129efe167e5e702c6784 Mon Sep 17 00:00:00 2001 From: Maxwell G Date: Sun, 16 Mar 2025 21:12:15 -0500 Subject: [PATCH 08/23] packit: add upstream_tag_include --- .packit.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.packit.yaml b/.packit.yaml index 3f9979a..398c024 100644 --- a/.packit.yaml +++ b/.packit.yaml @@ -4,6 +4,7 @@ upstream_project_url: https://github.com/ansible/ansible upstream_tag_template: v{version} issue_repository: https://pagure.io/ansible-packit-issues +upstream_tag_include: "v2.18" jobs: - job: pull_from_upstream trigger: release From 4f3593d370c3b604151229860f9d79779464e8b9 Mon Sep 17 00:00:00 2001 From: Packit Date: Mon, 17 Mar 2025 02:13:31 +0000 Subject: [PATCH 09/23] Update to 2.18.3 upstream release - Resolves: rhbz#2342365 Upstream tag: v2.18.3 Upstream commit: b9d76325 Commit authored by Packit automation (https://packit.dev/) --- .gitignore | 2 ++ README.packit | 3 +++ ansible-core.spec | 8 ++++++-- sources | 4 ++-- 4 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 README.packit diff --git a/.gitignore b/.gitignore index fbc245c..f7d23b5 100644 --- a/.gitignore +++ b/.gitignore @@ -73,3 +73,5 @@ /ansible-documentation-2.18.0.tar.gz /ansible-core-2.18.1.tar.gz /ansible-documentation-2.18.1.tar.gz +/ansible-core-2.18.3.tar.gz +/ansible-documentation-2.18.3.tar.gz diff --git a/README.packit b/README.packit new file mode 100644 index 0000000..f5cc99f --- /dev/null +++ b/README.packit @@ -0,0 +1,3 @@ +This repository is maintained by packit. +https://packit.dev/ +The file was generated using packit 1.2.0.post1.dev13+g55ed4527. diff --git a/ansible-core.spec b/ansible-core.spec index e86a0fc..9560d25 100644 --- a/ansible-core.spec +++ b/ansible-core.spec @@ -13,9 +13,9 @@ %undefine _py3_shebang_s Name: ansible-core -Version: 2.18.1 +Version: 2.18.3 %global uversion %{version_no_tilde %{quote:%nil}} -Release: 2%{?dist} +Release: 1%{?dist} Summary: A radically simple IT automation system # The main license is GPLv3+. Many of the files in lib/ansible/module_utils @@ -261,6 +261,10 @@ install -Dpm 0644 licenses/* -t %{buildroot}%{_pkglicensedir} %changelog +* Mon Mar 17 2025 Packit - 2.18.3-1 +- Update to version 2.18.3 +- Resolves: rhbz#2342365 + * Thu Jan 16 2025 Fedora Release Engineering - 2.18.1-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild diff --git a/sources b/sources index 7c3a57a..8980dba 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (ansible-core-2.18.1.tar.gz) = 5358d5f8e9408457c56582a8b9234861bb40f773517408dd66e8f1511a80ffeaaafd4db81cc34ff1bf5ba79e3fb6a3b7fdccc6c5ed8531b41f31b617baecf8ca -SHA512 (ansible-documentation-2.18.1.tar.gz) = 2384beb447ef0ea8ec27331ac8a5f1e0d4247e8ab8a4788c9f8280141d6feb591141a8b7aee60eebf55049d068bcba0128f5edf72d5ef65f8d43ec4e20bae3e3 +SHA512 (ansible-core-2.18.3.tar.gz) = d973b317be7ac0bcfd5982f46afcdde35eb5c60d9ebf3a0b357e7ca905c568d51608b23dc4cb01c3e5c46179d670dc597aa16f80bf1726192f284cbf13e86437 +SHA512 (ansible-documentation-2.18.3.tar.gz) = 18031844a266968de569e8bb71340629cdc82e0d4d6a8aa10cbd0c327dd0a6779e7803ecf531dd7f7b7511c9a5d0f65c917934be755361cdd9783b8dab91fcd7 From e07cd22941331cad2489e70da2cbcd7114ac1b7b Mon Sep 17 00:00:00 2001 From: Maxwell G Date: Sun, 16 Mar 2025 21:26:40 -0500 Subject: [PATCH 10/23] packit: remove sync note --- .packit.yaml | 1 + README.packit | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) delete mode 100644 README.packit diff --git a/.packit.yaml b/.packit.yaml index 398c024..2224bf7 100644 --- a/.packit.yaml +++ b/.packit.yaml @@ -4,6 +4,7 @@ upstream_project_url: https://github.com/ansible/ansible upstream_tag_template: v{version} issue_repository: https://pagure.io/ansible-packit-issues +create_sync_note: false upstream_tag_include: "v2.18" jobs: - job: pull_from_upstream diff --git a/README.packit b/README.packit deleted file mode 100644 index f5cc99f..0000000 --- a/README.packit +++ /dev/null @@ -1,3 +0,0 @@ -This repository is maintained by packit. -https://packit.dev/ -The file was generated using packit 1.2.0.post1.dev13+g55ed4527. From 4393c9cc081cae24e809a8a20be381953122739c Mon Sep 17 00:00:00 2001 From: Packit Date: Tue, 25 Mar 2025 19:05:50 +0000 Subject: [PATCH 11/23] Update to 2.18.4 upstream release - Resolves: rhbz#2354908 Upstream tag: v2.18.4 Upstream commit: 06c507c0 Commit authored by Packit automation (https://packit.dev/) --- .gitignore | 2 ++ ansible-core.spec | 6 +++++- sources | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index f7d23b5..889257f 100644 --- a/.gitignore +++ b/.gitignore @@ -75,3 +75,5 @@ /ansible-documentation-2.18.1.tar.gz /ansible-core-2.18.3.tar.gz /ansible-documentation-2.18.3.tar.gz +/ansible-core-2.18.4.tar.gz +/ansible-documentation-2.18.4.tar.gz diff --git a/ansible-core.spec b/ansible-core.spec index 9560d25..11f0190 100644 --- a/ansible-core.spec +++ b/ansible-core.spec @@ -13,7 +13,7 @@ %undefine _py3_shebang_s Name: ansible-core -Version: 2.18.3 +Version: 2.18.4 %global uversion %{version_no_tilde %{quote:%nil}} Release: 1%{?dist} Summary: A radically simple IT automation system @@ -261,6 +261,10 @@ install -Dpm 0644 licenses/* -t %{buildroot}%{_pkglicensedir} %changelog +* Tue Mar 25 2025 Packit - 2.18.4-1 +- Update to version 2.18.4 +- Resolves: rhbz#2354908 + * Mon Mar 17 2025 Packit - 2.18.3-1 - Update to version 2.18.3 - Resolves: rhbz#2342365 diff --git a/sources b/sources index 8980dba..cf21c16 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (ansible-core-2.18.3.tar.gz) = d973b317be7ac0bcfd5982f46afcdde35eb5c60d9ebf3a0b357e7ca905c568d51608b23dc4cb01c3e5c46179d670dc597aa16f80bf1726192f284cbf13e86437 -SHA512 (ansible-documentation-2.18.3.tar.gz) = 18031844a266968de569e8bb71340629cdc82e0d4d6a8aa10cbd0c327dd0a6779e7803ecf531dd7f7b7511c9a5d0f65c917934be755361cdd9783b8dab91fcd7 +SHA512 (ansible-core-2.18.4.tar.gz) = 2d2e0341557c843ce8fe280e30785ff9871bec0f9072c951131e666cf97a953f38550915efa77d69f9bd0b0a0af02c9c3f42706c389aaa399e40996b249dd1d6 +SHA512 (ansible-documentation-2.18.4.tar.gz) = 2e00e234cacd1728b5209be046c48c24314afba97126ab55fafb6ecdfceab69ab22abfbd0f9391b84588bfedfc790d37b7191ad0ac01971d96456b39cc36f1b7 From 097797b333919f68c60f7b59991ced1dc5c8a125 Mon Sep 17 00:00:00 2001 From: Python Maint Date: Wed, 4 Jun 2025 01:05:51 +0200 Subject: [PATCH 12/23] Rebuilt for Python 3.14 --- ansible-core.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ansible-core.spec b/ansible-core.spec index 11f0190..6f4cc95 100644 --- a/ansible-core.spec +++ b/ansible-core.spec @@ -15,7 +15,7 @@ Name: ansible-core Version: 2.18.4 %global uversion %{version_no_tilde %{quote:%nil}} -Release: 1%{?dist} +Release: 2%{?dist} Summary: A radically simple IT automation system # The main license is GPLv3+. Many of the files in lib/ansible/module_utils @@ -261,6 +261,9 @@ install -Dpm 0644 licenses/* -t %{buildroot}%{_pkglicensedir} %changelog +* Tue Jun 03 2025 Python Maint - 2.18.4-2 +- Rebuilt for Python 3.14 + * Tue Mar 25 2025 Packit - 2.18.4-1 - Update to version 2.18.4 - Resolves: rhbz#2354908 From 2140cacf0d22f25fdc1a49b0ab7cf062a7d482b8 Mon Sep 17 00:00:00 2001 From: Maxwell G Date: Sat, 7 Jun 2025 01:51:20 -0500 Subject: [PATCH 13/23] Update to 2.18.6. Fixes rhbz#2354908. --- .gitignore | 2 ++ ansible-core.spec | 7 +++++-- sources | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 889257f..706d7a3 100644 --- a/.gitignore +++ b/.gitignore @@ -77,3 +77,5 @@ /ansible-documentation-2.18.3.tar.gz /ansible-core-2.18.4.tar.gz /ansible-documentation-2.18.4.tar.gz +/ansible-core-2.18.6.tar.gz +/ansible-documentation-2.18.6.tar.gz diff --git a/ansible-core.spec b/ansible-core.spec index 6f4cc95..4fecca9 100644 --- a/ansible-core.spec +++ b/ansible-core.spec @@ -13,9 +13,9 @@ %undefine _py3_shebang_s Name: ansible-core -Version: 2.18.4 +Version: 2.18.6 %global uversion %{version_no_tilde %{quote:%nil}} -Release: 2%{?dist} +Release: 1%{?dist} Summary: A radically simple IT automation system # The main license is GPLv3+. Many of the files in lib/ansible/module_utils @@ -261,6 +261,9 @@ install -Dpm 0644 licenses/* -t %{buildroot}%{_pkglicensedir} %changelog +* Sat Jun 07 2025 Maxwell G - 2.18.6-1 +- Update to 2.18.6. Fixes rhbz#2354908. + * Tue Jun 03 2025 Python Maint - 2.18.4-2 - Rebuilt for Python 3.14 diff --git a/sources b/sources index cf21c16..22e5d89 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (ansible-core-2.18.4.tar.gz) = 2d2e0341557c843ce8fe280e30785ff9871bec0f9072c951131e666cf97a953f38550915efa77d69f9bd0b0a0af02c9c3f42706c389aaa399e40996b249dd1d6 -SHA512 (ansible-documentation-2.18.4.tar.gz) = 2e00e234cacd1728b5209be046c48c24314afba97126ab55fafb6ecdfceab69ab22abfbd0f9391b84588bfedfc790d37b7191ad0ac01971d96456b39cc36f1b7 +SHA512 (ansible-core-2.18.6.tar.gz) = 1b23cd170ecaf79ce0b7e5260e743912d1a9e7a6ab185527dd65dcb16a2788add2054c8b6ec1a6197190c9910f81d6287493ae17860898de9a70251dff1a77a0 +SHA512 (ansible-documentation-2.18.6.tar.gz) = e0f109aa9c1befe4ce458d942425413a0e7666eef56151b3dfebc1ccc5e67e4710a8df25e368e8a34a004f284ac7f619f72323975801035203a20f7c9d0c5e6e From f0b7fba103b7ac88d2d1804ca82df28817886601 Mon Sep 17 00:00:00 2001 From: Maxwell G Date: Sat, 7 Jun 2025 15:48:37 -0500 Subject: [PATCH 14/23] Add initial support for Python 3.14 (rhbz#2366307) --- 0002-Initial-support-for-Python-3.14.patch | 182 +++++++++++++++++++++ ansible-core.spec | 9 +- 2 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 0002-Initial-support-for-Python-3.14.patch diff --git a/0002-Initial-support-for-Python-3.14.patch b/0002-Initial-support-for-Python-3.14.patch new file mode 100644 index 0000000..8ce96ba --- /dev/null +++ b/0002-Initial-support-for-Python-3.14.patch @@ -0,0 +1,182 @@ +From 5014eb4f248b63085522041d211fabc5c3c47ac1 Mon Sep 17 00:00:00 2001 +From: Maxwell G +Date: Sat, 7 Jun 2025 15:42:53 -0500 +Subject: [PATCH 2/2] Initial support for Python 3.14 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is a downstream Fedora patch to make ansible-core work with Python +3.14 until it is properly supported upstream. +Note that parts of ansible-test will not work properly until we update +to an version that officially supports Python 3.14 due to missing +upstream test infrastructure. + +Co-authored-by: Miro Hrončok +--- + .../_data/requirements/ansible-test.txt | 2 +- + .../ansible_test/_internal/coverage_util.py | 2 +- + .../_util/target/common/constants.py | 1 + + .../module_utils/common/test_collections.py | 6 +- + .../test_check_required_arguments.py | 7 +- + test/units/modules/test_copy.py | 74 ++++++++++--------- + 6 files changed, 54 insertions(+), 38 deletions(-) + +diff --git a/test/lib/ansible_test/_data/requirements/ansible-test.txt b/test/lib/ansible_test/_data/requirements/ansible-test.txt +index 50f951c845..5edd5cc4de 100644 +--- a/test/lib/ansible_test/_data/requirements/ansible-test.txt ++++ b/test/lib/ansible_test/_data/requirements/ansible-test.txt +@@ -1,2 +1,2 @@ + # The test-constraints sanity test verifies this file, but changes must be made manually to keep it in up-to-date. +-coverage == 7.6.1 ; python_version >= '3.8' and python_version <= '3.13' ++coverage == 7.6.1 ; python_version >= '3.8' and python_version <= '3.14' +diff --git a/test/lib/ansible_test/_internal/coverage_util.py b/test/lib/ansible_test/_internal/coverage_util.py +index 2bec9c791e..e900ddb801 100644 +--- a/test/lib/ansible_test/_internal/coverage_util.py ++++ b/test/lib/ansible_test/_internal/coverage_util.py +@@ -69,7 +69,7 @@ class CoverageVersion: + + COVERAGE_VERSIONS = ( + # IMPORTANT: Keep this in sync with the ansible-test.txt requirements file. +- CoverageVersion('7.6.1', 7, (3, 8), (3, 13)), ++ CoverageVersion('7.6.1', 7, (3, 8), (3, 14)), + ) + """ + This tuple specifies the coverage version to use for Python version ranges. +diff --git a/test/lib/ansible_test/_util/target/common/constants.py b/test/lib/ansible_test/_util/target/common/constants.py +index 31f56adcda..4e4055462d 100644 +--- a/test/lib/ansible_test/_util/target/common/constants.py ++++ b/test/lib/ansible_test/_util/target/common/constants.py +@@ -14,4 +14,5 @@ CONTROLLER_PYTHON_VERSIONS = ( + '3.11', + '3.12', + '3.13', ++ '3.14', + ) +diff --git a/test/units/module_utils/common/test_collections.py b/test/units/module_utils/common/test_collections.py +index 381d583004..78d7d19dde 100644 +--- a/test/units/module_utils/common/test_collections.py ++++ b/test/units/module_utils/common/test_collections.py +@@ -5,6 +5,8 @@ + + from __future__ import annotations + ++import re ++ + import pytest + + from collections.abc import Sequence +@@ -143,7 +145,9 @@ class TestImmutableDict: + # ImmutableDict is unhashable when one of its values is unhashable + imdict = ImmutableDict({u'café': u'くらとみ', 1: [1, 2]}) + +- expected_reason = r"^unhashable type: 'list'$" ++ python314_reason = re.escape("cannot use 'tuple' as a set element (unhashable type: 'list')") ++ expected_reasons = (r"^unhashable type: 'list'$", rf"^{python314_reason}$") ++ expected_reason = "|".join(expected_reasons) + + with pytest.raises(TypeError, match=expected_reason): + hash(imdict) +diff --git a/test/units/module_utils/common/validation/test_check_required_arguments.py b/test/units/module_utils/common/validation/test_check_required_arguments.py +index 16e79fe7dc..761cd0acd1 100644 +--- a/test/units/module_utils/common/validation/test_check_required_arguments.py ++++ b/test/units/module_utils/common/validation/test_check_required_arguments.py +@@ -84,4 +84,9 @@ def test_check_required_arguments_missing_none(): + def test_check_required_arguments_no_params(arguments_terms): + with pytest.raises(TypeError) as te: + check_required_arguments(arguments_terms, None) +- assert "'NoneType' is not iterable" in to_native(te.value) ++ value = to_native(te.value) ++ options = ( ++ "'NoneType' is not iterable", # Python < 3.14 ++ "argument of type 'NoneType' is not a container or iterable" # 3.14+ ++ ) ++ assert any(o in value for o in options) +diff --git a/test/units/modules/test_copy.py b/test/units/modules/test_copy.py +index 6f15bed122..799ba4b52f 100644 +--- a/test/units/modules/test_copy.py ++++ b/test/units/modules/test_copy.py +@@ -95,40 +95,46 @@ ONE_DIR_DATA: tuple[tuple[str, tuple[str, list[str]] | None, tuple[str, list[str + ONE_DIR_DATA += tuple(item[:3] for item in TWO_DIRS_DATA) + + +-@pytest.mark.parametrize('directory, expected', ((d[0], d[4]) for d in THREE_DIRS_DATA)) +-@pytest.mark.xfail(reason='broken test and/or code, original test missing assert', strict=False) +-def test_split_pre_existing_dir_three_levels_exist(directory, expected, mocker): +- mocker.patch('os.path.exists', side_effect=[True, True, True]) +- assert split_pre_existing_dir(directory) == expected +- +- +-@pytest.mark.parametrize('directory, expected', ((d[0], d[3]) for d in TWO_DIRS_DATA)) +-@pytest.mark.xfail(reason='broken test and/or code, original test missing assert', strict=False) +-def test_split_pre_existing_dir_two_levels_exist(directory, expected, mocker): +- mocker.patch('os.path.exists', side_effect=[True, True, False]) +- assert split_pre_existing_dir(directory) == expected +- +- +-@pytest.mark.parametrize('directory, expected', ((d[0], d[2]) for d in ONE_DIR_DATA)) +-@pytest.mark.xfail(reason='broken test and/or code, original test missing assert', strict=False) +-def test_split_pre_existing_dir_one_level_exists(directory, expected, mocker): +- mocker.patch('os.path.exists', side_effect=[True, False, False]) +- assert split_pre_existing_dir(directory) == expected +- +- +-@pytest.mark.parametrize('directory', (d[0] for d in ONE_DIR_DATA if d[1] is None)) +-def test_split_pre_existing_dir_root_does_not_exist(directory, mocker): +- mocker.patch('os.path.exists', return_value=False) +- with pytest.raises(AnsibleModuleError) as excinfo: +- split_pre_existing_dir(directory) +- assert excinfo.value.results['msg'].startswith("The '/' directory doesn't exist on this machine.") +- +- +-@pytest.mark.parametrize('directory, expected', ((d[0], d[1]) for d in ONE_DIR_DATA if not d[0].startswith('/'))) +-@pytest.mark.xfail(reason='broken test and/or code, original test missing assert', strict=False) +-def test_split_pre_existing_dir_working_dir_exists(directory, expected, mocker): +- mocker.patch('os.path.exists', return_value=False) +- assert split_pre_existing_dir(directory) == expected ++# NOTE(gotmax23): These tests are all broken (marked with xfail) to begin with. ++# On Python 3.14, they also cause pytest to crash, as the os.path.exists patch ++# does not get cleaned up in time for some reason and other internal pytest ++# code calls the mock instead of the actual function. ++# Comment them out for now. ++ ++# @pytest.mark.parametrize('directory, expected', ((d[0], d[4]) for d in THREE_DIRS_DATA)) ++# @pytest.mark.xfail(reason='broken test and/or code, original test missing assert', strict=False) ++# def test_split_pre_existing_dir_three_levels_exist(directory, expected, mocker): ++# mocker.patch('os.path.exists', side_effect=[True, True, True]) ++# assert split_pre_existing_dir(directory) == expected ++# ++# ++# @pytest.mark.parametrize('directory, expected', ((d[0], d[3]) for d in TWO_DIRS_DATA)) ++# @pytest.mark.xfail(reason='broken test and/or code, original test missing assert', strict=False) ++# def test_split_pre_existing_dir_two_levels_exist(directory, expected, mocker): ++# mocker.patch('os.path.exists', side_effect=[True, True, False]) ++# assert split_pre_existing_dir(directory) == expected ++# ++# ++# @pytest.mark.parametrize('directory, expected', ((d[0], d[2]) for d in ONE_DIR_DATA)) ++# @pytest.mark.xfail(reason='broken test and/or code, original test missing assert', strict=False) ++# def test_split_pre_existing_dir_one_level_exists(directory, expected, mocker): ++# mocker.patch('os.path.exists', side_effect=[True, False, False]) ++# assert split_pre_existing_dir(directory) == expected ++# ++# ++# @pytest.mark.parametrize('directory', (d[0] for d in ONE_DIR_DATA if d[1] is None)) ++# def test_split_pre_existing_dir_root_does_not_exist(directory, mocker): ++# mocker.patch('os.path.exists', return_value=False) ++# with pytest.raises(AnsibleModuleError) as excinfo: ++# split_pre_existing_dir(directory) ++# assert excinfo.value.results['msg'].startswith("The '/' directory doesn't exist on this machine.") ++# ++# ++# @pytest.mark.parametrize('directory, expected', ((d[0], d[1]) for d in ONE_DIR_DATA if not d[0].startswith('/'))) ++# @pytest.mark.xfail(reason='broken test and/or code, original test missing assert', strict=False) ++# def test_split_pre_existing_dir_working_dir_exists(directory, expected, mocker): ++# mocker.patch('os.path.exists', return_value=False) ++# assert split_pre_existing_dir(directory) == expected + + + # +-- +2.49.0 + diff --git a/ansible-core.spec b/ansible-core.spec index 4fecca9..11ed82d 100644 --- a/ansible-core.spec +++ b/ansible-core.spec @@ -15,7 +15,7 @@ Name: ansible-core Version: 2.18.6 %global uversion %{version_no_tilde %{quote:%nil}} -Release: 1%{?dist} +Release: 2%{?dist} Summary: A radically simple IT automation system # The main license is GPLv3+. Many of the files in lib/ansible/module_utils @@ -31,6 +31,10 @@ Source1: https://github.com/ansible/ansible-documentation/archive/v%{uver # https://github.com/ansible/ansible/pull/84292.patch # https://bugzilla.redhat.com/2322751 Patch: 0001-dnf5-apt-add-auto_install_module_deps-option-84292.patch +# Initial support for Python 3.14 +# Downstream patch. See comments in patch file. +# https://bugzilla.redhat.com/2366307 +Patch: 0002-Initial-support-for-Python-3.14.patch BuildArch: noarch @@ -261,6 +265,9 @@ install -Dpm 0644 licenses/* -t %{buildroot}%{_pkglicensedir} %changelog +* Sat Jun 07 2025 Maxwell G - 2.18.6-2 +- Add initial support for Python 3.14 (rhbz#2366307) + * Sat Jun 07 2025 Maxwell G - 2.18.6-1 - Update to 2.18.6. Fixes rhbz#2354908. From 46821bd2bf0493b4e5fe173abb4d68c61b15d9a9 Mon Sep 17 00:00:00 2001 From: Maxwell G Date: Wed, 16 Jul 2025 14:06:12 -0500 Subject: [PATCH 15/23] Update to 2.18.7. Fixes rhbz#2380244. --- .gitignore | 2 ++ ...uto_install_module_deps-option-84292.patch | 32 +++++++++---------- 0002-Initial-support-for-Python-3.14.patch | 4 +-- ansible-core.spec | 7 ++-- sources | 4 +-- 5 files changed, 27 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index 706d7a3..6b50dca 100644 --- a/.gitignore +++ b/.gitignore @@ -79,3 +79,5 @@ /ansible-documentation-2.18.4.tar.gz /ansible-core-2.18.6.tar.gz /ansible-documentation-2.18.6.tar.gz +/ansible-core-2.18.7.tar.gz +/ansible-documentation-2.18.7.tar.gz diff --git a/0001-dnf5-apt-add-auto_install_module_deps-option-84292.patch b/0001-dnf5-apt-add-auto_install_module_deps-option-84292.patch index 826e39b..340012a 100644 --- a/0001-dnf5-apt-add-auto_install_module_deps-option-84292.patch +++ b/0001-dnf5-apt-add-auto_install_module_deps-option-84292.patch @@ -1,7 +1,7 @@ -From e951ca7cc9fa55a626239ed88f3afb7cd67d1fcc Mon Sep 17 00:00:00 2001 +From 9c9f20128efdf041a093f0de37fc316c6ec18b66 Mon Sep 17 00:00:00 2001 From: Martin Krizek Date: Thu, 21 Nov 2024 17:06:18 +0100 -Subject: [PATCH] dnf5,apt: add auto_install_module_deps option (#84292) +Subject: [PATCH 1/2] dnf5,apt: add auto_install_module_deps option (#84292) * dnf5,apt: add auto_install_module_deps option @@ -14,7 +14,7 @@ Fixes #84206 lib/ansible/modules/dnf5.py | 52 ++++++++--- test/integration/targets/apt/tasks/apt.yml | 28 ++++-- test/integration/targets/dnf5/playbook.yml | 21 ++++- - 5 files changed, 132 insertions(+), 61 deletions(-) + 5 files changed, 133 insertions(+), 60 deletions(-) create mode 100644 changelogs/fragments/84206-dnf5-apt-auto-install-module-deps.yml diff --git a/changelogs/fragments/84206-dnf5-apt-auto-install-module-deps.yml b/changelogs/fragments/84206-dnf5-apt-auto-install-module-deps.yml @@ -162,7 +162,7 @@ index 70a2a07cc0..c18bd36fe4 100644 if p['clean'] is True: aptclean_stdout, aptclean_stderr, aptclean_diff = aptclean(module) diff --git a/lib/ansible/modules/dnf5.py b/lib/ansible/modules/dnf5.py -index 0e429d3a43..2eef580933 100644 +index 24ae91432b..a0e4a4ef5a 100644 --- a/lib/ansible/modules/dnf5.py +++ b/lib/ansible/modules/dnf5.py @@ -14,6 +14,12 @@ description: @@ -189,7 +189,7 @@ index 0e429d3a43..2eef580933 100644 version_added: 2.15 """ -@@ -460,6 +470,8 @@ def get_unneeded_pkgs(base): +@@ -474,6 +484,8 @@ def get_unneeded_pkgs(base): class Dnf5Module(YumDnf): def __init__(self, module): super(Dnf5Module, self).__init__(module) @@ -198,7 +198,7 @@ index 0e429d3a43..2eef580933 100644 self._ensure_dnf() self.pkg_mgr_name = "dnf5" -@@ -509,21 +521,30 @@ class Dnf5Module(YumDnf): +@@ -530,21 +542,30 @@ class Dnf5Module(YumDnf): ] if not has_respawned(): @@ -242,7 +242,7 @@ index 0e429d3a43..2eef580933 100644 failures=[], ) -@@ -780,6 +801,11 @@ class Dnf5Module(YumDnf): +@@ -795,6 +816,11 @@ class Dnf5Module(YumDnf): def main(): @@ -251,9 +251,9 @@ index 0e429d3a43..2eef580933 100644 + auto_install_module_deps=dict(type="bool", default=True), + ) + ) - Dnf5Module(AnsibleModule(**yumdnf_argument_spec)).run() - - + module = AnsibleModule(**yumdnf_argument_spec) + try: + Dnf5Module(module).run() diff --git a/test/integration/targets/apt/tasks/apt.yml b/test/integration/targets/apt/tasks/apt.yml index 64e00d3ca9..dda5fc1fab 100644 --- a/test/integration/targets/apt/tasks/apt.yml @@ -311,15 +311,15 @@ index 64e00d3ca9..dda5fc1fab 100644 # With 'python-apt' uninstalled, the first call to 'apt' should install # python-apt without updating the cache. diff --git a/test/integration/targets/dnf5/playbook.yml b/test/integration/targets/dnf5/playbook.yml -index a1024f4b3d..a36c17a202 100644 +index d9a79ced7e..a36c17a202 100644 --- a/test/integration/targets/dnf5/playbook.yml +++ b/test/integration/targets/dnf5/playbook.yml -@@ -2,9 +2,26 @@ +@@ -1,8 +1,27 @@ + - hosts: localhost tasks: - block: - - command: "dnf install -y 'dnf-command(copr)'" -- - command: dnf copr enable -y rpmsoftwaremanagement/dnf-nightly -- - command: dnf install -y -x condor python3-libdnf5 +- - command: dnf install -y python3-libdnf5 ++ - command: "dnf install -y 'dnf-command(copr)'" + - name: Test against dnf5 nightly build to detect any issues early + command: dnf copr enable -y rpmsoftwaremanagement/dnf-nightly @@ -344,5 +344,5 @@ index a1024f4b3d..a36c17a202 100644 name: dnf vars: -- -2.47.0 +2.50.1 diff --git a/0002-Initial-support-for-Python-3.14.patch b/0002-Initial-support-for-Python-3.14.patch index 8ce96ba..8b71591 100644 --- a/0002-Initial-support-for-Python-3.14.patch +++ b/0002-Initial-support-for-Python-3.14.patch @@ -1,4 +1,4 @@ -From 5014eb4f248b63085522041d211fabc5c3c47ac1 Mon Sep 17 00:00:00 2001 +From 36c1e6ff0d889cef5c57af64d4f6fc08b455bada Mon Sep 17 00:00:00 2001 From: Maxwell G Date: Sat, 7 Jun 2025 15:42:53 -0500 Subject: [PATCH 2/2] Initial support for Python 3.14 @@ -178,5 +178,5 @@ index 6f15bed122..799ba4b52f 100644 # -- -2.49.0 +2.50.1 diff --git a/ansible-core.spec b/ansible-core.spec index 11ed82d..41bcc07 100644 --- a/ansible-core.spec +++ b/ansible-core.spec @@ -13,9 +13,9 @@ %undefine _py3_shebang_s Name: ansible-core -Version: 2.18.6 +Version: 2.18.7 %global uversion %{version_no_tilde %{quote:%nil}} -Release: 2%{?dist} +Release: 1%{?dist} Summary: A radically simple IT automation system # The main license is GPLv3+. Many of the files in lib/ansible/module_utils @@ -265,6 +265,9 @@ install -Dpm 0644 licenses/* -t %{buildroot}%{_pkglicensedir} %changelog +* Wed Jul 16 2025 Maxwell G - 2.18.7-1 +- Update to 2.18.7. Fixes rhbz#2380244. + * Sat Jun 07 2025 Maxwell G - 2.18.6-2 - Add initial support for Python 3.14 (rhbz#2366307) diff --git a/sources b/sources index 22e5d89..0aa4c9a 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (ansible-core-2.18.6.tar.gz) = 1b23cd170ecaf79ce0b7e5260e743912d1a9e7a6ab185527dd65dcb16a2788add2054c8b6ec1a6197190c9910f81d6287493ae17860898de9a70251dff1a77a0 -SHA512 (ansible-documentation-2.18.6.tar.gz) = e0f109aa9c1befe4ce458d942425413a0e7666eef56151b3dfebc1ccc5e67e4710a8df25e368e8a34a004f284ac7f619f72323975801035203a20f7c9d0c5e6e +SHA512 (ansible-core-2.18.7.tar.gz) = 577e6939d4ad309209c6d2d683695d288ece26034aeadfa7cbd4c461795482373b79f4f6255390d50fc782015460a22207b9fd5c65daf664492acb3055169631 +SHA512 (ansible-documentation-2.18.7.tar.gz) = ab813cd31e541bfa9738f7b75a83f0f59d7bd4b08d3fed2da1be919284ab83c998747a76dfeda1d98906436b63101486f7f41f1a55bb19d3b047c57cf0ff7e5c From 24d3ca7b59e3c57ff26856ca01860e24657ab1a6 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 23 Jul 2025 17:02:18 +0000 Subject: [PATCH 16/23] Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild --- ansible-core.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ansible-core.spec b/ansible-core.spec index 41bcc07..70a77ee 100644 --- a/ansible-core.spec +++ b/ansible-core.spec @@ -15,7 +15,7 @@ Name: ansible-core Version: 2.18.7 %global uversion %{version_no_tilde %{quote:%nil}} -Release: 1%{?dist} +Release: 2%{?dist} Summary: A radically simple IT automation system # The main license is GPLv3+. Many of the files in lib/ansible/module_utils @@ -265,6 +265,9 @@ install -Dpm 0644 licenses/* -t %{buildroot}%{_pkglicensedir} %changelog +* Wed Jul 23 2025 Fedora Release Engineering - 2.18.7-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + * Wed Jul 16 2025 Maxwell G - 2.18.7-1 - Update to 2.18.7. Fixes rhbz#2380244. From d1ce53157f956d495b7f38b9648b45f129f8dc80 Mon Sep 17 00:00:00 2001 From: Python Maint Date: Fri, 15 Aug 2025 12:38:08 +0200 Subject: [PATCH 17/23] Rebuilt for Python 3.14.0rc2 bytecode --- ansible-core.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ansible-core.spec b/ansible-core.spec index 70a77ee..d8cacfd 100644 --- a/ansible-core.spec +++ b/ansible-core.spec @@ -15,7 +15,7 @@ Name: ansible-core Version: 2.18.7 %global uversion %{version_no_tilde %{quote:%nil}} -Release: 2%{?dist} +Release: 3%{?dist} Summary: A radically simple IT automation system # The main license is GPLv3+. Many of the files in lib/ansible/module_utils @@ -265,6 +265,9 @@ install -Dpm 0644 licenses/* -t %{buildroot}%{_pkglicensedir} %changelog +* Fri Aug 15 2025 Python Maint - 2.18.7-3 +- Rebuilt for Python 3.14.0rc2 bytecode + * Wed Jul 23 2025 Fedora Release Engineering - 2.18.7-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild From 8919faacd55c8adcaf32897148f09905ab1a70fd Mon Sep 17 00:00:00 2001 From: Python Maint Date: Fri, 19 Sep 2025 12:06:55 +0200 Subject: [PATCH 18/23] Rebuilt for Python 3.14.0rc3 bytecode --- ansible-core.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ansible-core.spec b/ansible-core.spec index d8cacfd..6e4a1b5 100644 --- a/ansible-core.spec +++ b/ansible-core.spec @@ -15,7 +15,7 @@ Name: ansible-core Version: 2.18.7 %global uversion %{version_no_tilde %{quote:%nil}} -Release: 3%{?dist} +Release: 4%{?dist} Summary: A radically simple IT automation system # The main license is GPLv3+. Many of the files in lib/ansible/module_utils @@ -265,6 +265,9 @@ install -Dpm 0644 licenses/* -t %{buildroot}%{_pkglicensedir} %changelog +* Fri Sep 19 2025 Python Maint - 2.18.7-4 +- Rebuilt for Python 3.14.0rc3 bytecode + * Fri Aug 15 2025 Python Maint - 2.18.7-3 - Rebuilt for Python 3.14.0rc2 bytecode From 38bca2f841ffefa078d3b156c0b4c2d6d6526ece Mon Sep 17 00:00:00 2001 From: Maxwell G Date: Sat, 27 Sep 2025 02:13:26 -0500 Subject: [PATCH 19/23] Update to 2.18.9. --- .gitignore | 2 ++ ansible-core.spec | 7 +++++-- sources | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 6b50dca..c7e0097 100644 --- a/.gitignore +++ b/.gitignore @@ -81,3 +81,5 @@ /ansible-documentation-2.18.6.tar.gz /ansible-core-2.18.7.tar.gz /ansible-documentation-2.18.7.tar.gz +/ansible-core-2.18.9.tar.gz +/ansible-documentation-2.18.9.tar.gz diff --git a/ansible-core.spec b/ansible-core.spec index 6e4a1b5..0667e63 100644 --- a/ansible-core.spec +++ b/ansible-core.spec @@ -13,9 +13,9 @@ %undefine _py3_shebang_s Name: ansible-core -Version: 2.18.7 +Version: 2.18.9 %global uversion %{version_no_tilde %{quote:%nil}} -Release: 4%{?dist} +Release: 1%{?dist} Summary: A radically simple IT automation system # The main license is GPLv3+. Many of the files in lib/ansible/module_utils @@ -265,6 +265,9 @@ install -Dpm 0644 licenses/* -t %{buildroot}%{_pkglicensedir} %changelog +* Sat Sep 27 2025 Maxwell G - 2.18.9-1 +- Update to 2.18.9. + * Fri Sep 19 2025 Python Maint - 2.18.7-4 - Rebuilt for Python 3.14.0rc3 bytecode diff --git a/sources b/sources index 0aa4c9a..afbdc19 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (ansible-core-2.18.7.tar.gz) = 577e6939d4ad309209c6d2d683695d288ece26034aeadfa7cbd4c461795482373b79f4f6255390d50fc782015460a22207b9fd5c65daf664492acb3055169631 -SHA512 (ansible-documentation-2.18.7.tar.gz) = ab813cd31e541bfa9738f7b75a83f0f59d7bd4b08d3fed2da1be919284ab83c998747a76dfeda1d98906436b63101486f7f41f1a55bb19d3b047c57cf0ff7e5c +SHA512 (ansible-core-2.18.9.tar.gz) = 7d670c6427f7a7d157e8e5f866371da4c6a0061f1169a9086aec9c8350efd2d3769744cf791a5a1901f3d4ae49823fc99d4d1696938f99c417666a453ece8496 +SHA512 (ansible-documentation-2.18.9.tar.gz) = a56c61a900c92ac88bb346fc2abb133b3b48eae4a57812128f1ad6f9b5906a7edee822519cee8a41314b2273b3ed027698e0d0a1f6a24417fc5201e20844d088 From bbb03c2bb1fcfff0292c5c41f7e973e4aa760d0c Mon Sep 17 00:00:00 2001 From: Packit Date: Mon, 17 Nov 2025 14:59:11 +0000 Subject: [PATCH 20/23] Update to 2.18.11 upstream release Upstream tag: v2.18.11 Upstream commit: 932dc80f Commit authored by Packit automation (https://packit.dev/) --- .gitignore | 2 ++ ansible-core.spec | 5 ++++- sources | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index c7e0097..bcabcc8 100644 --- a/.gitignore +++ b/.gitignore @@ -83,3 +83,5 @@ /ansible-documentation-2.18.7.tar.gz /ansible-core-2.18.9.tar.gz /ansible-documentation-2.18.9.tar.gz +/ansible-core-2.18.11.tar.gz +/ansible-documentation-2.18.11.tar.gz diff --git a/ansible-core.spec b/ansible-core.spec index 0667e63..1a9154d 100644 --- a/ansible-core.spec +++ b/ansible-core.spec @@ -13,7 +13,7 @@ %undefine _py3_shebang_s Name: ansible-core -Version: 2.18.9 +Version: 2.18.11 %global uversion %{version_no_tilde %{quote:%nil}} Release: 1%{?dist} Summary: A radically simple IT automation system @@ -265,6 +265,9 @@ install -Dpm 0644 licenses/* -t %{buildroot}%{_pkglicensedir} %changelog +* Mon Nov 17 2025 Packit - 2.18.11-1 +- Update to version 2.18.11 + * Sat Sep 27 2025 Maxwell G - 2.18.9-1 - Update to 2.18.9. diff --git a/sources b/sources index afbdc19..0dc6e1e 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (ansible-core-2.18.9.tar.gz) = 7d670c6427f7a7d157e8e5f866371da4c6a0061f1169a9086aec9c8350efd2d3769744cf791a5a1901f3d4ae49823fc99d4d1696938f99c417666a453ece8496 -SHA512 (ansible-documentation-2.18.9.tar.gz) = a56c61a900c92ac88bb346fc2abb133b3b48eae4a57812128f1ad6f9b5906a7edee822519cee8a41314b2273b3ed027698e0d0a1f6a24417fc5201e20844d088 +SHA512 (ansible-core-2.18.11.tar.gz) = 18302562c449634d9114ec0c113cad3b19866b35e1aec1ccb82ed1bfaa34496a8bccf548a7596d7ab5a989ac985e34a8a796b624f5216f63f3877d6e11edff5b +SHA512 (ansible-documentation-2.18.11.tar.gz) = d1144b427b57c466db402ec1fb5b3e6cf80710e059c7d4a22e26360eaa7303b8ff4a937b3d233fc04cd9092ef1adbd28d456a2deedb281c239de8c5dd9f7a091 From b1149c15f6afd5b815cc47563ccdc7e8449d91f0 Mon Sep 17 00:00:00 2001 From: Maxwell G Date: Mon, 17 Nov 2025 08:55:22 -0600 Subject: [PATCH 21/23] packit: update stable branches --- .packit.yaml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.packit.yaml b/.packit.yaml index 2224bf7..118fa81 100644 --- a/.packit.yaml +++ b/.packit.yaml @@ -5,16 +5,21 @@ upstream_project_url: https://github.com/ansible/ansible upstream_tag_template: v{version} issue_repository: https://pagure.io/ansible-packit-issues create_sync_note: false +# TODO: Remove pending https://fedoraproject.org/wiki/Changes/Ansible13 upstream_tag_include: "v2.18" jobs: - job: pull_from_upstream trigger: release dist_git_branches: - - rawhide + # Fast forward merge rawhide while it is held at v2.18. + rawhide: + fast_forward_merge_into: + - fedora-43 + - fedora-42 - job: koji_build trigger: commit dist_git_branches: - - rawhide + - fedora-all sidetag_group: "ansible" dependents: - ansible From 0d8611fc1bb8657a22a1d71554873405ff706c7f Mon Sep 17 00:00:00 2001 From: Maxwell G Date: Tue, 9 Dec 2025 12:23:51 -0600 Subject: [PATCH 22/23] Update to 2.20.1. Fixes rhbz#2382388. - Update bundled() Provides - Update License to GPL-3.0-or-later AND BSD-2-Clause AND BSD-3-Clause AND PSF-2.0 AND MIT AND Apache-2.0 - Remove upstreamed patches - Remove old Provides and Obsoletes for ansible-base and Ansible <= 2.9 --- .gitignore | 2 + ...uto_install_module_deps-option-84292.patch | 348 ------------------ 0002-Initial-support-for-Python-3.14.patch | 182 --------- ansible-core.spec | 35 +- sources | 4 +- 5 files changed, 19 insertions(+), 552 deletions(-) delete mode 100644 0001-dnf5-apt-add-auto_install_module_deps-option-84292.patch delete mode 100644 0002-Initial-support-for-Python-3.14.patch diff --git a/.gitignore b/.gitignore index bcabcc8..9594499 100644 --- a/.gitignore +++ b/.gitignore @@ -85,3 +85,5 @@ /ansible-documentation-2.18.9.tar.gz /ansible-core-2.18.11.tar.gz /ansible-documentation-2.18.11.tar.gz +/ansible-core-2.20.1.tar.gz +/ansible-documentation-2.20.1.tar.gz diff --git a/0001-dnf5-apt-add-auto_install_module_deps-option-84292.patch b/0001-dnf5-apt-add-auto_install_module_deps-option-84292.patch deleted file mode 100644 index 340012a..0000000 --- a/0001-dnf5-apt-add-auto_install_module_deps-option-84292.patch +++ /dev/null @@ -1,348 +0,0 @@ -From 9c9f20128efdf041a093f0de37fc316c6ec18b66 Mon Sep 17 00:00:00 2001 -From: Martin Krizek -Date: Thu, 21 Nov 2024 17:06:18 +0100 -Subject: [PATCH 1/2] dnf5,apt: add auto_install_module_deps option (#84292) - -* dnf5,apt: add auto_install_module_deps option - -Fixes #84206 - -(cherry picked from commit 2a53b851fee8ebaa07c1341122dd905354659237) ---- - ...4206-dnf5-apt-auto-install-module-deps.yml | 2 + - lib/ansible/modules/apt.py | 90 +++++++++++-------- - lib/ansible/modules/dnf5.py | 52 ++++++++--- - test/integration/targets/apt/tasks/apt.yml | 28 ++++-- - test/integration/targets/dnf5/playbook.yml | 21 ++++- - 5 files changed, 133 insertions(+), 60 deletions(-) - create mode 100644 changelogs/fragments/84206-dnf5-apt-auto-install-module-deps.yml - -diff --git a/changelogs/fragments/84206-dnf5-apt-auto-install-module-deps.yml b/changelogs/fragments/84206-dnf5-apt-auto-install-module-deps.yml -new file mode 100644 -index 0000000000..14d595449c ---- /dev/null -+++ b/changelogs/fragments/84206-dnf5-apt-auto-install-module-deps.yml -@@ -0,0 +1,2 @@ -+minor_changes: -+ - dnf5, apt - add ``auto_install_module_deps`` option (https://github.com/ansible/ansible/issues/84206) -diff --git a/lib/ansible/modules/apt.py b/lib/ansible/modules/apt.py -index 70a2a07cc0..c18bd36fe4 100644 ---- a/lib/ansible/modules/apt.py -+++ b/lib/ansible/modules/apt.py -@@ -17,6 +17,12 @@ description: - - Manages I(apt) packages (such as for Debian/Ubuntu). - version_added: "0.0.2" - options: -+ auto_install_module_deps: -+ description: -+ - Automatically install dependencies required to run this module. -+ type: bool -+ default: yes -+ version_added: 2.19 - name: - description: - - A list of package names, like V(foo), or package specifier with version, like V(foo=1.0) or V(foo>=1.0). -@@ -191,8 +197,7 @@ options: - default: 60 - version_added: "2.12" - requirements: -- - python-apt (python 2) -- - python3-apt (python 3) -+ - python3-apt - - aptitude (before 2.4) - author: "Matthew Williams (@mgwilliams)" - extends_documentation_fragment: action_common_attributes -@@ -214,8 +219,8 @@ notes: - - When used with a C(loop:) each package will be processed individually, it is much more efficient to pass the list directly to the O(name) option. - - When O(default_release) is used, an implicit priority of 990 is used. This is the same behavior as C(apt-get -t). - - When an exact version is specified, an implicit priority of 1001 is used. -- - If the interpreter can't import C(python-apt)/C(python3-apt) the module will check for it in system-owned interpreters as well. -- If the dependency can't be found, the module will attempt to install it. -+ - If the interpreter can't import C(python3-apt) the module will check for it in system-owned interpreters as well. -+ If the dependency can't be found, depending on the value of O(auto_install_module_deps) the module will attempt to install it. - If the dependency is found or installed, the module will be respawned under the correct interpreter. - ''' - -@@ -1233,6 +1238,7 @@ def main(): - allow_downgrade=dict(type='bool', default=False, aliases=['allow-downgrade', 'allow_downgrades', 'allow-downgrades']), - allow_change_held_packages=dict(type='bool', default=False), - lock_timeout=dict(type='int', default=60), -+ auto_install_module_deps=dict(type='bool', default=True), - ), - mutually_exclusive=[['deb', 'package', 'upgrade']], - required_one_of=[['autoremove', 'deb', 'package', 'update_cache', 'upgrade']], -@@ -1268,7 +1274,7 @@ def main(): - if not HAS_PYTHON_APT: - # This interpreter can't see the apt Python library- we'll do the following to try and fix that: - # 1) look in common locations for system-owned interpreters that can see it; if we find one, respawn under it -- # 2) finding none, try to install a matching python-apt package for the current interpreter version; -+ # 2) finding none, try to install a matching python3-apt package for the current interpreter version; - # we limit to the current interpreter version to try and avoid installing a whole other Python just - # for apt support - # 3) if we installed a support package, try to respawn under what we think is the right interpreter (could be -@@ -1294,39 +1300,47 @@ def main(): - - # don't make changes if we're in check_mode - if module.check_mode: -- module.fail_json(msg="%s must be installed to use check mode. " -- "If run normally this module can auto-install it." % apt_pkg_name) -- -- # We skip cache update in auto install the dependency if the -- # user explicitly declared it with update_cache=no. -- if module.params.get('update_cache') is False: -- module.warn("Auto-installing missing dependency without updating cache: %s" % apt_pkg_name) -- else: -- module.warn("Updating cache and auto-installing missing dependency: %s" % apt_pkg_name) -- module.run_command([APT_GET_CMD, 'update'], check_rc=True) -- -- # try to install the apt Python binding -- apt_pkg_cmd = [APT_GET_CMD, 'install', apt_pkg_name, '-y', '-q', dpkg_options] -- -- if install_recommends is False: -- apt_pkg_cmd.extend(["-o", "APT::Install-Recommends=no"]) -- elif install_recommends is True: -- apt_pkg_cmd.extend(["-o", "APT::Install-Recommends=yes"]) -- # install_recommends is None uses the OS default -- -- module.run_command(apt_pkg_cmd, check_rc=True) -- -- # try again to find the bindings in common places -- interpreter = probe_interpreters_for_module(interpreters, 'apt') -- -- if interpreter: -- # found the Python bindings; respawn this module under the interpreter where we found them -- # NB: respawn is somewhat wasteful if it's this interpreter, but simplifies the code -- respawn_module(interpreter) -- # this is the end of the line for this process, it will exit here once the respawned module has completed -- else: -- # we've done all we can do; just tell the user it's busted and get out -- module.fail_json(msg="{0} must be installed and visible from {1}.".format(apt_pkg_name, sys.executable)) -+ module.fail_json( -+ msg=f"{apt_pkg_name} must be installed to use check mode. " -+ "If run normally this module can auto-install it, " -+ "see the auto_install_module_deps option.", -+ ) -+ elif p['auto_install_module_deps']: -+ # We skip cache update in auto install the dependency if the -+ # user explicitly declared it with update_cache=no. -+ if module.params.get('update_cache') is False: -+ module.warn("Auto-installing missing dependency without updating cache: %s" % apt_pkg_name) -+ else: -+ module.warn("Updating cache and auto-installing missing dependency: %s" % apt_pkg_name) -+ module.run_command([APT_GET_CMD, 'update'], check_rc=True) -+ -+ # try to install the apt Python binding -+ apt_pkg_cmd = [APT_GET_CMD, 'install', apt_pkg_name, '-y', '-q', dpkg_options] -+ -+ if install_recommends is False: -+ apt_pkg_cmd.extend(["-o", "APT::Install-Recommends=no"]) -+ elif install_recommends is True: -+ apt_pkg_cmd.extend(["-o", "APT::Install-Recommends=yes"]) -+ # install_recommends is None uses the OS default -+ -+ module.run_command(apt_pkg_cmd, check_rc=True) -+ -+ # try again to find the bindings in common places -+ interpreter = probe_interpreters_for_module(interpreters, 'apt') -+ -+ if interpreter: -+ # found the Python bindings; respawn this module under the interpreter where we found them -+ # NB: respawn is somewhat wasteful if it's this interpreter, but simplifies the code -+ respawn_module(interpreter) -+ # this is the end of the line for this process, it will exit here once the respawned module has completed -+ -+ # we've done all we can do; just tell the user it's busted and get out -+ py_version = sys.version.replace("\n", "") -+ module.fail_json( -+ msg=f"Could not import the {apt_pkg_name} module using {sys.executable} ({py_version}). " -+ f"Ensure {apt_pkg_name} package is installed (either manually or via the auto_install_module_deps option) " -+ f"or that you have specified the correct ansible_python_interpreter. (attempted {interpreters}).", -+ ) - - if p['clean'] is True: - aptclean_stdout, aptclean_stderr, aptclean_diff = aptclean(module) -diff --git a/lib/ansible/modules/dnf5.py b/lib/ansible/modules/dnf5.py -index 24ae91432b..a0e4a4ef5a 100644 ---- a/lib/ansible/modules/dnf5.py -+++ b/lib/ansible/modules/dnf5.py -@@ -14,6 +14,12 @@ description: - provides are implemented in M(ansible.builtin.dnf5), please consult specific options for more information." - short_description: Manages packages with the I(dnf5) package manager - options: -+ auto_install_module_deps: -+ description: -+ - Automatically install dependencies required to run this module. -+ type: bool -+ default: yes -+ version_added: 2.19 - name: - description: - - "A package name or package specifier with version, like C(name-1.0). -@@ -246,6 +252,10 @@ attributes: - platforms: rhel - requirements: - - "python3-libdnf5" -+notes: -+ - If the interpreter can't import C(python3-libdnf5) the module will check for it in system-owned interpreters as well. -+ If the dependency can't be found, depending on the value of O(auto_install_module_deps) the module will attempt to install it. -+ If the dependency is found or installed, the module will be respawned under the correct interpreter. - version_added: 2.15 - """ - -@@ -474,6 +484,8 @@ def get_unneeded_pkgs(base): - class Dnf5Module(YumDnf): - def __init__(self, module): - super(Dnf5Module, self).__init__(module) -+ self.auto_install_module_deps = self.module.params["auto_install_module_deps"] -+ - self._ensure_dnf() - - self.pkg_mgr_name = "dnf5" -@@ -530,21 +542,30 @@ class Dnf5Module(YumDnf): - ] - - if not has_respawned(): -- # probe well-known system Python locations for accessible bindings, favoring py3 -- interpreter = probe_interpreters_for_module(system_interpreters, "libdnf5") -- -- if interpreter: -- # respawn under the interpreter where the bindings should be found -- respawn_module(interpreter) -- # end of the line for this module, the process will exit here once the respawned module completes -+ for attempt in (1, 2): -+ # probe well-known system Python locations for accessible bindings -+ interpreter = probe_interpreters_for_module(system_interpreters, "libdnf5") -+ if interpreter: -+ # respawn under the interpreter where the bindings should be found -+ respawn_module(interpreter) -+ # end of the line for this module, the process will exit here once the respawned module completes -+ if attempt == 1: -+ if self.module.check_mode: -+ self.module.fail_json( -+ msg="python3-libdnf5 must be installed to use check mode. " -+ "If run normally this module can auto-install it, " -+ "see the auto_install_module_deps option.", -+ ) -+ elif self.auto_install_module_deps: -+ self.module.run_command(["dnf", "install", "-y", "python3-libdnf5"], check_rc=True) -+ else: -+ break - -- # done all we can do, something is just broken (auto-install isn't useful anymore with respawn, so it was removed) -+ py_version = sys.version.replace("\n", "") - self.module.fail_json( -- msg="Could not import the libdnf5 python module using {0} ({1}). " -- "Please install python3-libdnf5 package or ensure you have specified the " -- "correct ansible_python_interpreter. (attempted {2})".format( -- sys.executable, sys.version.replace("\n", ""), system_interpreters -- ), -+ msg=f"Could not import the libdnf5 python module using {sys.executable} ({py_version}). " -+ "Ensure python3-libdnf5 package is installed (either manually or via the auto_install_module_deps option) " -+ f"or that you have specified the correct ansible_python_interpreter. (attempted {system_interpreters}).", - failures=[], - ) - -@@ -795,6 +816,11 @@ class Dnf5Module(YumDnf): - - - def main(): -+ yumdnf_argument_spec["argument_spec"].update( -+ dict( -+ auto_install_module_deps=dict(type="bool", default=True), -+ ) -+ ) - module = AnsibleModule(**yumdnf_argument_spec) - try: - Dnf5Module(module).run() -diff --git a/test/integration/targets/apt/tasks/apt.yml b/test/integration/targets/apt/tasks/apt.yml -index 64e00d3ca9..dda5fc1fab 100644 ---- a/test/integration/targets/apt/tasks/apt.yml -+++ b/test/integration/targets/apt/tasks/apt.yml -@@ -8,17 +8,17 @@ - distro_mirror: http://archive.ubuntu.com/ubuntu - when: ansible_distribution == 'Ubuntu' - --# UNINSTALL 'python-apt' --# The `apt` module has the smarts to auto-install `python-apt(3)`. To test, we --# will first uninstall `python-apt`. --- name: uninstall python-apt with apt -+# UNINSTALL 'python3-apt' -+# The `apt` module has the smarts to auto-install `python3-apt`. To test, we -+# will first uninstall `python3-apt`. -+- name: uninstall python3-apt with apt - apt: -- pkg: [python-apt, python3-apt] -+ pkg: python3-apt - state: absent - purge: yes - register: apt_result - --# In check mode, auto-install of `python-apt` must fail -+# In check mode, auto-install of `python3-apt` must fail - - name: test fail uninstall hello without required apt deps in check mode - apt: - pkg: hello -@@ -32,13 +32,25 @@ - assert: - that: - - apt_result is failed -- - '"If run normally this module can auto-install it." in apt_result.msg' -+ - '"If run normally this module can auto-install it" in apt_result.msg' - - - name: check with dpkg -- shell: dpkg -s python-apt python3-apt -+ shell: dpkg -s python3-apt - register: dpkg_result - ignore_errors: true - -+- name: Test the auto_install_module_deps option -+ apt: -+ pkg: hello -+ auto_install_module_deps: false -+ register: r -+ ignore_errors: true -+ -+- assert: -+ that: -+ - r is failed -+ - r.msg is contains("Could not import the python3-apt module") -+ - # UNINSTALL 'hello' - # With 'python-apt' uninstalled, the first call to 'apt' should install - # python-apt without updating the cache. -diff --git a/test/integration/targets/dnf5/playbook.yml b/test/integration/targets/dnf5/playbook.yml -index d9a79ced7e..a36c17a202 100644 ---- a/test/integration/targets/dnf5/playbook.yml -+++ b/test/integration/targets/dnf5/playbook.yml -@@ -1,8 +1,27 @@ - - hosts: localhost - tasks: - - block: -- - command: dnf install -y python3-libdnf5 -+ - command: "dnf install -y 'dnf-command(copr)'" -+ - name: Test against dnf5 nightly build to detect any issues early -+ command: dnf copr enable -y rpmsoftwaremanagement/dnf-nightly - -+ - name: Ensure module deps are not installed -+ command: dnf remove -y python3-libdnf5 -+ -+ - name: Test the auto_install_module_deps option -+ dnf5: -+ name: sos -+ auto_install_module_deps: false -+ register: r -+ ignore_errors: true -+ -+ - assert: -+ that: -+ - r is failed -+ - r.msg is contains("Could not import the libdnf5 python module") -+ -+ # Now the first dnf5 task in the dnf role should auto install python3-libdnf5 as -+ # auto_install_module_deps is true by default. - - include_role: - name: dnf - vars: --- -2.50.1 - diff --git a/0002-Initial-support-for-Python-3.14.patch b/0002-Initial-support-for-Python-3.14.patch deleted file mode 100644 index 8b71591..0000000 --- a/0002-Initial-support-for-Python-3.14.patch +++ /dev/null @@ -1,182 +0,0 @@ -From 36c1e6ff0d889cef5c57af64d4f6fc08b455bada Mon Sep 17 00:00:00 2001 -From: Maxwell G -Date: Sat, 7 Jun 2025 15:42:53 -0500 -Subject: [PATCH 2/2] Initial support for Python 3.14 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This is a downstream Fedora patch to make ansible-core work with Python -3.14 until it is properly supported upstream. -Note that parts of ansible-test will not work properly until we update -to an version that officially supports Python 3.14 due to missing -upstream test infrastructure. - -Co-authored-by: Miro Hrončok ---- - .../_data/requirements/ansible-test.txt | 2 +- - .../ansible_test/_internal/coverage_util.py | 2 +- - .../_util/target/common/constants.py | 1 + - .../module_utils/common/test_collections.py | 6 +- - .../test_check_required_arguments.py | 7 +- - test/units/modules/test_copy.py | 74 ++++++++++--------- - 6 files changed, 54 insertions(+), 38 deletions(-) - -diff --git a/test/lib/ansible_test/_data/requirements/ansible-test.txt b/test/lib/ansible_test/_data/requirements/ansible-test.txt -index 50f951c845..5edd5cc4de 100644 ---- a/test/lib/ansible_test/_data/requirements/ansible-test.txt -+++ b/test/lib/ansible_test/_data/requirements/ansible-test.txt -@@ -1,2 +1,2 @@ - # The test-constraints sanity test verifies this file, but changes must be made manually to keep it in up-to-date. --coverage == 7.6.1 ; python_version >= '3.8' and python_version <= '3.13' -+coverage == 7.6.1 ; python_version >= '3.8' and python_version <= '3.14' -diff --git a/test/lib/ansible_test/_internal/coverage_util.py b/test/lib/ansible_test/_internal/coverage_util.py -index 2bec9c791e..e900ddb801 100644 ---- a/test/lib/ansible_test/_internal/coverage_util.py -+++ b/test/lib/ansible_test/_internal/coverage_util.py -@@ -69,7 +69,7 @@ class CoverageVersion: - - COVERAGE_VERSIONS = ( - # IMPORTANT: Keep this in sync with the ansible-test.txt requirements file. -- CoverageVersion('7.6.1', 7, (3, 8), (3, 13)), -+ CoverageVersion('7.6.1', 7, (3, 8), (3, 14)), - ) - """ - This tuple specifies the coverage version to use for Python version ranges. -diff --git a/test/lib/ansible_test/_util/target/common/constants.py b/test/lib/ansible_test/_util/target/common/constants.py -index 31f56adcda..4e4055462d 100644 ---- a/test/lib/ansible_test/_util/target/common/constants.py -+++ b/test/lib/ansible_test/_util/target/common/constants.py -@@ -14,4 +14,5 @@ CONTROLLER_PYTHON_VERSIONS = ( - '3.11', - '3.12', - '3.13', -+ '3.14', - ) -diff --git a/test/units/module_utils/common/test_collections.py b/test/units/module_utils/common/test_collections.py -index 381d583004..78d7d19dde 100644 ---- a/test/units/module_utils/common/test_collections.py -+++ b/test/units/module_utils/common/test_collections.py -@@ -5,6 +5,8 @@ - - from __future__ import annotations - -+import re -+ - import pytest - - from collections.abc import Sequence -@@ -143,7 +145,9 @@ class TestImmutableDict: - # ImmutableDict is unhashable when one of its values is unhashable - imdict = ImmutableDict({u'café': u'くらとみ', 1: [1, 2]}) - -- expected_reason = r"^unhashable type: 'list'$" -+ python314_reason = re.escape("cannot use 'tuple' as a set element (unhashable type: 'list')") -+ expected_reasons = (r"^unhashable type: 'list'$", rf"^{python314_reason}$") -+ expected_reason = "|".join(expected_reasons) - - with pytest.raises(TypeError, match=expected_reason): - hash(imdict) -diff --git a/test/units/module_utils/common/validation/test_check_required_arguments.py b/test/units/module_utils/common/validation/test_check_required_arguments.py -index 16e79fe7dc..761cd0acd1 100644 ---- a/test/units/module_utils/common/validation/test_check_required_arguments.py -+++ b/test/units/module_utils/common/validation/test_check_required_arguments.py -@@ -84,4 +84,9 @@ def test_check_required_arguments_missing_none(): - def test_check_required_arguments_no_params(arguments_terms): - with pytest.raises(TypeError) as te: - check_required_arguments(arguments_terms, None) -- assert "'NoneType' is not iterable" in to_native(te.value) -+ value = to_native(te.value) -+ options = ( -+ "'NoneType' is not iterable", # Python < 3.14 -+ "argument of type 'NoneType' is not a container or iterable" # 3.14+ -+ ) -+ assert any(o in value for o in options) -diff --git a/test/units/modules/test_copy.py b/test/units/modules/test_copy.py -index 6f15bed122..799ba4b52f 100644 ---- a/test/units/modules/test_copy.py -+++ b/test/units/modules/test_copy.py -@@ -95,40 +95,46 @@ ONE_DIR_DATA: tuple[tuple[str, tuple[str, list[str]] | None, tuple[str, list[str - ONE_DIR_DATA += tuple(item[:3] for item in TWO_DIRS_DATA) - - --@pytest.mark.parametrize('directory, expected', ((d[0], d[4]) for d in THREE_DIRS_DATA)) --@pytest.mark.xfail(reason='broken test and/or code, original test missing assert', strict=False) --def test_split_pre_existing_dir_three_levels_exist(directory, expected, mocker): -- mocker.patch('os.path.exists', side_effect=[True, True, True]) -- assert split_pre_existing_dir(directory) == expected -- -- --@pytest.mark.parametrize('directory, expected', ((d[0], d[3]) for d in TWO_DIRS_DATA)) --@pytest.mark.xfail(reason='broken test and/or code, original test missing assert', strict=False) --def test_split_pre_existing_dir_two_levels_exist(directory, expected, mocker): -- mocker.patch('os.path.exists', side_effect=[True, True, False]) -- assert split_pre_existing_dir(directory) == expected -- -- --@pytest.mark.parametrize('directory, expected', ((d[0], d[2]) for d in ONE_DIR_DATA)) --@pytest.mark.xfail(reason='broken test and/or code, original test missing assert', strict=False) --def test_split_pre_existing_dir_one_level_exists(directory, expected, mocker): -- mocker.patch('os.path.exists', side_effect=[True, False, False]) -- assert split_pre_existing_dir(directory) == expected -- -- --@pytest.mark.parametrize('directory', (d[0] for d in ONE_DIR_DATA if d[1] is None)) --def test_split_pre_existing_dir_root_does_not_exist(directory, mocker): -- mocker.patch('os.path.exists', return_value=False) -- with pytest.raises(AnsibleModuleError) as excinfo: -- split_pre_existing_dir(directory) -- assert excinfo.value.results['msg'].startswith("The '/' directory doesn't exist on this machine.") -- -- --@pytest.mark.parametrize('directory, expected', ((d[0], d[1]) for d in ONE_DIR_DATA if not d[0].startswith('/'))) --@pytest.mark.xfail(reason='broken test and/or code, original test missing assert', strict=False) --def test_split_pre_existing_dir_working_dir_exists(directory, expected, mocker): -- mocker.patch('os.path.exists', return_value=False) -- assert split_pre_existing_dir(directory) == expected -+# NOTE(gotmax23): These tests are all broken (marked with xfail) to begin with. -+# On Python 3.14, they also cause pytest to crash, as the os.path.exists patch -+# does not get cleaned up in time for some reason and other internal pytest -+# code calls the mock instead of the actual function. -+# Comment them out for now. -+ -+# @pytest.mark.parametrize('directory, expected', ((d[0], d[4]) for d in THREE_DIRS_DATA)) -+# @pytest.mark.xfail(reason='broken test and/or code, original test missing assert', strict=False) -+# def test_split_pre_existing_dir_three_levels_exist(directory, expected, mocker): -+# mocker.patch('os.path.exists', side_effect=[True, True, True]) -+# assert split_pre_existing_dir(directory) == expected -+# -+# -+# @pytest.mark.parametrize('directory, expected', ((d[0], d[3]) for d in TWO_DIRS_DATA)) -+# @pytest.mark.xfail(reason='broken test and/or code, original test missing assert', strict=False) -+# def test_split_pre_existing_dir_two_levels_exist(directory, expected, mocker): -+# mocker.patch('os.path.exists', side_effect=[True, True, False]) -+# assert split_pre_existing_dir(directory) == expected -+# -+# -+# @pytest.mark.parametrize('directory, expected', ((d[0], d[2]) for d in ONE_DIR_DATA)) -+# @pytest.mark.xfail(reason='broken test and/or code, original test missing assert', strict=False) -+# def test_split_pre_existing_dir_one_level_exists(directory, expected, mocker): -+# mocker.patch('os.path.exists', side_effect=[True, False, False]) -+# assert split_pre_existing_dir(directory) == expected -+# -+# -+# @pytest.mark.parametrize('directory', (d[0] for d in ONE_DIR_DATA if d[1] is None)) -+# def test_split_pre_existing_dir_root_does_not_exist(directory, mocker): -+# mocker.patch('os.path.exists', return_value=False) -+# with pytest.raises(AnsibleModuleError) as excinfo: -+# split_pre_existing_dir(directory) -+# assert excinfo.value.results['msg'].startswith("The '/' directory doesn't exist on this machine.") -+# -+# -+# @pytest.mark.parametrize('directory, expected', ((d[0], d[1]) for d in ONE_DIR_DATA if not d[0].startswith('/'))) -+# @pytest.mark.xfail(reason='broken test and/or code, original test missing assert', strict=False) -+# def test_split_pre_existing_dir_working_dir_exists(directory, expected, mocker): -+# mocker.patch('os.path.exists', return_value=False) -+# assert split_pre_existing_dir(directory) == expected - - - # --- -2.50.1 - diff --git a/ansible-core.spec b/ansible-core.spec index 1a9154d..a6e2f82 100644 --- a/ansible-core.spec +++ b/ansible-core.spec @@ -13,7 +13,7 @@ %undefine _py3_shebang_s Name: ansible-core -Version: 2.18.11 +Version: 2.20.1 %global uversion %{version_no_tilde %{quote:%nil}} Release: 1%{?dist} Summary: A radically simple IT automation system @@ -21,21 +21,13 @@ Summary: A radically simple IT automation system # The main license is GPLv3+. Many of the files in lib/ansible/module_utils # are BSD licensed. There are various files scattered throughout the codebase # containing code under different licenses. -License: GPL-3.0-or-later AND BSD-2-Clause AND PSF-2.0 AND MIT AND Apache-2.0 +# The ssh-agent helper code is BSD-3-Clause. +License: GPL-3.0-or-later AND BSD-2-Clause AND BSD-3-Clause AND PSF-2.0 AND MIT AND Apache-2.0 URL: https://ansible.com Source0: https://github.com/ansible/ansible/archive/v%{uversion}/%{name}-%{uversion}.tar.gz Source1: https://github.com/ansible/ansible-documentation/archive/v%{uversion}/ansible-documentation-%{uversion}.tar.gz -# dnf5,apt: add auto_install_module_deps option (#84292) -# https://github.com/ansible/ansible/pull/84292.patch -# https://bugzilla.redhat.com/2322751 -Patch: 0001-dnf5-apt-add-auto_install_module_deps-option-84292.patch -# Initial support for Python 3.14 -# Downstream patch. See comments in patch file. -# https://bugzilla.redhat.com/2366307 -Patch: 0002-Initial-support-for-Python-3.14.patch - BuildArch: noarch # Virtual provides for bundled libraries @@ -47,14 +39,11 @@ Provides: bundled(python3dist(distro)) = 1.9.0 # lib/ansible/module_utils/six/* # SPDX-License-Identifier: MIT -Provides: bundled(python3dist(six)) = 1.16.0 +Provides: bundled(python3dist(six)) = 1.17.0 -Conflicts: ansible <= 2.9.99 -# -# obsoletes/provides for ansible-base -# -Provides: ansible-base = %{version}-%{release} -Obsoletes: ansible-base < 2.10.6-1 +# lib/ansible/_internal/_wrapt.py +# SPDX-License-Identifier: BSD-2-Clause +Provides: bundled(python3dist(wrapt)) = 1.17.2 BuildRequires: make BuildRequires: python%{python3_pkgversion}-devel @@ -245,8 +234,8 @@ install -Dpm 0644 licenses/* -t %{buildroot}%{_pkglicensedir} %files -f %{pyproject_files} %license COPYING -%license %{_pkglicensedir}/{Apache-License,MIT-license,PSF-license,simplified_bsd}.txt -%doc README.md changelogs/CHANGELOG-v2.1?.rst +%license %{_pkglicensedir}/{Apache-License,MIT-license,PSF-license,simplified_bsd,BSD-3-Clause}.txt +%doc README.md changelogs/CHANGELOG-v2.2?.rst %dir %{_sysconfdir}/ansible/ %config(noreplace) %{_sysconfdir}/ansible/* %{_bindir}/ansible* @@ -265,6 +254,12 @@ install -Dpm 0644 licenses/* -t %{buildroot}%{_pkglicensedir} %changelog +* Tue Dec 09 2025 Maxwell G - 2.20.1-1 +- Update to 2.20.1. Fixes rhbz#2382388. +- Update bundled() Provides +- Remove upstreamed patches +- Remove old Provides and Obsoletes for ansible-base and Ansible <= 2.9 + * Mon Nov 17 2025 Packit - 2.18.11-1 - Update to version 2.18.11 diff --git a/sources b/sources index 0dc6e1e..47c7d63 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (ansible-core-2.18.11.tar.gz) = 18302562c449634d9114ec0c113cad3b19866b35e1aec1ccb82ed1bfaa34496a8bccf548a7596d7ab5a989ac985e34a8a796b624f5216f63f3877d6e11edff5b -SHA512 (ansible-documentation-2.18.11.tar.gz) = d1144b427b57c466db402ec1fb5b3e6cf80710e059c7d4a22e26360eaa7303b8ff4a937b3d233fc04cd9092ef1adbd28d456a2deedb281c239de8c5dd9f7a091 +SHA512 (ansible-core-2.20.1.tar.gz) = fa0a4836e3548cd4e432e87b241beb6fb556765699c25b1f3b1c47111a1c44d5ba3244aeb8793408e72ab63564d6e848148becbfb550bd965e466752d7f78229 +SHA512 (ansible-documentation-2.20.1.tar.gz) = 0dc20cb62280c715e4b06788a5eb2c757c388d0da646a38fc3ab56e38d236ddb0fd7586a567d973e530ed3ed2310ff26542cdb0e1621e0049147dc747e20205b From 99b9eaafbddc38642c31931c0ab5e6ea9da75ef5 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 16 Jan 2026 03:43:36 +0000 Subject: [PATCH 23/23] Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild --- ansible-core.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ansible-core.spec b/ansible-core.spec index a6e2f82..4df897f 100644 --- a/ansible-core.spec +++ b/ansible-core.spec @@ -15,7 +15,7 @@ Name: ansible-core Version: 2.20.1 %global uversion %{version_no_tilde %{quote:%nil}} -Release: 1%{?dist} +Release: 2%{?dist} Summary: A radically simple IT automation system # The main license is GPLv3+. Many of the files in lib/ansible/module_utils @@ -254,6 +254,9 @@ install -Dpm 0644 licenses/* -t %{buildroot}%{_pkglicensedir} %changelog +* Fri Jan 16 2026 Fedora Release Engineering - 2.20.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild + * Tue Dec 09 2025 Maxwell G - 2.20.1-1 - Update to 2.20.1. Fixes rhbz#2382388. - Update bundled() Provides