Compare commits

...

13 Commits

Author SHA1 Message Date
sivel / Matt Martz 4f1fe10921
New release v2.20.0b2 (#85950) 2 months ago
sivel / Matt Martz ff29cd4ff0
Update DataLoader.get_basedir to be an abspath (#85940)
(cherry picked from commit 6673a14a9e)
2 months ago
s-hamann 06f272129c
fetch - return file in result when changed is true (#85729)
Set the (source) file attribute in the return value if the file changed
(e.g. on initial fetch). The attribute is already set in all other
cases.

(cherry picked from commit 0c7dcb65cf)
2 months ago
Martin Krizek 0f079fd23f
Deprecate `ansible.module_utils.six` (#85934)
* Deprecate `ansible.module_utils.six`

Fixes #85920

(cherry picked from commit 686c3658ae)
2 months ago
Sloane Hertel cbeb1da98b
Remove support for resolvelib < 0.8.0 (#85936)
* Remove support for resolvelib < 0.8.0

Remove code handling differences between resolvelib 0.5.3 and 0.8.0

Drop some versions from the test to reduce the time it takes to run

Co-authored-by: Sviatoslav Sydorenko <wk@sydorenko.org.ua>

* Remove type annotation

---------

Co-authored-by: Sviatoslav Sydorenko <wk@sydorenko.org.ua>
(cherry picked from commit cb2ecda514)
2 months ago
Martin Krizek 7db5959813
Don't special case implicit meta tasks when filtering on tags (#85805)
* Don't special case implicit meta tasks when filtering on tags

Fixes #85475

(cherry picked from commit 313c6f6b4d)
2 months ago
Abhijeet Kasurde 40b11f86fb
known_hosts: return rc and stderr in fail_json (#85871)
* When ssh-keygen fails, return rc and stderr in fail_json
  in order to help debugging.

Fixes: #85850

Signed-off-by: Abhijeet Kasurde <Akasurde@redhat.com>
(cherry picked from commit 6bee84318d)
2 months ago
Martin Krizek 580eb781dc
import_tasks processing closer to include_tasks (#85877)
Fixes #69882
Closes #83853
Fixes #85855
Fixes #85856

(cherry picked from commit c3f87b31d1)
2 months ago
Abhijeet Kasurde f23224d7b4
falsy: Update doc (#85913)
Signed-off-by: Abhijeet Kasurde <Akasurde@redhat.com>
(cherry picked from commit c5e6227bdb)
2 months ago
Luca Steinke 418746dcfc
fix description of truthy test (#85911)
There's a "not" too much here.

Maybe further examples can be found.

(cherry picked from commit eafa139f77)
2 months ago
Felix Fontein 48ef23fe4f
Make sure ansible-doc doesn't crash when scanning collections whose path contains ansible_collections twice (#85361)
Ref: https://github.com/ansible/ansible/issues/84909#issuecomment-2767335761

Co-authored-by: s-hertel <19572925+s-hertel@users.noreply.github.com>
Co-authored-by: Brian Coca <bcoca@users.noreply.github.com>
(cherry picked from commit c6d8d206af)
2 months ago
Matt Davis 00ee6040b6
Update Ansible release version to v2.20.0b1.post0. (#85902) 2 months ago
Matt Davis 21de43ab65
New release v2.20.0b1 (#85901) 2 months ago

@ -0,0 +1,174 @@
======================================================
ansible-core 2.20 "Good Times Bad Times" Release Notes
======================================================
.. contents:: Topics
v2.20.0b2
=========
Release Summary
---------------
| Release Date: 2025-10-06
| `Porting Guide <https://docs.ansible.com/ansible-core/2.20/porting_guides/porting_guide_core_2.20.html>`__
Minor Changes
-------------
- DataLoader - Update ``DataLoader.get_basedir`` to be an abspath
- known_hosts - return rc and stderr when ssh-keygen command fails for further debugging (https://github.com/ansible/ansible/issues/85850).
Deprecated Features
-------------------
- Deprecate the ``ansible.module_utils.six`` module. Use the Python standard library equivalent instead.
Removed Features (previously deprecated)
----------------------------------------
- ansible-galaxy - remove support for resolvelib >= 0.5.3, < 0.8.0.
Bugfixes
--------
- Fix issue where play tags prevented executing notified handlers (https://github.com/ansible/ansible/issues/85475)
- Fix issues with keywords being incorrectly validated on ``import_tasks`` (https://github.com/ansible/ansible/issues/85855, https://github.com/ansible/ansible/issues/85856)
- Fix traceback when trying to import non-existing file via nested ``import_tasks`` (https://github.com/ansible/ansible/issues/69882)
- ansible-doc - prevent crash when scanning collections in paths that have more than one ``ansible_collections`` in it (https://github.com/ansible/ansible/issues/84909, https://github.com/ansible/ansible/pull/85361).
- fetch - also return ``file`` in the result when changed is ``True`` (https://github.com/ansible/ansible/pull/85729).
v2.20.0b1
=========
Release Summary
---------------
| Release Date: 2025-09-23
| `Porting Guide <https://docs.ansible.com/ansible-core/2.20/porting_guides/porting_guide_core_2.20.html>`__
Major Changes
-------------
- ansible - Add support for Python 3.14.
- ansible - Drop support for Python 3.11 on the controller.
- ansible - Drop support for Python 3.8 on targets.
Minor Changes
-------------
- Add tech preview play argument spec validation, which can be enabled by setting the play keyword ``validate_argspec`` to ``True`` or the name of an argument spec. When ``validate_argspec`` is set to ``True``, a play ``name`` is required and used as the argument spec name. When enabled, the argument spec is loaded from a file matching the pattern <playbook_name>.meta.yml. At minimum, this file should contain ``{"argument_specs": {"name": {"options": {}}}}``, where "name" is the name of the play or configured argument spec.
- Added Univention Corporate Server as a part of Debian OS distribution family (https://github.com/ansible/ansible/issues/85490).
- AnsibleModule - Add temporary internal monkeypatch-able hook to alter module result serialization by splitting serialization from ``_return_formatted`` into ``_record_module_result``.
- Python type hints applied to ``to_text`` and ``to_bytes`` functions for better type hint interactions with code utilizing these functions.
- ansible now warns if you use reserved tags that were only meant for selection and not for use in play.
- ansible-doc - Return a more verbose error message when the ``description`` field is missing.
- ansible-doc - show ``notes``, ``seealso``, and top-level ``version_added`` for role entrypoints (https://github.com/ansible/ansible/pull/81796).
- ansible-doc adds support for RETURN documentation to support doc fragment plugins
- ansible-test - Implement new authentication methods for accessing the Ansible Core CI service.
- ansible-test - Improve formatting of generated coverage config file.
- ansible-test - Removed support for automatic provisioning of obsolete instances for network-integration tests.
- ansible-test - Replace FreeBSD 14.2 with 14.3.
- ansible-test - Replace RHEL 9.5 with 9.6.
- ansible-test - Update Ubuntu containers.
- ansible-test - Update pinned sanity test requirements.
- ansible-test - Update test containers.
- ansible-test - Upgrade Alpine 3.21 to 3.22.
- ansible-test - Upgrade Fedora 41 to Fedora 42.
- ansible-test - Upgrade to ``coverage`` version 7.10.6 for Python 3.9 and later.
- ansible-test - Use OS packages to satisfy controller requirements on FreeBSD 13.5 during managed instance bootstrapping.
- apt_repository - use correct debug method to print debug message.
- blockinfile - add new module option ``encoding`` to support files in encodings other than UTF-8 (https://github.com/ansible/ansible/pull/85291).
- deb822_repository - Add automatic installation of the ``python3-debian`` package if it is missing by adding the parameter ``install_python_debian``
- default callback plugin - add option to configure indentation for JSON and YAML output (https://github.com/ansible/ansible/pull/85497).
- encrypt - check datatype of salt_size in password_hash filter.
- fetch_file - add ca_path and cookies parameter arguments (https://github.com/ansible/ansible/issues/85172).
- include_vars - Raise an error if 'extensions' is not specified as a list.
- include_vars - Raise an error if 'ignore_files' is not specified as a list.
- lineinfile - add new module option ``encoding`` to support files in encodings other than UTF-8 (https://github.com/ansible/ansible/pull/84999).
- regex - Document the match_type fullmatch.
- regex - Ensure that match_type is one of match, fullmatch, or search (https://github.com/ansible/ansible/pull/85629).
- replace - read/write files in text-mode as unicode chars instead of as bytes and switch regex matching to unicode chars instead of bytes. (https://github.com/ansible/ansible/pull/85785).
- service_facts - handle keyerror exceptions with warning.
- service_facts - warn user about missing service details instead of ignoring.
- setup - added new subkey ``lvs`` within each entry of ``ansible_facts['vgs']`` to provide complete logical volume data scoped by volume group. The top level ``lvs`` fact by comparison, deduplicates logical volume names across volume groups and may be incomplete. (https://github.com/ansible/ansible/issues/85632)
- six - bump six version from 1.16.0 to 1.17.0 (https://github.com/ansible/ansible/issues/85408).
- stat module - add SELinux context as a return value, and add a new option to trigger this return, which is False by default. (https://github.com/ansible/ansible/issues/85217).
- tags now warn when using reserved keywords.
- wrapt - bump version from 1.15.0 to 1.17.2 (https://github.com/ansible/ansible/issues/85407).
Breaking Changes / Porting Guide
--------------------------------
- powershell - Removed code that tried to remote quotes from paths when performing Windows operations like copying and fetching file. This should not affect normal playbooks unless a value is quoted too many times.
Deprecated Features
-------------------
- Deprecated the shell plugin's ``wrap_for_exec`` function. This API is not used in Ansible or any known collection and is being removed to simplify the plugin API. Plugin authors should wrap their command to execute within an explicit shell or other known executable.
- INJECT_FACTS_AS_VARS configuration currently defaults to ``True``, this is now deprecated and it will switch to ``False`` by Ansible 2.24. You will only get notified if you are accessing 'injected' facts (for example, ansible_os_distribution vs ansible_facts['os_distribution']).
- hash_params function in roles/__init__ is being deprecated as it is not in use.
- include_vars - Specifying 'ignore_files' as a string is deprecated.
- vars, the internal variable cache will be removed in 2.24. This cache, once used internally exposes variables in inconsistent states, the 'vars' and 'varnames' lookups should be used instead.
Removed Features (previously deprecated)
----------------------------------------
- Removed the option to set the ``DEFAULT_TRANSPORT`` configuration to ``smart`` that selects the default transport as either ``ssh`` or ``paramiko`` based on the underlying platform configuraton.
- ``vault``/``unvault`` filters - remove the deprecated ``vaultid`` parameter.
- ansible-doc - role entrypoint attributes are no longer shown
- ansible-galaxy - removed the v2 Galaxy server API. Galaxy servers hosting collections must support v3.
- dnf/dnf5 - remove deprecated ``install_repoquery`` option.
- encrypt - remove deprecated passlib_or_crypt API.
- paramiko - Removed the ``PARAMIKO_HOST_KEY_AUTO_ADD`` and ``PARAMIKO_LOOK_FOR_KEYS`` configuration keys, which were previously deprecated.
- py3compat - remove deprecated ``py3compat.environ`` call.
- vars plugins - removed the deprecated ``get_host_vars`` or ``get_group_vars`` fallback for vars plugins that do not inherit from ``BaseVarsPlugin`` and define a ``get_vars`` method.
- yum_repository - remove deprecated ``keepcache`` option.
Bugfixes
--------
- Do not re-add ``tags`` on blocks from within ``import_tasks``.
- The ``ansible_failed_task`` variable is now correctly exposed in a rescue section, even when a failing handler is triggered by the ``flush_handlers`` task in the corresponding ``block`` (https://github.com/ansible/ansible/issues/85682)
- Windows async - Handle running PowerShell modules with trailing data after the module result
- ``ansible-galaxy collection list`` - fail when none of the configured collection paths exist.
- ``ternary`` filter - evaluate values lazily (https://github.com/ansible/ansible/issues/85743)
- ansible-doc --list/--list_files/--metadata-dump - fixed relative imports in nested filter/test plugin files (https://github.com/ansible/ansible/issues/85753).
- ansible-galaxy - Use the provided import task url, instead of parsing to get the task id and reconstructing the URL
- ansible-galaxy no longer shows the internal protomatter collection when listing.
- ansible-test - Always exclude the ``tests/output/`` directory from a collection's code coverage. (https://github.com/ansible/ansible/issues/84244)
- ansible-test - Fix a traceback that can occur when using delegation before the ansible-test temp directory is created.
- ansible-test - Limit package install retries during managed remote instance bootstrapping.
- ansible-test - Use a consistent coverage config for all collection testing.
- apt - mark dependencies installed as part of deb file installation as auto (https://github.com/ansible/ansible/issues/78123).
- argspec validation - The ``str`` argspec type treats ``None`` values as empty string for better consistency with pre-2.19 templating conversions.
- cache plugins - close temp cache file before moving it to fix error on WSL. (https://github.com/ansible/ansible/pull/85816)
- callback plugins - fix displaying the rendered ``ansible_host`` variable with ``delegate_to`` (https://github.com/ansible/ansible/issues/84922).
- callback plugins - improve consistency accessing the Task object's resolved_action attribute.
- conditionals - When displaying a broken conditional error or deprecation warning, the origin of the non-boolean result is included (if available), and the raw result is omitted.
- display - Fixed reference to undefined `_DeferredWarningContext` when issuing early warnings during startup. (https://github.com/ansible/ansible/issues/85886)
- dnf - Check if installroot is directory or not (https://github.com/ansible/ansible/issues/85680).
- failed_when - When using ``failed_when`` to suppress an error, the ``exception`` key in the result is renamed to ``failed_when_suppressed_exception``. This prevents the error from being displayed by callbacks after being suppressed. (https://github.com/ansible/ansible/issues/85505)
- import_tasks - fix templating parent include arguments.
- include_role - allow host specific values in all ``*_from`` arguments (https://github.com/ansible/ansible/issues/66497)
- pip - Fix pip module output so that it returns changed when the only operation is initializing a venv.
- plugins config, get_option_and_origin now correctly displays the value and origin of the option.
- run_command - Fixed premature selector unregistration on empty read from stdout/stderr that caused truncated output or hangs in rare situations.
- script inventory plugin will now show correct 'incorrect' type when doing implicit conversions on groups.
- ssh connection - fix documented variables for the ``host`` option. Connection options can be configured with delegated variables in general.
- template lookup - Skip finalization on the internal templating operation to allow markers to be returned and handled by, e.g. the ``default`` filter. Previously, finalization tripped markers, causing an exception to end processing of the current template pipeline. (https://github.com/ansible/ansible/issues/85674)
- templating - Avoid tripping markers within Jinja generated code. (https://github.com/ansible/ansible/issues/85674)
- templating - Ensure filter plugin result processing occurs under the correct call context. (https://github.com/ansible/ansible/issues/85585)
- templating - Fix slicing of tuples in templating (https://github.com/ansible/ansible/issues/85606).
- templating - Multi-node template results coerce embedded ``None`` nodes to empty string (instead of rendering literal ``None`` to the output).
- templating - Undefined marker values sourced from the Jinja ``getattr->getitem`` fallback are now accessed correctly, raising AnsibleUndefinedVariable for user plugins that do not understand markers. Previously, these values were erroneously returned to user plugin code that had not opted in to marker acceptance.
- tqm - use display.error_as_warning instead of display.warning_as_error.
- tqm - use display.error_as_warning instead of self.warning.
- uri - fix form-multipart file not being found when task is retried (https://github.com/ansible/ansible/issues/85009)
- validate-modules sanity test - fix handling of missing doc fragments (https://github.com/ansible/ansible/pull/85638).
Known Issues
------------
- templating - Exceptions raised in a Jinja ``set`` or ``with`` block which are not accessed by the template are ignored in the same manner as undefined values.
- templating - Passing a container created in a Jinja ``set`` or ``with`` block to a method results in a copy of that container. Mutations to that container which are not returned by the method will be discarded.

@ -1,2 +1,319 @@
ancestor: 2.18.0
releases: {}
releases:
2.20.0b1:
changes:
breaking_changes:
- powershell - Removed code that tried to remote quotes from paths when performing
Windows operations like copying and fetching file. This should not affect
normal playbooks unless a value is quoted too many times.
bugfixes:
- Do not re-add ``tags`` on blocks from within ``import_tasks``.
- The ``ansible_failed_task`` variable is now correctly exposed in a rescue
section, even when a failing handler is triggered by the ``flush_handlers``
task in the corresponding ``block`` (https://github.com/ansible/ansible/issues/85682)
- Windows async - Handle running PowerShell modules with trailing data after
the module result
- '``ansible-galaxy collection list`` - fail when none of the configured collection
paths exist.'
- '``ternary`` filter - evaluate values lazily (https://github.com/ansible/ansible/issues/85743)'
- ansible-doc --list/--list_files/--metadata-dump - fixed relative imports in
nested filter/test plugin files (https://github.com/ansible/ansible/issues/85753).
- ansible-galaxy - Use the provided import task url, instead of parsing to get
the task id and reconstructing the URL
- ansible-galaxy no longer shows the internal protomatter collection when listing.
- ansible-test - Always exclude the ``tests/output/`` directory from a collection's
code coverage. (https://github.com/ansible/ansible/issues/84244)
- ansible-test - Fix a traceback that can occur when using delegation before
the ansible-test temp directory is created.
- ansible-test - Limit package install retries during managed remote instance
bootstrapping.
- ansible-test - Use a consistent coverage config for all collection testing.
- apt - mark dependencies installed as part of deb file installation as auto
(https://github.com/ansible/ansible/issues/78123).
- argspec validation - The ``str`` argspec type treats ``None`` values as empty
string for better consistency with pre-2.19 templating conversions.
- cache plugins - close temp cache file before moving it to fix error on WSL.
(https://github.com/ansible/ansible/pull/85816)
- callback plugins - fix displaying the rendered ``ansible_host`` variable with
``delegate_to`` (https://github.com/ansible/ansible/issues/84922).
- callback plugins - improve consistency accessing the Task object's resolved_action
attribute.
- conditionals - When displaying a broken conditional error or deprecation warning,
the origin of the non-boolean result is included (if available), and the raw
result is omitted.
- display - Fixed reference to undefined `_DeferredWarningContext` when issuing
early warnings during startup. (https://github.com/ansible/ansible/issues/85886)
- dnf - Check if installroot is directory or not (https://github.com/ansible/ansible/issues/85680).
- failed_when - When using ``failed_when`` to suppress an error, the ``exception``
key in the result is renamed to ``failed_when_suppressed_exception``. This
prevents the error from being displayed by callbacks after being suppressed.
(https://github.com/ansible/ansible/issues/85505)
- import_tasks - fix templating parent include arguments.
- include_role - allow host specific values in all ``*_from`` arguments (https://github.com/ansible/ansible/issues/66497)
- pip - Fix pip module output so that it returns changed when the only operation
is initializing a venv.
- plugins config, get_option_and_origin now correctly displays the value and
origin of the option.
- run_command - Fixed premature selector unregistration on empty read from stdout/stderr
that caused truncated output or hangs in rare situations.
- script inventory plugin will now show correct 'incorrect' type when doing
implicit conversions on groups.
- ssh connection - fix documented variables for the ``host`` option. Connection
options can be configured with delegated variables in general.
- template lookup - Skip finalization on the internal templating operation to
allow markers to be returned and handled by, e.g. the ``default`` filter.
Previously, finalization tripped markers, causing an exception to end processing
of the current template pipeline. (https://github.com/ansible/ansible/issues/85674)
- templating - Avoid tripping markers within Jinja generated code. (https://github.com/ansible/ansible/issues/85674)
- templating - Ensure filter plugin result processing occurs under the correct
call context. (https://github.com/ansible/ansible/issues/85585)
- templating - Fix slicing of tuples in templating (https://github.com/ansible/ansible/issues/85606).
- templating - Multi-node template results coerce embedded ``None`` nodes to
empty string (instead of rendering literal ``None`` to the output).
- templating - Undefined marker values sourced from the Jinja ``getattr->getitem``
fallback are now accessed correctly, raising AnsibleUndefinedVariable for
user plugins that do not understand markers. Previously, these values were
erroneously returned to user plugin code that had not opted in to marker acceptance.
- tqm - use display.error_as_warning instead of display.warning_as_error.
- tqm - use display.error_as_warning instead of self.warning.
- uri - fix form-multipart file not being found when task is retried (https://github.com/ansible/ansible/issues/85009)
- validate-modules sanity test - fix handling of missing doc fragments (https://github.com/ansible/ansible/pull/85638).
deprecated_features:
- Deprecated the shell plugin's ``wrap_for_exec`` function. This API is not
used in Ansible or any known collection and is being removed to simplify the
plugin API. Plugin authors should wrap their command to execute within an
explicit shell or other known executable.
- INJECT_FACTS_AS_VARS configuration currently defaults to ``True``, this is
now deprecated and it will switch to ``False`` by Ansible 2.24. You will only
get notified if you are accessing 'injected' facts (for example, ansible_os_distribution
vs ansible_facts['os_distribution']).
- hash_params function in roles/__init__ is being deprecated as it is not in
use.
- include_vars - Specifying 'ignore_files' as a string is deprecated.
- vars, the internal variable cache will be removed in 2.24. This cache, once
used internally exposes variables in inconsistent states, the 'vars' and 'varnames'
lookups should be used instead.
known_issues:
- templating - Exceptions raised in a Jinja ``set`` or ``with`` block which
are not accessed by the template are ignored in the same manner as undefined
values.
- templating - Passing a container created in a Jinja ``set`` or ``with`` block
to a method results in a copy of that container. Mutations to that container
which are not returned by the method will be discarded.
major_changes:
- ansible - Add support for Python 3.14.
- ansible - Drop support for Python 3.11 on the controller.
- ansible - Drop support for Python 3.8 on targets.
minor_changes:
- 'Add tech preview play argument spec validation, which can be enabled by setting
the play keyword ``validate_argspec`` to ``True`` or the name of an argument
spec. When ``validate_argspec`` is set to ``True``, a play ``name`` is required
and used as the argument spec name. When enabled, the argument spec is loaded
from a file matching the pattern <playbook_name>.meta.yml. At minimum, this
file should contain ``{"argument_specs": {"name": {"options": {}}}}``, where
"name" is the name of the play or configured argument spec.'
- Added Univention Corporate Server as a part of Debian OS distribution family
(https://github.com/ansible/ansible/issues/85490).
- AnsibleModule - Add temporary internal monkeypatch-able hook to alter module
result serialization by splitting serialization from ``_return_formatted``
into ``_record_module_result``.
- Python type hints applied to ``to_text`` and ``to_bytes`` functions for better
type hint interactions with code utilizing these functions.
- ansible now warns if you use reserved tags that were only meant for selection
and not for use in play.
- ansible-doc - Return a more verbose error message when the ``description``
field is missing.
- ansible-doc - show ``notes``, ``seealso``, and top-level ``version_added``
for role entrypoints (https://github.com/ansible/ansible/pull/81796).
- ansible-doc adds support for RETURN documentation to support doc fragment
plugins
- ansible-test - Implement new authentication methods for accessing the Ansible
Core CI service.
- ansible-test - Improve formatting of generated coverage config file.
- ansible-test - Removed support for automatic provisioning of obsolete instances
for network-integration tests.
- ansible-test - Replace FreeBSD 14.2 with 14.3.
- ansible-test - Replace RHEL 9.5 with 9.6.
- ansible-test - Update Ubuntu containers.
- ansible-test - Update pinned sanity test requirements.
- ansible-test - Update test containers.
- ansible-test - Upgrade Alpine 3.21 to 3.22.
- ansible-test - Upgrade Fedora 41 to Fedora 42.
- ansible-test - Upgrade to ``coverage`` version 7.10.6 for Python 3.9 and later.
- ansible-test - Use OS packages to satisfy controller requirements on FreeBSD
13.5 during managed instance bootstrapping.
- apt_repository - use correct debug method to print debug message.
- blockinfile - add new module option ``encoding`` to support files in encodings
other than UTF-8 (https://github.com/ansible/ansible/pull/85291).
- deb822_repository - Add automatic installation of the ``python3-debian`` package
if it is missing by adding the parameter ``install_python_debian``
- default callback plugin - add option to configure indentation for JSON and
YAML output (https://github.com/ansible/ansible/pull/85497).
- encrypt - check datatype of salt_size in password_hash filter.
- fetch_file - add ca_path and cookies parameter arguments (https://github.com/ansible/ansible/issues/85172).
- include_vars - Raise an error if 'extensions' is not specified as a list.
- include_vars - Raise an error if 'ignore_files' is not specified as a list.
- lineinfile - add new module option ``encoding`` to support files in encodings
other than UTF-8 (https://github.com/ansible/ansible/pull/84999).
- regex - Document the match_type fullmatch.
- regex - Ensure that match_type is one of match, fullmatch, or search (https://github.com/ansible/ansible/pull/85629).
- replace - read/write files in text-mode as unicode chars instead of as bytes
and switch regex matching to unicode chars instead of bytes. (https://github.com/ansible/ansible/pull/85785).
- service_facts - handle keyerror exceptions with warning.
- service_facts - warn user about missing service details instead of ignoring.
- setup - added new subkey ``lvs`` within each entry of ``ansible_facts['vgs']``
to provide complete logical volume data scoped by volume group. The top level
``lvs`` fact by comparison, deduplicates logical volume names across volume
groups and may be incomplete. (https://github.com/ansible/ansible/issues/85632)
- six - bump six version from 1.16.0 to 1.17.0 (https://github.com/ansible/ansible/issues/85408).
- stat module - add SELinux context as a return value, and add a new option
to trigger this return, which is False by default. (https://github.com/ansible/ansible/issues/85217).
- tags now warn when using reserved keywords.
- wrapt - bump version from 1.15.0 to 1.17.2 (https://github.com/ansible/ansible/issues/85407).
release_summary: '| Release Date: 2025-09-23
| `Porting Guide <https://docs.ansible.com/ansible-core/2.20/porting_guides/porting_guide_core_2.20.html>`__
'
removed_features:
- Removed the option to set the ``DEFAULT_TRANSPORT`` configuration to ``smart``
that selects the default transport as either ``ssh`` or ``paramiko`` based
on the underlying platform configuraton.
- '``vault``/``unvault`` filters - remove the deprecated ``vaultid`` parameter.'
- ansible-doc - role entrypoint attributes are no longer shown
- ansible-galaxy - removed the v2 Galaxy server API. Galaxy servers hosting
collections must support v3.
- dnf/dnf5 - remove deprecated ``install_repoquery`` option.
- encrypt - remove deprecated passlib_or_crypt API.
- paramiko - Removed the ``PARAMIKO_HOST_KEY_AUTO_ADD`` and ``PARAMIKO_LOOK_FOR_KEYS``
configuration keys, which were previously deprecated.
- py3compat - remove deprecated ``py3compat.environ`` call.
- vars plugins - removed the deprecated ``get_host_vars`` or ``get_group_vars``
fallback for vars plugins that do not inherit from ``BaseVarsPlugin`` and
define a ``get_vars`` method.
- yum_repository - remove deprecated ``keepcache`` option.
codename: Good Times Bad Times
fragments:
- 2.20.0b1_summary.yaml
- 66497-include_role-_from-dedup.yml
- 81796-ansible-doc-roles.yml
- 85010-uri-multipart-file-on-retry.yml
- 85217-stat-add-selinux-context.yml
- 85487-add-dependency-installation-to-deb822_repository.yml
- 85497-default-callback-indent.yml
- 85524-resolve-task-resolved_action-early.yml
- 85556-fix-pip-changed.yml
- 85596-hide-proto.yml
- 85599-fix-templating-import_tasks-parent-include.yml
- 85632-setup-logical-volume-name-uniqueness.yml
- 85638-ansible-test-validate-modules-doc-fragments.yml
- 85682-rescue-flush_handlers.yml
- 85743-lazy-ternary.yml
- 85816-wsl-cache-files.yml
- ansible-doc-description-verbosity.yml
- ansible-test-auth-update.yml
- ansible-test-bootstrap-retry.yml
- ansible-test-containers.yml
- ansible-test-coverage-config.yml
- ansible-test-coverage-upgrade.yml
- ansible-test-freebsd-14.3.yml
- ansible-test-freebsd-bootstrap.yml
- ansible-test-ios.yml
- ansible-test-missing-dir-fix.yml
- ansible-test-remotes.yml
- ansible-test-rhel-9.6.yml
- ansible-test-sanity-requirements.yml
- apt_deb_install.yml
- apt_repo_debug.yml
- blockinfile-new-module-option-encoding.yml
- concat_coerce_none_to_empty.yml
- deprecate_inject.yml
- display_internals.yml
- dnf-remove-install_repoquery.yml
- dnf_installroot_dir.yml
- elide_broken_conditional_result.yml
- encrypt.yml
- failed-when-exception.yml
- fetch_file.yml
- fix-displaying-delegate_to-ansible_host.yml
- fix-listing-nested-filter-and-test-plugins.yml
- fix_script_error.yml
- galaxy-use-import-task-url.yml
- getattr_marker_access.yml
- hide_proto.yml
- import_tasks-dont-readd-tags.yml
- include_vars.yml
- known_issues_jinja_error.yml
- lineinfile-new-module-option-encoding.yml
- module_direct_exec.yml
- openrc.yml
- paramiko-global-config-removal.yml
- password_hash_encrypt.yml
- play-argument-spec-validation.yml
- plugins_fix_origin.yml
- powershell-quoting.yml
- python-support.yml
- regex_test.yml
- remove-role-entrypoint-attrs.yml
- remove-v2-galaxy-api.yml
- remove_hash_params.yml
- remove_py3compat.yml
- replace-update-string-comparison-method-to-unicode.yml
- return_fragments.yml
- run_command_output_selector.yml
- shell-wrap_for_exec_deprecation.yml
- six_1.7.0.yml
- smart-transport-removal.yml
- tag_u_it.yml
- template-tuple-fix.yml
- template_lookup_skip_finalize.yml
- templating-filter-generators.yml
- to-text-to-bytes.yml
- tqm.yml
- ucs.yml
- vars-remove-get_hostgroup_vars.yml
- vars_begone.yml
- vault-vaultid-removal.yml
- warn_reserved_tags.yml
- win_async-junk-output.yml
- wrapt_1.17.2.yml
- yum_repository-remove-keepcache.yml
release_date: '2025-09-23'
2.20.0b2:
changes:
bugfixes:
- Fix issue where play tags prevented executing notified handlers (https://github.com/ansible/ansible/issues/85475)
- Fix issues with keywords being incorrectly validated on ``import_tasks`` (https://github.com/ansible/ansible/issues/85855,
https://github.com/ansible/ansible/issues/85856)
- Fix traceback when trying to import non-existing file via nested ``import_tasks``
(https://github.com/ansible/ansible/issues/69882)
- ansible-doc - prevent crash when scanning collections in paths that have more
than one ``ansible_collections`` in it (https://github.com/ansible/ansible/issues/84909,
https://github.com/ansible/ansible/pull/85361).
- fetch - also return ``file`` in the result when changed is ``True`` (https://github.com/ansible/ansible/pull/85729).
deprecated_features:
- Deprecate the ``ansible.module_utils.six`` module. Use the Python standard
library equivalent instead.
minor_changes:
- DataLoader - Update ``DataLoader.get_basedir`` to be an abspath
- known_hosts - return rc and stderr when ssh-keygen command fails for further
debugging (https://github.com/ansible/ansible/issues/85850).
release_summary: '| Release Date: 2025-10-06
| `Porting Guide <https://docs.ansible.com/ansible-core/2.20/porting_guides/porting_guide_core_2.20.html>`__
'
removed_features:
- ansible-galaxy - remove support for resolvelib >= 0.5.3, < 0.8.0.
codename: Good Times Bad Times
fragments:
- 2.20.0b2_summary.yaml
- 85361-collection-name-from-path-none.yml
- 85475-fix-flush_handlers-play-tags.yml
- data-loader-basedir-abspath.yml
- deprecate-six.yml
- drop-resolvelib-lt-0_8_0.yml
- fix-fetch-return-file.yml
- import_tasks-fixes.yml
- known_hosts.yml
release_date: '2025-10-06'

@ -0,0 +1,3 @@
release_summary: |
| Release Date: 2025-09-23
| `Porting Guide <https://docs.ansible.com/ansible-core/2.20/porting_guides/porting_guide_core_2.20.html>`__

@ -0,0 +1,3 @@
release_summary: |
| Release Date: 2025-10-06
| `Porting Guide <https://docs.ansible.com/ansible-core/2.20/porting_guides/porting_guide_core_2.20.html>`__

@ -0,0 +1,3 @@
bugfixes:
- "ansible-doc - prevent crash when scanning collections in paths that have more than one ``ansible_collections`` in it
(https://github.com/ansible/ansible/issues/84909, https://github.com/ansible/ansible/pull/85361)."

@ -0,0 +1,2 @@
bugfixes:
- Fix issue where play tags prevented executing notified handlers (https://github.com/ansible/ansible/issues/85475)

@ -0,0 +1,2 @@
minor_changes:
- DataLoader - Update ``DataLoader.get_basedir`` to be an abspath

@ -0,0 +1,2 @@
deprecated_features:
- Deprecate the ``ansible.module_utils.six`` module. Use the Python standard library equivalent instead.

@ -0,0 +1,2 @@
removed_features:
- ansible-galaxy - remove support for resolvelib >= 0.5.3, < 0.8.0.

@ -0,0 +1,2 @@
bugfixes:
- fetch - also return ``file`` in the result when changed is ``True`` (https://github.com/ansible/ansible/pull/85729).

@ -0,0 +1,3 @@
bugfixes:
- Fix traceback when trying to import non-existing file via nested ``import_tasks`` (https://github.com/ansible/ansible/issues/69882)
- Fix issues with keywords being incorrectly validated on ``import_tasks`` (https://github.com/ansible/ansible/issues/85855, https://github.com/ansible/ansible/issues/85856)

@ -0,0 +1,3 @@
---
minor_changes:
- known_hosts - return rc and stderr when ssh-keygen command fails for further debugging (https://github.com/ansible/ansible/issues/85850).

@ -236,7 +236,9 @@ class RoleMixin(object):
b_colldirs = list_collection_dirs(coll_filter=collection_filter)
for b_path in b_colldirs:
path = to_text(b_path, errors='surrogate_or_strict')
collname = _get_collection_name_from_path(b_path)
if not (collname := _get_collection_name_from_path(b_path)):
display.debug(f'Skipping invalid path {b_path!r}')
continue
roles_dir = os.path.join(path, 'roles')
if os.path.exists(roles_dir):

@ -17,8 +17,10 @@ def list_collections(coll_filter=None, search_paths=None, dedupe=True, artifacts
collections = {}
for candidate in list_collection_dirs(search_paths=search_paths, coll_filter=coll_filter, artifacts_manager=artifacts_manager, dedupe=dedupe):
collection = _get_collection_name_from_path(candidate)
collections[collection] = candidate
if collection := _get_collection_name_from_path(candidate):
collections[collection] = candidate
else:
display.debug(f'Skipping invalid collection in path: {candidate!r}')
return collections

@ -5,6 +5,7 @@
from __future__ import annotations
import collections.abc as _c
import functools
import typing as t
@ -37,16 +38,16 @@ except ImportError:
# TODO: add python requirements to ansible-test's ansible-core distribution info and remove the hardcoded lowerbound/upperbound fallback
RESOLVELIB_LOWERBOUND = SemanticVersion("0.5.3")
RESOLVELIB_LOWERBOUND = SemanticVersion("0.8.0")
RESOLVELIB_UPPERBOUND = SemanticVersion("2.0.0")
RESOLVELIB_VERSION = SemanticVersion.from_loose_version(LooseVersion(resolvelib_version))
class CollectionDependencyProviderBase(AbstractProvider):
class CollectionDependencyProvider(AbstractProvider):
"""Delegate providing a requirement interface for the resolver."""
def __init__(
self, # type: CollectionDependencyProviderBase
self,
apis, # type: MultiGalaxyAPIProxy
concrete_artifacts_manager=None, # type: ConcreteArtifactsManager
preferred_candidates=None, # type: t.Iterable[Candidate]
@ -102,8 +103,14 @@ class CollectionDependencyProviderBase(AbstractProvider):
"""
return requirement_or_candidate.canonical_package_id
def get_preference(self, *args, **kwargs):
# type: (t.Any, t.Any) -> t.Union[float, int]
def get_preference(
self,
identifier: str,
resolutions: _c.Mapping[str, Candidate],
candidates: _c.Mapping[str, _c.Iterator[Candidate]],
information: _c.Iterator[t.NamedTuple],
backtrack_causes: _c.Sequence,
) -> float | int:
"""Return sort key function return value for given requirement.
This result should be based on preference that is defined as
@ -111,38 +118,6 @@ class CollectionDependencyProviderBase(AbstractProvider):
The lower the return value is, the more preferred this
group of arguments is.
resolvelib >=0.5.3, <0.7.0
:param resolution: Currently pinned candidate, or ``None``.
:param candidates: A list of possible candidates.
:param information: A list of requirement information.
Each ``information`` instance is a named tuple with two entries:
* ``requirement`` specifies a requirement contributing to
the current candidate list
* ``parent`` specifies the candidate that provides
(depended on) the requirement, or `None`
to indicate a root requirement.
resolvelib >=0.7.0, < 0.8.0
:param identifier: The value returned by ``identify()``.
:param resolutions: Mapping of identifier, candidate pairs.
:param candidates: Possible candidates for the identifier.
Mapping of identifier, list of candidate pairs.
:param information: Requirement information of each package.
Mapping of identifier, list of named tuple pairs.
The named tuples have the entries ``requirement`` and ``parent``.
resolvelib >=0.8.0, <= 1.0.1
:param identifier: The value returned by ``identify()``.
:param resolutions: Mapping of identifier, candidate pairs.
@ -178,10 +153,6 @@ class CollectionDependencyProviderBase(AbstractProvider):
the value is, the more preferred this requirement is (i.e. the
sorting function is called with ``reverse=False``).
"""
raise NotImplementedError
def _get_preference(self, candidates):
# type: (list[Candidate]) -> t.Union[float, int]
if any(
candidate in self._preferred_candidates
for candidate in candidates
@ -191,8 +162,12 @@ class CollectionDependencyProviderBase(AbstractProvider):
return float('-inf')
return len(candidates)
def find_matches(self, *args, **kwargs):
# type: (t.Any, t.Any) -> list[Candidate]
def find_matches(
self,
identifier: str,
requirements: _c.Mapping[str, _c.Iterator[Requirement]],
incompatibilities: _c.Mapping[str, _c.Iterator[Candidate]],
) -> list[Candidate]:
r"""Find all possible candidates satisfying given requirements.
This tries to get candidates based on the requirements' types.
@ -203,32 +178,13 @@ class CollectionDependencyProviderBase(AbstractProvider):
For a "named" requirement, Galaxy-compatible APIs are consulted
to find concrete candidates for this requirement. If there's a
pre-installed candidate, it's prepended in front of others.
resolvelib >=0.5.3, <0.6.0
:param requirements: A collection of requirements which all of \
the returned candidates must match. \
All requirements are guaranteed to have \
the same identifier. \
The collection is never empty.
resolvelib >=0.6.0
:param identifier: The value returned by ``identify()``.
:param requirements: The requirements all returned candidates must satisfy.
Mapping of identifier, iterator of requirement pairs.
:param incompatibilities: Incompatible versions that must be excluded
from the returned list.
:returns: An iterable that orders candidates by preference, \
e.g. the most preferred candidate comes first.
"""
raise NotImplementedError
return [
match for match in self._find_matches(list(requirements[identifier]))
if not any(match.ver == incompat.ver for incompat in incompatibilities[identifier])
]
def _find_matches(self, requirements):
# type: (list[Requirement]) -> list[Candidate]
def _find_matches(self, requirements: list[Requirement]) -> list[Candidate]:
# FIXME: The first requirement may be a Git repo followed by
# FIXME: its cloned tmp dir. Using only the first one creates
# FIXME: loops that prevent any further dependency exploration.
@ -456,52 +412,3 @@ class CollectionDependencyProviderBase(AbstractProvider):
self._make_req_from_dict({'name': dep_name, 'version': dep_req})
for dep_name, dep_req in req_map.items()
]
# Classes to handle resolvelib API changes between minor versions for 0.X
class CollectionDependencyProvider050(CollectionDependencyProviderBase):
def find_matches(self, requirements): # type: ignore[override]
# type: (list[Requirement]) -> list[Candidate]
return self._find_matches(requirements)
def get_preference(self, resolution, candidates, information): # type: ignore[override]
# type: (t.Optional[Candidate], list[Candidate], list[t.NamedTuple]) -> t.Union[float, int]
return self._get_preference(candidates)
class CollectionDependencyProvider060(CollectionDependencyProviderBase):
def find_matches(self, identifier, requirements, incompatibilities): # type: ignore[override]
# type: (str, t.Mapping[str, t.Iterator[Requirement]], t.Mapping[str, t.Iterator[Requirement]]) -> list[Candidate]
return [
match for match in self._find_matches(list(requirements[identifier]))
if not any(match.ver == incompat.ver for incompat in incompatibilities[identifier])
]
def get_preference(self, resolution, candidates, information): # type: ignore[override]
# type: (t.Optional[Candidate], list[Candidate], list[t.NamedTuple]) -> t.Union[float, int]
return self._get_preference(candidates)
class CollectionDependencyProvider070(CollectionDependencyProvider060):
def get_preference(self, identifier, resolutions, candidates, information): # type: ignore[override]
# type: (str, t.Mapping[str, Candidate], t.Mapping[str, t.Iterator[Candidate]], t.Iterator[t.NamedTuple]) -> t.Union[float, int]
return self._get_preference(list(candidates[identifier]))
class CollectionDependencyProvider080(CollectionDependencyProvider060):
def get_preference(self, identifier, resolutions, candidates, information, backtrack_causes): # type: ignore[override]
# type: (str, t.Mapping[str, Candidate], t.Mapping[str, t.Iterator[Candidate]], t.Iterator[t.NamedTuple], t.Sequence) -> t.Union[float, int]
return self._get_preference(list(candidates[identifier]))
def _get_provider(): # type () -> CollectionDependencyProviderBase
if RESOLVELIB_VERSION >= SemanticVersion("0.8.0"):
return CollectionDependencyProvider080
if RESOLVELIB_VERSION >= SemanticVersion("0.7.0"):
return CollectionDependencyProvider070
if RESOLVELIB_VERSION >= SemanticVersion("0.6.0"):
return CollectionDependencyProvider060
return CollectionDependencyProvider050
CollectionDependencyProvider = _get_provider()

@ -33,6 +33,14 @@ import operator
import sys
import types
from ansible.module_utils.common import warnings as _warnings
_warnings.deprecate(
msg="The `ansible.module_utils.six` module is deprecated.",
help_text="Use the Python standard library equivalent instead.",
version="2.24",
)
# The following makes it easier for us to script updates of the bundled code. It is not part of
# upstream six
_BUNDLED_METADATA = {"pypi_name": "six", "version": "1.17.0"}

@ -225,7 +225,13 @@ def sanity_check(module, host, key, sshkeygen):
rc, stdout, stderr = module.run_command(sshkeygen_command)
if stdout == '': # host not found
module.fail_json(msg="Host parameter does not match hashed host field in supplied key")
results = {
"msg": "Host parameter does not match hashed host field in supplied key",
"rc": rc,
}
if stderr:
results["stderr"] = stderr
module.fail_json(**results)
def search_for_host_key(module, host, key, path, sshkeygen):

@ -54,7 +54,7 @@ class DataLoader:
def __init__(self) -> None:
self._basedir: str = '.'
self._basedir: str = os.path.abspath('.')
# NOTE: not effective with forks as the main copy does not get updated.
# avoids rereading files
@ -227,7 +227,7 @@ class DataLoader:
def set_basedir(self, basedir: str) -> None:
""" sets the base directory, used to find files when a relative path is given """
self._basedir = basedir
self._basedir = os.path.abspath(basedir)
def path_dwim(self, given: str) -> str:
"""

@ -17,7 +17,6 @@
from __future__ import annotations
import ansible.constants as C
from ansible.errors import AnsibleParserError
from ansible.module_utils.common.sentinel import Sentinel
from ansible.playbook.attribute import NonInheritableFieldAttribute
@ -316,8 +315,7 @@ class Block(Base, Conditional, CollectionSearch, Taggable, Notifiable, Delegatab
filtered_block = evaluate_block(task)
if filtered_block.has_tasks():
tmp_list.append(filtered_block)
elif ((task.action in C._ACTION_META and task.implicit) or
task.evaluate_tags(self._play.only_tags, self._play.skip_tags, all_vars=all_vars)):
elif task.evaluate_tags(self._play.only_tags, self._play.skip_tags, all_vars=all_vars):
tmp_list.append(task)
return tmp_list

@ -165,17 +165,29 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
subdir = 'tasks'
if use_handlers:
subdir = 'handlers'
try:
include_target = templar.template(task.args['_raw_params'])
except AnsibleUndefinedVariable as ex:
raise AnsibleParserError(
message=f"Error when evaluating variable in import path {task.args['_raw_params']!r}.",
help_text="When using static imports, ensure that any variables used in their names are defined in vars/vars_files\n"
"or extra-vars passed in from the command line. Static imports cannot use variables from facts or inventory\n"
"sources like group or host vars.",
obj=task_ds,
) from ex
# FIXME this appears to be (almost?) duplicate code as in IncludedFile for include_tasks
while parent_include is not None:
if not isinstance(parent_include, TaskInclude):
parent_include = parent_include._parent
continue
parent_include.post_validate(templar=templar)
parent_include_dir = os.path.dirname(parent_include.args.get('_raw_params'))
if isinstance(parent_include, IncludeRole):
parent_include_dir = parent_include._role_path
else:
parent_include_dir = os.path.dirname(templar.template(parent_include.args.get('_raw_params')))
if cumulative_path is None:
cumulative_path = parent_include_dir
elif not os.path.isabs(cumulative_path):
cumulative_path = os.path.join(parent_include_dir, cumulative_path)
include_target = templar.template(task.args['_raw_params'])
if task._role:
new_basedir = os.path.join(task._role._role_path, subdir, cumulative_path)
include_file = loader.path_dwim_relative(new_basedir, subdir, include_target)
@ -189,16 +201,6 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
parent_include = parent_include._parent
if not found:
try:
include_target = templar.template(task.args['_raw_params'])
except AnsibleUndefinedVariable as ex:
raise AnsibleParserError(
message=f"Error when evaluating variable in import path {task.args['_raw_params']!r}.",
help_text="When using static imports, ensure that any variables used in their names are defined in vars/vars_files\n"
"or extra-vars passed in from the command line. Static imports cannot use variables from facts or inventory\n"
"sources like group or host vars.",
obj=task_ds,
) from ex
if task._role:
include_file = loader.path_dwim_relative(task._role._role_path, subdir, include_target)
else:

@ -314,19 +314,9 @@ class Play(Base, Taggable, CollectionSearch):
t.args['_raw_params'] = 'flush_handlers'
t.implicit = True
t.set_loader(self._loader)
t.tags = ['always']
if self.tags:
# Avoid calling flush_handlers in case the whole play is skipped on tags,
# this could be performance improvement since calling flush_handlers on
# large inventories could be expensive even if no hosts are notified
# since we call flush_handlers per host.
# Block.filter_tagged_tasks ignores evaluating tags on implicit meta
# tasks so we need to explicitly call Task.evaluate_tags here.
t.tags = self.tags
if t.evaluate_tags(self.only_tags, self.skip_tags, all_vars=self.vars):
flush_block.block = [t]
else:
flush_block.block = [t]
flush_block.block = [t]
# NOTE keep flush_handlers tasks even if a section has no regular tasks,
# there may be notified handlers from the previous section

@ -192,7 +192,7 @@ class ActionModule(ActionBase):
msg="checksum mismatch", file=source, dest=dest, remote_md5sum=None,
checksum=new_checksum, remote_checksum=remote_checksum))
else:
result.update({'changed': True, 'md5sum': new_md5, 'dest': dest,
result.update({'changed': True, 'md5sum': new_md5, 'file': source, 'dest': dest,
'remote_md5sum': None, 'checksum': new_checksum,
'remote_checksum': remote_checksum})
else:

@ -5,7 +5,7 @@ DOCUMENTATION:
short_description: Pythonic false
description:
- This check is a more Python version of what is 'false'.
- It is the opposite of 'truthy'.
- It is the opposite of P(ansible.builtin.truthy#test).
options:
_input:
description: An expression that can be expressed in a boolean context.

@ -20,5 +20,5 @@ EXAMPLES: |
thisisfalse: '{{ "" is truthy }}'
RETURN:
_value:
description: Returns V(True) if the condition is not "Python truthy", V(False) otherwise.
description: Returns V(True) if the condition is "Python truthy", V(False) otherwise.
type: boolean

@ -17,6 +17,6 @@
from __future__ import annotations
__version__ = '2.20.0.dev0'
__version__ = '2.20.0b2'
__author__ = 'Ansible, Inc.'
__codename__ = "Good Times Bad Times"

@ -17,7 +17,6 @@
from __future__ import annotations
import os
import sys
import typing as t
@ -447,7 +446,7 @@ class VariableManager:
"""
variables = {}
variables['playbook_dir'] = os.path.abspath(self._loader.get_basedir())
variables['playbook_dir'] = self._loader.get_basedir()
variables['ansible_playbook_python'] = sys.executable
variables['ansible_config_file'] = C.CONFIG_FILE

@ -1,5 +1,5 @@
[build-system]
requires = ["setuptools >= 66.1.0, <= 80.3.1", "wheel == 0.45.1"] # lower bound to support controller Python versions, upper bound for latest version tested at release
requires = ["setuptools >= 66.1.0, <= 80.9.0", "wheel == 0.45.1"] # lower bound to support controller Python versions, upper bound for latest version tested at release
build-backend = "setuptools.build_meta"
[project]

@ -211,6 +211,13 @@ ANSIBLE_LIBRARY='./nolibrary' ansible-doc --metadata-dump --no-fail-on-errors --
output=$(ANSIBLE_LIBRARY='./nolibrary' ansible-doc --metadata-dump --playbook-dir broken-docs testns.testcol 2>&1 | grep -c 'ERROR' || true)
test "${output}" -eq 1
# ensure --metadata-dump does not crash if the ansible_collections is nested (https://github.com/ansible/ansible/issues/84909)
testdir="$(pwd)"
pbdir="collections/ansible_collections/testns/testcol/playbooks"
cd "$pbdir"
ANSIBLE_COLLECTIONS_PATH="$testdir/$pbdir/collections" ansible-doc -vvv --metadata-dump --no-fail-on-errors
cd "$testdir"
echo "test doc list on broken role metadata"
# ensure that role doc does not fail when --no-fail-on-errors is supplied
ANSIBLE_LIBRARY='./nolibrary' ansible-doc --no-fail-on-errors --playbook-dir broken-docs testns.testcol.testrole -t role 1>/dev/null 2>&1

@ -5,7 +5,5 @@ test_repo_path: "{{ galaxy_dir }}/development/ansible_test"
test_error_repo_path: "{{ galaxy_dir }}/development/error_test"
supported_resolvelib_versions:
- "0.5.3" # Oldest supported
- "0.6.0"
- "0.7.0"
- "0.8.0"
- "0.8.0" # Oldest supported
- "< 2.0.0"

@ -5,18 +5,14 @@ gpg_homedir: "{{ galaxy_dir }}/gpg"
offline_server: https://test-hub.demolab.local/api/galaxy/content/api/
# Test oldest and most recently supported, and versions with notable changes.
# The last breaking change for a feature ansible-galaxy uses was in 0.8.0.
# It would be redundant to test every minor version since 0.8.0, so we just test against the latest minor release.
# NOTE: If ansible-galaxy incorporates new resolvelib features, this matrix should be updated to verify the features work on all supported versions.
supported_resolvelib_versions:
- "0.5.3" # test CollectionDependencyProvider050
- "0.6.0" # test CollectionDependencyProvider060
- "0.7.0" # test CollectionDependencyProvider070
- "<2.0.0" # test CollectionDependencyProvider080
- "0.8.0"
- "< 2.0.0"
unsupported_resolvelib_versions:
- "0.2.0" # Fails on import
- "0.5.1"
- "0.5.3"
pulp_repositories:
- primary

@ -30,8 +30,10 @@
that:
- fetched is changed
- fetched.checksum == "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"
- fetched.file == remote_tmp_dir ~ "/orig"
- fetched_again is not changed
- fetched_again.checksum == "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"
- fetched_again.file == remote_tmp_dir ~ "/orig"
- fetched.remote_checksum == "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"
- lookup("file", output_dir + "/fetched/" + inventory_hostname + remote_tmp_dir + "/orig") == "test"
- fetch_check_mode is skipped

@ -229,6 +229,13 @@ ansible-playbook handler_notify_earlier_handler.yml "$@" 2>&1 | tee out.txt
ANSIBLE_DEBUG=1 ansible-playbook tagged_play.yml --skip-tags the_whole_play "$@" 2>&1 | tee out.txt
[ "$(grep out.txt -ce 'META: triggered running handlers')" = "0" ]
[ "$(grep out.txt -ce 'No handler notifications for')" = "0" ]
[ "$(grep out.txt -ce 'handler_ran')" = "0" ]
[ "$(grep out.txt -ce 'handler1_ran')" = "0" ]
ansible-playbook rescue_flush_handlers.yml "$@"
ANSIBLE_DEBUG=1 ansible-playbook tagged_play.yml --tags task_tag "$@" 2>&1 | tee out.txt
[ "$(grep out.txt -ce 'META: triggered running handlers')" = "1" ]
[ "$(grep out.txt -ce 'handler_ran')" = "0" ]
[ "$(grep out.txt -ce 'handler1_ran')" = "1" ]

@ -2,9 +2,19 @@
gather_facts: false
tags: the_whole_play
tasks:
- command: echo
- debug:
changed_when: true
notify: h
- debug:
changed_when: true
notify: h1
tags: task_tag
handlers:
- name: h
debug:
msg: handler_ran
- name: h1
debug:
msg: handler1_ran

@ -155,3 +155,9 @@ ansible-playbook test_null_include_filename.yml 2>&1 | tee test_null_include_fil
test "$(grep -c 'No file specified for ansible.builtin.include_tasks' test_null_include_filename.out)" = 1
test "$(grep -c '.*/include_import/null_filename/tasks.yml:4:3.*' test_null_include_filename.out)" = 1
test "$(grep -c '\- name: invalid include_task definition' test_null_include_filename.out)" = 1
# https://github.com/ansible/ansible/issues/69882
set +e
ansible-playbook test_nested_non_existent_tasks.yml 2>&1 | tee test_nested_non_existent_tasks.out
set -e
test "$(grep -c 'Could not find or access' test_nested_non_existent_tasks.out)" = 3

@ -0,0 +1,5 @@
- hosts: localhost
gather_facts: false
tasks:
- include_role:
name: nested_tasks

@ -10,4 +10,9 @@
that:
- nested_adjacent_count|int == 2
- set_fact:
not_available_at_parsing: root
- import_tasks: "{{ role_path }}/tests/main.yml"
become: true
become_user: "{{ not_available_at_parsing }}"

@ -0,0 +1,6 @@
- command: whoami
register: r
- assert:
that:
- r.stdout == not_available_at_parsing

@ -507,3 +507,4 @@
that:
- result is failed
- result.msg == 'Host parameter does not match hashed host field in supplied key'
- result.rc is defined

@ -2,6 +2,7 @@
from __future__ import annotations
import functools
import os
import typing as t
@ -108,10 +109,6 @@ class AnsibleUnwantedChecker(BaseChecker):
'Iterator',
)
),
'ansible.module_utils.six': UnwantedEntry(
'the Python standard library equivalent'
),
}
unwanted_functions = {
@ -136,6 +133,19 @@ class AnsibleUnwantedChecker(BaseChecker):
modules_only=True),
}
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
# ansible.module_utils.six is deprecated and collections can still use it until it is removed
if self.is_ansible_core:
self.unwanted_imports['ansible.module_utils.six'] = UnwantedEntry(
'the Python standard library equivalent'
)
@functools.cached_property
def is_ansible_core(self) -> bool:
"""True if ansible-core is being tested."""
return not self.linter.config.collection_name
def visit_import(self, node): # type: (astroid.node_classes.Import) -> None
"""Visit an import node."""
for name in node.names:

@ -17,6 +17,7 @@
from __future__ import annotations
import collections
import os
import pathlib
import tempfile
@ -109,9 +110,9 @@ class TestDataLoader(unittest.TestCase):
self.assertIn('/tmp/roles/testrole/tasks/included2.yml', called_args)
self.assertIn('/tmp/roles/testrole/tasks/tasks/included2.yml', called_args)
# relative directories below are taken in account too:
self.assertIn('tasks/included2.yml', called_args)
self.assertIn('included2.yml', called_args)
c = collections.Counter(called_args)
assert c['/tmp/roles/testrole/tasks/included2.yml'] == 1
assert c['/tmp/roles/testrole/tasks/tasks/included2.yml'] == 2
def test_path_dwim_root(self):
self.assertEqual(self._loader.path_dwim('/'), '/')
@ -167,7 +168,7 @@ class TestPathDwimRelativeStackDataLoader(unittest.TestCase):
self.assertRaisesRegex(AnsibleFileNotFound, 'on the Ansible Controller', self._loader.path_dwim_relative_stack, None, None, None)
def test_empty_strings(self):
self.assertEqual(self._loader.path_dwim_relative_stack('', '', ''), './')
self.assertEqual(self._loader.path_dwim_relative_stack('', '', ''), os.path.abspath('./') + '/')
def test_empty_lists(self):
self.assertEqual(self._loader.path_dwim_relative_stack([], '', '~/'), os.path.expanduser('~'))

Loading…
Cancel
Save