* deb822_repository: validate name parameter instead of over-normalizing
The deb822_repository module was silently mangling the name parameter by converting to lowercase, replacing underscores with hyphens, and removing other characters. This caused filename collisions where distinct repository names produced identical filenames.
This change validates that the name parameter contains only valid APT sources.list filename characters (a-zA-Z0-9_.-) and preserves the name as-is. Invalid characters now result in a clear error message.
Fixes: #86243
* fix: update install.yml test to use valid name without spaces
* deb822_repository: add backward compatibility for legacy filenames
Check if a file with the old normalized naming convention already exists before using the new naming. If a legacy file exists, reuse that slug to avoid creating duplicate files for the same repository.
This addresses feedback from #86343 to maintain backward compatibility.
* deb822_repository: adopt PR #86343 approach for backward compatibility
Based on maintainer feedback, removed strict validation that hard-failed on invalid characters. Instead:
- Convert spaces to hyphens (backward compatible with existing playbooks)
- Preserve case, underscores, and periods
- Check for legacy-normalized files and reuse them if they exist
This maintains backward compatibility while still avoiding over-normalization.
Addresses feedback from https://github.com/ansible/ansible/pull/86494#discussion_r1975816493
* Replicate PR #86343 structure and fix trailing whitespace
- Created name_handling.yml with exact tests from #86343
- Import name_handling.yml in main.yml
- Removed conflicting tests from test.yml
- Updated changelog to match #86343 format
- Fixed trailing whitespace on line 584 (pep8/pylint fix)
* Apply suggested change: inline name.replace() directly
* Fix discrepancy between ansible-galaxy and ansible runtime when identifying usable collections
When enumerating usable collections, ansible-galaxy validates the galaxy metadata in the MANIFEST.json/galaxy.yml matches the collection path.
When the metadata is incorrect ansible-galaxy emits a warning and falls back to using no metadata since it is not required for usable collections.
* ansible-galaxy collection verify now evaluates the collection that will be used at runtime, even if a collection inaccurately documents the same namespace and name earlier in the search path
* Add integration tests for ansible-galaxy collection verify, list, and install
Changes the logic used by `Ansible.ModuleUtils.AddType` to only include
the debug information when `DISPLAY_TRACEBACKS` is set to `error` or
`always`. This aligns with the new logic that no longer uses the
verbosity level to include extra traceback information with higher
verbosities.
The local connection plugin is incorrectly passing a bytearray to methods of become plugins that expect bytes. A recent change to the su plugin exposed this by breaking the become plugin for different locale settings (the bytearray was not properly converted to a str for comparison operations). This changes the local connection plugin to send bytes.
Fix the output of git checkmode when supplied with a nonexistent ref for the version parameter.
Uses git fetch --dry-run [ref] to check if the supplied ref actually exists.
PR #86461.
Prior to this patch, the core packaging metadata contained relative contributing and license file URLs in its description field, which is sourced from the `README.md` file. These URLs are relative to the website location they're rendered in. On GitHub, they'd point to neighboring files in the repository but PyPI does not host them and this makes relative URLs point to addresses on PyPI that do not exist.
The change updates the lin URLs to be absolute and point to the file views in the GitHub repository, which fixes#86460.
Co-authored-by: 🇺🇦 Sviatoslav Sydorenko (Святослав Сидоренко) <webknjaz@redhat.com>
This is a fix for a common issue where Ansible is setting the LIB env var to the data type (System.Collections.DictionaryEntry) and not the actual value.
It unfortunately causes downstream issues if you run PowerShell scripts that are affected by the LIB variable not being a search path, but an incorrect string. It causes Add-Type to fail on even the simples call (like `Add-Type "using System;"`
Fixes an issue where the user module would create the /nonexistent directory when modifying a user to add them to a group on FreeBSD. The /nonexistent path is a standard convention for system accounts on FreeBSD that should not exist physically on disk.
This commit adds a check in the FreeBsdUser.modify_user() method to skip home directory creation when the home path is /nonexistent.
Fixes#86368
Co-authored-by: zykov <zykov@biocad.ru>
* Consider the timezone offset while creating timestamp from `zipinfo -T`
information. This information is required while comparing to mtime of the file
on local filesystem (for idempotency purposes).
Fixes: #85779
Signed-off-by: Abhijeet Kasurde <Akasurde@redhat.com>
This commit validates changes in a shallow clone git repo and shows
a diff for combined check and diff mode in case if any old single
full commit sha is provided in version parameter instead of any
branch name or HEAD together with refspec parameter.
At present, if an old commit sha is provided to version parameter
for a shallow clone git repository initially cloned using depth: 1
and if ansible-playbook is executed with --diff --check together,
the command shows:
Failed to get proper diff between <before_sha> and <after_sha>
fatal: bad object <after_sha>
One has to look into the examples to realize the generaed UUID is a UUIDv5.
As of today, `to_uuid` returns a UUIDv5. Document it.
Link: f2357cdc53/lib/ansible/plugins/filter/core.py (L338-L346)
Signed-off-by: Ariel Otilibili <a.otilibili@instadeep.com>
* ansible-galaxy - Change error to warning when no paths exist
When listing collections, a warning is much more appropriate than an error
for missing paths.
* winrm - Add better Kerberos error
Adds a better error when Kerberos authentication is requested but the
`pykerberos` library is not installed. This also removes the fallback to
basic auth if the username is in the UPN format and no transport/auth
method is specified. This is because a UPN user must be a domain account
and domain accounts cannot be used with basic auth.
* Add more docs about user settings
* Fix some grammar issues
The stubs are taken from the unmerged PR [[1]] upstream. MyPy is set
up to rely on them instead of the missing package type annotations.
[1]: https://github.com/pypa/distlib/pull/195
When using sshpass the file descriptors leaks would happen in the reset
method that used _build_command that creates the pipe but the command
would not go through _bare_run which closes the pipe.
Another scenario would be _bare_run failing and not all code path would
properly close the pipe.
This patch fixes the issues by:
* move creating the pipe from _build_command closer to where it is used
in _bare_run
* wrap _bare_run with closing the pipe in case of a failure
* no need to re-create pipe in the retry code
* unrelated but simplify the reset method
* copy: honor directory_mode when specified with remote_src=True
* Honor directory_mode specified by user when copying directories
and remote_src=True
Fixes: #81292
Signed-off-by: Abhijeet Kasurde <Akasurde@redhat.com>
Refer to versions that are changed less frequently in AGENTS.md to reduce the frequency of updates needed to keep it up-to-date.
Also fix a few spacing issues.
* Support configuring callback plugins with --extra-vars
Callback plugins define variable names in the documentation for ConfigManager
Variable values can be omitted
* Added default callback variable configuration for display_skipped_hosts
Fixes#84469
Co-authored-by: Matt Clay <matt@mystile.com>
* GNU digest line may contain multiple spaces between
checksum and filename. Fix regex to handle this situation.
Fixes: #86132
Signed-off-by: Abhijeet Kasurde <Akasurde@redhat.com>
This patch fixes integration test jobs running under RHEL 10.0 that
don't have this extension pre-installed.
Co-Authored-By: sivel / Matt Martz <matt@sivel.net>
ci_complete
ci_coverage
* Prevent unnecessary match extension duplicates
I moved this to use a set instead of the
`if not in rule` just in case there's a comment
like 'owner' or another stray string that matches
the extension.
* Report bad-return-value-key for return values that cannot be accessed with Jinja's dot notation.
* Move constants into separate module.
* Add test to check FORBIDDEN_DICTIONARY_KEYS against current Python's key list.
* Remove unused constant.
* Apply suggestions from code review.
Co-authored-by: Matt Clay <matt@mystile.com>
* Add type annotations.
* Simplify typing.
Co-authored-by: Matt Clay <matt@mystile.com>
---------
Co-authored-by: Matt Clay <matt@mystile.com>
* Remove decrypt arg-docs mismatch
Removes the use of the arg in the action plugin
and removes the associated doc fragment. Changes
no behavior because the lack of decrypt in the
argspec prevents a value being passed in and
the args.get('decrypt', True) means that it is
always true.
Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
* Add an override of the `/review` slash command in claude code
* Add support for `CLAUDE.local.md` and `~/.claude/ansible.md`
Co-authored-by: 🇺🇦 Sviatoslav Sydorenko (Святослав Сидоренко) <wk.cvs.github@sydorenko.org.ua>
* Handle ValueError raised when user set invalid priority values
* Update tests to work with Pytest
Signed-off-by: Abhijeet Kasurde <Akasurde@redhat.com>
Co-authored-by: Mannu Silva <wise.tent4987@fastmail.com>
* Use json for test inventory - ci_complete
Uses the JSON/YAML format for the inventory files generated by
`ansible-test`. This solves minor issues with using complex values when
building the test inventory files like backslashes or more complex data
structures.
* Apply suggestions from code review
Co-authored-by: Matt Clay <matt@mystile.com>
* Add changelog and use more limited ext config var - ci_complete
---------
Co-authored-by: Matt Clay <matt@mystile.com>
Sometimes, AZP would mark steps in jobs as cancelled when they've
actually exited successfully but on the boundary of the default
60-minute timeout. Such logs might be difficult to reason about.
Additionally, `entry-point.sh` sets a 60-minute timeout for the main
test invocation but it would never trigger earlier that AZP would kill
such a job as the job-global timeout was 60 minutes already and it'd
always be hit earlier than the test runner one.
The patch sets maximum observable job timeouts with extra buffer to
account for flakiness.
PR #86073
Co-authored-by: Matt Clay <matt@mystile.com>
* File based cache plugins filenames fix
File based cache plugins will now correctly handle inventory_hostnames
with 'path symbols' in their names. This should allow those using
chroot and jail connection plugins to use file based caches now.
* Remove safe_eval from codebase
Resolves deprecations in 85996 and 85999
* Remove deprecations from sanity ignores
* Add changelog fragment
* Add newline to file
* Remove unused imports
* interpreter_discovery: removed auto_silent* option
* Removed deprecated auto_silent* option from interpreter_discovery_python
Fixes: #85995
Signed-off-by: Abhijeet Kasurde <Akasurde@redhat.com>
* Make CI green
Signed-off-by: Abhijeet Kasurde <Akasurde@redhat.com>
* Make CI green I
Signed-off-by: Abhijeet Kasurde <Akasurde@redhat.com>
---------
Signed-off-by: Abhijeet Kasurde <Akasurde@redhat.com>
* Add support for crypt/libxcrypt via ctypes, as an alternative to passlib
* move verbosity message to BaseHash
* Don't require DYLD_LIBRARY_PATH mods for standard homebrew installs on macos
* improve crypt_gensalt error handling
* Do not require wheel for building
- current version of setuptools (70.1+) does not need wheel at all
- older versions of setuptools would fetch wheel when building wheels (but not sdists)
* Pin setuptools to a version not requiring wheel
Now when we don't list wheel,
we are unable to pin it to a particular version.
Instead, use setuptools version that no longer uses it.
* include_role now behaves more like task on error
changes _from errors from syntax to task failures, by default
which makes it more consistent with other existing errors
* also force 'missing role' to behave as syntax error when false
* also error when subdir does not exist, previouslly we ignored missing
file
* add 'rescuable' toggle to allow user to chose error type
Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
Co-authored-by: Sloane Hertel <19572925+s-hertel@users.noreply.github.com>
show_origin and variable sources were broken for base config when 'forked' from plugins
---------
Co-authored-by: 🇺🇦 Sviatoslav Sydorenko (Святослав Сидоренко) <wk.cvs.github@sydorenko.org.ua>
Removes the warning emitted when using Add-Type and the cleanup of temp
files fails due to a file still being in use. The cleanup should be
handled by AnsibleModule on exit giving it more time to wait for any
open file handles to close. The exception is still present if calling
`Add-CSharpType` without an `AnsibleModule` object.
Apparently `codecovcli send-notifications` does not have a `--dry-run`
CLI option. This patch stops adding it to the command and implements
an external `dry-run` mode in the wrapper script or this case instead.
This is a follow-up for #85968.
Co-authored-by: Matt Clay <matt@mystile.com>
There were couple of occurrences where the hard 30 seconds limit on
running ssh-agent was not enough for the test to run and the ssh-agent
was killed resulting in the test failing with "Connection refused". This
change just lets the agent run in the background and kills it
manually after the tests finish.
* psrp - ReadTimeout exceptions now mark host as unreachable
* add try to _exec_psrp_script
* fix indent E111
* update raise format
switch to raise Exception from e
Co-authored-by: Jordan Borean <jborean93@gmail.com>
---------
Co-authored-by: Jordan Borean <jborean93@gmail.com>
The logs were displaying a series of numbers in parens like `(66.1.0)`
at the end of each error line. its unintuitive what that means. I had
to look into the source code to confirm my suspicion of it being the
version of `setuptools`. This patch spells it out.
This patch drops unnecessary default for
`CollectionDependencyProvider`'s `concrete_artifacts_manager` argument
as it is always passed, in every place across the code base where the
provider is constructed.
It was also causing MyPy violations on calls to
`_ComputedReqKindsMixin.from_requirement_dict()` in the "strict
optional" mode which is now enforced for $sbj, while remaining
disabled globally.
It is a #85545 follow-up.
This patch is a combination of `pyrefly autotype` and manual
post-processing. Parts of it migrate pre-existing comment-based
annotations, fixing incorrect ones where applicable.
The change also configures MyPy to run checks against actual
`resolvelib` annotations and includes a small tweak of
`ansible.galaxy.collection._resolve_depenency_map` to make it
compatible with those.
Co-Authored-By: Jordan Borean <jborean93@gmail.com>
Co-Authored-By: Matt Clay <matt@mystile.com>
Co-Authored-By: Sloane Hertel <19572925+s-hertel@users.noreply.github.com>
* 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>
* 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>
This file provides guidance to Claude Code (claude.ai/code) and other compatible agentic tools when working with code in this repository.
**Note:** This file is for AI assistant use only. For human developers, see the [Ansible Developer Guide](https://docs.ansible.com/ansible-core/devel/dev_guide/index.html).
## ⚠️ IMPORTANT: Always Start Here
**BEFORE starting any PR review or development task:**
1. **Read this file first** - Don't work from memory or assumptions
2. **Use TodoWrite** to create a task list and track progress systematically
3. **Follow the numbered steps** in the relevant process sections
4. **Reference Quick Reference** for correct commands and patterns
## ⚠️ CRITICAL: Licensing Requirements
**NEVER suggest, recommend, or approve code that violates these requirements:**
- **ansible-core**: All code must be **GPLv3 compatible**
- **lib/ansible/module_utils/**: Defaults to **BSD-2-Clause** (more permissive)
- **External dependencies**: Only recommend libraries compatible with these licenses
- **PR reviews**: Always verify any new dependencies or suggested libraries are license-compatible
- **When in doubt**: Ask about licensing compatibility rather than assuming
**This is non-negotiable** - licensing violations can create serious legal issues for the project.
## Quick Reference
Most commonly used commands and patterns:
```bash
# Testing
ansible-test sanity -v --docker default # Run all sanity tests
ansible-test sanity -v --docker default --test <test> # Run specific sanity test
ansible-test units -v --docker default # Run unit tests
ansible-test integration -v --docker ubuntu2404 # Run integration tests
# PR Review and CI
gh pr view <number> # Get PR details
gh pr view <number> --comments # Check for ansibot CI failures
gh pr checks <number> # Get Azure Pipelines URLs
gh pr checkout <number> # Switch to PR branch
gh pr diff <number> # See all changes
```
**Container Selection:**
- Sanity/Unit tests: `--docker default`
- Integration tests: `--docker ubuntu2204`, `--docker ubuntu2404`, etc. (NOT default/base)
**Critical Reminders:**
- **Licensing**: See [Licensing Requirements](#️-critical-licensing-requirements) - GPLv3/BSD-2-Clause only
## Development Environment Setup
Ansible development typically uses an editable install after forking and cloning:
```bash
# After forking and cloning the repository
pip install -e .
```
**Note:** ansible-core and all CLIs (including ansible-test) require a POSIX OS. On Windows, use WSL (Windows Subsystem for Linux).
## Testing and CI
### Basic Testing Commands
```bash
# Run sanity tests - these are linting/static analysis (pylint, mypy, pep8, etc.)
[](https://docs.ansible.com/ansible/devel/community/code_of_conduct.html)
[](https://bestpractices.coreinfrastructure.org/projects/2372)
# Ansible
@ -58,7 +58,7 @@ For more ways to get in touch, see [Communicating with the Ansible community](ht
## Contribute to Ansible
* Check out the [Contributor's Guide](./.github/CONTRIBUTING.md).
* Check out the [Contributor's Guide](https://github.com/ansible/ansible/blob/devel/.github/CONTRIBUTING.md).
* Read [Community Information](https://docs.ansible.com/ansible/devel/community) for all
kinds of ways to contribute to and interact with the project,
including how to submit bug reports and code to Ansible.
@ -98,4 +98,6 @@ and has contributions from over 5000 users (and growing). Thanks everyone!
- git - Correct the output of git checkmode to a failure when the ``version`` supplied is an invalid ref (https://github.com/ansible/ansible/issues/51580)
- ansible-test - The runtime-metadata sanity test now ignores pre-release and build identifiers in collection versions. This prevents errors if a tombstone version is ``X.0.0``, while the collection's version is ``X.0.0-prerelease`` (https://github.com/ansible/ansible/issues/85193)."
- 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).
- "Fix ``AnsibleModule.human_to_bytes()``, which was never adjusted after the standalone ``human_to_bytes()`` got a new parameter ``default_unit`` (https://github.com/ansible/ansible/pull/85259)."
``ansible.builtin.pip`` - Running the built-in pip module with ``check_mode`` and packages coming from VCS URLs, archives, or local filepaths now correctly outputs the ``changed`` status of the task.
Previously, it was always reported as changed due to improper package name resolution.
- 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)
- ansible_virtualization_role and ansible_virtualization_type facts - fix the detection of vms running inside FreeBSD Bhyve hypervisor and detection of jails (https://github.com/ansible/ansible/pull/85767)
- "copy - when a single-file local directory was specified as the source, ``changed`` used to be ``false`` even when the source was actually copied. It now makes sure ``changed`` is ``true`` in this case. (https://github.com/ansible/ansible/issues/85833)"
- Removed deprecated ``handle_stats_and_callbacks`` parameter of the ``StrategyBase._load_included_file`` method. (https://github.com/ansible/ansible/issues/86003)
- "ansible-test validate-modules sanity test - now reports bad return value keys that cannot be used with the dot notation in Jinja expressions (https://github.com/ansible/ansible/issues/86079)."
- "dnf - fix package installation when specifying architecture without version (e.g., ``libgcc.i686``) where a different architecture of the same package is already installed (https://github.com/ansible/ansible/issues/86156)."
- user - fix ``FreeBsdUser`` to not create ``/nonexistent`` directory when modifying user to add them to a group on FreeBSD (https://github.com/ansible/ansible/issues/86368)
- deb822_repository - Remove ``Install-Python-Debian`` from files outputted by the ``deb822_repository`` module (https://github.com/ansible/ansible/issues/86395)
- The ``get_platfrom()`` function from ``ansible.module_utils.basic`` is deprecated and will be removed in ansible-core 2.24. Use ``platform.system()`` from the Python standard library instead.
- The ``load_platform_subclass()`` function from ``ansible.module_utils.basic`` is deprecated and will be removed in ansible-core 2.24. Use ``get_platform_subclass()`` from ``ansible.module_utils.common.sys_info`` instead.
- The ``get_all_subclasses()`` function from ``ansible.module_utils.basic`` is deprecated and will be removed in ansible-core 2.24. Use ``get_all_subclasses()`` from ``ansible.module_utils.common._utils`` instead.
- basic - fail in controlled manner when ``run_command()`` attempts to parse a command with broken syntax passed in as a string (https://github.com/ansible/ansible/issues/85719).