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 2024-05-24 19:51:24 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ansible-core (Old) and /work/SRC/openSUSE:Factory/.ansible-core.new.24587 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ansible-core" Fri May 24 19:51:24 2024 rev:28 rq:1176470 version:2.16.7 Changes: -------- --- /work/SRC/openSUSE:Factory/ansible-core/ansible-core.changes 2024-04-18 22:13:47.268087707 +0200 +++ /work/SRC/openSUSE:Factory/.ansible-core.new.24587/ansible-core.changes 2024-05-24 19:51:37.910586907 +0200 @@ -1,0 +2,34 @@ +Thu May 23 11:07:12 UTC 2024 - Johannes Kastl <[email protected]> + +- update to 2.16.7: + https://github.com/ansible/ansible/blob/v2.16.7/changelogs/CHANGELOG-v2.16.rst + * Minor Changes + - ansible.builtin.user - Remove user not found warning (#80267) + * Bugfixes + - Add a version ceiling constraint for pypsrp to avoid + potential breaking changes in the 1.0.0 release. + - Fix NEVRA parsing of package names that include digit(s) in + them (#76463, #81018) + - Fix handlers not being executed in lockstep using the linear + strategy in some cases (#82307) + - Give the tombstone error for include pre-fork like other + tombstoned action/module plugins. + - Include the task location when a module or action plugin is + deprecated (#82450). + - Mirror the behavior of dnf on the command line when handling + NEVRAs with omitted epoch (#71808) + - ansible-test - Automatically enable the PyPI proxy for the + centos7 container to restore the ability to use pip in that + container. + - ansible_managed restored it's 'templatability' by ensuring + the possible injection routes are cut off earlier in the + process. + - assemble - fixed missing parameter 'content' in + `_get_diff_data` API (#82359). + - dnf - fix an issue when installing a package by specifying a + file it provides could result in installing a different + package providing the same file than the package already + installed resulting in resolution failure (#82461) + - uri - update the documentation for follow_redirects. + +------------------------------------------------------------------- Old: ---- ansible_core-2.16.6.tar.gz ansible_core-2.16.6.tar.gz.sha256 New: ---- ansible_core-2.16.7.tar.gz ansible_core-2.16.7.tar.gz.sha256 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ansible-core.spec ++++++ --- /var/tmp/diff_new_pack.WO9Yf1/_old 2024-05-24 19:51:39.658650852 +0200 +++ /var/tmp/diff_new_pack.WO9Yf1/_new 2024-05-24 19:51:39.674651438 +0200 @@ -38,7 +38,7 @@ %endif Name: ansible-core -Version: 2.16.6 +Version: 2.16.7 Release: 0 Summary: Radically simple IT automation License: GPL-3.0-or-later ++++++ ansible_core-2.16.6.tar.gz -> ansible_core-2.16.7.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/PKG-INFO new/ansible_core-2.16.7/PKG-INFO --- old/ansible_core-2.16.6/PKG-INFO 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/PKG-INFO 2024-05-20 20:41:55.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: ansible-core -Version: 2.16.6 +Version: 2.16.7 Summary: Radically simple IT automation Home-page: https://ansible.com/ Author: Ansible, Inc. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/changelogs/CHANGELOG-v2.16.rst new/ansible_core-2.16.7/changelogs/CHANGELOG-v2.16.rst --- old/ansible_core-2.16.6/changelogs/CHANGELOG-v2.16.rst 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/changelogs/CHANGELOG-v2.16.rst 2024-05-20 20:41:55.000000000 +0200 @@ -5,6 +5,36 @@ .. contents:: Topics +v2.16.7 +======= + +Release Summary +--------------- + +| Release Date: 2024-05-20 +| `Porting Guide <https://docs.ansible.com/ansible-core/2.16/porting_guides/porting_guide_core_2.16.html>`__ + + +Minor Changes +------------- + +- ansible.builtin.user - Remove user not found warning (https://github.com/ansible/ansible/issues/80267) + +Bugfixes +-------- + +- Add a version ceiling constraint for pypsrp to avoid potential breaking changes in the 1.0.0 release. +- Fix NEVRA parsing of package names that include digit(s) in them (https://github.com/ansible/ansible/issues/76463, https://github.com/ansible/ansible/issues/81018) +- Fix handlers not being executed in lockstep using the linear strategy in some cases (https://github.com/ansible/ansible/issues/82307) +- Give the tombstone error for ``include`` pre-fork like other tombstoned action/module plugins. +- Include the task location when a module or action plugin is deprecated (https://github.com/ansible/ansible/issues/82450). +- Mirror the behavior of dnf on the command line when handling NEVRAs with omitted epoch (https://github.com/ansible/ansible/issues/71808) +- ansible-test - Automatically enable the PyPI proxy for the ``centos7`` container to restore the ability to use ``pip`` in that container. +- ansible_managed restored it's 'templatability' by ensuring the possible injection routes are cut off earlier in the process. +- assemble - fixed missing parameter 'content' in _get_diff_data API (https://github.com/ansible/ansible/issues/82359). +- dnf - fix an issue when installing a package by specifying a file it provides could result in installing a different package providing the same file than the package already installed resulting in resolution failure (https://github.com/ansible/ansible/issues/82461) +- uri - update the documentation for follow_redirects. + v2.16.6 ======= @@ -100,6 +130,7 @@ - ``ansible-test sanity --test runtime-metadata`` - add ``action_plugin`` as a valid field for modules in the schema (https://github.com/ansible/ansible/pull/82562). - ansible-config init will now dedupe ini entries from plugins. - ansible-galaxy role import - exit with 1 when the import fails (https://github.com/ansible/ansible/issues/82175). +- ansible-galaxy role install - fix symlinks (https://github.com/ansible/ansible/issues/82702, https://github.com/ansible/ansible/issues/81965). - ansible-galaxy role install - normalize tarfile paths and symlinks using ``ansible.utils.path.unfrackpath`` and consider them valid as long as the realpath is in the tarfile's role directory (https://github.com/ansible/ansible/issues/81965). - delegate_to when set to an empty or undefined variable will now give a proper error. - dwim functions for lookups should be better at detectging role context even in abscense of tasks/main. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/changelogs/changelog.yaml new/ansible_core-2.16.7/changelogs/changelog.yaml --- old/ansible_core-2.16.6/changelogs/changelog.yaml 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/changelogs/changelog.yaml 2024-05-20 20:41:55.000000000 +0200 @@ -865,6 +865,8 @@ a valid field for modules in the schema (https://github.com/ansible/ansible/pull/82562).' - ansible-config init will now dedupe ini entries from plugins. - ansible-galaxy role import - exit with 1 when the import fails (https://github.com/ansible/ansible/issues/82175). + - ansible-galaxy role install - fix symlinks (https://github.com/ansible/ansible/issues/82702, + https://github.com/ansible/ansible/issues/81965). - ansible-galaxy role install - normalize tarfile paths and symlinks using ``ansible.utils.path.unfrackpath`` and consider them valid as long as the realpath is in the tarfile's role directory (https://github.com/ansible/ansible/issues/81965). @@ -1028,3 +1030,58 @@ - vmware_facts.yml - winrm-task-timeout.yml release_date: '2024-04-15' + 2.16.7: + changes: + release_summary: '| Release Date: 2024-05-20 + + | `Porting Guide <https://docs.ansible.com/ansible-core/2.16/porting_guides/porting_guide_core_2.16.html>`__ + + ' + codename: All My Love + fragments: + - 2.16.7_summary.yaml + release_date: '2024-05-20' + 2.16.7rc1: + changes: + bugfixes: + - Add a version ceiling constraint for pypsrp to avoid potential breaking changes + in the 1.0.0 release. + - Fix NEVRA parsing of package names that include digit(s) in them (https://github.com/ansible/ansible/issues/76463, + https://github.com/ansible/ansible/issues/81018) + - Fix handlers not being executed in lockstep using the linear strategy in some + cases (https://github.com/ansible/ansible/issues/82307) + - Give the tombstone error for ``include`` pre-fork like other tombstoned action/module + plugins. + - Include the task location when a module or action plugin is deprecated (https://github.com/ansible/ansible/issues/82450). + - Mirror the behavior of dnf on the command line when handling NEVRAs with omitted + epoch (https://github.com/ansible/ansible/issues/71808) + - ansible-test - Automatically enable the PyPI proxy for the ``centos7`` container + to restore the ability to use ``pip`` in that container. + - ansible_managed restored it's 'templatability' by ensuring the possible injection + routes are cut off earlier in the process. + - assemble - fixed missing parameter 'content' in _get_diff_data API (https://github.com/ansible/ansible/issues/82359). + - dnf - fix an issue when installing a package by specifying a file it provides + could result in installing a different package providing the same file than + the package already installed resulting in resolution failure (https://github.com/ansible/ansible/issues/82461) + - uri - update the documentation for follow_redirects. + minor_changes: + - ansible.builtin.user - Remove user not found warning (https://github.com/ansible/ansible/issues/80267) + release_summary: '| Release Date: 2024-05-13 + + | `Porting Guide <https://docs.ansible.com/ansible-core/2.16/porting_guides/porting_guide_core_2.16.html>`__ + + ' + codename: All My Love + fragments: + - 2.16.7rc1_summary.yaml + - 80267-ansible_builtin_user-remove-user-not-found-warning.yml + - 82307-handlers-lockstep-linear-fix.yml + - 82359_assemble_diff.yml + - 82461-dnf-provides.yml + - ansible-test-centos7-pypi-proxy.yml + - ansible_managed_restore.yml + - dnf-installed-checks-api.yml + - improve-tombstone-error.yml + - psrp-version-req.yml + - uri_follow_redirect_bool.yml + release_date: '2024-05-13' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/lib/ansible/executor/play_iterator.py new/ansible_core-2.16.7/lib/ansible/executor/play_iterator.py --- old/ansible_core-2.16.6/lib/ansible/executor/play_iterator.py 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/lib/ansible/executor/play_iterator.py 2024-05-20 20:41:55.000000000 +0200 @@ -429,13 +429,13 @@ # might be there from previous flush state.handlers = self.handlers[:] state.update_handlers = False - state.cur_handlers_task = 0 while True: try: task = state.handlers[state.cur_handlers_task] except IndexError: task = None + state.cur_handlers_task = 0 state.run_state = state.pre_flushing_run_state state.update_handlers = True break diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/lib/ansible/galaxy/role.py new/ansible_core-2.16.7/lib/ansible/galaxy/role.py --- old/ansible_core-2.16.6/lib/ansible/galaxy/role.py 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/lib/ansible/galaxy/role.py 2024-05-20 20:41:55.000000000 +0200 @@ -387,6 +387,8 @@ else: os.makedirs(self.path) + resolved_archive = unfrackpath(archive_parent_dir, follow=False) + # We strip off any higher-level directories for all of the files # contained within the tar file here. The default is 'github_repo-target'. # Gerrit instances, on the other hand, does not have a parent directory at all. @@ -401,33 +403,29 @@ if not (attr_value := getattr(member, attr, None)): continue - if attr_value.startswith(os.sep) and not is_subpath(attr_value, archive_parent_dir): - err = f"Invalid {attr} for tarfile member: path {attr_value} is not a subpath of the role {archive_parent_dir}" - raise AnsibleError(err) - if attr == 'linkname': # Symlinks are relative to the link - relative_to_archive_dir = os.path.dirname(getattr(member, 'name', '')) - archive_dir_path = os.path.join(archive_parent_dir, relative_to_archive_dir, attr_value) + relative_to = os.path.dirname(getattr(member, 'name', '')) else: # Normalize paths that start with the archive dir attr_value = attr_value.replace(archive_parent_dir, "", 1) attr_value = os.path.join(*attr_value.split(os.sep)) # remove leading os.sep - archive_dir_path = os.path.join(archive_parent_dir, attr_value) + relative_to = '' - resolved_archive = unfrackpath(archive_parent_dir) - resolved_path = unfrackpath(archive_dir_path) - if not is_subpath(resolved_path, resolved_archive): - err = f"Invalid {attr} for tarfile member: path {resolved_path} is not a subpath of the role {resolved_archive}" + full_path = os.path.join(resolved_archive, relative_to, attr_value) + if not is_subpath(full_path, resolved_archive, real=True): + err = f"Invalid {attr} for tarfile member: path {full_path} is not a subpath of the role {resolved_archive}" raise AnsibleError(err) - relative_path = os.path.join(*resolved_path.replace(resolved_archive, "", 1).split(os.sep)) or '.' + relative_path_dir = os.path.join(resolved_archive, relative_to) + relative_path = os.path.join(*full_path.replace(relative_path_dir, "", 1).split(os.sep)) setattr(member, attr, relative_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: + # Remove along with manual path filter once Python 3.12 is minimum supported version role_tar_file.extract(member, to_native(self.path)) # write out the install info file for later use diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/lib/ansible/module_utils/ansible_release.py new/ansible_core-2.16.7/lib/ansible/module_utils/ansible_release.py --- old/ansible_core-2.16.6/lib/ansible/module_utils/ansible_release.py 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/lib/ansible/module_utils/ansible_release.py 2024-05-20 20:41:55.000000000 +0200 @@ -19,6 +19,6 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type -__version__ = '2.16.6' +__version__ = '2.16.7' __author__ = 'Ansible, Inc.' __codename__ = "All My Love" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/lib/ansible/modules/dnf.py new/ansible_core-2.16.7/lib/ansible/modules/dnf.py --- old/ansible_core-2.16.6/lib/ansible/modules/dnf.py 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/lib/ansible/modules/dnf.py 2024-05-20 20:41:55.000000000 +0200 @@ -380,7 +380,6 @@ ''' import os -import re import sys from ansible.module_utils.common.text.converters import to_native, to_text @@ -482,94 +481,6 @@ return result - def _split_package_arch(self, packagename): - # This list was auto generated on a Fedora 28 system with the following one-liner - # printf '[ '; for arch in $(ls /usr/lib/rpm/platform); do printf '"%s", ' ${arch%-linux}; done; printf ']\n' - redhat_rpm_arches = [ - "aarch64", "alphaev56", "alphaev5", "alphaev67", "alphaev6", "alpha", - "alphapca56", "amd64", "armv3l", "armv4b", "armv4l", "armv5tejl", "armv5tel", - "armv5tl", "armv6hl", "armv6l", "armv7hl", "armv7hnl", "armv7l", "athlon", - "geode", "i386", "i486", "i586", "i686", "ia32e", "ia64", "m68k", "mips64el", - "mips64", "mips64r6el", "mips64r6", "mipsel", "mips", "mipsr6el", "mipsr6", - "noarch", "pentium3", "pentium4", "ppc32dy4", "ppc64iseries", "ppc64le", "ppc64", - "ppc64p7", "ppc64pseries", "ppc8260", "ppc8560", "ppciseries", "ppc", "ppcpseries", - "riscv64", "s390", "s390x", "sh3", "sh4a", "sh4", "sh", "sparc64", "sparc64v", - "sparc", "sparcv8", "sparcv9", "sparcv9v", "x86_64" - ] - - name, delimiter, arch = packagename.rpartition('.') - if name and arch and arch in redhat_rpm_arches: - return name, arch - return packagename, None - - def _packagename_dict(self, packagename): - """ - Return a dictionary of information for a package name string or None - if the package name doesn't contain at least all NVR elements - """ - - if packagename[-4:] == '.rpm': - packagename = packagename[:-4] - - rpm_nevr_re = re.compile(r'(\S+)-(?:(\d*):)?(.*)-(~?\w+[\w.+]*)') - try: - arch = None - nevr, arch = self._split_package_arch(packagename) - if arch: - packagename = nevr - rpm_nevr_match = rpm_nevr_re.match(packagename) - if rpm_nevr_match: - name, epoch, version, release = rpm_nevr_re.match(packagename).groups() - if not version or not version.split('.')[0].isdigit(): - return None - else: - return None - except AttributeError as e: - self.module.fail_json( - msg='Error attempting to parse package: %s, %s' % (packagename, to_native(e)), - rc=1, - results=[] - ) - - if not epoch: - epoch = "0" - - if ':' in name: - epoch_name = name.split(":") - - epoch = epoch_name[0] - name = ''.join(epoch_name[1:]) - - result = { - 'name': name, - 'epoch': epoch, - 'release': release, - 'version': version, - } - - return result - - # Original implementation from yum.rpmUtils.miscutils (GPLv2+) - # http://yum.baseurl.org/gitweb?p=yum.git;a=blob;f=rpmUtils/miscutils.py - def _compare_evr(self, e1, v1, r1, e2, v2, r2): - # return 1: a is newer than b - # 0: a and b are the same version - # -1: b is newer than a - if e1 is None: - e1 = '0' - else: - e1 = str(e1) - v1 = str(v1) - r1 = str(r1) - if e2 is None: - e2 = '0' - else: - e2 = str(e2) - v2 = str(v2) - r2 = str(r2) - rc = dnf.rpm.rpm.labelCompare((e1, v1, r1), (e2, v2, r2)) - return rc - def _ensure_dnf(self): locale = get_best_parsable_locale(self.module) os.environ['LC_ALL'] = os.environ['LC_MESSAGES'] = locale @@ -578,7 +489,6 @@ global dnf try: import dnf - import dnf.cli import dnf.const import dnf.exceptions import dnf.package @@ -809,43 +719,22 @@ self.module.exit_json(msg="", results=results) def _is_installed(self, pkg): - installed = self.base.sack.query().installed() - - package_spec = {} - name, arch = self._split_package_arch(pkg) - if arch: - package_spec['arch'] = arch - - package_details = self._packagename_dict(pkg) - if package_details: - package_details['epoch'] = int(package_details['epoch']) - package_spec.update(package_details) - else: - package_spec['name'] = name - - return bool(installed.filter(**package_spec)) + return bool( + dnf.subject.Subject(pkg).get_best_query(sack=self.base.sack).installed().run() + ) def _is_newer_version_installed(self, pkg_name): - candidate_pkg = self._packagename_dict(pkg_name) - if not candidate_pkg: - # The user didn't provide a versioned rpm, so version checking is - # not required - return False - - installed = self.base.sack.query().installed() - installed_pkg = installed.filter(name=candidate_pkg['name']).run() - if installed_pkg: - installed_pkg = installed_pkg[0] - - # this looks weird but one is a dict and the other is a dnf.Package - evr_cmp = self._compare_evr( - installed_pkg.epoch, installed_pkg.version, installed_pkg.release, - candidate_pkg['epoch'], candidate_pkg['version'], candidate_pkg['release'], - ) - - return evr_cmp == 1 - else: + try: + if isinstance(pkg_name, dnf.package.Package): + available = pkg_name + else: + available = sorted( + dnf.subject.Subject(pkg_name).get_best_query(sack=self.base.sack).available().run() + )[-1] + installed = sorted(self.base.sack.query().installed().filter(name=available.name).run())[-1] + except IndexError: return False + return installed > available def _mark_package_install(self, pkg_spec, upgrade=False): """Mark the package for install.""" @@ -917,17 +806,6 @@ "results": [] } - def _whatprovides(self, filepath): - self.base.read_all_repos() - available = self.base.sack.query().available() - # Search in file - files_filter = available.filter(file=filepath) - # And Search in provides - pkg_spec = files_filter.union(available.filter(provides=filepath)).run() - - if pkg_spec: - return pkg_spec[0].name - def _parse_spec_group_file(self): pkg_specs, grp_specs, module_specs, filenames = [], [], [], [] already_loaded_comps = False # Only load this if necessary, it's slow @@ -939,11 +817,13 @@ elif name.endswith(".rpm"): filenames.append(name) elif name.startswith('/'): - # like "dnf install /usr/bin/vi" - pkg_spec = self._whatprovides(name) - if pkg_spec: - pkg_specs.append(pkg_spec) - continue + # dnf install /usr/bin/vi + installed = self.base.sack.query().filter(provides=name, file=name).installed().run() + if installed: + pkg_specs.append(installed[0].name) # should be only one? + elif not self.update_only: + # not installed, pass the filename for dnf to process + pkg_specs.append(name) elif name.startswith("@") or ('/' in name): if not already_loaded_comps: self.base.read_comps() @@ -1005,7 +885,7 @@ else: for pkg in pkgs: try: - if self._is_newer_version_installed(self._package_dict(pkg)['nevra']): + if self._is_newer_version_installed(pkg): if self.allow_downgrade: self.base.package_install(pkg, strict=self.base.conf.strict) else: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/lib/ansible/modules/dnf5.py new/ansible_core-2.16.7/lib/ansible/modules/dnf5.py --- old/ansible_core-2.16.6/lib/ansible/modules/dnf5.py 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/lib/ansible/modules/dnf5.py 2024-05-20 20:41:55.000000000 +0200 @@ -361,19 +361,37 @@ spec_nevra = next(iter(libdnf5.rpm.Nevra.parse(spec))) except RuntimeError: return False - spec_name = spec_nevra.get_name() - v = spec_nevra.get_version() - r = spec_nevra.get_release() - if not v or not r: + + spec_version = spec_nevra.get_version() + if not spec_version: return False - spec_evr = "{}:{}-{}".format(spec_nevra.get_epoch() or "0", v, r) - query = libdnf5.rpm.PackageQuery(base) - query.filter_installed() - query.filter_name([spec_name]) - query.filter_evr([spec_evr], libdnf5.common.QueryCmp_GT) + installed = libdnf5.rpm.PackageQuery(base) + installed.filter_installed() + installed.filter_name([spec_nevra.get_name()]) + installed.filter_latest_evr() + try: + installed_package = list(installed)[-1] + except IndexError: + return False + + target = libdnf5.rpm.PackageQuery(base) + target.filter_name([spec_nevra.get_name()]) + target.filter_version([spec_version]) + spec_release = spec_nevra.get_release() + if spec_release: + target.filter_release([spec_release]) + spec_epoch = spec_nevra.get_epoch() + if spec_epoch: + target.filter_epoch([spec_epoch]) + target.filter_latest_evr() + try: + target_package = list(target)[-1] + except IndexError: + return False - return query.size() > 0 + # FIXME https://github.com/rpm-software-management/dnf5/issues/1104 + return libdnf5.rpm.rpmvercmp(installed_package.get_evr(), target_package.get_evr()) == 1 def package_to_dict(package): @@ -606,13 +624,7 @@ for spec in self.names: if is_newer_version_installed(base, spec): if self.allow_downgrade: - if upgrade: - if is_installed(base, spec): - goal.add_upgrade(spec, settings) - else: - goal.add_install(spec, settings) - else: - goal.add_install(spec, settings) + goal.add_install(spec, settings) elif is_installed(base, spec): if upgrade: goal.add_upgrade(spec, settings) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/lib/ansible/modules/uri.py new/ansible_core-2.16.7/lib/ansible/modules/uri.py --- old/ansible_core-2.16.6/lib/ansible/modules/uri.py 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/lib/ansible/modules/uri.py 2024-05-20 20:41:55.000000000 +0200 @@ -108,14 +108,15 @@ default: no follow_redirects: description: - - Whether or not the URI module should follow redirects. V(all) will follow all redirects. - V(safe) will follow only "safe" redirects, where "safe" means that the client is only - doing a GET or HEAD on the URI to which it is being redirected. V(none) will not follow - any redirects. Note that V(true) and V(false) choices are accepted for backwards compatibility, - where V(true) is the equivalent of V(all) and V(false) is the equivalent of V(safe). V(true) and V(false) - are deprecated and will be removed in some future version of Ansible. + - Whether or not the URI module should follow redirects. + - V(all) Will follow all redirects. + - V(none) Will not follow any redirects. + - V(safe) Only redirects doing GET or HEAD requests will be followed. + - V(urllib2) Defer to urllib2 behavior (As of writing this follows HTTP redirects). + - V('no') (DEPRECATED, will be removed in the future version) alias of V(none). + - V('yes') (DEPRECATED, will be removed in the future version) alias of V(all). + choices: ['all', 'none', 'safe', 'urllib2', 'yes', 'no'] type: str - choices: ['all', 'no', 'none', 'safe', 'urllib2', 'yes'] default: safe creates: description: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/lib/ansible/modules/user.py new/ansible_core-2.16.7/lib/ansible/modules/user.py --- old/ansible_core-2.16.6/lib/ansible/modules/user.py 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/lib/ansible/modules/user.py 2024-05-20 20:41:55.000000000 +0200 @@ -1063,12 +1063,6 @@ exists = True break - if not exists: - self.module.warn( - "'local: true' specified and user '{name}' was not found in {file}. " - "The local user account may already exist if the local account database exists " - "somewhere other than {file}.".format(file=self.PASSWORDFILE, name=self.name)) - return exists else: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/lib/ansible/parsing/mod_args.py new/ansible_core-2.16.7/lib/ansible/parsing/mod_args.py --- old/ansible_core-2.16.6/lib/ansible/parsing/mod_args.py 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/lib/ansible/parsing/mod_args.py 2024-05-20 20:41:55.000000000 +0200 @@ -48,7 +48,6 @@ BUILTIN_TASKS = frozenset(add_internal_fqcns(( 'meta', - 'include', 'include_tasks', 'include_role', 'import_tasks', @@ -304,9 +303,14 @@ elif skip_action_validation: is_action_candidate = True else: - context = action_loader.find_plugin_with_context(item, collection_list=self._collection_list) - if not context.resolved: - context = module_loader.find_plugin_with_context(item, collection_list=self._collection_list) + try: + context = action_loader.find_plugin_with_context(item, collection_list=self._collection_list) + if not context.resolved: + context = module_loader.find_plugin_with_context(item, collection_list=self._collection_list) + except AnsibleError as e: + if e.obj is None: + e.obj = self._task_ds + raise e is_action_candidate = context.resolved and bool(context.redirect_list) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/lib/ansible/plugins/action/__init__.py new/ansible_core-2.16.7/lib/ansible/plugins/action/__init__.py --- old/ansible_core-2.16.6/lib/ansible/plugins/action/__init__.py 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/lib/ansible/plugins/action/__init__.py 2024-05-20 20:41:55.000000000 +0200 @@ -1339,7 +1339,7 @@ display.debug(u"_low_level_execute_command() done: rc=%d, stdout=%s, stderr=%s" % (rc, out, err)) return dict(rc=rc, stdout=out, stdout_lines=out.splitlines(), stderr=err, stderr_lines=err.splitlines()) - def _get_diff_data(self, destination, source, task_vars, content, source_file=True): + def _get_diff_data(self, destination, source, task_vars, content=None, source_file=True): # Note: Since we do not diff the source and destination before we transform from bytes into # text the diff between source and destination may not be accurate. To fix this, we'd need diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/lib/ansible/plugins/connection/psrp.py new/ansible_core-2.16.7/lib/ansible/plugins/connection/psrp.py --- old/ansible_core-2.16.6/lib/ansible/plugins/connection/psrp.py 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/lib/ansible/plugins/connection/psrp.py 2024-05-20 20:41:55.000000000 +0200 @@ -14,7 +14,7 @@ underlying transport but instead runs in a PowerShell interpreter. version_added: "2.7" requirements: -- pypsrp>=0.4.0 (Python library) +- pypsrp>=0.4.0, <1.0.0 (Python library) extends_documentation_fragment: - connection_pipelining options: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/lib/ansible/plugins/lookup/url.py new/ansible_core-2.16.7/lib/ansible/plugins/lookup/url.py --- old/ansible_core-2.16.6/lib/ansible/plugins/lookup/url.py 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/lib/ansible/plugins/lookup/url.py 2024-05-20 20:41:55.000000000 +0200 @@ -88,7 +88,14 @@ - section: url_lookup key: force_basic_auth follow_redirects: - description: String of urllib2, all/yes, safe, none to determine how redirects are followed, see RedirectHandlerFactory for more information + description: + - String of urllib2, all/yes, safe, none to determine how redirects are followed, see RedirectHandlerFactory for more information. + - V(all) Will follow all redirects. + - V(none) Will not follow any redirects. + - V(safe) Only redirects doing GET or HEAD requests will be followed. + - V(urllib2) Defer to urllib2 behavior (As of writing this follows HTTP redirects). + - V('no') (DEPRECATED, will be removed in the future version) alias of V(none). + - V('yes') (DEPRECATED, will be removed in the future version) alias of V(all). type: string version_added: "2.10" default: 'urllib2' @@ -99,6 +106,7 @@ ini: - section: url_lookup key: follow_redirects + choices: ['all', 'none', 'safe', 'urllib2', 'yes', 'no'] use_gssapi: description: - Use GSSAPI handler of requests diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/lib/ansible/release.py new/ansible_core-2.16.7/lib/ansible/release.py --- old/ansible_core-2.16.6/lib/ansible/release.py 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/lib/ansible/release.py 2024-05-20 20:41:55.000000000 +0200 @@ -19,6 +19,6 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type -__version__ = '2.16.6' +__version__ = '2.16.7' __author__ = 'Ansible, Inc.' __codename__ = "All My Love" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/lib/ansible/template/__init__.py new/ansible_core-2.16.7/lib/ansible/template/__init__.py --- old/ansible_core-2.16.6/lib/ansible/template/__init__.py 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/lib/ansible/template/__init__.py 2024-05-20 20:41:55.000000000 +0200 @@ -86,26 +86,26 @@ template_uid = os.stat(b_path).st_uid temp_vars = { - 'template_host': to_text(os.uname()[1]), - 'template_path': path, + 'template_host': to_unsafe_text(os.uname()[1]), + 'template_path': to_unsafe_text(path), 'template_mtime': datetime.datetime.fromtimestamp(os.path.getmtime(b_path)), - 'template_uid': to_text(template_uid), + 'template_uid': to_unsafe_text(template_uid), 'template_run_date': datetime.datetime.now(), - 'template_destpath': to_native(dest_path) if dest_path else None, + 'template_destpath': wrap_var(to_native(dest_path)) if dest_path else None, } if fullpath is None: - temp_vars['template_fullpath'] = os.path.abspath(path) + temp_vars['template_fullpath'] = wrap_var(os.path.abspath(path)) else: - temp_vars['template_fullpath'] = fullpath + temp_vars['template_fullpath'] = wrap_var(fullpath) managed_default = C.DEFAULT_MANAGED_STR managed_str = managed_default.format( - host=temp_vars['template_host'], - uid=temp_vars['template_uid'], - file=temp_vars['template_path'].replace('%', '%%'), + host="{{ template_host }}", + uid="{{ template_uid }}", + file="{{ template_path }}" ) - temp_vars['ansible_managed'] = to_unsafe_text(time.strftime(to_native(managed_str), time.localtime(os.path.getmtime(b_path)))) + temp_vars['ansible_managed'] = time.strftime(to_native(managed_str), time.localtime(os.path.getmtime(b_path))) return temp_vars diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/lib/ansible_core.egg-info/PKG-INFO new/ansible_core-2.16.7/lib/ansible_core.egg-info/PKG-INFO --- old/ansible_core-2.16.6/lib/ansible_core.egg-info/PKG-INFO 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/lib/ansible_core.egg-info/PKG-INFO 2024-05-20 20:41:55.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: ansible-core -Version: 2.16.6 +Version: 2.16.7 Summary: Radically simple IT automation Home-page: https://ansible.com/ Author: Ansible, Inc. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/lib/ansible_core.egg-info/SOURCES.txt new/ansible_core-2.16.7/lib/ansible_core.egg-info/SOURCES.txt --- old/ansible_core-2.16.6/lib/ansible_core.egg-info/SOURCES.txt 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/lib/ansible_core.egg-info/SOURCES.txt 2024-05-20 20:41:55.000000000 +0200 @@ -891,6 +891,11 @@ test/integration/targets/ansible-galaxy-collection/vars/main.yml test/integration/targets/ansible-galaxy-role/aliases test/integration/targets/ansible-galaxy-role/files/create-role-archive.py +test/integration/targets/ansible-galaxy-role/files/safe-symlinks/defaults/main.yml +test/integration/targets/ansible-galaxy-role/files/safe-symlinks/defaults/common_vars/subdir/group0/main.yml +test/integration/targets/ansible-galaxy-role/files/safe-symlinks/handlers/utils.yml +test/integration/targets/ansible-galaxy-role/files/safe-symlinks/meta/main.yml +test/integration/targets/ansible-galaxy-role/files/safe-symlinks/tasks/utils/suite.yml test/integration/targets/ansible-galaxy-role/meta/main.yml test/integration/targets/ansible-galaxy-role/tasks/dir-traversal.yml test/integration/targets/ansible-galaxy-role/tasks/main.yml @@ -1790,6 +1795,7 @@ test/integration/targets/dict_transformations/tasks/test_convert_camelCase.yml test/integration/targets/dict_transformations/tasks/test_convert_snake_case.yml test/integration/targets/dnf/aliases +test/integration/targets/dnf/filter_plugins/dnf_module_list.py test/integration/targets/dnf/meta/main.yml test/integration/targets/dnf/tasks/cacheonly.yml test/integration/targets/dnf/tasks/dnf.yml @@ -1804,10 +1810,6 @@ test/integration/targets/dnf/tasks/repo.yml test/integration/targets/dnf/tasks/skip_broken_and_nobest.yml test/integration/targets/dnf/tasks/test_sos_removal.yml -test/integration/targets/dnf/vars/CentOS.yml -test/integration/targets/dnf/vars/Fedora.yml -test/integration/targets/dnf/vars/RedHat-9.yml -test/integration/targets/dnf/vars/RedHat.yml test/integration/targets/dnf/vars/main.yml test/integration/targets/dnf5/aliases test/integration/targets/dnf5/playbook.yml @@ -2031,6 +2033,7 @@ test/integration/targets/handlers/aliases test/integration/targets/handlers/from_handlers.yml test/integration/targets/handlers/handlers.yml +test/integration/targets/handlers/handlers_lockstep_82307.yml test/integration/targets/handlers/include_handlers_fail_force-handlers.yml test/integration/targets/handlers/include_handlers_fail_force.yml test/integration/targets/handlers/inventory.handlers @@ -3512,7 +3515,7 @@ test/integration/targets/template/aliases test/integration/targets/template/ansible_managed.cfg test/integration/targets/template/ansible_managed.yml -test/integration/targets/template/ansible_managed_79129.yml +test/integration/targets/template/ansible_managed_templated.cfg test/integration/targets/template/arg_template_overrides.j2 test/integration/targets/template/badnull1.cfg test/integration/targets/template/badnull2.cfg diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/packaging/release.py new/ansible_core-2.16.7/packaging/release.py --- old/ansible_core-2.16.6/packaging/release.py 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/packaging/release.py 2024-05-20 20:41:55.000000000 +0200 @@ -856,7 +856,7 @@ def get_sdist_path(version: Version, dist_dir: pathlib.Path = DIST_DIR) -> pathlib.Path: """Return the path to the sdist file.""" - return dist_dir / f"ansible-core-{version}.tar.gz" + return dist_dir / f"ansible_core-{version}.tar.gz" def get_wheel_path(version: Version, dist_dir: pathlib.Path = DIST_DIR) -> pathlib.Path: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/test/integration/targets/ansible-galaxy-role/tasks/valid-role-symlinks.yml new/ansible_core-2.16.7/test/integration/targets/ansible-galaxy-role/tasks/valid-role-symlinks.yml --- old/ansible_core-2.16.6/test/integration/targets/ansible-galaxy-role/tasks/valid-role-symlinks.yml 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/test/integration/targets/ansible-galaxy-role/tasks/valid-role-symlinks.yml 2024-05-20 20:41:55.000000000 +0200 @@ -1,78 +1,38 @@ -- name: create test directories - file: - path: '{{ remote_tmp_dir }}/dir-traversal/{{ item }}' - state: directory - loop: - - source - - target - - roles - -- name: create subdir in the role content to test relative symlinks - file: - dest: '{{ remote_tmp_dir }}/dir-traversal/source/role_subdir' - state: directory - -- copy: - dest: '{{ remote_tmp_dir }}/dir-traversal/source/role_subdir/.keep' - content: '' - -- set_fact: - installed_roles: "{{ remote_tmp_dir | realpath }}/dir-traversal/roles" - -- name: build role with symlink to a directory in the role - script: - chdir: '{{ remote_tmp_dir }}/dir-traversal/source' - cmd: create-role-archive.py safe-link-dir.tar ./ role_subdir/.. - executable: '{{ ansible_playbook_python }}' - -- name: install role successfully - command: - cmd: 'ansible-galaxy role install --roles-path {{ remote_tmp_dir }}/dir-traversal/roles safe-link-dir.tar' - chdir: '{{ remote_tmp_dir }}/dir-traversal/source' - register: galaxy_install_ok - -- name: check for the directory symlink in the role - stat: - path: "{{ installed_roles }}/safe-link-dir.tar/symlink" - register: symlink_in_role - -- assert: - that: - - symlink_in_role.stat.exists - - symlink_in_role.stat.lnk_source == installed_roles + '/safe-link-dir.tar' - -- name: remove tarfile for next test - file: - path: '{{ remote_tmp_dir }}/dir-traversal/source/safe-link-dir.tar' - state: absent - -- name: build role with safe relative symlink - script: - chdir: '{{ remote_tmp_dir }}/dir-traversal/source' - cmd: create-role-archive.py safe.tar ./ role_subdir/../context.txt - executable: '{{ ansible_playbook_python }}' - -- name: install role successfully - command: - cmd: 'ansible-galaxy role install --roles-path {{ remote_tmp_dir }}/dir-traversal/roles safe.tar' - chdir: '{{ remote_tmp_dir }}/dir-traversal/source' - register: galaxy_install_ok - -- name: check for symlink in role - stat: - path: "{{ installed_roles }}/safe.tar/symlink" - register: symlink_in_role - -- assert: - that: - - symlink_in_role.stat.exists - - symlink_in_role.stat.lnk_source == installed_roles + '/safe.tar/context.txt' - -- name: remove test directories - file: - path: '{{ remote_tmp_dir }}/dir-traversal/{{ item }}' - state: absent - loop: - - source - - target - - roles +- delegate_to: localhost + block: + - name: Create archive + command: "tar -cf safe-symlinks.tar {{ role_path }}/files/safe-symlinks" + args: + chdir: "{{ remote_tmp_dir }}" + + - name: Install role successfully + command: ansible-galaxy role install --roles-path '{{ remote_tmp_dir }}/roles' safe-symlinks.tar + args: + chdir: "{{ remote_tmp_dir }}" + + - name: Validate each of the symlinks exists + stat: + path: "{{ remote_tmp_dir }}/roles/safe-symlinks.tar/{{ item }}" + loop: + - defaults/main.yml + - handlers/utils.yml + register: symlink_stat + + - assert: + that: + - symlink_stat.results[0].stat.exists + - symlink_stat.results[0].stat.lnk_source == ((dest, 'roles/safe-symlinks.tar/defaults/common_vars/subdir/group0/main.yml') | path_join) + - symlink_stat.results[1].stat.exists + - symlink_stat.results[1].stat.lnk_source == ((dest, 'roles/safe-symlinks.tar/tasks/utils/suite.yml') | path_join) + vars: + dest: "{{ remote_tmp_dir | realpath }}" + + always: + - name: Clean up + file: + path: "{{ item }}" + state: absent + delegate_to: localhost + loop: + - "{{ remote_tmp_dir }}/roles/" + - "{{ remote_tmp_dir }}/safe-symlinks.tar" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/test/integration/targets/assemble/tasks/main.yml new/ansible_core-2.16.7/test/integration/targets/assemble/tasks/main.yml --- old/ansible_core-2.16.6/test/integration/targets/assemble/tasks/main.yml 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/test/integration/targets/assemble/tasks/main.yml 2024-05-20 20:41:55.000000000 +0200 @@ -152,3 +152,19 @@ that: - "result.state == 'file'" - "result.checksum == '505359f48c65b3904127cf62b912991d4da7ed6d'" + +- name: test assemble with diff + assemble: + src: "./" + dest: "{{remote_tmp_dir}}/assembled11" + remote_src: false + diff: true + register: result + +- name: assert the fragments were assembled with diff + assert: + that: + - result.changed + - result.diff.after is defined + - result.diff.before is defined + - "result.state == 'file'" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/test/integration/targets/collections/runme.sh new/ansible_core-2.16.7/test/integration/targets/collections/runme.sh --- old/ansible_core-2.16.6/test/integration/targets/collections/runme.sh 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/test/integration/targets/collections/runme.sh 2024-05-20 20:41:55.000000000 +0200 @@ -148,3 +148,12 @@ ./vars_plugin_tests.sh ./test_task_resolved_plugin.sh + +# Test tombstoned module/action plugins include the location of the fatal task +cat <<EOF > test_dead_ping_error.yml +- hosts: localhost + gather_facts: no + tasks: + - dead_ping: +EOF +ansible-playbook test_dead_ping_error.yml 2>&1 >/dev/null | grep -e 'line 4, column 5' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/test/integration/targets/dnf/filter_plugins/dnf_module_list.py new/ansible_core-2.16.7/test/integration/targets/dnf/filter_plugins/dnf_module_list.py --- old/ansible_core-2.16.6/test/integration/targets/dnf/filter_plugins/dnf_module_list.py 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.16.7/test/integration/targets/dnf/filter_plugins/dnf_module_list.py 2024-05-20 20:41:55.000000000 +0200 @@ -0,0 +1,40 @@ +# Copyright: Contributors to the Ansible project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import annotations + +from collections import Counter + + +def parse_module_list(stdout): + lines = stdout.splitlines() + name_offset = 0 + empty_offset = -1 + modules = [] + for i, line in enumerate(lines): + if line.startswith('Name '): + name_offset = i + 1 + if not line.strip(): + empty_offset = i + for line in lines[name_offset:empty_offset]: + cols = line.split()[:3] + modules.append({ + 'name': cols[0], + 'version': cols[1], + 'profile': cols[2].rstrip(','), # Just the first profile + }) + return modules + + +def get_first_single_version_module(stdout): + modules = parse_module_list(stdout) + name = Counter([m['name'] for m in modules]).most_common()[-1][0] + module, = [m for m in modules if m['name'] == name] + return module + + +class FilterModule: + def filters(self): + return { + 'get_first_single_version_module': get_first_single_version_module, + } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/test/integration/targets/dnf/tasks/main.yml new/ansible_core-2.16.7/test/integration/targets/dnf/tasks/main.yml --- old/ansible_core-2.16.6/test/integration/targets/dnf/tasks/main.yml 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/test/integration/targets/dnf/tasks/main.yml 2024-05-20 20:41:55.000000000 +0200 @@ -57,13 +57,30 @@ - ansible_distribution == 'Fedora' - ansible_distribution_major_version is version('23', '>=') -- include_tasks: modularity.yml - when: +- when: - (ansible_distribution == 'Fedora' and ansible_distribution_major_version is version('29', '>=')) or (ansible_distribution in ['RedHat', 'CentOS'] and ansible_distribution_major_version is version('8', '>=')) - not dnf5|default(false) - tags: - - dnf_modularity + block: + # FUTURE - look at including AppStream support in our local repo + - name: list modules + command: dnf module list -q + register: module_list + + # A module that only has a single version + - name: Find a module that meets our testing needs + set_fact: + astream_name: '@{{ module.name }}:{{ module.version }}/{{ module.profile }}' + astream_name_no_stream: '@{{ module.name }}/{{ module.profile }}' + vars: + module: '{{ module_list.stdout|get_first_single_version_module }}' + + - include_tasks: modularity.yml + tags: + - dnf_modularity + rescue: + # Just in case something crazy happens when listing or parsing modules + - meta: noop - include_tasks: logging.yml when: (ansible_distribution == 'Fedora' and ansible_distribution_major_version is version('31', '>=')) or diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/test/integration/targets/dnf/tasks/modularity.yml new/ansible_core-2.16.7/test/integration/targets/dnf/tasks/modularity.yml --- old/ansible_core-2.16.6/test/integration/targets/dnf/tasks/modularity.yml 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/test/integration/targets/dnf/tasks/modularity.yml 2024-05-20 20:41:55.000000000 +0200 @@ -1,12 +1,3 @@ -# FUTURE - look at including AppStream support in our local repo -- name: Include distribution specific variables - include_vars: "{{ item }}" - with_first_found: - - files: - - "{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_major_version }}.yml" - - "{{ ansible_facts.distribution }}.yml" - paths: ../vars - - name: install "{{ astream_name }}" module dnf: name: "{{ astream_name }}" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/test/integration/targets/dnf/tasks/repo.yml new/ansible_core-2.16.7/test/integration/targets/dnf/tasks/repo.yml --- old/ansible_core-2.16.6/test/integration/targets/dnf/tasks/repo.yml 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/test/integration/targets/dnf/tasks/repo.yml 2024-05-20 20:41:55.000000000 +0200 @@ -307,3 +307,88 @@ - dinginessentail-with-weak-dep - dinginessentail-weak-dep state: absent + +- name: > + test that when a package providing a file is installed then installing by specifying the file doesn't result in + installing a different package providing the same file + block: + - dnf: + name: provides_foo_b + state: "{{ item }}" + loop: + - absent + - present + + - dnf: + name: /foo.gif + state: present + register: dnf_result + + - command: rpm -q package_foo_a + ignore_errors: true + register: rpm_result + + - assert: + that: + - dnf_result is not changed + - rpm_result.rc == 1 + always: + - name: Clean up + dnf: + name: "{{ item }}" + state: absent + loop: + - provides_foo_b + +- name: ensure that a package named "$str-$number-$str" is parsed correctly + block: + - dnf: + name: number-11-name-11.0 + state: "{{ item }}" + loop: + - absent + - present + + - dnf: + name: number-11-name + state: present + register: dnf_result + + - assert: + that: + - dnf_result is not changed + + - dnf: + name: number-11-name + state: latest + update_only: true + register: dnf_result + + - assert: + that: + - dnf_result is changed + always: + - name: Clean up + dnf: + name: number-11-name + state: absent + +- name: test that epochs are handled the same way as via DNF on the command line + block: + - dnf: + name: "{{ item }}" + state: present + loop: + - "epochone-1.0-1.noarch" + - "epochone-1.1-1.noarch" + register: dnf_results + + - assert: + that: + - dnf_results["results"][0] is changed + - dnf_results["results"][1] is changed + always: + - name: Clean up + dnf: + name: epochone + state: absent diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/test/integration/targets/dnf/vars/CentOS.yml new/ansible_core-2.16.7/test/integration/targets/dnf/vars/CentOS.yml --- old/ansible_core-2.16.6/test/integration/targets/dnf/vars/CentOS.yml 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/test/integration/targets/dnf/vars/CentOS.yml 1970-01-01 01:00:00.000000000 +0100 @@ -1,2 +0,0 @@ -astream_name: '@php:7.2/minimal' -astream_name_no_stream: '@php/minimal' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/test/integration/targets/dnf/vars/Fedora.yml new/ansible_core-2.16.7/test/integration/targets/dnf/vars/Fedora.yml --- old/ansible_core-2.16.6/test/integration/targets/dnf/vars/Fedora.yml 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/test/integration/targets/dnf/vars/Fedora.yml 1970-01-01 01:00:00.000000000 +0100 @@ -1,6 +0,0 @@ -astream_name: '@varnish:6.0/default' - -# For this to work, it needs to be that only shows once in `dnf module list`. -# Such packages, that exist on all the versions we test on, are hard to come by. -# TODO: This would be solved by using our own repo with modularity/streams. -astream_name_no_stream: '@varnish/default' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/test/integration/targets/dnf/vars/RedHat-9.yml new/ansible_core-2.16.7/test/integration/targets/dnf/vars/RedHat-9.yml --- old/ansible_core-2.16.6/test/integration/targets/dnf/vars/RedHat-9.yml 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/test/integration/targets/dnf/vars/RedHat-9.yml 1970-01-01 01:00:00.000000000 +0100 @@ -1,2 +0,0 @@ -astream_name: '@php:8.1/minimal' -astream_name_no_stream: '@php/minimal' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/test/integration/targets/dnf/vars/RedHat.yml new/ansible_core-2.16.7/test/integration/targets/dnf/vars/RedHat.yml --- old/ansible_core-2.16.6/test/integration/targets/dnf/vars/RedHat.yml 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/test/integration/targets/dnf/vars/RedHat.yml 1970-01-01 01:00:00.000000000 +0100 @@ -1,2 +0,0 @@ -astream_name: '@php:7.2/minimal' -astream_name_no_stream: '@php/minimal' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/test/integration/targets/handlers/handlers_lockstep_82307.yml new/ansible_core-2.16.7/test/integration/targets/handlers/handlers_lockstep_82307.yml --- old/ansible_core-2.16.6/test/integration/targets/handlers/handlers_lockstep_82307.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.16.7/test/integration/targets/handlers/handlers_lockstep_82307.yml 2024-05-20 20:41:55.000000000 +0200 @@ -0,0 +1,25 @@ +- hosts: A,B + gather_facts: false + tasks: + - block: + - command: echo + notify: + - handler1 + - handler2 + + - fail: + when: inventory_hostname == "B" + + - meta: flush_handlers + always: + - name: always + debug: + msg: always + handlers: + - name: handler1 + debug: + msg: handler1 + + - name: handler2 + debug: + msg: handler2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/test/integration/targets/handlers/runme.sh new/ansible_core-2.16.7/test/integration/targets/handlers/runme.sh --- old/ansible_core-2.16.6/test/integration/targets/handlers/runme.sh 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/test/integration/targets/handlers/runme.sh 2024-05-20 20:41:55.000000000 +0200 @@ -208,3 +208,6 @@ ansible-playbook nested_flush_handlers_failure_force.yml -i inventory.handlers "$@" 2>&1 | tee out.txt [ "$(grep out.txt -ce 'flush_handlers_rescued')" = "1" ] [ "$(grep out.txt -ce 'flush_handlers_always')" = "2" ] + +ansible-playbook handlers_lockstep_82307.yml -i inventory.handlers "$@" 2>&1 | tee out.txt +[ "$(grep out.txt -ce 'TASK \[handler2\]')" = "0" ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/test/integration/targets/setup_rpm_repo/library/create_repo.py new/ansible_core-2.16.7/test/integration/targets/setup_rpm_repo/library/create_repo.py --- old/ansible_core-2.16.6/test/integration/targets/setup_rpm_repo/library/create_repo.py 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/test/integration/targets/setup_rpm_repo/library/create_repo.py 2024-05-20 20:41:55.000000000 +0200 @@ -15,10 +15,12 @@ HAS_RPMFLUFF = True can_use_rpm_weak_deps = None try: - from rpmfluff import SimpleRpmBuild + from rpmfluff import SimpleRpmBuild, GeneratedSourceFile, make_gif from rpmfluff import YumRepoBuild except ImportError: try: + from rpmfluff.make import make_gif + from rpmfluff.sourcefile import GeneratedSourceFile from rpmfluff.rpmbuild import SimpleRpmBuild from rpmfluff.yumrepobuild import YumRepoBuild except ImportError: @@ -35,20 +37,25 @@ pass -RPM = namedtuple('RPM', ['name', 'version', 'release', 'epoch', 'recommends', 'arch']) - +RPM = namedtuple('RPM', ['name', 'version', 'release', 'epoch', 'recommends', 'file', 'arch']) SPECS = [ - RPM('dinginessentail', '1.0', '1', None, None, None), - RPM('dinginessentail', '1.0', '2', '1', None, None), - RPM('dinginessentail', '1.1', '1', '1', None, None), - RPM('dinginessentail-olive', '1.0', '1', None, None, None), - RPM('dinginessentail-olive', '1.1', '1', None, None, None), - RPM('landsidescalping', '1.0', '1', None, None, None), - RPM('landsidescalping', '1.1', '1', None, None, None), - RPM('dinginessentail-with-weak-dep', '1.0', '1', None, ['dinginessentail-weak-dep'], None), - RPM('dinginessentail-weak-dep', '1.0', '1', None, None, None), - RPM('noarchfake', '1.0', '1', None, None, 'noarch'), + RPM('dinginessentail', '1.0', '1', None, None, None, None), + RPM('dinginessentail', '1.0', '2', '1', None, None, None), + RPM('dinginessentail', '1.1', '1', '1', None, None, None), + RPM('dinginessentail-olive', '1.0', '1', None, None, None, None), + RPM('dinginessentail-olive', '1.1', '1', None, None, None, None), + RPM('landsidescalping', '1.0', '1', None, None, None, None), + RPM('landsidescalping', '1.1', '1', None, None, None, None), + RPM('dinginessentail-with-weak-dep', '1.0', '1', None, ['dinginessentail-weak-dep'], None, None), + RPM('dinginessentail-weak-dep', '1.0', '1', None, None, None, None), + RPM('noarchfake', '1.0', '1', None, None, None, 'noarch'), + RPM('provides_foo_a', '1.0', '1', None, None, 'foo.gif', 'noarch'), + RPM('provides_foo_b', '1.0', '1', None, None, 'foo.gif', 'noarch'), + RPM('number-11-name', '11.0', '1', None, None, None, None), + RPM('number-11-name', '11.1', '1', None, None, None, None), + RPM('epochone', '1.0', '1', '1', None, None, "noarch"), + RPM('epochone', '1.1', '1', '1', None, None, "noarch"), ] @@ -66,6 +73,14 @@ for recommend in spec.recommends: pkg.add_recommends(recommend) + if spec.file: + pkg.add_installed_file( + "/" + spec.file, + GeneratedSourceFile( + spec.file, make_gif() + ) + ) + pkgs.append(pkg) # HACK: EPEL6 version of rpmfluff can't do multi-arch packaging, so we'll just build separately and copy diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/test/integration/targets/template/ansible_managed.yml new/ansible_core-2.16.7/test/integration/targets/template/ansible_managed.yml --- old/ansible_core-2.16.6/test/integration/targets/template/ansible_managed.yml 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/test/integration/targets/template/ansible_managed.yml 2024-05-20 20:41:55.000000000 +0200 @@ -2,13 +2,51 @@ - hosts: testhost gather_facts: False tasks: - - set_fact: + - name: set output_dir + set_fact: output_dir: "{{ lookup('env', 'OUTPUT_DIR') }}" - - file: - path: '{{ output_dir }}/café.txt' - state: 'absent' - # Smoketest that ansible_managed with non-ascii chars works: - # https://github.com/ansible/ansible/issues/27262 - - template: - src: 'templates/café.j2' - dest: '{{ output_dir }}/café.txt' + tags: ['always'] + + - name: Smoketest that ansible_managed with non-ascii chars works, https://github.com/ansible/ansible/issues/27262 + tags: ['27262'] + block: + - name: ensure output file does not exist + file: + path: '{{ output_dir }}/café.txt' + state: 'absent' + + - name: test templating with unicode in template name + template: + src: 'templates/café.j2' + dest: '{{ output_dir }}/café.txt' + + always: + - name: clean up! + file: + path: '{{ output_dir }}/café.txt' + state: 'absent' + + - name: check strftime resolution in ansible_managed, https://github.com/ansible/ansible/pull/79129 + tags: ['79129'] + block: + - template: + src: "templates/%necho Onii-chan help Im stuck;exit 1%n.j2" + dest: "{{ output_dir }}/strftime.sh" + mode: '0755' + + - shell: "exec {{ output_dir | quote }}/strftime.sh" + + - name: Avoid templating 'injections' via file names + template: + src: !unsafe "templates/completely{{ 1 % 0 }} safe template.j2" + dest: "{{ output_dir }}/jinja.sh" + mode: '0755' + + - shell: "exec {{ output_dir | quote }}/jinja.sh" + register: result + + - assert: + that: + - "'Hello' in result.stdout" + - "'uname' not in lookup('file', output_dir ~ '/strftime.sh')" + - "'uname' not in lookup('file', output_dir ~ '/jinja.sh')" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/test/integration/targets/template/ansible_managed_79129.yml new/ansible_core-2.16.7/test/integration/targets/template/ansible_managed_79129.yml --- old/ansible_core-2.16.6/test/integration/targets/template/ansible_managed_79129.yml 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/test/integration/targets/template/ansible_managed_79129.yml 1970-01-01 01:00:00.000000000 +0100 @@ -1,29 +0,0 @@ ---- -- hosts: testhost - gather_facts: false - tasks: - - set_fact: - output_dir: "{{ lookup('env', 'OUTPUT_DIR') }}" - - - name: check strftime - block: - - template: - src: "templates/%necho Onii-chan help Im stuck;exit 1%n.j2" - dest: "{{ output_dir }}/79129-strftime.sh" - mode: '0755' - - - shell: "exec {{ output_dir | quote }}/79129-strftime.sh" - - - name: check jinja template - block: - - template: - src: !unsafe "templates/completely{{ 1 % 0 }} safe template.j2" - dest: "{{ output_dir }}/79129-jinja.sh" - mode: '0755' - - - shell: "exec {{ output_dir | quote }}/79129-jinja.sh" - register: result - - - assert: - that: - - "'Hello' in result.stdout" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/test/integration/targets/template/ansible_managed_templated.cfg new/ansible_core-2.16.7/test/integration/targets/template/ansible_managed_templated.cfg --- old/ansible_core-2.16.6/test/integration/targets/template/ansible_managed_templated.cfg 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.16.7/test/integration/targets/template/ansible_managed_templated.cfg 2024-05-20 20:41:55.000000000 +0200 @@ -0,0 +1,2 @@ +[defaults] +ansible_managed=ansible_managed = Ansible managed: {file} modified on %Y-%m-%d %H:%M:%S by {uid} on {host}({{{{q('pipe', 'uname -a')}}}}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/test/integration/targets/template/runme.sh new/ansible_core-2.16.7/test/integration/targets/template/runme.sh --- old/ansible_core-2.16.6/test/integration/targets/template/runme.sh 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/test/integration/targets/template/runme.sh 2024-05-20 20:41:55.000000000 +0200 @@ -7,11 +7,11 @@ # Test for https://github.com/ansible/ansible/pull/35571 ansible testhost -i testhost, -m debug -a 'msg={{ hostvars["localhost"] }}' -e "vars1={{ undef() }}" -e "vars2={{ vars1 }}" -# Test for https://github.com/ansible/ansible/issues/27262 +# ansible_managed tests ANSIBLE_CONFIG=ansible_managed.cfg ansible-playbook ansible_managed.yml -i ../../inventory -v "$@" -# Test for https://github.com/ansible/ansible/pull/79129 -ANSIBLE_CONFIG=ansible_managed.cfg ansible-playbook ansible_managed_79129.yml -i ../../inventory -v "$@" +# same as above but with ansible_managed j2 template +ANSIBLE_CONFIG=ansible_managed_templated.cfg ansible-playbook ansible_managed.yml -i ../../inventory -v "$@" # Test for #42585 ANSIBLE_ROLES_PATH=../ ansible-playbook custom_template.yml -i ../../inventory -v "$@" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/test/integration/targets/user/tasks/test_local.yml new/ansible_core-2.16.7/test/integration/targets/user/tasks/test_local.yml --- old/ansible_core-2.16.6/test/integration/targets/user/tasks/test_local.yml 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/test/integration/targets/user/tasks/test_local.yml 2024-05-20 20:41:55.000000000 +0200 @@ -224,8 +224,6 @@ - name: Ensure warnings were displayed properly assert: that: - - local_user_test_1['warnings'] | length > 0 - - local_user_test_1['warnings'] | first is search('The local user account may already exist') - local_user_test_5['warnings'] is search("'append' is set, but no 'groups' are specified. Use 'groups'") - local_existing['warnings'] is not defined when: ansible_facts.system in ['Linux'] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/test/lib/ansible_test/_data/requirements/constraints.txt new/ansible_core-2.16.7/test/lib/ansible_test/_data/requirements/constraints.txt --- old/ansible_core-2.16.6/test/lib/ansible_test/_data/requirements/constraints.txt 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/test/lib/ansible_test/_data/requirements/constraints.txt 2024-05-20 20:41:55.000000000 +0200 @@ -1,6 +1,7 @@ # do not add a cryptography or pyopenssl constraint to this file, they require special handling, see get_cryptography_requirements in python_requirements.py # do not add a coverage constraint to this file, it is handled internally by ansible-test packaging < 21.0 ; python_version < '3.6' # packaging 21.0 requires Python 3.6 or newer +pypsrp < 1.0.0 # in case the next major version is too big of a change pywinrm >= 0.3.0 ; python_version < '3.11' # message encryption support pywinrm >= 0.4.3 ; python_version >= '3.11' # support for Python 3.11 pytest < 5.0.0, >= 4.5.0 ; python_version == '2.7' # pytest 5.0.0 and later will no longer support python 2.7 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/test/lib/ansible_test/_internal/pypi_proxy.py new/ansible_core-2.16.7/test/lib/ansible_test/_internal/pypi_proxy.py --- old/ansible_core-2.16.6/test/lib/ansible_test/_internal/pypi_proxy.py 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/test/lib/ansible_test/_internal/pypi_proxy.py 2024-05-20 20:41:55.000000000 +0200 @@ -14,6 +14,7 @@ from .host_configs import ( PosixConfig, + DockerConfig, ) from .util import ( @@ -55,8 +56,14 @@ return # user has overridden the proxy endpoint, there is nothing to provision versions_needing_proxy: tuple[str, ...] = tuple() # preserved for future use, no versions currently require this + containers_needing_proxy: set[str] = {'centos7'} posix_targets = [target for target in args.targets if isinstance(target, PosixConfig)] - need_proxy = targets_use_pypi and any(target.python.version in versions_needing_proxy for target in posix_targets) + need_proxy = targets_use_pypi and any( + target.python.version in versions_needing_proxy or + (isinstance(target, DockerConfig) and target.name in containers_needing_proxy) + for target in posix_targets + ) + use_proxy = args.pypi_proxy or need_proxy if not use_proxy: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.16.6/test/units/playbook/test_included_file.py new/ansible_core-2.16.7/test/units/playbook/test_included_file.py --- old/ansible_core-2.16.6/test/units/playbook/test_included_file.py 2024-04-16 01:57:44.000000000 +0200 +++ new/ansible_core-2.16.7/test/units/playbook/test_included_file.py 2024-05-20 20:41:55.000000000 +0200 @@ -318,9 +318,6 @@ task_ds_list = [ { - 'include': '' - }, - { 'include_tasks': '' }, { ++++++ ansible_core-2.16.6.tar.gz.sha256 -> ansible_core-2.16.7.tar.gz.sha256 ++++++ --- /work/SRC/openSUSE:Factory/ansible-core/ansible_core-2.16.6.tar.gz.sha256 2024-04-18 22:13:47.964113300 +0200 +++ /work/SRC/openSUSE:Factory/.ansible-core.new.24587/ansible_core-2.16.7.tar.gz.sha256 2024-05-24 19:51:38.058592321 +0200 @@ -1 +1 @@ -111e55d358c2297ec0ce03ba98e6c5ce95947fdf50d878215eb8c183d0c275e4 ansible_core-2.16.6.tar.gz +a8c8f4facba30514571d47abec5c62a5768b86fef3d80d724911c8f20b7b34b7 ansible_core-2.16.7.tar.gz
