Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package ansible-core for openSUSE:Factory checked in at 2023-09-12 21:03:59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ansible-core (Old) and /work/SRC/openSUSE:Factory/.ansible-core.new.1766 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ansible-core" Tue Sep 12 21:03:59 2023 rev:18 rq:1110578 version:2.15.4 Changes: -------- --- /work/SRC/openSUSE:Factory/ansible-core/ansible-core.changes 2023-09-08 21:17:08.789913301 +0200 +++ /work/SRC/openSUSE:Factory/.ansible-core.new.1766/ansible-core.changes 2023-09-12 21:05:18.761374708 +0200 @@ -1,0 +2,33 @@ +Tue Sep 12 08:13:53 UTC 2023 - Johannes Kastl <ka...@b1-systems.de> + +- update to 2.15.4: + * Deprecated Features + - vault and unfault filters - the undocumented vaultid + parameter is deprecated and will be removed in ansible-core + 2.20. Use vault_id instead. + * Bugfixes + - PowerShell - Remove some code which is no longer valid for + dotnet 5+ + - Prompting - add a short sleep between polling for user input + to reduce CPU consumption (#81516). + - ansible-galaxy - Enabled the data tarfile filter during role + installation for Python versions that support it. A probing + mechanism is used to avoid Python versions with a broken + implementation. + - ansible-test - Always use ansible-test managed entry points + for ansible-core CLI tools when not running from source. This + fixes issues where CLI entry points created during install + are not compatible with ansible-test. + - first found lookup has been updated to use the normalized + argument parsing (pythonic) matching the documented examples. + - handlers - the listen keyword can affect only one handler + with the same name, the last one defined as it is a case with + the notify keyword (#81013) + - include_role - expose variables from parent roles to role's + handlers (#80459) + - tarfile - handle data filter deprecation warning message for + extract and extractall (#80832). + - vault and unvault filters now properly take vault_id + parameter. + +------------------------------------------------------------------- Old: ---- ansible-core-2.15.3.tar.gz New: ---- ansible-core-2.15.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ansible-core.spec ++++++ --- /var/tmp/diff_new_pack.xOjPpl/_old 2023-09-12 21:05:19.905415515 +0200 +++ /var/tmp/diff_new_pack.xOjPpl/_new 2023-09-12 21:05:19.905415515 +0200 @@ -38,7 +38,7 @@ %endif Name: ansible-core -Version: 2.15.3 +Version: 2.15.4 Release: 0 Summary: Radically simple IT automation License: GPL-3.0-or-later ++++++ ansible-core-2.15.3.tar.gz -> ansible-core-2.15.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/PKG-INFO new/ansible-core-2.15.4/PKG-INFO --- old/ansible-core-2.15.3/PKG-INFO 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/PKG-INFO 2023-09-12 00:11:17.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: ansible-core -Version: 2.15.3 +Version: 2.15.4 Summary: Radically simple IT automation Home-page: https://ansible.com/ Author: Ansible, Inc. @@ -31,6 +31,12 @@ Requires-Python: >=3.9 Description-Content-Type: text/markdown License-File: COPYING +Requires-Dist: jinja2>=3.0.0 +Requires-Dist: PyYAML>=5.1 +Requires-Dist: cryptography +Requires-Dist: packaging +Requires-Dist: importlib_resources<5.1,>=5.0; python_version < "3.10" +Requires-Dist: resolvelib<1.1.0,>=0.5.3 [](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.15.3/changelogs/CHANGELOG-v2.15.rst new/ansible-core-2.15.4/changelogs/CHANGELOG-v2.15.rst --- old/ansible-core-2.15.3/changelogs/CHANGELOG-v2.15.rst 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/changelogs/CHANGELOG-v2.15.rst 2023-09-12 00:11:17.000000000 +0200 @@ -5,6 +5,34 @@ .. contents:: Topics +v2.15.4 +======= + +Release Summary +--------------- + +| Release Date: 2023-09-11 +| `Porting Guide <https://docs.ansible.com/ansible-core/2.15/porting_guides/porting_guide_core_2.15.html>`__ + + +Deprecated Features +------------------- + +- vault and unfault filters - the undocumented ``vaultid`` parameter is deprecated and will be removed in ansible-core 2.20. Use ``vault_id`` instead. + +Bugfixes +-------- + +- PowerShell - Remove some code which is no longer valid for dotnet 5+ +- Prompting - add a short sleep between polling for user input to reduce CPU consumption (https://github.com/ansible/ansible/issues/81516). +- ansible-galaxy - Enabled the ``data`` tarfile filter during role installation for Python versions that support it. A probing mechanism is used to avoid Python versions with a broken implementation. +- ansible-test - Always use ansible-test managed entry points for ansible-core CLI tools when not running from source. This fixes issues where CLI entry points created during install are not compatible with ansible-test. +- first found lookup has been updated to use the normalized argument parsing (pythonic) matching the documented examples. +- handlers - the ``listen`` keyword can affect only one handler with the same name, the last one defined as it is a case with the ``notify`` keyword (https://github.com/ansible/ansible/issues/81013) +- include_role - expose variables from parent roles to role's handlers (https://github.com/ansible/ansible/issues/80459) +- tarfile - handle data filter deprecation warning message for extract and extractall (https://github.com/ansible/ansible/issues/80832). +- vault and unvault filters now properly take ``vault_id`` parameter. + v2.15.3 ======= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/changelogs/changelog.yaml new/ansible-core-2.15.4/changelogs/changelog.yaml --- old/ansible-core-2.15.3/changelogs/changelog.yaml 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/changelogs/changelog.yaml 2023-09-12 00:11:17.000000000 +0200 @@ -1069,3 +1069,54 @@ - urls-client-cert-py12.yml - urls-unit-test-latest-cryptography.yml release_date: '2023-08-07' + 2.15.4: + changes: + release_summary: '| Release Date: 2023-09-11 + + | `Porting Guide <https://docs.ansible.com/ansible-core/2.15/porting_guides/porting_guide_core_2.15.html>`__ + + ' + codename: Ten Years Gone + fragments: + - 2.15.4_summary.yaml + release_date: '2023-09-11' + 2.15.4rc1: + changes: + bugfixes: + - PowerShell - Remove some code which is no longer valid for dotnet 5+ + - Prompting - add a short sleep between polling for user input to reduce CPU + consumption (https://github.com/ansible/ansible/issues/81516). + - ansible-galaxy - Enabled the ``data`` tarfile filter during role installation + for Python versions that support it. A probing mechanism is used to avoid + Python versions with a broken implementation. + - ansible-test - Always use ansible-test managed entry points for ansible-core + CLI tools when not running from source. This fixes issues where CLI entry + points created during install are not compatible with ansible-test. + - first found lookup has been updated to use the normalized argument parsing + (pythonic) matching the documented examples. + - handlers - the ``listen`` keyword can affect only one handler with the same + name, the last one defined as it is a case with the ``notify`` keyword (https://github.com/ansible/ansible/issues/81013) + - include_role - expose variables from parent roles to role's handlers (https://github.com/ansible/ansible/issues/80459) + - tarfile - handle data filter deprecation warning message for extract and extractall + (https://github.com/ansible/ansible/issues/80832). + - vault and unvault filters now properly take ``vault_id`` parameter. + deprecated_features: + - vault and unfault filters - the undocumented ``vaultid`` parameter is deprecated + and will be removed in ansible-core 2.20. Use ``vault_id`` instead. + release_summary: '| Release Date: 2023-09-05 + + | `Porting Guide <https://docs.ansible.com/ansible-core/2.15/porting_guides/porting_guide_core_2.15.html>`__ + + ' + codename: Ten Years Gone + fragments: + - 2.15.4rc1_summary.yaml + - 80459-handlers-nested-includes-vars.yml + - 81013-handlers-listen-last-defined-only.yml + - ansible-test-entry-points.yml + - dotnet-preparation.yml + - first_found_fixes.yml + - fix-display-prompt-cpu-consumption.yml + - tarfile_extract_warn.yml + - vault_unvault_id_fix.yml + release_date: '2023-09-05' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/lib/ansible/galaxy/role.py new/ansible-core-2.15.4/lib/ansible/galaxy/role.py --- old/ansible-core-2.15.3/lib/ansible/galaxy/role.py 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/lib/ansible/galaxy/role.py 2023-09-12 00:11:17.000000000 +0200 @@ -24,6 +24,7 @@ import errno import datetime +import functools import os import tarfile import tempfile @@ -45,6 +46,32 @@ display = Display() +@functools.cache +def _check_working_data_filter() -> bool: + """ + Check if tarfile.data_filter implementation is working + for the current Python version or not + """ + + # Implemented the following code to circumvent broken implementation of data_filter + # in tarfile. See for more information - https://github.com/python/cpython/issues/107845 + # deprecated: description='probing broken data filter implementation' python_version='3.11' + ret = False + if hasattr(tarfile, 'data_filter'): + # We explicitly check if tarfile.data_filter is broken or not + ti = tarfile.TarInfo('docs/README.md') + ti.type = tarfile.SYMTYPE + ti.linkname = '../README.md' + + try: + tarfile.data_filter(ti, '/foo') + except tarfile.LinkOutsideDestinationError: + pass + else: + ret = True + return ret + + class GalaxyRole(object): SUPPORTED_SCMS = set(['git', 'hg']) @@ -379,7 +406,12 @@ if n_part != '..' and not n_part.startswith('~') and '$' not in n_part: n_final_parts.append(n_part) member.name = os.path.join(*n_final_parts) - role_tar_file.extract(member, to_native(self.path)) + + if _check_working_data_filter(): + # deprecated: description='extract fallback without filter' python_version='3.11' + role_tar_file.extract(member, to_native(self.path), filter='data') # type: ignore[call-arg] + else: + role_tar_file.extract(member, to_native(self.path)) # write out the install info file for later use self._write_galaxy_install_info() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/lib/ansible/module_utils/ansible_release.py new/ansible-core-2.15.4/lib/ansible/module_utils/ansible_release.py --- old/ansible-core-2.15.3/lib/ansible/module_utils/ansible_release.py 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/lib/ansible/module_utils/ansible_release.py 2023-09-12 00:11:17.000000000 +0200 @@ -19,6 +19,6 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type -__version__ = '2.15.3' +__version__ = '2.15.4' __author__ = 'Ansible, Inc.' __codename__ = "Ten Years Gone" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/lib/ansible/module_utils/basic.py new/ansible-core-2.15.4/lib/ansible/module_utils/basic.py --- old/ansible-core-2.15.3/lib/ansible/module_utils/basic.py 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/lib/ansible/module_utils/basic.py 2023-09-12 00:11:17.000000000 +0200 @@ -1852,6 +1852,14 @@ ''' Execute a command, returns rc, stdout, and stderr. + The mechanism of this method for reading stdout and stderr differs from + that of CPython subprocess.Popen.communicate, in that this method will + stop reading once the spawned command has exited and stdout and stderr + have been consumed, as opposed to waiting until stdout/stderr are + closed. This can be an important distinction, when taken into account + that a forked or backgrounded process may hold stdout or stderr open + for longer than the spawned command. + :arg args: is the command to run * If args is a list, the command will be run with shell=False. * If args is a string and use_unsafe_shell=False it will split args to a list and run with shell=False @@ -2031,17 +2039,17 @@ if before_communicate_callback: before_communicate_callback(cmd) - # the communication logic here is essentially taken from that - # of the _communicate() function in ssh.py - stdout = b'' stderr = b'' - try: - selector = selectors.DefaultSelector() - except (IOError, OSError): - # Failed to detect default selector for the given platform - # Select PollSelector which is supported by major platforms + + # Mirror the CPython subprocess logic and preference for the selector to use. + # poll/select have the advantage of not requiring any extra file + # descriptor, contrarily to epoll/kqueue (also, they require a single + # syscall). + if hasattr(selectors, 'PollSelector'): selector = selectors.PollSelector() + else: + selector = selectors.SelectSelector() if data: if not binary_data: @@ -2049,53 +2057,58 @@ if isinstance(data, text_type): data = to_bytes(data) - if not prompt_re: - stdout, stderr = cmd.communicate(input=data) - else: - # We only need this to look for a prompt, to abort instead of hanging - selector.register(cmd.stdout, selectors.EVENT_READ) - selector.register(cmd.stderr, selectors.EVENT_READ) - if os.name == 'posix': - fcntl.fcntl(cmd.stdout.fileno(), fcntl.F_SETFL, fcntl.fcntl(cmd.stdout.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK) - fcntl.fcntl(cmd.stderr.fileno(), fcntl.F_SETFL, fcntl.fcntl(cmd.stderr.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK) - - if data: - cmd.stdin.write(data) - cmd.stdin.close() - - while True: - events = selector.select(1) - for key, event in events: - b_chunk = key.fileobj.read() - if b_chunk == b(''): - selector.unregister(key.fileobj) - if key.fileobj == cmd.stdout: - stdout += b_chunk - elif key.fileobj == cmd.stderr: - stderr += b_chunk - # if we're checking for prompts, do it now - if prompt_re: - if prompt_re.search(stdout) and not data: - if encoding: - stdout = to_native(stdout, encoding=encoding, errors=errors) - return (257, stdout, "A prompt was encountered while running a command, but no input data was specified") - # only break out if no pipes are left to read or - # the pipes are completely read and - # the process is terminated - if (not events or not selector.get_map()) and cmd.poll() is not None: - break - # No pipes are left to read but process is not yet terminated - # Only then it is safe to wait for the process to be finished - # NOTE: Actually cmd.poll() is always None here if no selectors are left - elif not selector.get_map() and cmd.poll() is None: - cmd.wait() - # The process is terminated. Since no pipes to read from are - # left, there is no need to call select() again. - break - - cmd.stdout.close() - cmd.stderr.close() - selector.close() + selector.register(cmd.stdout, selectors.EVENT_READ) + selector.register(cmd.stderr, selectors.EVENT_READ) + + if os.name == 'posix': + fcntl.fcntl(cmd.stdout.fileno(), fcntl.F_SETFL, fcntl.fcntl(cmd.stdout.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK) + fcntl.fcntl(cmd.stderr.fileno(), fcntl.F_SETFL, fcntl.fcntl(cmd.stderr.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK) + + if data: + cmd.stdin.write(data) + cmd.stdin.close() + + while True: + # A timeout of 1 is both a little short and a little long. + # With None we could deadlock, with a lower value we would + # waste cycles. As it is, this is a mild inconvenience if + # we need to exit, and likely doesn't waste too many cycles + events = selector.select(1) + stdout_changed = False + for key, event in events: + b_chunk = key.fileobj.read(32768) + if not b_chunk: + selector.unregister(key.fileobj) + elif key.fileobj == cmd.stdout: + stdout += b_chunk + stdout_changed = True + elif key.fileobj == cmd.stderr: + stderr += b_chunk + + # if we're checking for prompts, do it now, but only if stdout + # actually changed since the last loop + if prompt_re and stdout_changed and prompt_re.search(stdout) and not data: + if encoding: + stdout = to_native(stdout, encoding=encoding, errors=errors) + return (257, stdout, "A prompt was encountered while running a command, but no input data was specified") + + # break out if no pipes are left to read or the pipes are completely read + # and the process is terminated + if (not events or not selector.get_map()) and cmd.poll() is not None: + break + + # No pipes are left to read but process is not yet terminated + # Only then it is safe to wait for the process to be finished + # NOTE: Actually cmd.poll() is always None here if no selectors are left + elif not selector.get_map() and cmd.poll() is None: + cmd.wait() + # The process is terminated. Since no pipes to read from are + # left, there is no need to call select() again. + break + + cmd.stdout.close() + cmd.stderr.close() + selector.close() rc = cmd.returncode except (OSError, IOError) as e: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/lib/ansible/module_utils/csharp/Ansible.AccessToken.cs new/ansible-core-2.15.4/lib/ansible/module_utils/csharp/Ansible.AccessToken.cs --- old/ansible-core-2.15.3/lib/ansible/module_utils/csharp/Ansible.AccessToken.cs 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/lib/ansible/module_utils/csharp/Ansible.AccessToken.cs 2023-09-12 00:11:17.000000000 +0200 @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; using System.Security.Principal; using System.Text; @@ -123,7 +122,6 @@ base.SetHandle(handle); } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { Marshal.FreeHGlobal(handle); @@ -247,7 +245,6 @@ public SafeNativeHandle() : base(true) { } public SafeNativeHandle(IntPtr handle) : base(true) { this.handle = handle; } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { return NativeMethods.CloseHandle(handle); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/lib/ansible/module_utils/csharp/Ansible.Become.cs new/ansible-core-2.15.4/lib/ansible/module_utils/csharp/Ansible.Become.cs --- old/ansible-core-2.15.3/lib/ansible/module_utils/csharp/Ansible.Become.cs 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/lib/ansible/module_utils/csharp/Ansible.Become.cs 2023-09-12 00:11:17.000000000 +0200 @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; using System.Security.AccessControl; using System.Security.Principal; @@ -175,7 +174,6 @@ { public SafeLsaHandle() : base(true) { } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { UInt32 res = NativeMethods.LsaDeregisterLogonProcess(handle); @@ -187,7 +185,6 @@ { public SafeLsaMemoryBuffer() : base(true) { } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { UInt32 res = NativeMethods.LsaFreeReturnBuffer(handle); @@ -200,7 +197,6 @@ public NoopSafeHandle() : base(IntPtr.Zero, false) { } public override bool IsInvalid { get { return false; } } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { return true; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/lib/ansible/module_utils/csharp/Ansible.Privilege.cs new/ansible-core-2.15.4/lib/ansible/module_utils/csharp/Ansible.Privilege.cs --- old/ansible-core-2.15.3/lib/ansible/module_utils/csharp/Ansible.Privilege.cs 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/lib/ansible/module_utils/csharp/Ansible.Privilege.cs 2023-09-12 00:11:17.000000000 +0200 @@ -3,7 +3,6 @@ using System.Collections; using System.Collections.Generic; using System.Linq; -using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; using System.Security.Principal; using System.Text; @@ -92,7 +91,6 @@ { base.SetHandle(handle); } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { Marshal.FreeHGlobal(handle); @@ -104,7 +102,7 @@ { public SafeNativeHandle() : base(true) { } public SafeNativeHandle(IntPtr handle) : base(true) { this.handle = handle; } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] + protected override bool ReleaseHandle() { return NativeMethods.CloseHandle(handle); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/lib/ansible/module_utils/csharp/Ansible.Process.cs new/ansible-core-2.15.4/lib/ansible/module_utils/csharp/Ansible.Process.cs --- old/ansible-core-2.15.3/lib/ansible/module_utils/csharp/Ansible.Process.cs 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/lib/ansible/module_utils/csharp/Ansible.Process.cs 2023-09-12 00:11:17.000000000 +0200 @@ -3,7 +3,6 @@ using System.Collections; using System.IO; using System.Linq; -using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; using System.Text; using System.Threading; @@ -176,7 +175,6 @@ base.SetHandle(handle); } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { Marshal.FreeHGlobal(handle); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/lib/ansible/playbook/role_include.py new/ansible-core-2.15.4/lib/ansible/playbook/role_include.py --- old/ansible-core-2.15.3/lib/ansible/playbook/role_include.py 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/lib/ansible/playbook/role_include.py 2023-09-12 00:11:17.000000000 +0200 @@ -113,7 +113,7 @@ b.collections = actual_role.collections # updated available handlers in play - handlers = actual_role.get_handler_blocks(play=myplay) + handlers = actual_role.get_handler_blocks(play=myplay, dep_chain=dep_chain) for h in handlers: h._parent = p_block myplay.handlers = myplay.handlers + handlers diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/lib/ansible/plugins/filter/encryption.py new/ansible-core-2.15.4/lib/ansible/plugins/filter/encryption.py --- old/ansible-core-2.15.3/lib/ansible/plugins/filter/encryption.py 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/lib/ansible/plugins/filter/encryption.py 2023-09-12 00:11:17.000000000 +0200 @@ -17,7 +17,7 @@ display = Display() -def do_vault(data, secret, salt=None, vaultid='filter_default', wrap_object=False): +def do_vault(data, secret, salt=None, vault_id='filter_default', wrap_object=False, vaultid=None): if not isinstance(secret, (string_types, binary_type, Undefined)): raise AnsibleFilterTypeError("Secret passed is required to be a string, instead we got: %s" % type(secret)) @@ -25,11 +25,18 @@ if not isinstance(data, (string_types, binary_type, Undefined)): raise AnsibleFilterTypeError("Can only vault strings, instead we got: %s" % type(data)) + if vaultid is not None: + display.deprecated("Use of undocumented 'vaultid', use 'vault_id' instead", version='2.20') + if vault_id == 'filter_default': + vault_id = vaultid + else: + display.warning("Ignoring vaultid as vault_id is already set.") + vault = '' vs = VaultSecret(to_bytes(secret)) vl = VaultLib() try: - vault = vl.encrypt(to_bytes(data), vs, vaultid, salt) + vault = vl.encrypt(to_bytes(data), vs, vault_id, salt) except UndefinedError: raise except Exception as e: @@ -43,7 +50,7 @@ return vault -def do_unvault(vault, secret, vaultid='filter_default'): +def do_unvault(vault, secret, vault_id='filter_default', vaultid=None): if not isinstance(secret, (string_types, binary_type, Undefined)): raise AnsibleFilterTypeError("Secret passed is required to be as string, instead we got: %s" % type(secret)) @@ -51,9 +58,16 @@ if not isinstance(vault, (string_types, binary_type, AnsibleVaultEncryptedUnicode, Undefined)): raise AnsibleFilterTypeError("Vault should be in the form of a string, instead we got: %s" % type(vault)) + if vaultid is not None: + display.deprecated("Use of undocumented 'vaultid', use 'vault_id' instead", version='2.20') + if vault_id == 'filter_default': + vault_id = vaultid + else: + display.warning("Ignoring vaultid as vault_id is already set.") + data = '' vs = VaultSecret(to_bytes(secret)) - vl = VaultLib([(vaultid, vs)]) + vl = VaultLib([(vault_id, vs)]) if isinstance(vault, AnsibleVaultEncryptedUnicode): vault.vault = vl data = vault.data diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/lib/ansible/plugins/lookup/first_found.py new/ansible-core-2.15.4/lib/ansible/plugins/lookup/first_found.py --- old/ansible-core-2.15.3/lib/ansible/plugins/lookup/first_found.py 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/lib/ansible/plugins/lookup/first_found.py 2023-09-12 00:11:17.000000000 +0200 @@ -165,6 +165,9 @@ total_search = [] skip = False + if not terms and kwargs: + terms = [''] + # can use a dict instead of list item to pass inline config for term in terms: if isinstance(term, Mapping): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/lib/ansible/plugins/strategy/__init__.py new/ansible-core-2.15.4/lib/ansible/plugins/strategy/__init__.py --- old/ansible-core-2.15.3/lib/ansible/plugins/strategy/__init__.py 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/lib/ansible/plugins/strategy/__init__.py 2023-09-12 00:11:17.000000000 +0200 @@ -509,8 +509,11 @@ def search_handlers_by_notification(self, notification: str, iterator: PlayIterator) -> t.Generator[Handler, None, None]: templar = Templar(None) + handlers = [h for b in reversed(iterator._play.handlers) for h in b.block] # iterate in reversed order since last handler loaded with the same name wins - for handler in (h for b in reversed(iterator._play.handlers) for h in b.block if h.name): + for handler in handlers: + if not handler.name: + continue if not handler.cached_name: if templar.is_template(handler.name): templar.available_variables = self._variable_manager.get_vars( @@ -548,7 +551,8 @@ break templar.available_variables = {} - for handler in (h for b in iterator._play.handlers for h in b.block): + seen = [] + for handler in handlers: if listeners := handler.listen: if notification in handler.get_validated_value( 'listen', @@ -556,6 +560,9 @@ listeners, templar, ): + if handler.name and handler.name in seen: + continue + seen.append(handler.name) yield handler @debug_closure diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/lib/ansible/release.py new/ansible-core-2.15.4/lib/ansible/release.py --- old/ansible-core-2.15.3/lib/ansible/release.py 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/lib/ansible/release.py 2023-09-12 00:11:17.000000000 +0200 @@ -19,6 +19,6 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type -__version__ = '2.15.3' +__version__ = '2.15.4' __author__ = 'Ansible, Inc.' __codename__ = "Ten Years Gone" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/lib/ansible/utils/display.py new/ansible-core-2.15.4/lib/ansible/utils/display.py --- old/ansible-core-2.15.3/lib/ansible/utils/display.py 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/lib/ansible/utils/display.py 2023-09-12 00:11:17.000000000 +0200 @@ -698,6 +698,8 @@ os.set_blocking(self._stdin_fd, False) while key_pressed is None and (seconds is None or (time.time() - start < seconds)): key_pressed = self._stdin.read(1) + # throttle to prevent excess CPU consumption + time.sleep(C.DEFAULT_INTERNAL_POLL_INTERVAL) finally: os.set_blocking(self._stdin_fd, True) if key_pressed is None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/lib/ansible_core.egg-info/PKG-INFO new/ansible-core-2.15.4/lib/ansible_core.egg-info/PKG-INFO --- old/ansible-core-2.15.3/lib/ansible_core.egg-info/PKG-INFO 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/lib/ansible_core.egg-info/PKG-INFO 2023-09-12 00:11:17.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: ansible-core -Version: 2.15.3 +Version: 2.15.4 Summary: Radically simple IT automation Home-page: https://ansible.com/ Author: Ansible, Inc. @@ -31,6 +31,12 @@ Requires-Python: >=3.9 Description-Content-Type: text/markdown License-File: COPYING +Requires-Dist: jinja2>=3.0.0 +Requires-Dist: PyYAML>=5.1 +Requires-Dist: cryptography +Requires-Dist: packaging +Requires-Dist: importlib_resources<5.1,>=5.0; python_version < "3.10" +Requires-Dist: resolvelib<1.1.0,>=0.5.3 [](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.15.3/lib/ansible_core.egg-info/SOURCES.txt new/ansible-core-2.15.4/lib/ansible_core.egg-info/SOURCES.txt --- old/ansible-core-2.15.3/lib/ansible_core.egg-info/SOURCES.txt 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/lib/ansible_core.egg-info/SOURCES.txt 2023-09-12 00:11:17.000000000 +0200 @@ -984,6 +984,10 @@ test/integration/targets/ansible-test-git/collection-tests/git-common.bash test/integration/targets/ansible-test-git/collection-tests/install-git.yml test/integration/targets/ansible-test-git/collection-tests/uninstall-git.yml +test/integration/targets/ansible-test-installed/aliases +test/integration/targets/ansible-test-installed/runme.sh +test/integration/targets/ansible-test-installed/ansible_collections/ns/col/tests/integration/targets/installed/aliases +test/integration/targets/ansible-test-installed/ansible_collections/ns/col/tests/integration/targets/installed/runme.sh test/integration/targets/ansible-test-integration/aliases test/integration/targets/ansible-test-integration/runme.sh test/integration/targets/ansible-test-integration-constraints/aliases @@ -1590,6 +1594,7 @@ test/integration/targets/command_shell/files/remove_afile.sh test/integration/targets/command_shell/files/test.sh test/integration/targets/command_shell/meta/main.yml +test/integration/targets/command_shell/scripts/yoink.sh test/integration/targets/command_shell/tasks/main.yml test/integration/targets/common_network/aliases test/integration/targets/common_network/tasks/main.yml @@ -2002,6 +2007,7 @@ test/integration/targets/handlers/test_handlers_meta.yml test/integration/targets/handlers/test_handlers_template_run_once.yml test/integration/targets/handlers/test_include_role_handler_once.yml +test/integration/targets/handlers/test_listen_role_dedup.yml test/integration/targets/handlers/test_listening_handlers.yml test/integration/targets/handlers/test_notify_included-handlers.yml test/integration/targets/handlers/test_notify_included.yml @@ -2010,6 +2016,10 @@ test/integration/targets/handlers/test_skip_flush.yml test/integration/targets/handlers/test_templating_in_handlers.yml test/integration/targets/handlers/roles/import_template_handler_names/tasks/main.yml +test/integration/targets/handlers/roles/r1-dep_chain-vars/defaults/main.yml +test/integration/targets/handlers/roles/r1-dep_chain-vars/tasks/main.yml +test/integration/targets/handlers/roles/r2-dep_chain-vars/handlers/main.yml +test/integration/targets/handlers/roles/r2-dep_chain-vars/tasks/main.yml test/integration/targets/handlers/roles/template_handler_names/handlers/main.yml test/integration/targets/handlers/roles/template_handler_names/tasks/evaluation_time.yml test/integration/targets/handlers/roles/template_handler_names/tasks/lazy_evaluation.yml @@ -2028,6 +2038,11 @@ test/integration/targets/handlers/roles/test_handlers_meta/handlers/alternate.yml test/integration/targets/handlers/roles/test_handlers_meta/handlers/main.yml test/integration/targets/handlers/roles/test_handlers_meta/tasks/main.yml +test/integration/targets/handlers/roles/test_listen_role_dedup_global/handlers/main.yml +test/integration/targets/handlers/roles/test_listen_role_dedup_role1/meta/main.yml +test/integration/targets/handlers/roles/test_listen_role_dedup_role1/tasks/main.yml +test/integration/targets/handlers/roles/test_listen_role_dedup_role2/meta/main.yml +test/integration/targets/handlers/roles/test_listen_role_dedup_role2/tasks/main.yml test/integration/targets/handlers/roles/test_role_handlers_include_tasks/handlers/A.yml test/integration/targets/handlers/roles/test_role_handlers_include_tasks/handlers/main.yml test/integration/targets/handlers/roles/test_role_handlers_include_tasks/tasks/B.yml diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/packaging/release.py new/ansible-core-2.15.4/packaging/release.py --- old/ansible-core-2.15.3/packaging/release.py 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/packaging/release.py 2023-09-12 00:11:17.000000000 +0200 @@ -42,7 +42,7 @@ # region CLI Framework -C = t.TypeVar("C", bound=t.Callable[[...], None]) +C = t.TypeVar("C", bound=t.Callable[..., None]) def path_to_str(value: t.Any) -> str: @@ -50,12 +50,27 @@ return f"{value}/" if isinstance(value, pathlib.Path) and value.is_dir() else str(value) +@t.overload +def run(*args: t.Any, env: dict[str, t.Any] | None, cwd: pathlib.Path | str, capture_output: t.Literal[True]) -> CompletedProcess: + ... + + +@t.overload +def run(*args: t.Any, env: dict[str, t.Any] | None, cwd: pathlib.Path | str, capture_output: t.Literal[False]) -> None: + ... + + +@t.overload +def run(*args: t.Any, env: dict[str, t.Any] | None, cwd: pathlib.Path | str) -> None: + ... + + def run( *args: t.Any, env: dict[str, t.Any] | None, cwd: pathlib.Path | str, capture_output: bool = False, -) -> CompletedProcess: +) -> CompletedProcess | None: """Run the specified command.""" args = [arg.relative_to(cwd) if isinstance(arg, pathlib.Path) else arg for arg in args] @@ -76,16 +91,18 @@ stderr=ex.stderr, ) from None + if not capture_output: + return None + # improve type hinting return CompletedProcess( - args=str_args, stdout=p.stdout, stderr=p.stderr, ) @contextlib.contextmanager -def suppress_when(error_as_warning: bool) -> None: +def suppress_when(error_as_warning: bool) -> t.Generator[None, None, None]: """Conditionally convert an ApplicationError in the provided context to a warning.""" if error_as_warning: try: @@ -122,9 +139,8 @@ class CompletedProcess: """Results from a completed process.""" - args: tuple[str, ...] - stdout: str | None - stderr: str | None + stdout: str + stderr: str class Display: @@ -167,7 +183,7 @@ """ def __init__(self, **kwargs: dict[str, t.Any] | None) -> None: - self.commands: list[C] = [] + self.commands: list[t.Callable[..., None]] = [] self.arguments = kwargs self.parsed_arguments: argparse.Namespace | None = None @@ -176,7 +192,7 @@ self.commands.append(func) return func - def run(self, *args: C, **kwargs) -> None: + def run(self, *args: t.Callable[..., None], **kwargs) -> None: """Run the specified command(s), using any provided internal args.""" for arg in args: self._run(arg, **kwargs) @@ -203,6 +219,9 @@ arguments = arguments.copy() exclusive = arguments.pop("exclusive", None) + # noinspection PyProtectedMember, PyUnresolvedReferences + command_parser: argparse._ActionsContainer + if exclusive: if exclusive not in exclusive_groups: exclusive_groups[exclusive] = func_parser.add_mutually_exclusive_group() @@ -234,7 +253,7 @@ display.fatal(ex) sys.exit(1) - def _run(self, func: C, **kwargs) -> None: + def _run(self, func: t.Callable[..., None], **kwargs) -> None: """Run the specified command, using any provided internal args.""" signature = inspect.signature(func) func_args = {name: getattr(self.parsed_arguments, name) for name in signature.parameters if hasattr(self.parsed_arguments, name)} @@ -253,7 +272,7 @@ display.show(f"<== {label}", color=Display.BLUE) @staticmethod - def _format_command_name(func: C) -> str: + def _format_command_name(func: t.Callable[..., None]) -> str: """Return the friendly name of the given command.""" return func.__name__.replace("_", "-") @@ -441,7 +460,22 @@ raise NotImplementedError(self) -def git(*args: t.Any, capture_output: bool = False) -> CompletedProcess: +@t.overload +def git(*args: t.Any, capture_output: t.Literal[True]) -> CompletedProcess: + ... + + +@t.overload +def git(*args: t.Any, capture_output: t.Literal[False]) -> None: + ... + + +@t.overload +def git(*args: t.Any) -> None: + ... + + +def git(*args: t.Any, capture_output: t.Literal[True] | t.Literal[False] = False) -> CompletedProcess | None: """Run the specified git command.""" return run("git", *args, env=None, cwd=CHECKOUT_DIR, capture_output=capture_output) @@ -534,10 +568,6 @@ ##### ISSUE TYPE Feature Pull Request - -##### COMPONENT NAME - -ansible """ return body.lstrip() @@ -629,7 +659,7 @@ @functools.cache -def ensure_venv() -> dict[str, str]: +def ensure_venv() -> dict[str, t.Any]: """Ensure the release venv is ready and return the env vars needed to use it.""" # TODO: consider freezing the ansible and release requirements along with their dependencies @@ -943,7 +973,7 @@ variables = dict( version=version, releases=get_release_artifact_details(repository, version, validate), - changelog=f"https://github.com/{upstream.user}/{upstream.repo}/blob/v{ version }/changelogs/CHANGELOG-v{ version.major }.{ version.minor }.rst", + changelog=f"https://github.com/{upstream.user}/{upstream.repo}/blob/v{version}/changelogs/CHANGELOG-v{version.major}.{version.minor}.rst", ) release_notes = template.render(**variables).strip() @@ -1274,7 +1304,7 @@ commit_time = int(git("show", "-s", "--format=%ct", capture_output=True).stdout) env.update( - SOURCE_DATE_EPOCH=str(commit_time), + SOURCE_DATE_EPOCH=commit_time, ) git("worktree", "add", "-d", temp_dir) @@ -1312,7 +1342,11 @@ except FileNotFoundError: raise ApplicationError(f"Missing sdist: {sdist_file.relative_to(CHECKOUT_DIR)}") from None - sdist.extractall(temp_dir) + # deprecated: description='extractall fallback without filter' python_version='3.11' + if hasattr(tarfile, 'data_filter'): + sdist.extractall(temp_dir, filter='data') # type: ignore[call-arg] + else: + sdist.extractall(temp_dir) pyc_glob = "*.pyc*" pyc_files = sorted(path.relative_to(temp_dir) for path in temp_dir.rglob(pyc_glob)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/integration/targets/ansible-galaxy-collection/library/setup_collections.py new/ansible-core-2.15.4/test/integration/targets/ansible-galaxy-collection/library/setup_collections.py --- old/ansible-core-2.15.3/test/integration/targets/ansible-galaxy-collection/library/setup_collections.py 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/test/integration/targets/ansible-galaxy-collection/library/setup_collections.py 2023-09-12 00:11:17.000000000 +0200 @@ -152,7 +152,12 @@ # Extract the tarfile to sign the MANIFEST.json with tarfile.open(collection_path, mode='r') as collection_tar: - collection_tar.extractall(path=os.path.join(collection_dir, '%s-%s-%s' % (namespace, name, version))) + # deprecated: description='extractall fallback without filter' python_version='3.11' + # Replace 'tar_filter' with 'data_filter' and 'filter=tar' with 'filter=data' once Python 3.12 is minimum requirement. + if hasattr(tarfile, 'tar_filter'): + collection_tar.extractall(path=os.path.join(collection_dir, '%s-%s-%s' % (namespace, name, version)), filter='tar') + else: + collection_tar.extractall(path=os.path.join(collection_dir, '%s-%s-%s' % (namespace, name, version))) manifest_path = os.path.join(collection_dir, '%s-%s-%s' % (namespace, name, version), 'MANIFEST.json') signature_path = os.path.join(module.params['signature_dir'], '%s-%s-%s-MANIFEST.json.asc' % (namespace, name, version)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/integration/targets/ansible-test-installed/aliases new/ansible-core-2.15.4/test/integration/targets/ansible-test-installed/aliases --- old/ansible-core-2.15.3/test/integration/targets/ansible-test-installed/aliases 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible-core-2.15.4/test/integration/targets/ansible-test-installed/aliases 2023-09-12 00:11:17.000000000 +0200 @@ -0,0 +1,4 @@ +shippable/posix/group3 # runs in the distro test containers +shippable/generic/group1 # runs in the default test container +context/controller +needs/target/collection diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/integration/targets/ansible-test-installed/ansible_collections/ns/col/tests/integration/targets/installed/aliases new/ansible-core-2.15.4/test/integration/targets/ansible-test-installed/ansible_collections/ns/col/tests/integration/targets/installed/aliases --- old/ansible-core-2.15.3/test/integration/targets/ansible-test-installed/ansible_collections/ns/col/tests/integration/targets/installed/aliases 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible-core-2.15.4/test/integration/targets/ansible-test-installed/ansible_collections/ns/col/tests/integration/targets/installed/aliases 2023-09-12 00:11:17.000000000 +0200 @@ -0,0 +1 @@ +context/controller diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/integration/targets/ansible-test-installed/ansible_collections/ns/col/tests/integration/targets/installed/runme.sh new/ansible-core-2.15.4/test/integration/targets/ansible-test-installed/ansible_collections/ns/col/tests/integration/targets/installed/runme.sh --- old/ansible-core-2.15.3/test/integration/targets/ansible-test-installed/ansible_collections/ns/col/tests/integration/targets/installed/runme.sh 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible-core-2.15.4/test/integration/targets/ansible-test-installed/ansible_collections/ns/col/tests/integration/targets/installed/runme.sh 2023-09-12 00:11:17.000000000 +0200 @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# This test ensures that the bin entry points created by ansible-test work +# when ansible-test is running from an install instead of from source. + +set -eux + +# The third PATH entry is the injected bin directory created by ansible-test. +bin_dir="$(python -c 'import os; print(os.environ["PATH"].split(":")[2])')" + +while IFS= read -r name +do + bin="${bin_dir}/${name}" + + entry_point="${name//ansible-/}" + entry_point="${entry_point//ansible/adhoc}" + + echo "=== ${name} (${entry_point})=${bin} ===" + + if [ "${name}" == "ansible-test" ]; then + echo "skipped - ansible-test does not support self-testing from an install" + else + "${bin}" --version | tee /dev/stderr | grep -Eo "(^${name}\ \[core\ .*|executable location = ${bin}$)" + fi +done < entry-points.txt diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/integration/targets/ansible-test-installed/runme.sh new/ansible-core-2.15.4/test/integration/targets/ansible-test-installed/runme.sh --- old/ansible-core-2.15.3/test/integration/targets/ansible-test-installed/runme.sh 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible-core-2.15.4/test/integration/targets/ansible-test-installed/runme.sh 2023-09-12 00:11:17.000000000 +0200 @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +base_dir="$(dirname "$(dirname "$(dirname "$(dirname "${OUTPUT_DIR}")")")")" +bin_dir="${base_dir}/bin" + +source ../collection/setup.sh +source virtualenv.sh + +unset PYTHONPATH + +# find the bin entry points to test +ls "${bin_dir}" > tests/integration/targets/installed/entry-points.txt + +# deps are already installed, using --no-deps to avoid re-installing them +pip install "${base_dir}" --disable-pip-version-check --no-deps + +# verify entry point generation without delegation +ansible-test integration --color --truncate 0 "${@}" + +# verify entry point generation with same-host delegation +ansible-test integration --venv --color --truncate 0 "${@}" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/integration/targets/command_shell/scripts/yoink.sh new/ansible-core-2.15.4/test/integration/targets/command_shell/scripts/yoink.sh --- old/ansible-core-2.15.3/test/integration/targets/command_shell/scripts/yoink.sh 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible-core-2.15.4/test/integration/targets/command_shell/scripts/yoink.sh 2023-09-12 00:11:17.000000000 +0200 @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +sleep 10 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/integration/targets/command_shell/tasks/main.yml new/ansible-core-2.15.4/test/integration/targets/command_shell/tasks/main.yml --- old/ansible-core-2.15.3/test/integration/targets/command_shell/tasks/main.yml 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/test/integration/targets/command_shell/tasks/main.yml 2023-09-12 00:11:17.000000000 +0200 @@ -546,3 +546,8 @@ - command_strip.stderr == 'hello \n ' - command_no_strip.stdout== 'hello \n \r\n' - command_no_strip.stderr == 'hello \n \r\n' + +- name: Run command that backgrounds, to ensure no hang + shell: '{{ role_path }}/scripts/yoink.sh &' + delegate_to: localhost + timeout: 5 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/integration/targets/filter_encryption/base.yml new/ansible-core-2.15.4/test/integration/targets/filter_encryption/base.yml --- old/ansible-core-2.15.3/test/integration/targets/filter_encryption/base.yml 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/test/integration/targets/filter_encryption/base.yml 2023-09-12 00:11:17.000000000 +0200 @@ -2,6 +2,7 @@ gather_facts: true vars: data: secret + data2: 'foo: bar\n' dvault: '{{ "secret"|vault("test")}}' password: test s_32: '{{(2**31-1)}}' @@ -21,6 +22,15 @@ is_64: '{{ "64" in ansible_facts["architecture"] }}' salt: '{{ is_64|bool|ternary(s_64, s_32)|random(seed=inventory_hostname)}}' vaultedstring: '{{ is_64|bool|ternary(vaultedstring_64, vaultedstring_32) }}' + # command line vaulted data2 + vaulted_id: !vault | + $ANSIBLE_VAULT;1.2;AES256;test1 + 36383733336533656264393332663131613335333332346439356164383935656234663631356430 + 3533353537343834333538356366376233326364613362640a623832636339363966336238393039 + 35316562626335306534356162623030613566306235623863373036626531346364626166656134 + 3063376436656635330a363636376131663362633731313964353061663661376638326461393736 + 3863 + vaulted_to_id: "{{data2|vault('test1@secret', vault_id='test1')}}" tasks: - name: check vaulting @@ -35,3 +45,5 @@ that: - vaultedstring|unvault(password) == data - vault|unvault(password) == data + - vaulted_id|unvault('test1@secret', vault_id='test1') + - vaulted_to_id|unvault('test1@secret', vault_id='test1') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/integration/targets/handlers/roles/r1-dep_chain-vars/defaults/main.yml new/ansible-core-2.15.4/test/integration/targets/handlers/roles/r1-dep_chain-vars/defaults/main.yml --- old/ansible-core-2.15.3/test/integration/targets/handlers/roles/r1-dep_chain-vars/defaults/main.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible-core-2.15.4/test/integration/targets/handlers/roles/r1-dep_chain-vars/defaults/main.yml 2023-09-12 00:11:17.000000000 +0200 @@ -0,0 +1 @@ +v: foo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/integration/targets/handlers/roles/r1-dep_chain-vars/tasks/main.yml new/ansible-core-2.15.4/test/integration/targets/handlers/roles/r1-dep_chain-vars/tasks/main.yml --- old/ansible-core-2.15.3/test/integration/targets/handlers/roles/r1-dep_chain-vars/tasks/main.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible-core-2.15.4/test/integration/targets/handlers/roles/r1-dep_chain-vars/tasks/main.yml 2023-09-12 00:11:17.000000000 +0200 @@ -0,0 +1,2 @@ +- include_role: + name: r2-dep_chain-vars diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/integration/targets/handlers/roles/r2-dep_chain-vars/handlers/main.yml new/ansible-core-2.15.4/test/integration/targets/handlers/roles/r2-dep_chain-vars/handlers/main.yml --- old/ansible-core-2.15.3/test/integration/targets/handlers/roles/r2-dep_chain-vars/handlers/main.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible-core-2.15.4/test/integration/targets/handlers/roles/r2-dep_chain-vars/handlers/main.yml 2023-09-12 00:11:17.000000000 +0200 @@ -0,0 +1,4 @@ +- name: h + assert: + that: + - v is defined diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/integration/targets/handlers/roles/r2-dep_chain-vars/tasks/main.yml new/ansible-core-2.15.4/test/integration/targets/handlers/roles/r2-dep_chain-vars/tasks/main.yml --- old/ansible-core-2.15.3/test/integration/targets/handlers/roles/r2-dep_chain-vars/tasks/main.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible-core-2.15.4/test/integration/targets/handlers/roles/r2-dep_chain-vars/tasks/main.yml 2023-09-12 00:11:17.000000000 +0200 @@ -0,0 +1,2 @@ +- command: echo + notify: h diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/integration/targets/handlers/roles/test_listen_role_dedup_global/handlers/main.yml new/ansible-core-2.15.4/test/integration/targets/handlers/roles/test_listen_role_dedup_global/handlers/main.yml --- old/ansible-core-2.15.3/test/integration/targets/handlers/roles/test_listen_role_dedup_global/handlers/main.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible-core-2.15.4/test/integration/targets/handlers/roles/test_listen_role_dedup_global/handlers/main.yml 2023-09-12 00:11:17.000000000 +0200 @@ -0,0 +1,4 @@ +- name: role_handler + debug: + msg: "a handler from a role" + listen: role_handler diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/integration/targets/handlers/roles/test_listen_role_dedup_role1/meta/main.yml new/ansible-core-2.15.4/test/integration/targets/handlers/roles/test_listen_role_dedup_role1/meta/main.yml --- old/ansible-core-2.15.3/test/integration/targets/handlers/roles/test_listen_role_dedup_role1/meta/main.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible-core-2.15.4/test/integration/targets/handlers/roles/test_listen_role_dedup_role1/meta/main.yml 2023-09-12 00:11:17.000000000 +0200 @@ -0,0 +1,2 @@ +dependencies: + - test_listen_role_dedup_global diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/integration/targets/handlers/roles/test_listen_role_dedup_role1/tasks/main.yml new/ansible-core-2.15.4/test/integration/targets/handlers/roles/test_listen_role_dedup_role1/tasks/main.yml --- old/ansible-core-2.15.3/test/integration/targets/handlers/roles/test_listen_role_dedup_role1/tasks/main.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible-core-2.15.4/test/integration/targets/handlers/roles/test_listen_role_dedup_role1/tasks/main.yml 2023-09-12 00:11:17.000000000 +0200 @@ -0,0 +1,3 @@ +- name: a task from role1 + command: echo + notify: role_handler diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/integration/targets/handlers/roles/test_listen_role_dedup_role2/meta/main.yml new/ansible-core-2.15.4/test/integration/targets/handlers/roles/test_listen_role_dedup_role2/meta/main.yml --- old/ansible-core-2.15.3/test/integration/targets/handlers/roles/test_listen_role_dedup_role2/meta/main.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible-core-2.15.4/test/integration/targets/handlers/roles/test_listen_role_dedup_role2/meta/main.yml 2023-09-12 00:11:17.000000000 +0200 @@ -0,0 +1,2 @@ +dependencies: + - test_listen_role_dedup_global diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/integration/targets/handlers/roles/test_listen_role_dedup_role2/tasks/main.yml new/ansible-core-2.15.4/test/integration/targets/handlers/roles/test_listen_role_dedup_role2/tasks/main.yml --- old/ansible-core-2.15.3/test/integration/targets/handlers/roles/test_listen_role_dedup_role2/tasks/main.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible-core-2.15.4/test/integration/targets/handlers/roles/test_listen_role_dedup_role2/tasks/main.yml 2023-09-12 00:11:17.000000000 +0200 @@ -0,0 +1,3 @@ +- name: a task from role2 + command: echo + notify: role_handler diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/integration/targets/handlers/runme.sh new/ansible-core-2.15.4/test/integration/targets/handlers/runme.sh --- old/ansible-core-2.15.3/test/integration/targets/handlers/runme.sh 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/test/integration/targets/handlers/runme.sh 2023-09-12 00:11:17.000000000 +0200 @@ -187,3 +187,8 @@ ansible-playbook test_include_role_handler_once.yml -i inventory.handlers "$@" 2>&1 | tee out.txt [ "$(grep out.txt -ce 'handler ran')" = "1" ] + +ansible-playbook test_listen_role_dedup.yml "$@" 2>&1 | tee out.txt +[ "$(grep out.txt -ce 'a handler from a role')" = "1" ] + +ansible localhost -m include_role -a "name=r1-dep_chain-vars" "$@" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/integration/targets/handlers/test_listen_role_dedup.yml new/ansible-core-2.15.4/test/integration/targets/handlers/test_listen_role_dedup.yml --- old/ansible-core-2.15.3/test/integration/targets/handlers/test_listen_role_dedup.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible-core-2.15.4/test/integration/targets/handlers/test_listen_role_dedup.yml 2023-09-12 00:11:17.000000000 +0200 @@ -0,0 +1,5 @@ +- hosts: localhost + gather_facts: false + roles: + - test_listen_role_dedup_role1 + - test_listen_role_dedup_role2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/integration/targets/lookup_first_found/tasks/main.yml new/ansible-core-2.15.4/test/integration/targets/lookup_first_found/tasks/main.yml --- old/ansible-core-2.15.3/test/integration/targets/lookup_first_found/tasks/main.yml 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/test/integration/targets/lookup_first_found/tasks/main.yml 2023-09-12 00:11:17.000000000 +0200 @@ -94,3 +94,11 @@ - assert: that: - foo is defined + +# TODO: no 'terms' test +- name: test first_found lookup with no terms + set_fact: + no_terms: "{{ query('first_found', files=['missing1', 'hosts', 'missing2'], paths=['/etc'], errors='ignore') }}" + +- assert: + that: "no_terms|first == '/etc/hosts'" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/integration/targets/module_utils_Ansible.Become/library/ansible_become_tests.ps1 new/ansible-core-2.15.4/test/integration/targets/module_utils_Ansible.Become/library/ansible_become_tests.ps1 --- old/ansible-core-2.15.3/test/integration/targets/module_utils_Ansible.Become/library/ansible_become_tests.ps1 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/test/integration/targets/module_utils_Ansible.Become/library/ansible_become_tests.ps1 2023-09-12 00:11:17.000000000 +0200 @@ -48,7 +48,6 @@ Add-Type -TypeDefinition @' using Microsoft.Win32.SafeHandles; using System; -using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; using System.Security.Principal; using System.Text; @@ -212,7 +211,6 @@ { public SafeLsaMemoryBuffer() : base(true) { } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { UInt32 res = NativeMethods.LsaFreeReturnBuffer(handle); @@ -232,7 +230,6 @@ base.SetHandle(handle); } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { Marshal.FreeHGlobal(handle); @@ -245,7 +242,6 @@ public SafeNativeHandle() : base(true) { } public SafeNativeHandle(IntPtr handle) : base(true) { this.handle = handle; } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { return NativeMethods.CloseHandle(handle); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/integration/targets/unvault/main.yml new/ansible-core-2.15.4/test/integration/targets/unvault/main.yml --- old/ansible-core-2.15.3/test/integration/targets/unvault/main.yml 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/test/integration/targets/unvault/main.yml 2023-09-12 00:11:17.000000000 +0200 @@ -1,4 +1,5 @@ - hosts: localhost + gather_facts: false tasks: - set_fact: unvaulted: "{{ lookup('unvault', 'vault') }}" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/integration/targets/unvault/runme.sh new/ansible-core-2.15.4/test/integration/targets/unvault/runme.sh --- old/ansible-core-2.15.3/test/integration/targets/unvault/runme.sh 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/test/integration/targets/unvault/runme.sh 2023-09-12 00:11:17.000000000 +0200 @@ -2,5 +2,5 @@ set -eux - +# simple run ansible-playbook --vault-password-file password main.yml diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/lib/ansible_test/_internal/ansible_util.py new/ansible-core-2.15.4/test/lib/ansible_test/_internal/ansible_util.py --- old/ansible-core-2.15.3/test/lib/ansible_test/_internal/ansible_util.py 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/test/lib/ansible_test/_internal/ansible_util.py 2023-09-12 00:11:17.000000000 +0200 @@ -3,9 +3,11 @@ import json import os +import shutil import typing as t from .constants import ( + ANSIBLE_BIN_SYMLINK_MAP, SOFT_RLIMIT_NOFILE, ) @@ -17,12 +19,15 @@ common_environment, ApplicationError, ANSIBLE_LIB_ROOT, + ANSIBLE_TEST_ROOT, ANSIBLE_TEST_DATA_ROOT, - ANSIBLE_BIN_PATH, + ANSIBLE_ROOT, ANSIBLE_SOURCE_ROOT, ANSIBLE_TEST_TOOLS_ROOT, + MODE_FILE_EXECUTE, get_ansible_version, raw_command, + verified_chmod, ) from .util_common import ( @@ -78,8 +83,10 @@ env = common_environment() path = env['PATH'] - if not path.startswith(ANSIBLE_BIN_PATH + os.path.pathsep): - path = ANSIBLE_BIN_PATH + os.path.pathsep + path + ansible_bin_path = get_ansible_bin_path(args) + + if not path.startswith(ansible_bin_path + os.path.pathsep): + path = ansible_bin_path + os.path.pathsep + path if not ansible_config: # use the default empty configuration unless one has been provided @@ -197,6 +204,52 @@ @mutex +def get_ansible_bin_path(args: CommonConfig) -> str: + """ + Return a directory usable for PATH, containing only the ansible entry points. + If a temporary directory is required, it will be cached for the lifetime of the process and cleaned up at exit. + """ + try: + return get_ansible_bin_path.bin_path # type: ignore[attr-defined] + except AttributeError: + pass + + if ANSIBLE_SOURCE_ROOT: + # when running from source there is no need for a temporary directory since we already have known entry point scripts + bin_path = os.path.join(ANSIBLE_ROOT, 'bin') + else: + # when not running from source the installed entry points cannot be relied upon + # doing so would require using the interpreter specified by those entry points, which conflicts with using our interpreter and injector + # instead a temporary directory is created which contains only ansible entry points + # symbolic links cannot be used since the files are likely not executable + bin_path = create_temp_dir(prefix='ansible-test-', suffix='-bin') + bin_links = {os.path.join(bin_path, name): get_cli_path(path) for name, path in ANSIBLE_BIN_SYMLINK_MAP.items()} + + if not args.explain: + for dst, src in bin_links.items(): + shutil.copy(src, dst) + verified_chmod(dst, MODE_FILE_EXECUTE) + + get_ansible_bin_path.bin_path = bin_path # type: ignore[attr-defined] + + return bin_path + + +def get_cli_path(path: str) -> str: + """Return the absolute path to the CLI script from the given path which is relative to the `bin` directory of the original source tree layout.""" + path_rewrite = { + '../lib/ansible/': ANSIBLE_LIB_ROOT, + '../test/lib/ansible_test/': ANSIBLE_TEST_ROOT, + } + + for prefix, destination in path_rewrite.items(): + if path.startswith(prefix): + return os.path.join(destination, path[len(prefix):]) + + raise RuntimeError(path) + + +@mutex def get_ansible_python_path(args: CommonConfig) -> str: """ Return a directory usable for PYTHONPATH, containing only the ansible package. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/lib/ansible_test/_internal/commands/sanity/bin_symlinks.py new/ansible-core-2.15.4/test/lib/ansible_test/_internal/commands/sanity/bin_symlinks.py --- old/ansible-core-2.15.3/test/lib/ansible_test/_internal/commands/sanity/bin_symlinks.py 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/test/lib/ansible_test/_internal/commands/sanity/bin_symlinks.py 2023-09-12 00:11:17.000000000 +0200 @@ -32,7 +32,7 @@ ) from ...util import ( - ANSIBLE_BIN_PATH, + ANSIBLE_SOURCE_ROOT, ) @@ -52,7 +52,7 @@ return True def test(self, args: SanityConfig, targets: SanityTargets) -> TestResult: - bin_root = ANSIBLE_BIN_PATH + bin_root = os.path.join(ANSIBLE_SOURCE_ROOT, 'bin') bin_names = os.listdir(bin_root) bin_paths = sorted(os.path.join(bin_root, path) for path in bin_names) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/lib/ansible_test/_internal/commands/sanity/mypy.py new/ansible-core-2.15.4/test/lib/ansible_test/_internal/commands/sanity/mypy.py --- old/ansible-core-2.15.3/test/lib/ansible_test/_internal/commands/sanity/mypy.py 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/test/lib/ansible_test/_internal/commands/sanity/mypy.py 2023-09-12 00:11:17.000000000 +0200 @@ -73,7 +73,7 @@ """Return the given list of test targets, filtered to include only those relevant for the test.""" return [target for target in targets if os.path.splitext(target.path)[1] == '.py' and target.path not in self.vendored_paths and ( target.path.startswith('lib/ansible/') or target.path.startswith('test/lib/ansible_test/_internal/') - or target.path.startswith('packaging/cli-doc/') + or target.path.startswith('packaging/') or target.path.startswith('test/lib/ansible_test/_util/target/sanity/import/'))] @property @@ -117,7 +117,7 @@ MyPyContext('ansible-test', ['test/lib/ansible_test/_internal/'], controller_python_versions), MyPyContext('ansible-core', ['lib/ansible/'], controller_python_versions), MyPyContext('modules', ['lib/ansible/modules/', 'lib/ansible/module_utils/'], remote_only_python_versions), - MyPyContext('packaging', ['packaging/cli-doc/'], controller_python_versions), + MyPyContext('packaging', ['packaging/'], controller_python_versions), ) unfiltered_messages: list[SanityMessage] = [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/lib/ansible_test/_internal/commands/sanity/validate_modules.py new/ansible-core-2.15.4/test/lib/ansible_test/_internal/commands/sanity/validate_modules.py --- old/ansible-core-2.15.3/test/lib/ansible_test/_internal/commands/sanity/validate_modules.py 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/test/lib/ansible_test/_internal/commands/sanity/validate_modules.py 2023-09-12 00:11:17.000000000 +0200 @@ -159,7 +159,11 @@ temp_dir = process_scoped_temporary_directory(args) with tarfile.open(path) as file: - file.extractall(temp_dir) + # deprecated: description='extractall fallback without filter' python_version='3.11' + if hasattr(tarfile, 'data_filter'): + file.extractall(temp_dir, filter='data') # type: ignore[call-arg] + else: + file.extractall(temp_dir) cmd.extend([ '--original-plugins', temp_dir, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/lib/ansible_test/_internal/constants.py new/ansible-core-2.15.4/test/lib/ansible_test/_internal/constants.py --- old/ansible-core-2.15.3/test/lib/ansible_test/_internal/constants.py 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/test/lib/ansible_test/_internal/constants.py 2023-09-12 00:11:17.000000000 +0200 @@ -33,6 +33,7 @@ # This bin symlink map must exactly match the contents of the bin directory. # It is necessary for payload creation to reconstruct the bin directory when running ansible-test from an installed version of ansible. # It is also used to construct the injector directory at runtime. +# It is also used to construct entry points when not running ansible-test from source. ANSIBLE_BIN_SYMLINK_MAP = { 'ansible': '../lib/ansible/cli/adhoc.py', 'ansible-config': '../lib/ansible/cli/config.py', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/lib/ansible_test/_internal/delegation.py new/ansible-core-2.15.4/test/lib/ansible_test/_internal/delegation.py --- old/ansible-core-2.15.3/test/lib/ansible_test/_internal/delegation.py 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/test/lib/ansible_test/_internal/delegation.py 2023-09-12 00:11:17.000000000 +0200 @@ -33,7 +33,6 @@ SubprocessError, display, filter_args, - ANSIBLE_BIN_PATH, ANSIBLE_LIB_ROOT, ANSIBLE_TEST_ROOT, OutputStream, @@ -44,6 +43,10 @@ process_scoped_temporary_directory, ) +from .ansible_util import ( + get_ansible_bin_path, +) + from .containers import ( support_container_context, ContainerDatabase, @@ -145,7 +148,7 @@ con.extract_archive(chdir=working_directory, src=payload_file) else: content_root = working_directory - ansible_bin_path = ANSIBLE_BIN_PATH + ansible_bin_path = get_ansible_bin_path(args) command = generate_command(args, host_state.controller_profile.python, ansible_bin_path, content_root, exclude, require) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/lib/ansible_test/_internal/util.py new/ansible-core-2.15.4/test/lib/ansible_test/_internal/util.py --- old/ansible-core-2.15.3/test/lib/ansible_test/_internal/util.py 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/test/lib/ansible_test/_internal/util.py 2023-09-12 00:11:17.000000000 +0200 @@ -74,14 +74,12 @@ # assume running from install ANSIBLE_ROOT = os.path.dirname(ANSIBLE_TEST_ROOT) -ANSIBLE_BIN_PATH = os.path.dirname(os.path.abspath(sys.argv[0])) ANSIBLE_LIB_ROOT = os.path.join(ANSIBLE_ROOT, 'ansible') ANSIBLE_SOURCE_ROOT = None if not os.path.exists(ANSIBLE_LIB_ROOT): # running from source ANSIBLE_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(ANSIBLE_TEST_ROOT))) - ANSIBLE_BIN_PATH = os.path.join(ANSIBLE_ROOT, 'bin') ANSIBLE_LIB_ROOT = os.path.join(ANSIBLE_ROOT, 'lib', 'ansible') ANSIBLE_SOURCE_ROOT = ANSIBLE_ROOT diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/support/windows-integration/plugins/module_utils/Ansible.Service.cs new/ansible-core-2.15.4/test/support/windows-integration/plugins/module_utils/Ansible.Service.cs --- old/ansible-core-2.15.3/test/support/windows-integration/plugins/module_utils/Ansible.Service.cs 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/test/support/windows-integration/plugins/module_utils/Ansible.Service.cs 2023-09-12 00:11:17.000000000 +0200 @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; using System.Security.Principal; using System.Text; @@ -274,7 +273,6 @@ base.SetHandle(handle); } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { Marshal.FreeHGlobal(handle); @@ -287,7 +285,6 @@ public SafeServiceHandle() : base(true) { } public SafeServiceHandle(IntPtr handle) : base(true) { this.handle = handle; } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { return NativeMethods.CloseServiceHandle(handle); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-core-2.15.3/test/units/module_utils/basic/test_run_command.py new/ansible-core-2.15.4/test/units/module_utils/basic/test_run_command.py --- old/ansible-core-2.15.3/test/units/module_utils/basic/test_run_command.py 2023-08-14 20:18:23.000000000 +0200 +++ new/ansible-core-2.15.4/test/units/module_utils/basic/test_run_command.py 2023-09-12 00:11:17.000000000 +0200 @@ -109,7 +109,7 @@ super(MockSelector, self).close() self._file_objs = [] - selectors.DefaultSelector = MockSelector + selectors.PollSelector = MockSelector subprocess = mocker.patch('ansible.module_utils.basic.subprocess') subprocess._output = {mocker.sentinel.stdout: SpecialBytesIO(b'', fh=mocker.sentinel.stdout), @@ -147,7 +147,7 @@ for (arg, cmd_lst, cmd_str), sh in product(ARGS_DATA, (True, False))), indirect=['stdin']) def test_args(self, cmd, expected, shell, rc_am): - rc_am.run_command(cmd, use_unsafe_shell=shell, prompt_regex='i_dont_exist') + rc_am.run_command(cmd, use_unsafe_shell=shell) assert rc_am._subprocess.Popen.called args, kwargs = rc_am._subprocess.Popen.call_args assert args == (expected, ) @@ -163,17 +163,17 @@ class TestRunCommandCwd: @pytest.mark.parametrize('stdin', [{}], indirect=['stdin']) def test_cwd(self, mocker, rc_am): - rc_am.run_command('/bin/ls', cwd='/new', prompt_regex='i_dont_exist') + rc_am.run_command('/bin/ls', cwd='/new') assert rc_am._subprocess.Popen.mock_calls[0][2]['cwd'] == b'/new' @pytest.mark.parametrize('stdin', [{}], indirect=['stdin']) def test_cwd_relative_path(self, mocker, rc_am): - rc_am.run_command('/bin/ls', cwd='sub-dir', prompt_regex='i_dont_exist') + rc_am.run_command('/bin/ls', cwd='sub-dir') assert rc_am._subprocess.Popen.mock_calls[0][2]['cwd'] == b'/home/foo/sub-dir' @pytest.mark.parametrize('stdin', [{}], indirect=['stdin']) def test_cwd_not_a_dir(self, mocker, rc_am): - rc_am.run_command('/bin/ls', cwd='/not-a-dir', prompt_regex='i_dont_exist') + rc_am.run_command('/bin/ls', cwd='/not-a-dir') assert rc_am._subprocess.Popen.mock_calls[0][2]['cwd'] == b'/not-a-dir' @pytest.mark.parametrize('stdin', [{}], indirect=['stdin']) @@ -212,14 +212,14 @@ @pytest.mark.parametrize('stdin', [{}], indirect=['stdin']) def test_check_rc_false(self, rc_am): rc_am._subprocess.Popen.return_value.returncode = 1 - (rc, _, _) = rc_am.run_command('/bin/false', check_rc=False, prompt_regex='i_dont_exist') + (rc, _, _) = rc_am.run_command('/bin/false', check_rc=False) assert rc == 1 @pytest.mark.parametrize('stdin', [{}], indirect=['stdin']) def test_check_rc_true(self, rc_am): rc_am._subprocess.Popen.return_value.returncode = 1 with pytest.raises(SystemExit): - rc_am.run_command('/bin/false', check_rc=True, prompt_regex='i_dont_exist') + rc_am.run_command('/bin/false', check_rc=True) assert rc_am.fail_json.called args, kwargs = rc_am.fail_json.call_args assert kwargs['rc'] == 1 @@ -228,7 +228,7 @@ class TestRunCommandOutput: @pytest.mark.parametrize('stdin', [{}], indirect=['stdin']) def test_text_stdin(self, rc_am): - (rc, stdout, stderr) = rc_am.run_command('/bin/foo', data='hello world', prompt_regex='i_dont_exist') + (rc, stdout, stderr) = rc_am.run_command('/bin/foo', data='hello world') assert rc_am._subprocess.Popen.return_value.stdin.getvalue() == b'hello world\n' @pytest.mark.parametrize('stdin', [{}], indirect=['stdin']) @@ -237,7 +237,7 @@ SpecialBytesIO(b'hello', fh=mocker.sentinel.stdout), mocker.sentinel.stderr: SpecialBytesIO(b'', fh=mocker.sentinel.stderr)} - (rc, stdout, stderr) = rc_am.run_command('/bin/cat hello.txt', prompt_regex='i_dont_exist') + (rc, stdout, stderr) = rc_am.run_command('/bin/cat hello.txt') assert rc == 0 # module_utils function. On py3 it returns text and py2 it returns # bytes because it's returning native strings @@ -251,7 +251,7 @@ mocker.sentinel.stderr: SpecialBytesIO(u'ÙØ±Ø¦ÙØ³ÙØ©'.encode('utf-8'), fh=mocker.sentinel.stderr)} - (rc, stdout, stderr) = rc_am.run_command('/bin/something_ugly', prompt_regex='i_dont_exist') + (rc, stdout, stderr) = rc_am.run_command('/bin/something_ugly') assert rc == 0 # module_utils function. On py3 it returns text and py2 it returns # bytes because it's returning native strings