Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package ansible-core-2.17 for openSUSE:Factory checked in at 2025-01-29 16:18:05 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ansible-core-2.17 (Old) and /work/SRC/openSUSE:Factory/.ansible-core-2.17.new.2316 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ansible-core-2.17" Wed Jan 29 16:18:05 2025 rev:3 rq:1241115 version:2.17.8 Changes: -------- --- /work/SRC/openSUSE:Factory/ansible-core-2.17/ansible-core-2.17.changes 2024-12-05 17:10:31.838341730 +0100 +++ /work/SRC/openSUSE:Factory/.ansible-core-2.17.new.2316/ansible-core-2.17.changes 2025-01-29 16:18:49.172473467 +0100 @@ -1,0 +2,26 @@ +Tue Jan 28 18:55:05 UTC 2025 - Johannes Kastl <opensuse_buildserv...@ojkastl.de> + +- update to 2.17.8: + * Bugfixes + - Ansible will now also warn when reserved keywords are set via + a module (set_fact, include_vars, etc). + - Ansible.Basic - Fix required_if check when the option value + to check is unset or set to null. + - Use consistent multiprocessing context for action write locks + - ansible-test - Fix up coverage reporting to properly + translate the temporary path of integration test modules to + the expected static test module path. + - ansible-vault will now correctly handle --prompt, previously + it would issue an error about stdin if no 2nd argument was + passed + - copy action now prevents user from setting internal options. + - gather_facts action now defaults to ansible.legacy.setup if + smart was set, no network OS was found and no other alias for + setup was present. + - gather_facts action will now issues errors and warnings as + appropriate if a network OS is detected but no facts modules + are defined for it. + - ssh - connection options were incorrectly templated during + reset_connection tasks (#84238). + +------------------------------------------------------------------- Old: ---- ansible_core-2.17.7.tar.gz ansible_core-2.17.7.tar.gz.sha256 New: ---- ansible_core-2.17.8.tar.gz ansible_core-2.17.8.tar.gz.sha256 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ansible-core-2.17.spec ++++++ --- /var/tmp/diff_new_pack.ffEavZ/_old 2025-01-29 16:18:50.036509298 +0100 +++ /var/tmp/diff_new_pack.ffEavZ/_new 2025-01-29 16:18:50.040509464 +0100 @@ -1,7 +1,7 @@ # # spec file for package ansible-core-2.17 # -# Copyright (c) 2024 SUSE LLC +# Copyright (c) 2025 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -43,7 +43,7 @@ %endif Name: ansible-core-2.17 -Version: 2.17.7 +Version: 2.17.8 Release: 0 Summary: Radically simple IT automation License: GPL-3.0-or-later ++++++ ansible_core-2.17.7.tar.gz -> ansible_core-2.17.8.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/PKG-INFO new/ansible_core-2.17.8/PKG-INFO --- old/ansible_core-2.17.7/PKG-INFO 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/PKG-INFO 2025-01-27 20:45:28.000000000 +0100 @@ -1,6 +1,6 @@ -Metadata-Version: 2.1 +Metadata-Version: 2.2 Name: ansible-core -Version: 2.17.7 +Version: 2.17.8 Summary: Radically simple IT automation Home-page: https://ansible.com/ Author: Ansible, Inc. @@ -36,6 +36,7 @@ Requires-Dist: cryptography Requires-Dist: packaging Requires-Dist: resolvelib<1.1.0,>=0.5.3 +Dynamic: requires-dist [](https://pypi.org/project/ansible-core) [](https://docs.ansible.com/ansible/latest/) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/bin/ansible-vault new/ansible_core-2.17.8/bin/ansible-vault --- old/ansible_core-2.17.7/bin/ansible-vault 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/bin/ansible-vault 2025-01-27 20:45:28.000000000 +0100 @@ -138,11 +138,12 @@ raise AnsibleOptionsError("At most one input file may be used with the --output option") if options.action == 'encrypt_string': - if '-' in options.args or not options.args or options.encrypt_string_stdin_name: + if '-' in options.args or options.encrypt_string_stdin_name or (not options.args and not options.encrypt_string_prompt): + # prompting from stdin and reading from stdin are mutually exclusive, if stdin is still provided, it is ignored self.encrypt_string_read_stdin = True - # TODO: prompting from stdin and reading from stdin seem mutually exclusive, but verify that. if options.encrypt_string_prompt and self.encrypt_string_read_stdin: + # should only trigger if prompt + either - or encrypt string stdin name were provided raise AnsibleOptionsError('The --prompt option is not supported if also reading input from stdin') return options diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/changelogs/CHANGELOG-v2.17.rst new/ansible_core-2.17.8/changelogs/CHANGELOG-v2.17.rst --- old/ansible_core-2.17.7/changelogs/CHANGELOG-v2.17.rst 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/changelogs/CHANGELOG-v2.17.rst 2025-01-27 20:45:28.000000000 +0100 @@ -4,6 +4,28 @@ .. contents:: Topics +v2.17.8 +======= + +Release Summary +--------------- + +| Release Date: 2025-01-27 +| `Porting Guide <https://docs.ansible.com/ansible-core/2.17/porting_guides/porting_guide_core_2.17.html>`__ + +Bugfixes +-------- + +- Ansible will now also warn when reserved keywords are set via a module (set_fact, include_vars, etc). +- Ansible.Basic - Fix ``required_if`` check when the option value to check is unset or set to null. +- Use consistent multiprocessing context for action write locks +- ansible-test - Fix up coverage reporting to properly translate the temporary path of integration test modules to the expected static test module path. +- ansible-vault will now correctly handle `--prompt`, previously it would issue an error about stdin if no 2nd argument was passed +- copy action now prevents user from setting internal options. +- gather_facts action now defaults to `ansible.legacy.setup` if `smart` was set, no network OS was found and no other alias for `setup` was present. +- gather_facts action will now issues errors and warnings as appropriate if a network OS is detected but no facts modules are defined for it. +- ssh - connection options were incorrectly templated during ``reset_connection`` tasks (https://github.com/ansible/ansible/pull/84238). + v2.17.7 ======= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/changelogs/changelog.yaml new/ansible_core-2.17.8/changelogs/changelog.yaml --- old/ansible_core-2.17.7/changelogs/changelog.yaml 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/changelogs/changelog.yaml 2025-01-27 20:45:28.000000000 +0100 @@ -1029,3 +1029,50 @@ - selinux_import.yml - unsafe_hostvars_fix.yml release_date: '2024-11-25' + 2.17.8: + changes: + release_summary: '| Release Date: 2025-01-27 + + | `Porting Guide <https://docs.ansible.com/ansible-core/2.17/porting_guides/porting_guide_core_2.17.html>`__ + + ' + codename: Gallows Pole + fragments: + - 2.17.8_summary.yaml + release_date: '2025-01-27' + 2.17.8rc1: + changes: + bugfixes: + - Ansible will now also warn when reserved keywords are set via a module (set_fact, + include_vars, etc). + - Ansible.Basic - Fix ``required_if`` check when the option value to check is + unset or set to null. + - Use consistent multiprocessing context for action write locks + - ansible-test - Fix up coverage reporting to properly translate the temporary + path of integration test modules to the expected static test module path. + - ansible-vault will now correctly handle `--prompt`, previously it would issue + an error about stdin if no 2nd argument was passed + - copy action now prevents user from setting internal options. + - gather_facts action now defaults to `ansible.legacy.setup` if `smart` was + set, no network OS was found and no other alias for `setup` was present. + - gather_facts action will now issues errors and warnings as appropriate if + a network OS is detected but no facts modules are defined for it. + - ssh - connection options were incorrectly templated during ``reset_connection`` + tasks (https://github.com/ansible/ansible/pull/84238). + release_summary: '| Release Date: 2025-01-20 + + | `Porting Guide <https://docs.ansible.com/ansible-core/2.17/porting_guides/porting_guide_core_2.17.html>`__ + + ' + codename: Gallows Pole + fragments: + - 2.17.8rc1_summary.yaml + - 84238-fix-reset_connection-ssh_executable-templated.yml + - Ansible.Basic-required_if-null.yml + - ansible-test-coverage-test-files.yml + - copy_validate_input.yml + - gather_facts_netos_fixes.yml + - macos-correct-lock.yml + - reserved_module_chekc.yml + - vault_cli_fix.yml + release_date: '2025-01-20' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/lib/ansible/cli/vault.py new/ansible_core-2.17.8/lib/ansible/cli/vault.py --- old/ansible_core-2.17.7/lib/ansible/cli/vault.py 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/lib/ansible/cli/vault.py 2025-01-27 20:45:28.000000000 +0100 @@ -138,11 +138,12 @@ raise AnsibleOptionsError("At most one input file may be used with the --output option") if options.action == 'encrypt_string': - if '-' in options.args or not options.args or options.encrypt_string_stdin_name: + if '-' in options.args or options.encrypt_string_stdin_name or (not options.args and not options.encrypt_string_prompt): + # prompting from stdin and reading from stdin are mutually exclusive, if stdin is still provided, it is ignored self.encrypt_string_read_stdin = True - # TODO: prompting from stdin and reading from stdin seem mutually exclusive, but verify that. if options.encrypt_string_prompt and self.encrypt_string_read_stdin: + # should only trigger if prompt + either - or encrypt string stdin name were provided raise AnsibleOptionsError('The --prompt option is not supported if also reading input from stdin') return options diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/lib/ansible/executor/action_write_locks.py new/ansible_core-2.17.8/lib/ansible/executor/action_write_locks.py --- old/ansible_core-2.17.7/lib/ansible/executor/action_write_locks.py 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/lib/ansible/executor/action_write_locks.py 2025-01-27 20:45:28.000000000 +0100 @@ -19,7 +19,7 @@ import multiprocessing.synchronize -from multiprocessing import Lock +from ansible.utils.multiprocessing import context as multiprocessing_context from ansible.module_utils.facts.system.pkg_mgr import PKG_MGRS @@ -32,7 +32,7 @@ # Below is a Lock for use when we weren't expecting a named module. It gets used when an action # plugin invokes a module whose name does not match with the action's name. Slightly less # efficient as all processes with unexpected module names will wait on this lock - action_write_locks[None] = Lock() + action_write_locks[None] = multiprocessing_context.Lock() # These plugins are known to be called directly by action plugins with names differing from the # action plugin name. We precreate them here as an optimization. @@ -41,4 +41,4 @@ mods.update(('copy', 'file', 'setup', 'slurp', 'stat')) for mod_name in mods: - action_write_locks[mod_name] = Lock() + action_write_locks[mod_name] = multiprocessing_context.Lock() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/lib/ansible/executor/task_executor.py new/ansible_core-2.17.8/lib/ansible/executor/task_executor.py --- old/ansible_core-2.17.7/lib/ansible/executor/task_executor.py 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/lib/ansible/executor/task_executor.py 2025-01-27 20:45:28.000000000 +0100 @@ -1044,18 +1044,6 @@ option_vars = C.config.get_plugin_vars('connection', self._connection._load_name) varnames.extend(option_vars) - # create dict of 'templated vars' - options = {'_extras': {}} - for k in option_vars: - if k in variables: - options[k] = templar.template(variables[k]) - - # add extras if plugin supports them - if getattr(self._connection, 'allow_extras', False): - for k in variables: - if k.startswith('ansible_%s_' % self._connection.extras_prefix) and k not in options: - options['_extras'][k] = templar.template(variables[k]) - task_keys = self._task.dump_attrs() # The task_keys 'timeout' attr is the task's timeout, not the connection timeout. @@ -1073,7 +1061,8 @@ del task_keys['retries'] # set options with 'templated vars' specific to this plugin and dependent ones - self._connection.set_options(task_keys=task_keys, var_options=options) + var_options = self._connection._resolve_option_variables(variables, templar) + self._connection.set_options(task_keys=task_keys, var_options=var_options) varnames.extend(self._set_plugin_options('shell', variables, templar, task_keys)) if self._connection.become is not None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/lib/ansible/executor/task_queue_manager.py new/ansible_core-2.17.8/lib/ansible/executor/task_queue_manager.py --- old/ansible_core-2.17.7/lib/ansible/executor/task_queue_manager.py 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/lib/ansible/executor/task_queue_manager.py 2025-01-27 20:45:28.000000000 +0100 @@ -39,7 +39,6 @@ from ansible.plugins.callback import CallbackBase from ansible.template import Templar from ansible.vars.hostvars import HostVars -from ansible.vars.reserved import warn_if_reserved from ansible.utils.display import Display from ansible.utils.lock import lock_decorator from ansible.utils.multiprocessing import context as multiprocessing_context @@ -282,7 +281,6 @@ all_vars = self._variable_manager.get_vars(play=play) templar = Templar(loader=self._loader, variables=all_vars) - warn_if_reserved(all_vars, templar.environment.globals.keys()) new_play = play.copy() new_play.post_validate(templar) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/lib/ansible/module_utils/ansible_release.py new/ansible_core-2.17.8/lib/ansible/module_utils/ansible_release.py --- old/ansible_core-2.17.7/lib/ansible/module_utils/ansible_release.py 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/lib/ansible/module_utils/ansible_release.py 2025-01-27 20:45:28.000000000 +0100 @@ -17,6 +17,6 @@ from __future__ import annotations -__version__ = '2.17.7' +__version__ = '2.17.8' __author__ = 'Ansible, Inc.' __codename__ = "Gallows Pole" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/lib/ansible/module_utils/csharp/Ansible.Basic.cs new/ansible_core-2.17.8/lib/ansible/module_utils/csharp/Ansible.Basic.cs --- old/ansible_core-2.17.7/lib/ansible/module_utils/csharp/Ansible.Basic.cs 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/lib/ansible/module_utils/csharp/Ansible.Basic.cs 2025-01-27 20:45:28.000000000 +0100 @@ -1210,7 +1210,7 @@ object val = requiredCheck[1]; IList requirements = (IList)requiredCheck[2]; - if (ParseStr(param[key]) != ParseStr(val)) + if (param[key] == null || ParseStr(param[key]) != ParseStr(val)) continue; string term = "all"; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/lib/ansible/module_utils/facts/ansible_collector.py new/ansible_core-2.17.8/lib/ansible/module_utils/facts/ansible_collector.py --- old/ansible_core-2.17.7/lib/ansible/module_utils/facts/ansible_collector.py 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/lib/ansible/module_utils/facts/ansible_collector.py 2025-01-27 20:45:28.000000000 +0100 @@ -113,7 +113,13 @@ self.module_setup = module_setup def collect(self, module=None, collected_facts=None): + # NOTE: deprecate/remove once DT lands + # we can return this data, but should not be top level key meta_facts = {'gather_subset': self.gather_subset} + + # NOTE: this is just a boolean indicator that 'facts were gathered' + # and should be moved to the 'gather_facts' action plugin + # probably revised to handle modules/subsets combos if self.module_setup: meta_facts['module_setup'] = self.module_setup return meta_facts diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/lib/ansible/playbook/play.py new/ansible_core-2.17.8/lib/ansible/playbook/play.py --- old/ansible_core-2.17.7/lib/ansible/playbook/play.py 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/lib/ansible/playbook/play.py 2025-01-27 20:45:28.000000000 +0100 @@ -31,7 +31,6 @@ from ansible.playbook.role import Role, hash_params from ansible.playbook.task import Task from ansible.playbook.taggable import Taggable -from ansible.vars.manager import preprocess_vars from ansible.utils.display import Display display = Display() @@ -245,6 +244,9 @@ return self.roles def _load_vars_prompt(self, attr, ds): + # avoid circular dep + from ansible.vars.manager import preprocess_vars + new_ds = preprocess_vars(ds) vars_prompts = [] if new_ds is not None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/lib/ansible/plugins/action/copy.py new/ansible_core-2.17.8/lib/ansible/plugins/action/copy.py --- old/ansible_core-2.17.7/lib/ansible/plugins/action/copy.py 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/lib/ansible/plugins/action/copy.py 2025-01-27 20:45:28.000000000 +0100 @@ -26,7 +26,7 @@ import traceback from ansible import constants as C -from ansible.errors import AnsibleError, AnsibleFileNotFound +from ansible.errors import AnsibleError, AnsibleActionFail, AnsibleFileNotFound from ansible.module_utils.basic import FILE_COMMON_ARGUMENTS from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text from ansible.module_utils.parsing.convert_bool import boolean @@ -414,6 +414,11 @@ result = super(ActionModule, self).run(tmp, task_vars) del tmp # tmp no longer has any effect + # ensure user is not setting internal parameters + for internal in ('_original_basename', '_diff_peek'): + if self._task.args.get(internal, None) is not None: + raise AnsibleActionFail(f'Invalid parameter specified: "{internal}"') + source = self._task.args.get('src', None) content = self._task.args.get('content', None) dest = self._task.args.get('dest', None) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/lib/ansible/plugins/action/gather_facts.py new/ansible_core-2.17.8/lib/ansible/plugins/action/gather_facts.py --- old/ansible_core-2.17.7/lib/ansible/plugins/action/gather_facts.py 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/lib/ansible/plugins/action/gather_facts.py 2025-01-27 20:45:28.000000000 +0100 @@ -8,6 +8,7 @@ import typing as t from ansible import constants as C +from ansible.errors import AnsibleActionFail from ansible.executor.module_common import get_action_args_with_defaults from ansible.module_utils.parsing.convert_bool import boolean from ansible.plugins.action import ActionBase @@ -61,6 +62,7 @@ return mod_args def _combine_task_result(self, result: dict[str, t.Any], task_result: dict[str, t.Any]) -> dict[str, t.Any]: + """ builds the final result to return """ filtered_res = { 'ansible_facts': task_result.get('ansible_facts', {}), 'warnings': task_result.get('warnings', []), @@ -70,6 +72,33 @@ # on conflict the last plugin processed wins, but try to do deep merge and append to lists. return merge_hash(result, filtered_res, list_merge='append_rp') + def _handle_smart(self, modules: list, task_vars: dict[str, t.Any]): + """ Updates the module list when 'smart' is used, lookup network os mappings or use setup, warn when things seem inconsistent """ + + if 'smart' not in modules: + return + + modules.pop(modules.index('smart')) # remove as this will cause 'module not found' errors + network_os = self._task.args.get('network_os', task_vars.get('ansible_network_os', task_vars.get('ansible_facts', {}).get('network_os'))) + + if network_os: + + connection_map = C.config.get_config_value('CONNECTION_FACTS_MODULES', variables=task_vars) + if network_os in connection_map: + modules.append(connection_map[network_os]) + elif not modules: + raise AnsibleActionFail(f"No fact modules available and we could not find a fact module for your network OS ({network_os}), " + "try setting one via the `FACTS_MODULES` configuration.") + + if set(modules).intersection(set(C._ACTION_SETUP)): + # most don't realize how setup works with networking connection plugins (forced_local) + self._display.warning("Detected 'setup' module and a network OS is set, the output when running it will reflect 'localhost'" + " and not the target when a netwoking connection plugin is used.") + + elif not set(modules).difference(set(C._ACTION_SETUP)): + # no network OS and setup not in list, add setup by default since 'smart' + modules.append('ansible.legacy.setup') + def run(self, tmp: t.Optional[str] = None, task_vars: t.Optional[dict[str, t.Any]] = None) -> dict[str, t.Any]: result = super(ActionModule, self).run(tmp, task_vars) @@ -77,13 +106,9 @@ # copy the value with list() so we don't mutate the config modules = list(C.config.get_config_value('FACTS_MODULES', variables=task_vars)) + self._handle_smart(modules, task_vars) parallel = task_vars.pop('ansible_facts_parallel', self._task.args.pop('parallel', None)) - if 'smart' in modules: - connection_map = C.config.get_config_value('CONNECTION_FACTS_MODULES', variables=task_vars) - network_os = self._task.args.get('network_os', task_vars.get('ansible_network_os', task_vars.get('ansible_facts', {}).get('network_os'))) - modules.extend([connection_map.get(network_os or self._connection.ansible_name, 'ansible.legacy.setup')]) - modules.pop(modules.index('smart')) failed = {} skipped = {} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/lib/ansible/plugins/connection/__init__.py new/ansible_core-2.17.8/lib/ansible/plugins/connection/__init__.py --- old/ansible_core-2.17.7/lib/ansible/plugins/connection/__init__.py 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/lib/ansible/plugins/connection/__init__.py 2025-01-27 20:45:28.000000000 +0100 @@ -285,6 +285,27 @@ display.debug('Set connection var {0} to {1}'.format(varname, value)) variables[varname] = value + def _resolve_option_variables(self, variables, templar): + """ + Return a dict of variable -> templated value, for any variables that + that match options registered by this plugin. + """ + # create dict of 'templated vars' + var_options = { + '_extras': {}, + } + for var_name in C.config.get_plugin_vars('connection', self._load_name): + if var_name in variables: + var_options[var_name] = templar.template(variables[var_name]) + + # add extras if plugin supports them + if getattr(self, 'allow_extras', False): + for var_name in variables: + if var_name.startswith(f'ansible_{self.extras_prefix}_') and var_name not in var_options: + var_options['_extras'][var_name] = templar.template(variables[var_name]) + + return var_options + class NetworkConnectionBase(ConnectionBase): """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/lib/ansible/plugins/filter/regex_search.yml new/ansible_core-2.17.8/lib/ansible/plugins/filter/regex_search.yml --- old/ansible_core-2.17.7/lib/ansible/plugins/filter/regex_search.yml 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/lib/ansible/plugins/filter/regex_search.yml 2025-01-27 20:45:28.000000000 +0100 @@ -8,6 +8,9 @@ - Maps to Python's C(re.search). - 'The substring matched by the group is accessible via the symbolic group name or the ``\{number}`` special sequence. See examples section.' + - The return for no match will be C(None) in most cases, depending on whether it is used with other filters/tests or not. + It also depends on the Jinja version used and whether native is enabled. + - "For a more complete explanation see U(https://docs.ansible.com/ansible-core/devel/reference_appendices/faq.html#why-does-the-regex-search-filter-return-none-instead-of-an-empty-string)." positional: _input, _regex options: _input: @@ -52,5 +55,5 @@ RETURN: _value: - description: Matched string or empty string if no match. + description: Matched string or if no match a C(None) or an empty string (see notes) type: str diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/lib/ansible/plugins/strategy/__init__.py new/ansible_core-2.17.8/lib/ansible/plugins/strategy/__init__.py --- old/ansible_core-2.17.7/lib/ansible/plugins/strategy/__init__.py 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/lib/ansible/plugins/strategy/__init__.py 2025-01-27 20:45:28.000000000 +0100 @@ -28,7 +28,7 @@ import typing as t from collections import deque -from multiprocessing import Lock + from jinja2.exceptions import UndefinedError @@ -55,6 +55,7 @@ from ansible.utils.unsafe_proxy import wrap_var from ansible.utils.sentinel import Sentinel from ansible.utils.vars import combine_vars +from ansible.utils.multiprocessing import context as multiprocessing_context from ansible.vars.clean import strip_internal_keys, module_response_deepcopy display = Display() @@ -365,7 +366,7 @@ if task.action not in action_write_locks.action_write_locks: display.debug('Creating lock for %s' % task.action) - action_write_locks.action_write_locks[task.action] = Lock() + action_write_locks.action_write_locks[task.action] = multiprocessing_context.Lock() # create a templar and template things we need later for the queuing process templar = Templar(loader=self._loader, variables=task_vars) @@ -1059,7 +1060,8 @@ del self._active_connections[target_host] else: connection = plugin_loader.connection_loader.get(play_context.connection, play_context, os.devnull) - connection.set_options(task_keys=task.dump_attrs(), var_options=all_vars) + var_options = connection._resolve_option_variables(all_vars, templar) + connection.set_options(task_keys=task.dump_attrs(), var_options=var_options) play_context.set_attributes_from_plugin(connection) if connection: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/lib/ansible/release.py new/ansible_core-2.17.8/lib/ansible/release.py --- old/ansible_core-2.17.7/lib/ansible/release.py 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/lib/ansible/release.py 2025-01-27 20:45:28.000000000 +0100 @@ -17,6 +17,6 @@ from __future__ import annotations -__version__ = '2.17.7' +__version__ = '2.17.8' __author__ = 'Ansible, Inc.' __codename__ = "Gallows Pole" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/lib/ansible/vars/manager.py new/ansible_core-2.17.8/lib/ansible/vars/manager.py --- old/ansible_core-2.17.7/lib/ansible/vars/manager.py 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/lib/ansible/vars/manager.py 2025-01-27 20:45:28.000000000 +0100 @@ -41,6 +41,7 @@ from ansible.utils.unsafe_proxy import wrap_var from ansible.vars.clean import namespace_facts, clean_facts from ansible.vars.plugins import get_vars_from_inventory_sources, get_vars_from_path +from ansible.vars.reserved import warn_if_reserved display = Display() @@ -417,6 +418,9 @@ # extra vars all_vars = _combine_and_track(all_vars, self._extra_vars, "extra vars") + # before we add 'reserved vars', check we didn't add any reserved vars + warn_if_reserved(all_vars.keys()) + # magic variables all_vars = _combine_and_track(all_vars, magic_variables, "magic vars") @@ -703,6 +707,7 @@ if not isinstance(facts, Mapping): raise AnsibleAssertionError("the type of 'facts' to set for host_facts should be a Mapping but is a %s" % type(facts)) + warn_if_reserved(facts.keys()) try: host_cache = self._fact_cache[host] except KeyError: @@ -726,15 +731,18 @@ if not isinstance(facts, Mapping): raise AnsibleAssertionError("the type of 'facts' to set for nonpersistent_facts should be a Mapping but is a %s" % type(facts)) + warn_if_reserved(facts.keys()) try: self._nonpersistent_fact_cache[host] |= facts except KeyError: self._nonpersistent_fact_cache[host] = facts def set_host_variable(self, host, varname, value): - ''' + """ Sets a value in the vars_cache for a host. - ''' + """ + + warn_if_reserved(varname) if host not in self._vars_cache: self._vars_cache[host] = dict() if varname in self._vars_cache[host] and isinstance(self._vars_cache[host][varname], MutableMapping) and isinstance(value, MutableMapping): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/lib/ansible/vars/reserved.py new/ansible_core-2.17.8/lib/ansible/vars/reserved.py --- old/ansible_core-2.17.7/lib/ansible/vars/reserved.py 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/lib/ansible/vars/reserved.py 2025-01-27 20:45:28.000000000 +0100 @@ -21,15 +21,17 @@ from ansible.playbook.block import Block from ansible.playbook.role import Role from ansible.playbook.task import Task +from ansible.template import Templar from ansible.utils.display import Display display = Display() -def get_reserved_names(include_private=True): - ''' this function returns the list of reserved names associated with play objects''' +def get_reserved_names(include_private: bool = True) -> set[str]: + """ this function returns the list of reserved names associated with play objects""" - public = set() + templar = Templar(loader=None) + public = set(templar.environment.globals.keys()) private = set() result = set() @@ -58,11 +60,15 @@ else: result = public + # due to Collectors always adding, need to ignore this + # eventually should remove after we deprecate it in setup.py + result.remove('gather_subset') + return result -def warn_if_reserved(myvars, additional=None): - ''' this function warns if any variable passed conflicts with internally reserved names ''' +def warn_if_reserved(myvars: list[str], additional: list[str] | None = None) -> None: + """ this function warns if any variable passed conflicts with internally reserved names """ if additional is None: reserved = _RESERVED_NAMES @@ -75,7 +81,7 @@ display.warning('Found variable using reserved name: %s' % varname) -def is_reserved_name(name): +def is_reserved_name(name: str) -> bool: return name in _RESERVED_NAMES diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/lib/ansible_core.egg-info/PKG-INFO new/ansible_core-2.17.8/lib/ansible_core.egg-info/PKG-INFO --- old/ansible_core-2.17.7/lib/ansible_core.egg-info/PKG-INFO 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/lib/ansible_core.egg-info/PKG-INFO 2025-01-27 20:45:28.000000000 +0100 @@ -1,6 +1,6 @@ -Metadata-Version: 2.1 +Metadata-Version: 2.2 Name: ansible-core -Version: 2.17.7 +Version: 2.17.8 Summary: Radically simple IT automation Home-page: https://ansible.com/ Author: Ansible, Inc. @@ -36,6 +36,7 @@ Requires-Dist: cryptography Requires-Dist: packaging Requires-Dist: resolvelib<1.1.0,>=0.5.3 +Dynamic: requires-dist [](https://pypi.org/project/ansible-core) [](https://docs.ansible.com/ansible/latest/) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/lib/ansible_core.egg-info/SOURCES.txt new/ansible_core-2.17.8/lib/ansible_core.egg-info/SOURCES.txt --- old/ansible_core-2.17.7/lib/ansible_core.egg-info/SOURCES.txt 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/lib/ansible_core.egg-info/SOURCES.txt 2025-01-27 20:45:28.000000000 +0100 @@ -969,6 +969,12 @@ test/integration/targets/ansible-test-container/runme.sh test/integration/targets/ansible-test-coverage/aliases test/integration/targets/ansible-test-coverage/runme.sh +test/integration/targets/ansible-test-coverage-windows/aliases +test/integration/targets/ansible-test-coverage-windows/runme.sh +test/integration/targets/ansible-test-coverage-windows/test-coverage.py +test/integration/targets/ansible-test-coverage-windows/ansible_collections/ns/col/plugins/modules/win_collection.ps1 +test/integration/targets/ansible-test-coverage-windows/ansible_collections/ns/col/tests/integration/targets/win_collection/library/test_win_collection.ps1 +test/integration/targets/ansible-test-coverage-windows/ansible_collections/ns/col/tests/integration/targets/win_collection/tasks/main.yml test/integration/targets/ansible-test-coverage/ansible_collections/ns/col/plugins/module_utils/test_util.py test/integration/targets/ansible-test-docker/aliases test/integration/targets/ansible-test-docker/runme.sh @@ -1686,6 +1692,7 @@ test/integration/targets/connection/test.sh test/integration/targets/connection/test_connection.yml test/integration/targets/connection/test_reset_connection.yml +test/integration/targets/connection/test_reset_connection_templated.yml test/integration/targets/connection_delegation/aliases test/integration/targets/connection_delegation/inventory.ini test/integration/targets/connection_delegation/runme.sh @@ -3848,8 +3855,12 @@ test/integration/targets/var_precedence/roles/test_var_precedence_role3/vars/main.yml test/integration/targets/var_precedence/vars/test_var_precedence.yml test/integration/targets/var_reserved/aliases -test/integration/targets/var_reserved/reserved_varname_warning.yml -test/integration/targets/var_reserved/runme.sh +test/integration/targets/var_reserved/tasks/block_vars.yml +test/integration/targets/var_reserved/tasks/main.yml +test/integration/targets/var_reserved/tasks/play_vars.yml +test/integration/targets/var_reserved/tasks/set_fact.yml +test/integration/targets/var_reserved/tasks/task_vars.yml +test/integration/targets/var_reserved/tasks/task_vars_used.yml test/integration/targets/var_templating/aliases test/integration/targets/var_templating/ansible_debug_template.j2 test/integration/targets/var_templating/runme.sh diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/pyproject.toml new/ansible_core-2.17.8/pyproject.toml --- old/ansible_core-2.17.7/pyproject.toml 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/pyproject.toml 2025-01-27 20:45:28.000000000 +0100 @@ -1,3 +1,3 @@ [build-system] -requires = ["setuptools >= 66.1.0, <= 75.6.0"] # lower bound to support controller Python versions, upper bound for latest version tested at release +requires = ["setuptools >= 66.1.0, <= 75.8.0"] # lower bound to support controller Python versions, upper bound for latest version tested at release build-backend = "setuptools.build_meta" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/integration/targets/ansible-test-coverage-windows/aliases new/ansible_core-2.17.8/test/integration/targets/ansible-test-coverage-windows/aliases --- old/ansible_core-2.17.7/test/integration/targets/ansible-test-coverage-windows/aliases 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.17.8/test/integration/targets/ansible-test-coverage-windows/aliases 2025-01-27 20:45:28.000000000 +0100 @@ -0,0 +1,3 @@ +shippable/windows/group1 +windows +needs/target/collection diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/integration/targets/ansible-test-coverage-windows/ansible_collections/ns/col/plugins/modules/win_collection.ps1 new/ansible_core-2.17.8/test/integration/targets/ansible-test-coverage-windows/ansible_collections/ns/col/plugins/modules/win_collection.ps1 --- old/ansible_core-2.17.7/test/integration/targets/ansible-test-coverage-windows/ansible_collections/ns/col/plugins/modules/win_collection.ps1 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.17.8/test/integration/targets/ansible-test-coverage-windows/ansible_collections/ns/col/plugins/modules/win_collection.ps1 2025-01-27 20:45:28.000000000 +0100 @@ -0,0 +1,6 @@ +#!powershell + +#AnsibleRequires -CSharpUtil Ansible.Basic + +$module = [Ansible.Basic.AnsibleModule]::Create($args, @{}) +$module.ExitJson() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/integration/targets/ansible-test-coverage-windows/ansible_collections/ns/col/tests/integration/targets/win_collection/library/test_win_collection.ps1 new/ansible_core-2.17.8/test/integration/targets/ansible-test-coverage-windows/ansible_collections/ns/col/tests/integration/targets/win_collection/library/test_win_collection.ps1 --- old/ansible_core-2.17.7/test/integration/targets/ansible-test-coverage-windows/ansible_collections/ns/col/tests/integration/targets/win_collection/library/test_win_collection.ps1 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.17.8/test/integration/targets/ansible-test-coverage-windows/ansible_collections/ns/col/tests/integration/targets/win_collection/library/test_win_collection.ps1 2025-01-27 20:45:28.000000000 +0100 @@ -0,0 +1,6 @@ +#!powershell + +#AnsibleRequires -CSharpUtil Ansible.Basic + +$module = [Ansible.Basic.AnsibleModule]::Create($args, @{}) +$module.ExitJson() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/integration/targets/ansible-test-coverage-windows/ansible_collections/ns/col/tests/integration/targets/win_collection/tasks/main.yml new/ansible_core-2.17.8/test/integration/targets/ansible-test-coverage-windows/ansible_collections/ns/col/tests/integration/targets/win_collection/tasks/main.yml --- old/ansible_core-2.17.7/test/integration/targets/ansible-test-coverage-windows/ansible_collections/ns/col/tests/integration/targets/win_collection/tasks/main.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.17.8/test/integration/targets/ansible-test-coverage-windows/ansible_collections/ns/col/tests/integration/targets/win_collection/tasks/main.yml 2025-01-27 20:45:28.000000000 +0100 @@ -0,0 +1,5 @@ +- name: run module in collection to test coverage for collection plugins + win_collection: + +- name: run module in library adjacent to test coverage for test plugins + test_win_collection: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/integration/targets/ansible-test-coverage-windows/runme.sh new/ansible_core-2.17.8/test/integration/targets/ansible-test-coverage-windows/runme.sh --- old/ansible_core-2.17.7/test/integration/targets/ansible-test-coverage-windows/runme.sh 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.17.8/test/integration/targets/ansible-test-coverage-windows/runme.sh 2025-01-27 20:45:28.000000000 +0100 @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +TEST_PATH="${PWD}/test-coverage.py" + +source ../collection/setup.sh +cp "${INVENTORY_PATH}" tests/integration/inventory.winrm + +set -x + +# common args for all tests +common=(--venv --color --truncate 0 "${@}") + +# run command that generates coverage data for Windows +ansible-test windows-integration win_collection "${common[@]}" --coverage + +# report on code coverage in all supported formats +ansible-test coverage report "${common[@]}" + +# test we covered the 2 files we expect to have been covered and their lines +python "${TEST_PATH}" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/integration/targets/ansible-test-coverage-windows/test-coverage.py new/ansible_core-2.17.8/test/integration/targets/ansible-test-coverage-windows/test-coverage.py --- old/ansible_core-2.17.7/test/integration/targets/ansible-test-coverage-windows/test-coverage.py 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.17.8/test/integration/targets/ansible-test-coverage-windows/test-coverage.py 2025-01-27 20:45:28.000000000 +0100 @@ -0,0 +1,27 @@ +from __future__ import annotations + +import json +import os +import os.path + + +def main() -> None: + collection_root = os.getcwd() + print(f"Running windows-integration coverage test in '{collection_root}'") + + result_path = os.path.join(collection_root, "tests", "output", "coverage", "coverage-powershell") + module_path = os.path.join(collection_root, "plugins", "modules", "win_collection.ps1") + test_path = os.path.join(collection_root, "tests", "integration", "targets", "win_collection", "library", "test_win_collection.ps1") + with open(result_path, mode="rb") as fd: + data = json.load(fd) + + for path, result in data.items(): + print(f"Testing result for path '{path}' -> {result!r}") + assert path in [module_path, test_path], f"Found unexpected coverage result path '{path}'" + assert result == {'5': 1, '6': 1}, "Coverage result did not pick up a hit on lines 5 and 6" + + assert len(data) == 2, f"Expected coverage results for 2 files but got {len(data)}" + + +if __name__ == '__main__': + main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/integration/targets/collection/setup.sh new/ansible_core-2.17.8/test/integration/targets/collection/setup.sh --- old/ansible_core-2.17.7/test/integration/targets/collection/setup.sh 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/test/integration/targets/collection/setup.sh 2025-01-27 20:45:28.000000000 +0100 @@ -12,6 +12,9 @@ # # 3) Sanity tests which are multi-version require an ignore entry per Python version. # This script replicates these ignore entries for each supported Python version based on the ignored path. +# +# 4) Windows tests need access to the ansible.windows vendored collection. +# This script copies any of the existing collections in ANSIBLE_COLLECTIONS_PATH to the temporary directory. set -eu -o pipefail @@ -26,4 +29,8 @@ cp -a "${TEST_DIR}/ansible_collections" "${WORK_DIR}" cd "${WORK_DIR}/ansible_collections/ns/${COLLECTION_NAME:-col}" +if [ "${ANSIBLE_COLLECTIONS_PATH:+set}" = "set" ]; then + cp -aL "${ANSIBLE_COLLECTIONS_PATH}"/ansible_collections/* "${WORK_DIR}/ansible_collections" +fi + "${TEST_DIR}/../collection/update-ignore.py" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/integration/targets/connection/test.sh new/ansible_core-2.17.8/test/integration/targets/connection/test.sh --- old/ansible_core-2.17.7/test/integration/targets/connection/test.sh 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/test/integration/targets/connection/test.sh 2025-01-27 20:45:28.000000000 +0100 @@ -20,3 +20,4 @@ fi ansible-playbook test_reset_connection.yml -i "${INVENTORY}" "$@" +ansible-playbook test_reset_connection_templated.yml -i "${INVENTORY}" "$@" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/integration/targets/connection/test_reset_connection_templated.yml new/ansible_core-2.17.8/test/integration/targets/connection/test_reset_connection_templated.yml --- old/ansible_core-2.17.7/test/integration/targets/connection/test_reset_connection_templated.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.17.8/test/integration/targets/connection/test_reset_connection_templated.yml 2025-01-27 20:45:28.000000000 +0100 @@ -0,0 +1,7 @@ +- hosts: "{{ target_hosts }}" + gather_facts: false + vars: + ansible_ssh_executable: "{{ 'ssh' | trim }}" + tasks: + # https://github.com/ansible/ansible/issues/84238 + - meta: reset_connection diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/integration/targets/copy/tasks/main.yml new/ansible_core-2.17.8/test/integration/targets/copy/tasks/main.yml --- old/ansible_core-2.17.7/test/integration/targets/copy/tasks/main.yml 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/test/integration/targets/copy/tasks/main.yml 2025-01-27 20:45:28.000000000 +0100 @@ -109,6 +109,20 @@ - name: tests with remote_src and non files import_tasks: src_remote_file_is_not_file.yml + - name: Test internal options + copy: + content: 'irrelevant' + dest: '{{ local_temp_dir}}/file.txt' + _diff_peek: true + register: peek + ignore_errors: true + + - name: Test internal options + assert: + that: + - peek is failed + - "'_diff_peek' in peek['msg']" + always: - name: Cleaning file: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/integration/targets/gathering_facts/runme.sh new/ansible_core-2.17.8/test/integration/targets/gathering_facts/runme.sh --- old/ansible_core-2.17.7/test/integration/targets/gathering_facts/runme.sh 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/test/integration/targets/gathering_facts/runme.sh 2025-01-27 20:45:28.000000000 +0100 @@ -38,4 +38,11 @@ # test parallelism ANSIBLE_FACTS_MODULES='dummy1,dummy2,dummy3' ansible -m gather_facts localhost --playbook-dir ./ -a 'gather_timeout=30 parallel=true' "$@" 2>&1 + +# ensure we error out on bad network os +ANSIBLE_FACTS_MODULES='smart' ansible -m gather_facts localhost -e 'ansible_network_os="N/A"' "$@" 2>&1 | grep "No fact modules available" + +# ensure we warn on setup + network OS +ANSIBLE_FACTS_MODULES='smart, setup' ansible -m gather_facts localhost -e 'ansible_network_os="N/A"' "$@" 2>&1 | grep "Detected 'setup' module and a network OS is set" + rm "${OUTPUT_DIR}/canary.txt" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/integration/targets/module_utils_Ansible.Basic/library/ansible_basic_tests.ps1 new/ansible_core-2.17.8/test/integration/targets/module_utils_Ansible.Basic/library/ansible_basic_tests.ps1 --- old/ansible_core-2.17.7/test/integration/targets/module_utils_Ansible.Basic/library/ansible_basic_tests.ps1 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/test/integration/targets/module_utils_Ansible.Basic/library/ansible_basic_tests.ps1 2025-01-27 20:45:28.000000000 +0100 @@ -3054,6 +3054,34 @@ $actual.invocation | Assert-DictionaryEqual -Expected @{module_args = $complex_args } } + "Required if for unset option" = { + $spec = @{ + options = @{ + state = @{ choices = "absent", "present" } + name = @{} + path = @{} + } + required_if = @(, @("state", "absent", @("name", "path"))) + } + Set-Variable -Name complex_args -Scope Global -Value @{} + $m = [Ansible.Basic.AnsibleModule]::Create(@(), $spec) + + $failed = $false + try { + $m.ExitJson() + } + catch [System.Management.Automation.RuntimeException] { + $failed = $true + $_.Exception.Message | Assert-Equal -Expected "exit: 0" + $actual = [Ansible.Basic.AnsibleModule]::FromJson($_.Exception.InnerException.Output) + } + $failed | Assert-Equal -Expected $true + + $actual.Keys.Count | Assert-Equal -Expected 2 + $actual.changed | Assert-Equal -Expected $false + $actual.invocation | Assert-DictionaryEqual -Expected @{ module_args = $complex_args } + } + "PS Object in return result" = { $m = [Ansible.Basic.AnsibleModule]::Create(@(), @{}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/integration/targets/result_pickle_error/action_plugins/result_pickle_error.py new/ansible_core-2.17.8/test/integration/targets/result_pickle_error/action_plugins/result_pickle_error.py --- old/ansible_core-2.17.7/test/integration/targets/result_pickle_error/action_plugins/result_pickle_error.py 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/test/integration/targets/result_pickle_error/action_plugins/result_pickle_error.py 2025-01-27 20:45:28.000000000 +0100 @@ -5,10 +5,14 @@ from __future__ import annotations from ansible.plugins.action import ActionBase -from jinja2 import Undefined + + +class CannotBePickled: + def __getstate__(self): + raise Exception('pickle intentionally not supported') class ActionModule(ActionBase): def run(self, tmp=None, task_vars=None): - return {'obj': Undefined('obj')} + return {'obj': CannotBePickled()} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/integration/targets/result_pickle_error/tasks/main.yml new/ansible_core-2.17.8/test/integration/targets/result_pickle_error/tasks/main.yml --- old/ansible_core-2.17.7/test/integration/targets/result_pickle_error/tasks/main.yml 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/test/integration/targets/result_pickle_error/tasks/main.yml 2025-01-27 20:45:28.000000000 +0100 @@ -8,7 +8,7 @@ - result.msg == expected_msg - result is failed vars: - expected_msg: "cannot pickle 'Undefined' object" + expected_msg: "pickle intentionally not supported" - debug: msg: Success, no hang diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/integration/targets/var_reserved/reserved_varname_warning.yml new/ansible_core-2.17.8/test/integration/targets/var_reserved/reserved_varname_warning.yml --- old/ansible_core-2.17.7/test/integration/targets/var_reserved/reserved_varname_warning.yml 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/test/integration/targets/var_reserved/reserved_varname_warning.yml 1970-01-01 01:00:00.000000000 +0100 @@ -1,6 +0,0 @@ -- hosts: localhost - gather_facts: false - vars: - lipsum: jinja2 uses me internally - tasks: - - debug: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/integration/targets/var_reserved/runme.sh new/ansible_core-2.17.8/test/integration/targets/var_reserved/runme.sh --- old/ansible_core-2.17.7/test/integration/targets/var_reserved/runme.sh 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/test/integration/targets/var_reserved/runme.sh 1970-01-01 01:00:00.000000000 +0100 @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -set -eux - -ansible-playbook reserved_varname_warning.yml "$@" 2>&1| grep 'Found variable using reserved name: lipsum' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/integration/targets/var_reserved/tasks/block_vars.yml new/ansible_core-2.17.8/test/integration/targets/var_reserved/tasks/block_vars.yml --- old/ansible_core-2.17.7/test/integration/targets/var_reserved/tasks/block_vars.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.17.8/test/integration/targets/var_reserved/tasks/block_vars.yml 2025-01-27 20:45:28.000000000 +0100 @@ -0,0 +1,8 @@ +- hosts: localhost + gather_facts: false + tasks: + - name: test block + vars: + query: jinja2 uses me internally + block: + - debug: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/integration/targets/var_reserved/tasks/main.yml new/ansible_core-2.17.8/test/integration/targets/var_reserved/tasks/main.yml --- old/ansible_core-2.17.7/test/integration/targets/var_reserved/tasks/main.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.17.8/test/integration/targets/var_reserved/tasks/main.yml 2025-01-27 20:45:28.000000000 +0100 @@ -0,0 +1,23 @@ +- name: check output for warning + vars: + canary: Found variable using reserved name + block: + - shell: ansible-playbook '{{[ role_path, "tasks", item ~ ".yml"] | path_join }}' + environment: + ANSIBLE_LOCALHOST_WARNING: 0 + failed_when: false + loop: + - play_vars + - block_vars + - task_vars + - task_vars_used + - set_fact + register: play_out + + - name: check they all complain about bad defined var + assert: + that: + - canary in item['stderr'] + loop: '{{play_out.results}}' + loop_control: + label: '{{item.item}}' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/integration/targets/var_reserved/tasks/play_vars.yml new/ansible_core-2.17.8/test/integration/targets/var_reserved/tasks/play_vars.yml --- old/ansible_core-2.17.7/test/integration/targets/var_reserved/tasks/play_vars.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.17.8/test/integration/targets/var_reserved/tasks/play_vars.yml 2025-01-27 20:45:28.000000000 +0100 @@ -0,0 +1,6 @@ +- hosts: localhost + gather_facts: false + vars: + lipsum: jinja2 uses me internally + tasks: + - debug: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/integration/targets/var_reserved/tasks/set_fact.yml new/ansible_core-2.17.8/test/integration/targets/var_reserved/tasks/set_fact.yml --- old/ansible_core-2.17.7/test/integration/targets/var_reserved/tasks/set_fact.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.17.8/test/integration/targets/var_reserved/tasks/set_fact.yml 2025-01-27 20:45:28.000000000 +0100 @@ -0,0 +1,5 @@ +- hosts: localhost + gather_facts: false + tasks: + - set_fact: + lookup: jinja2 uses me internally diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/integration/targets/var_reserved/tasks/task_vars.yml new/ansible_core-2.17.8/test/integration/targets/var_reserved/tasks/task_vars.yml --- old/ansible_core-2.17.7/test/integration/targets/var_reserved/tasks/task_vars.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.17.8/test/integration/targets/var_reserved/tasks/task_vars.yml 2025-01-27 20:45:28.000000000 +0100 @@ -0,0 +1,6 @@ +- hosts: localhost + gather_facts: false + tasks: + - debug: + vars: + query: jinja2 uses me internally diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/integration/targets/var_reserved/tasks/task_vars_used.yml new/ansible_core-2.17.8/test/integration/targets/var_reserved/tasks/task_vars_used.yml --- old/ansible_core-2.17.7/test/integration/targets/var_reserved/tasks/task_vars_used.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.17.8/test/integration/targets/var_reserved/tasks/task_vars_used.yml 2025-01-27 20:45:28.000000000 +0100 @@ -0,0 +1,8 @@ +- hosts: localhost + gather_facts: false + tasks: + - name: task fails due to overriding q, but we should also see warning + debug: + msg: "{{q('pipe', 'pwd')}}" + vars: + q: jinja2 uses me internally diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/lib/ansible_test/_internal/commands/coverage/__init__.py new/ansible_core-2.17.8/test/lib/ansible_test/_internal/commands/coverage/__init__.py --- old/ansible_core-2.17.7/test/lib/ansible_test/_internal/commands/coverage/__init__.py 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/test/lib/ansible_test/_internal/commands/coverage/__init__.py 2025-01-27 20:45:28.000000000 +0100 @@ -293,6 +293,11 @@ new_name = re.sub('^.*/ansible_modlib.zip/ansible/', ansible_path, filename) display.info('%s -> %s' % (filename, new_name), verbosity=3) filename = new_name + elif integration_temp_path in filename: + # Rewrite the path of code running from an integration test temporary directory. + new_name = re.sub(r'^.*' + re.escape(integration_temp_path) + '[^/]+/', root_path, filename) + display.info('%s -> %s' % (filename, new_name), verbosity=3) + filename = new_name elif collection_search_re and collection_search_re.search(filename): new_name = os.path.abspath(collection_sub_re.sub('', filename)) display.info('%s -> %s' % (filename, new_name), verbosity=3) @@ -328,11 +333,6 @@ new_name = re.sub('^(/.*?)?/root/ansible/', root_path, filename) display.info('%s -> %s' % (filename, new_name), verbosity=3) filename = new_name - elif integration_temp_path in filename: - # Rewrite the path of code running from an integration test temporary directory. - new_name = re.sub(r'^.*' + re.escape(integration_temp_path) + '[^/]+/', root_path, filename) - display.info('%s -> %s' % (filename, new_name), verbosity=3) - filename = new_name filename = os.path.abspath(filename) # make sure path is absolute (will be relative if previously exported) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.17.7/test/units/cli/test_vault.py new/ansible_core-2.17.8/test/units/cli/test_vault.py --- old/ansible_core-2.17.7/test/units/cli/test_vault.py 2024-12-02 18:46:41.000000000 +0100 +++ new/ansible_core-2.17.8/test/units/cli/test_vault.py 2025-01-27 20:45:28.000000000 +0100 @@ -120,8 +120,21 @@ mock_setup_vault_secrets.return_value = [('default', TextVaultSecret('password'))] cli = VaultCLI(args=['ansible-vault', 'encrypt_string', - '--prompt', - 'some string to encrypt']) + '--prompt']) + cli.parse() + cli.run() + args, kwargs = mock_display.call_args + assert kwargs["private"] + + @patch('ansible.cli.vault.VaultCLI.setup_vault_secrets') + @patch('ansible.cli.vault.VaultEditor') + @patch('ansible.cli.vault.display.prompt', return_value='a_prompt') + def test_shadowed_encrypt_string_prompt_plus(self, mock_display, mock_vault_editor, mock_setup_vault_secrets): + mock_setup_vault_secrets.return_value = [('default', TextVaultSecret('password'))] + cli = VaultCLI(args=['ansible-vault', + 'encrypt_string', + 'some string to encrypt', + '--prompt']) cli.parse() cli.run() args, kwargs = mock_display.call_args ++++++ ansible_core-2.17.7.tar.gz.sha256 -> ansible_core-2.17.8.tar.gz.sha256 ++++++ --- /work/SRC/openSUSE:Factory/ansible-core-2.17/ansible_core-2.17.7.tar.gz.sha256 2024-12-05 17:10:31.982347761 +0100 +++ /work/SRC/openSUSE:Factory/.ansible-core-2.17.new.2316/ansible_core-2.17.8.tar.gz.sha256 2025-01-29 16:18:49.400482922 +0100 @@ -1 +1 @@ -3aaab735d6c4e2d6239bc326800dc0ecda2a1490caa8455b41084ec0bc54dacf ansible_core-2.17.7.tar.gz +39be8a7986a2c7d36069b0d97220bc2f6783c65fea7c6d7e0e2d00d1ac8af877 ansible_core-2.17.8.tar.gz