Compare commits

...

20 Commits
3.8.3 ... 3.8.4

Author SHA1 Message Date
Felix Fontein
f7276b152b Release 3.8.4. 2022-01-11 06:41:56 +01:00
Felix Fontein
5e503bfcc7 Prepare 3.8.4 release. 2022-01-10 23:06:20 +01:00
patchback[bot]
d2b4151b7a fix alternatives parsing when they are part of a group (#3976) (#4020)
* fix alternatives parsing when they are part of a group

* add changelog fragment

Co-authored-by: Guillaume Rousse <guillaume.rousse@renater.fr>
(cherry picked from commit a675afcba9)

Co-authored-by: Guillaume Rousse <guillomovitch@gmail.com>
2022-01-10 07:27:12 +01:00
patchback[bot]
57b73e0d5e Fix example code for flattened lookup (#4013) (#4015)
Co-authored-by: Lee Garrett <lgarrett@rocketjump.eu>
(cherry picked from commit d19ab93faf)

Co-authored-by: Lee Garrett <leegarrett@users.noreply.github.com>
2022-01-09 12:29:19 +01:00
patchback[bot]
5f47d47f27 Restrict PyNaCL to 1.4.x on RHEL8 when using Python 3.6 (#4006) (#4009)
* Restrict PyNaCL to 1.4.x on RHEL8 when using Python 3.6.

* Fix typo.

(cherry picked from commit 77a930cf6b)

Co-authored-by: Felix Fontein <felix@fontein.de>
2022-01-08 15:07:00 +01:00
patchback[bot]
7e2f20f482 Fix 2.9 unit tests (#4002) (#4004)
* Fix 2.9 unit tests.

* Another try.

(cherry picked from commit 26a91e811f)

Co-authored-by: Felix Fontein <felix@fontein.de>
2022-01-08 12:40:05 +01:00
patchback[bot]
3023312334 Fix comment. (#3993) (#3994)
(cherry picked from commit a6a8cd02b6)

Co-authored-by: Felix Fontein <felix@fontein.de>
2022-01-06 15:10:46 +01:00
Felix Fontein
fe3de232f0 Fix BOTMETA and corresponding sanity test (#3989) (#3991)
* Fix BOTMETA and authors mistakes.

* Fix BOTMETA sanity test regex.

(cherry picked from commit 11205eefee)
2022-01-06 06:56:10 +01:00
patchback[bot]
2024dc37af Use vendored copy of distutils.version. (#3984) (#3986)
(cherry picked from commit cf7a33356c)

Co-authored-by: Felix Fontein <felix@fontein.de>
2022-01-05 22:05:06 +01:00
Felix Fontein
b8469a5c28 Re-enable snap tests (#3967) (#3982)
* Re-enable snap tests.

* Skip tests on RHEL 8.2 and 8.3.

* Refactor snap setup.

* Try to simplify setup.

(cherry picked from commit bb78d98f8f)
2022-01-05 18:12:03 +01:00
patchback[bot]
2a0ec9c572 Get rid of distutils.spawn and distutils.util (#3934) (#3973)
* Replace distutils.spawn.find_executable.

* Replace distutils.util.strtobool.

(cherry picked from commit 77b7b4f75b)

Co-authored-by: Felix Fontein <felix@fontein.de>
2022-01-04 07:27:02 +01:00
patchback[bot]
fa92f8efb0 slack - use UTF-8 charset in content-type header (#3933) (#3970)
* Use UTF-8 charset in content-type header

* Add changelog fragment

(cherry picked from commit a4ab85fd68)

Co-authored-by: bluikko <14869000+bluikko@users.noreply.github.com>
2022-01-03 19:43:47 +01:00
patchback[bot]
03e068e298 Restrict redis to < 4.1.0 for ansible-base 2.10. (#3955) (#3958)
(cherry picked from commit 3f2364574d)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-12-27 21:17:06 +01:00
patchback[bot]
8f084ac065 fix scaleway_user_data (#3940) (#3953)
* fix  scaleway_user_data

scaleway_user_data put cloud-init valuer with 2 unexpected " (begin and end of value)

If Content-Type is not change , it's jsonify ( file module_utils/scaleway.py ligne 131 )

fix the probleme  when "Content-Type" is used instead of "Content-type"

* Create 3940_fix_contenttype_scaleway_user_data.yml

* Update changelogs/fragments/3940_fix_contenttype_scaleway_user_data.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 043b407412)

Co-authored-by: pmangin <96626847+pmangin@users.noreply.github.com>
2021-12-27 19:55:43 +01:00
Felix Fontein
e02568d28a Prepare for distutils.version being removed in Python 3.12 (#3936) (#3942)
* Prepare for distutils.version being removed in Python 2.12.

* Fix copy'n'paste error.

* Re-add Loose prefix.

* Fix Python version typos.

* Improve formulation.

* Move message into own line.

* Fix casing, now that the object is no longer called Version.

(cherry picked from commit a2f72be6c8)
2021-12-24 19:15:51 +01:00
patchback[bot]
73580d09e0 Fix filesystem tests (so they run on their own) (#3937) (#3938)
* Don't use loops for installing packages.

* Install util-linux-systemd on OpenSuSE so that findmnt is around.

(cherry picked from commit f34c454412)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-12-23 12:38:22 +01:00
Felix Fontein
093036a2ae Disable snap tests. (#3922) (#3924)
(cherry picked from commit 51838adf8c)
2021-12-20 10:59:11 +01:00
patchback[bot]
7f1de4869e Fix nrdp string arguments without an encoding (#3909) (#3911)
* Fix nrdp string arguments without an encoding

* added changelog fragment

Signed-off-by: Jesse Harris <zigford@gmail.com>

* Update changelogs/fragments/3909-nrdp_fix_string_args_without_encoding.yaml

Co-authored-by: Felix Fontein <felix@fontein.de>

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 40ffd559ac)

Co-authored-by: Jesse Harris <zigford@gmail.com>
2021-12-17 22:13:50 +01:00
patchback[bot]
8df1b93531 jira - fixed 'body' dict key error (#3867) (#3913)
* fixed

* added changelog fragment

* improved fail output when placing JIRA API requests

* Update plugins/modules/web_infrastructure/jira.py

Co-authored-by: Felix Fontein <felix@fontein.de>

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit e6c773a4f3)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-12-17 22:13:21 +01:00
Felix Fontein
c055ea2bcc Next expected release is 3.8.4. 2021-12-14 07:57:25 +01:00
71 changed files with 605 additions and 122 deletions

10
.github/BOTMETA.yml vendored
View File

@@ -164,7 +164,7 @@ files:
$inventories/proxmox.py: $inventories/proxmox.py:
maintainers: $team_virt ilijamt maintainers: $team_virt ilijamt
$inventories/icinga2.py: $inventories/icinga2.py:
maintainers: bongoeadgc6 maintainers: BongoEADGC6
$inventories/scaleway.py: $inventories/scaleway.py:
maintainers: $team_scaleway maintainers: $team_scaleway
labels: cloud scaleway labels: cloud scaleway
@@ -320,6 +320,10 @@ files:
$modules/cloud/misc/proxmox_kvm.py: $modules/cloud/misc/proxmox_kvm.py:
maintainers: helldorado maintainers: helldorado
ignore: skvidal ignore: skvidal
$modules/cloud/misc/proxmox_nic.py:
maintainers: Kogelvis
$modules/cloud/misc/proxmox_tasks_info:
maintainers: paginabianca
$modules/cloud/misc/proxmox_template.py: $modules/cloud/misc/proxmox_template.py:
maintainers: UnderGreen maintainers: UnderGreen
ignore: skvidal ignore: skvidal
@@ -914,6 +918,10 @@ files:
$modules/remote_management/manageiq/: $modules/remote_management/manageiq/:
labels: manageiq labels: manageiq
maintainers: $team_manageiq maintainers: $team_manageiq
$modules/remote_management/manageiq/manageiq_alert_profiles.py:
maintainers: elad661
$modules/remote_management/manageiq/manageiq_alerts.py:
maintainers: elad661
$modules/remote_management/manageiq/manageiq_group.py: $modules/remote_management/manageiq/manageiq_group.py:
maintainers: evertmulder maintainers: evertmulder
$modules/remote_management/manageiq/manageiq_tenant.py: $modules/remote_management/manageiq/manageiq_tenant.py:

View File

@@ -6,6 +6,29 @@ Community General Release Notes
This changelog describes changes after version 2.0.0. This changelog describes changes after version 2.0.0.
v3.8.4
======
Release Summary
---------------
Regular bugfix release.
Bugfixes
--------
- Various modules and plugins - use vendored version of ``distutils.version`` instead of the deprecated Python standard library ``distutils`` (https://github.com/ansible-collections/community.general/pull/3936).
- alternatives - fix output parsing for alternatives groups (https://github.com/ansible-collections/community.general/pull/3976).
- jail connection plugin - replace deprecated ``distutils.spawn.find_executable`` with Ansible's ``get_bin_path`` to find the executable (https://github.com/ansible-collections/community.general/pull/3934).
- jira - fixed bug where module returns error related to dictionary key ``body`` (https://github.com/ansible-collections/community.general/issues/3419).
- lxd connection plugin - replace deprecated ``distutils.spawn.find_executable`` with Ansible's ``get_bin_path`` to find the ``lxc`` executable (https://github.com/ansible-collections/community.general/pull/3934).
- nrdp callback plugin - fix error ``string arguments without an encoding`` (https://github.com/ansible-collections/community.general/issues/3903).
- passwordstore lookup plugin - replace deprecated ``distutils.util.strtobool`` with Ansible's ``convert_bool.boolean`` to interpret values for the ``create``, ``returnall``, ``overwrite``, 'backup``, and ``nosymbols`` options (https://github.com/ansible-collections/community.general/pull/3934).
- say callback plugin - replace deprecated ``distutils.spawn.find_executable`` with Ansible's ``get_bin_path`` to find the ``say`` resp. ``espeak`` executables (https://github.com/ansible-collections/community.general/pull/3934).
- scaleway_user_data - fix double-quote added where no double-quote is needed to user data in scaleway's server (``Content-type`` -> ``Content-Type``) (https://github.com/ansible-collections/community.general/pull/3940).
- slack - add ``charset`` to HTTP headers to avoid Slack API warning (https://github.com/ansible-collections/community.general/issues/3932).
- zone connection plugin - replace deprecated ``distutils.spawn.find_executable`` with Ansible's ``get_bin_path`` to find the executable (https://github.com/ansible-collections/community.general/pull/3934).
v3.8.3 v3.8.3
====== ======

View File

@@ -2030,3 +2030,39 @@ releases:
- 3874-proxmox-fix-onboot-param.yml - 3874-proxmox-fix-onboot-param.yml
- 3896-nmcli_vlan_missing_options.yaml - 3896-nmcli_vlan_missing_options.yaml
release_date: '2021-12-14' release_date: '2021-12-14'
3.8.4:
changes:
bugfixes:
- Various modules and plugins - use vendored version of ``distutils.version``
instead of the deprecated Python standard library ``distutils`` (https://github.com/ansible-collections/community.general/pull/3936).
- alternatives - fix output parsing for alternatives groups (https://github.com/ansible-collections/community.general/pull/3976).
- jail connection plugin - replace deprecated ``distutils.spawn.find_executable``
with Ansible's ``get_bin_path`` to find the executable (https://github.com/ansible-collections/community.general/pull/3934).
- jira - fixed bug where module returns error related to dictionary key ``body``
(https://github.com/ansible-collections/community.general/issues/3419).
- lxd connection plugin - replace deprecated ``distutils.spawn.find_executable``
with Ansible's ``get_bin_path`` to find the ``lxc`` executable (https://github.com/ansible-collections/community.general/pull/3934).
- nrdp callback plugin - fix error ``string arguments without an encoding``
(https://github.com/ansible-collections/community.general/issues/3903).
- passwordstore lookup plugin - replace deprecated ``distutils.util.strtobool``
with Ansible's ``convert_bool.boolean`` to interpret values for the ``create``,
``returnall``, ``overwrite``, 'backup``, and ``nosymbols`` options (https://github.com/ansible-collections/community.general/pull/3934).
- say callback plugin - replace deprecated ``distutils.spawn.find_executable``
with Ansible's ``get_bin_path`` to find the ``say`` resp. ``espeak`` executables
(https://github.com/ansible-collections/community.general/pull/3934).
- scaleway_user_data - fix double-quote added where no double-quote is needed
to user data in scaleway's server (``Content-type`` -> ``Content-Type``) (https://github.com/ansible-collections/community.general/pull/3940).
- slack - add ``charset`` to HTTP headers to avoid Slack API warning (https://github.com/ansible-collections/community.general/issues/3932).
- zone connection plugin - replace deprecated ``distutils.spawn.find_executable``
with Ansible's ``get_bin_path`` to find the executable (https://github.com/ansible-collections/community.general/pull/3934).
release_summary: Regular bugfix release.
fragments:
- 3.8.4.yml
- 3867-jira-fix-body.yaml
- 3909-nrdp_fix_string_args_without_encoding.yaml
- 3933-slack-charset-header.yaml
- 3934-distutils.yml
- 3936-distutils.version.yml
- 3940_fix_contenttype_scaleway_user_data.yml
- 3976-fix-alternatives-parsing.yml
release_date: '2022-01-11'

View File

@@ -1,6 +1,6 @@
namespace: community namespace: community
name: general name: general
version: 3.8.3 version: 3.8.4
readme: README.md readme: README.md
authors: authors:
- Ansible (https://github.com/ansible) - Ansible (https://github.com/ansible)

View File

@@ -70,6 +70,7 @@ import os
import json import json
from ansible.module_utils.six.moves.urllib.parse import urlencode from ansible.module_utils.six.moves.urllib.parse import urlencode
from ansible.module_utils.common.text.converters import to_bytes
from ansible.module_utils.urls import open_url from ansible.module_utils.urls import open_url
from ansible.plugins.callback import CallbackBase from ansible.plugins.callback import CallbackBase
@@ -143,7 +144,7 @@ class CallbackModule(CallbackBase):
body = { body = {
'cmd': 'submitcheck', 'cmd': 'submitcheck',
'token': self.token, 'token': self.token,
'XMLDATA': bytes(xmldata) 'XMLDATA': to_bytes(xmldata)
} }
try: try:

View File

@@ -21,11 +21,11 @@ DOCUMENTATION = '''
- In 2.8, this callback has been renamed from C(osx_say) into M(community.general.say). - In 2.8, this callback has been renamed from C(osx_say) into M(community.general.say).
''' '''
import distutils.spawn
import platform import platform
import subprocess import subprocess
import os import os
from ansible.module_utils.common.process import get_bin_path
from ansible.plugins.callback import CallbackBase from ansible.plugins.callback import CallbackBase
@@ -47,21 +47,24 @@ class CallbackModule(CallbackBase):
self.HAPPY_VOICE = None self.HAPPY_VOICE = None
self.LASER_VOICE = None self.LASER_VOICE = None
self.synthesizer = distutils.spawn.find_executable('say') try:
if not self.synthesizer: self.synthesizer = get_bin_path('say')
self.synthesizer = distutils.spawn.find_executable('espeak') if platform.system() != 'Darwin':
if self.synthesizer: # 'say' binary available, it might be GNUstep tool which doesn't support 'voice' parameter
self._display.warning("'say' executable found but system is '%s': ignoring voice parameter" % platform.system())
else:
self.FAILED_VOICE = 'Zarvox'
self.REGULAR_VOICE = 'Trinoids'
self.HAPPY_VOICE = 'Cellos'
self.LASER_VOICE = 'Princess'
except ValueError:
try:
self.synthesizer = get_bin_path('espeak')
self.FAILED_VOICE = 'klatt' self.FAILED_VOICE = 'klatt'
self.HAPPY_VOICE = 'f5' self.HAPPY_VOICE = 'f5'
self.LASER_VOICE = 'whisper' self.LASER_VOICE = 'whisper'
elif platform.system() != 'Darwin': except ValueError:
# 'say' binary available, it might be GNUstep tool which doesn't support 'voice' parameter self.synthesizer = None
self._display.warning("'say' executable found but system is '%s': ignoring voice parameter" % platform.system())
else:
self.FAILED_VOICE = 'Zarvox'
self.REGULAR_VOICE = 'Trinoids'
self.HAPPY_VOICE = 'Cellos'
self.LASER_VOICE = 'Princess'
# plugin disable itself if say is not present # plugin disable itself if say is not present
# ansible will not call any callback if disabled is set to True # ansible will not call any callback if disabled is set to True

View File

@@ -31,7 +31,6 @@ DOCUMENTATION = '''
- name: ansible_jail_user - name: ansible_jail_user
''' '''
import distutils.spawn
import os import os
import os.path import os.path
import subprocess import subprocess
@@ -39,6 +38,7 @@ import traceback
from ansible.errors import AnsibleError from ansible.errors import AnsibleError
from ansible.module_utils.six.moves import shlex_quote from ansible.module_utils.six.moves import shlex_quote
from ansible.module_utils.common.process import get_bin_path
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
from ansible.plugins.connection import ConnectionBase, BUFSIZE from ansible.plugins.connection import ConnectionBase, BUFSIZE
from ansible.utils.display import Display from ansible.utils.display import Display
@@ -75,10 +75,10 @@ class Connection(ConnectionBase):
@staticmethod @staticmethod
def _search_executable(executable): def _search_executable(executable):
cmd = distutils.spawn.find_executable(executable) try:
if not cmd: return get_bin_path(executable)
except ValueError:
raise AnsibleError("%s command not found in PATH" % executable) raise AnsibleError("%s command not found in PATH" % executable)
return cmd
def list_jails(self): def list_jails(self):
p = subprocess.Popen([self.jls_cmd, '-q', 'name'], p = subprocess.Popen([self.jls_cmd, '-q', 'name'],

View File

@@ -43,10 +43,10 @@ DOCUMENTATION = '''
''' '''
import os import os
from distutils.spawn import find_executable
from subprocess import Popen, PIPE from subprocess import Popen, PIPE
from ansible.errors import AnsibleError, AnsibleConnectionFailure, AnsibleFileNotFound from ansible.errors import AnsibleError, AnsibleConnectionFailure, AnsibleFileNotFound
from ansible.module_utils.common.process import get_bin_path
from ansible.module_utils.common.text.converters import to_bytes, to_text from ansible.module_utils.common.text.converters import to_bytes, to_text
from ansible.plugins.connection import ConnectionBase from ansible.plugins.connection import ConnectionBase
@@ -62,9 +62,9 @@ class Connection(ConnectionBase):
super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs) super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)
self._host = self._play_context.remote_addr self._host = self._play_context.remote_addr
self._lxc_cmd = find_executable("lxc") try:
self._lxc_cmd = get_bin_path("lxc")
if not self._lxc_cmd: except ValueError:
raise AnsibleError("lxc command not found in PATH") raise AnsibleError("lxc command not found in PATH")
if self._play_context.remote_user is not None and self._play_context.remote_user != 'root': if self._play_context.remote_user is not None and self._play_context.remote_user != 'root':

View File

@@ -26,7 +26,6 @@ DOCUMENTATION = '''
- name: ansible_zone_host - name: ansible_zone_host
''' '''
import distutils.spawn
import os import os
import os.path import os.path
import subprocess import subprocess
@@ -34,6 +33,7 @@ import traceback
from ansible.errors import AnsibleError from ansible.errors import AnsibleError
from ansible.module_utils.six.moves import shlex_quote from ansible.module_utils.six.moves import shlex_quote
from ansible.module_utils.common.process import get_bin_path
from ansible.module_utils.common.text.converters import to_bytes from ansible.module_utils.common.text.converters import to_bytes
from ansible.plugins.connection import ConnectionBase, BUFSIZE from ansible.plugins.connection import ConnectionBase, BUFSIZE
from ansible.utils.display import Display from ansible.utils.display import Display
@@ -64,10 +64,10 @@ class Connection(ConnectionBase):
@staticmethod @staticmethod
def _search_executable(executable): def _search_executable(executable):
cmd = distutils.spawn.find_executable(executable) try:
if not cmd: return get_bin_path(executable)
except ValueError:
raise AnsibleError("%s command not found in PATH" % executable) raise AnsibleError("%s command not found in PATH" % executable)
return cmd
def list_zones(self): def list_zones(self):
process = subprocess.Popen([self.zoneadm_cmd, 'list', '-ip'], process = subprocess.Popen([self.zoneadm_cmd, 'list', '-ip'],

View File

@@ -5,7 +5,7 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
from distutils.version import LooseVersion from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
def version_sort(value, reverse=False): def version_sort(value, reverse=False):

View File

@@ -68,7 +68,6 @@ user: ansible-tester
password: secure password: secure
''' '''
from distutils.version import LooseVersion
import socket import socket
from ansible.errors import AnsibleError from ansible.errors import AnsibleError

View File

@@ -119,12 +119,13 @@ compose:
import re import re
from ansible.module_utils.common._collections_compat import MutableMapping from ansible.module_utils.common._collections_compat import MutableMapping
from distutils.version import LooseVersion
from ansible.errors import AnsibleError from ansible.errors import AnsibleError
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
from ansible.module_utils.six.moves.urllib.parse import urlencode from ansible.module_utils.six.moves.urllib.parse import urlencode
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
# 3rd party imports # 3rd party imports
try: try:
import requests import requests

View File

@@ -23,7 +23,7 @@ DOCUMENTATION = '''
EXAMPLES = """ EXAMPLES = """
- name: "'unnest' all elements into single list" - name: "'unnest' all elements into single list"
ansible.builtin.debug: ansible.builtin.debug:
msg: "all in one list {{lookup('community.general.flattened', [1,2,3,[5,6]], [a,b,c], [[5,6,1,3], [34,a,b,c]])}}" msg: "all in one list {{lookup('community.general.flattened', [1,2,3,[5,6]], ['a','b','c'], [[5,6,1,3], [34,'a','b','c']])}}"
""" """
RETURN = """ RETURN = """

View File

@@ -141,9 +141,9 @@ import time
import yaml import yaml
from distutils import util
from ansible.errors import AnsibleError, AnsibleAssertionError from ansible.errors import AnsibleError, AnsibleAssertionError
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
from ansible.module_utils.parsing.convert_bool import boolean
from ansible.utils.display import Display from ansible.utils.display import Display
from ansible.utils.encrypt import random_password from ansible.utils.encrypt import random_password
from ansible.plugins.lookup import LookupBase from ansible.plugins.lookup import LookupBase
@@ -211,7 +211,7 @@ class LookupModule(LookupBase):
try: try:
for key in ['create', 'returnall', 'overwrite', 'backup', 'nosymbols']: for key in ['create', 'returnall', 'overwrite', 'backup', 'nosymbols']:
if not isinstance(self.paramvals[key], bool): if not isinstance(self.paramvals[key], bool):
self.paramvals[key] = util.strtobool(self.paramvals[key]) self.paramvals[key] = boolean(self.paramvals[key])
except (ValueError, AssertionError) as e: except (ValueError, AssertionError) as e:
raise AnsibleError(e) raise AnsibleError(e)
if self.paramvals['missing'] not in ['error', 'warn', 'create', 'empty']: if self.paramvals['missing'] not in ['error', 'warn', 'create', 'empty']:

View File

@@ -0,0 +1,343 @@
# Vendored copy of distutils/version.py from CPython 3.9.5
#
# Implements multiple version numbering conventions for the
# Python Module Distribution Utilities.
#
# PSF License (see licenses/PSF-license.txt or https://opensource.org/licenses/Python-2.0)
#
"""Provides classes to represent module version numbers (one class for
each style of version numbering). There are currently two such classes
implemented: StrictVersion and LooseVersion.
Every version number class implements the following interface:
* the 'parse' method takes a string and parses it to some internal
representation; if the string is an invalid version number,
'parse' raises a ValueError exception
* the class constructor takes an optional string argument which,
if supplied, is passed to 'parse'
* __str__ reconstructs the string that was passed to 'parse' (or
an equivalent string -- ie. one that will generate an equivalent
version number instance)
* __repr__ generates Python code to recreate the version number instance
* _cmp compares the current instance with either another instance
of the same class or a string (which will be parsed to an instance
of the same class, thus must follow the same rules)
"""
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import re
try:
RE_FLAGS = re.VERBOSE | re.ASCII
except AttributeError:
RE_FLAGS = re.VERBOSE
class Version:
"""Abstract base class for version numbering classes. Just provides
constructor (__init__) and reproducer (__repr__), because those
seem to be the same for all version numbering classes; and route
rich comparisons to _cmp.
"""
def __init__(self, vstring=None):
if vstring:
self.parse(vstring)
def __repr__(self):
return "%s ('%s')" % (self.__class__.__name__, str(self))
def __eq__(self, other):
c = self._cmp(other)
if c is NotImplemented:
return c
return c == 0
def __lt__(self, other):
c = self._cmp(other)
if c is NotImplemented:
return c
return c < 0
def __le__(self, other):
c = self._cmp(other)
if c is NotImplemented:
return c
return c <= 0
def __gt__(self, other):
c = self._cmp(other)
if c is NotImplemented:
return c
return c > 0
def __ge__(self, other):
c = self._cmp(other)
if c is NotImplemented:
return c
return c >= 0
# Interface for version-number classes -- must be implemented
# by the following classes (the concrete ones -- Version should
# be treated as an abstract class).
# __init__ (string) - create and take same action as 'parse'
# (string parameter is optional)
# parse (string) - convert a string representation to whatever
# internal representation is appropriate for
# this style of version numbering
# __str__ (self) - convert back to a string; should be very similar
# (if not identical to) the string supplied to parse
# __repr__ (self) - generate Python code to recreate
# the instance
# _cmp (self, other) - compare two version numbers ('other' may
# be an unparsed version string, or another
# instance of your version class)
class StrictVersion(Version):
"""Version numbering for anal retentives and software idealists.
Implements the standard interface for version number classes as
described above. A version number consists of two or three
dot-separated numeric components, with an optional "pre-release" tag
on the end. The pre-release tag consists of the letter 'a' or 'b'
followed by a number. If the numeric components of two version
numbers are equal, then one with a pre-release tag will always
be deemed earlier (lesser) than one without.
The following are valid version numbers (shown in the order that
would be obtained by sorting according to the supplied cmp function):
0.4 0.4.0 (these two are equivalent)
0.4.1
0.5a1
0.5b3
0.5
0.9.6
1.0
1.0.4a3
1.0.4b1
1.0.4
The following are examples of invalid version numbers:
1
2.7.2.2
1.3.a4
1.3pl1
1.3c4
The rationale for this version numbering system will be explained
in the distutils documentation.
"""
version_re = re.compile(r'^(\d+) \. (\d+) (\. (\d+))? ([ab](\d+))?$',
RE_FLAGS)
def parse(self, vstring):
match = self.version_re.match(vstring)
if not match:
raise ValueError("invalid version number '%s'" % vstring)
(major, minor, patch, prerelease, prerelease_num) = \
match.group(1, 2, 4, 5, 6)
if patch:
self.version = tuple(map(int, [major, minor, patch]))
else:
self.version = tuple(map(int, [major, minor])) + (0,)
if prerelease:
self.prerelease = (prerelease[0], int(prerelease_num))
else:
self.prerelease = None
def __str__(self):
if self.version[2] == 0:
vstring = '.'.join(map(str, self.version[0:2]))
else:
vstring = '.'.join(map(str, self.version))
if self.prerelease:
vstring = vstring + self.prerelease[0] + str(self.prerelease[1])
return vstring
def _cmp(self, other):
if isinstance(other, str):
other = StrictVersion(other)
elif not isinstance(other, StrictVersion):
return NotImplemented
if self.version != other.version:
# numeric versions don't match
# prerelease stuff doesn't matter
if self.version < other.version:
return -1
else:
return 1
# have to compare prerelease
# case 1: neither has prerelease; they're equal
# case 2: self has prerelease, other doesn't; other is greater
# case 3: self doesn't have prerelease, other does: self is greater
# case 4: both have prerelease: must compare them!
if (not self.prerelease and not other.prerelease):
return 0
elif (self.prerelease and not other.prerelease):
return -1
elif (not self.prerelease and other.prerelease):
return 1
elif (self.prerelease and other.prerelease):
if self.prerelease == other.prerelease:
return 0
elif self.prerelease < other.prerelease:
return -1
else:
return 1
else:
raise AssertionError("never get here")
# end class StrictVersion
# The rules according to Greg Stein:
# 1) a version number has 1 or more numbers separated by a period or by
# sequences of letters. If only periods, then these are compared
# left-to-right to determine an ordering.
# 2) sequences of letters are part of the tuple for comparison and are
# compared lexicographically
# 3) recognize the numeric components may have leading zeroes
#
# The LooseVersion class below implements these rules: a version number
# string is split up into a tuple of integer and string components, and
# comparison is a simple tuple comparison. This means that version
# numbers behave in a predictable and obvious way, but a way that might
# not necessarily be how people *want* version numbers to behave. There
# wouldn't be a problem if people could stick to purely numeric version
# numbers: just split on period and compare the numbers as tuples.
# However, people insist on putting letters into their version numbers;
# the most common purpose seems to be:
# - indicating a "pre-release" version
# ('alpha', 'beta', 'a', 'b', 'pre', 'p')
# - indicating a post-release patch ('p', 'pl', 'patch')
# but of course this can't cover all version number schemes, and there's
# no way to know what a programmer means without asking him.
#
# The problem is what to do with letters (and other non-numeric
# characters) in a version number. The current implementation does the
# obvious and predictable thing: keep them as strings and compare
# lexically within a tuple comparison. This has the desired effect if
# an appended letter sequence implies something "post-release":
# eg. "0.99" < "0.99pl14" < "1.0", and "5.001" < "5.001m" < "5.002".
#
# However, if letters in a version number imply a pre-release version,
# the "obvious" thing isn't correct. Eg. you would expect that
# "1.5.1" < "1.5.2a2" < "1.5.2", but under the tuple/lexical comparison
# implemented here, this just isn't so.
#
# Two possible solutions come to mind. The first is to tie the
# comparison algorithm to a particular set of semantic rules, as has
# been done in the StrictVersion class above. This works great as long
# as everyone can go along with bondage and discipline. Hopefully a
# (large) subset of Python module programmers will agree that the
# particular flavour of bondage and discipline provided by StrictVersion
# provides enough benefit to be worth using, and will submit their
# version numbering scheme to its domination. The free-thinking
# anarchists in the lot will never give in, though, and something needs
# to be done to accommodate them.
#
# Perhaps a "moderately strict" version class could be implemented that
# lets almost anything slide (syntactically), and makes some heuristic
# assumptions about non-digits in version number strings. This could
# sink into special-case-hell, though; if I was as talented and
# idiosyncratic as Larry Wall, I'd go ahead and implement a class that
# somehow knows that "1.2.1" < "1.2.2a2" < "1.2.2" < "1.2.2pl3", and is
# just as happy dealing with things like "2g6" and "1.13++". I don't
# think I'm smart enough to do it right though.
#
# In any case, I've coded the test suite for this module (see
# ../test/test_version.py) specifically to fail on things like comparing
# "1.2a2" and "1.2". That's not because the *code* is doing anything
# wrong, it's because the simple, obvious design doesn't match my
# complicated, hairy expectations for real-world version numbers. It
# would be a snap to fix the test suite to say, "Yep, LooseVersion does
# the Right Thing" (ie. the code matches the conception). But I'd rather
# have a conception that matches common notions about version numbers.
class LooseVersion(Version):
"""Version numbering for anarchists and software realists.
Implements the standard interface for version number classes as
described above. A version number consists of a series of numbers,
separated by either periods or strings of letters. When comparing
version numbers, the numeric components will be compared
numerically, and the alphabetic components lexically. The following
are all valid version numbers, in no particular order:
1.5.1
1.5.2b2
161
3.10a
8.02
3.4j
1996.07.12
3.2.pl0
3.1.1.6
2g6
11g
0.960923
2.2beta29
1.13++
5.5.kw
2.0b1pl0
In fact, there is no such thing as an invalid version number under
this scheme; the rules for comparison are simple and predictable,
but may not always give the results you want (for some definition
of "want").
"""
component_re = re.compile(r'(\d+ | [a-z]+ | \.)', re.VERBOSE)
def __init__(self, vstring=None):
if vstring:
self.parse(vstring)
def parse(self, vstring):
# I've given up on thinking I can reconstruct the version string
# from the parsed tuple -- so I just store the string here for
# use by __str__
self.vstring = vstring
components = [x for x in self.component_re.split(vstring) if x and x != '.']
for i, obj in enumerate(components):
try:
components[i] = int(obj)
except ValueError:
pass
self.version = components
def __str__(self):
return self.vstring
def __repr__(self):
return "LooseVersion ('%s')" % str(self)
def _cmp(self, other):
if isinstance(other, str):
other = LooseVersion(other)
elif not isinstance(other, LooseVersion):
return NotImplemented
if self.version == other.version:
return 0
if self.version < other.version:
return -1
if self.version > other.version:
return 1
# end class LooseVersion

View File

@@ -8,12 +8,13 @@ from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
import json import json
from distutils.version import StrictVersion
from ansible.module_utils.basic import missing_required_lib from ansible.module_utils.basic import missing_required_lib
from ansible.module_utils.urls import fetch_url from ansible.module_utils.urls import fetch_url
from ansible.module_utils.common.text.converters import to_native from ansible.module_utils.common.text.converters import to_native
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
try: try:
from urllib import quote_plus # Python 2.X from urllib import quote_plus # Python 2.X
except ImportError: except ImportError:
@@ -90,7 +91,7 @@ def gitlabAuthentication(module):
# python-gitlab library remove support for username/password authentication since 1.13.0 # python-gitlab library remove support for username/password authentication since 1.13.0
# Changelog : https://github.com/python-gitlab/python-gitlab/releases/tag/v1.13.0 # Changelog : https://github.com/python-gitlab/python-gitlab/releases/tag/v1.13.0
# This condition allow to still support older version of the python-gitlab library # This condition allow to still support older version of the python-gitlab library
if StrictVersion(gitlab.__version__) < StrictVersion("1.13.0"): if LooseVersion(gitlab.__version__) < LooseVersion("1.13.0"):
gitlab_instance = gitlab.Gitlab(url=gitlab_url, ssl_verify=validate_certs, email=gitlab_user, password=gitlab_password, gitlab_instance = gitlab.Gitlab(url=gitlab_url, ssl_verify=validate_certs, email=gitlab_user, password=gitlab_password,
private_token=gitlab_token, api_version=4) private_token=gitlab_token, api_version=4)
else: else:

View File

@@ -9,7 +9,8 @@ __metaclass__ = type
import traceback import traceback
from ansible.module_utils.basic import missing_required_lib from ansible.module_utils.basic import missing_required_lib
from distutils.version import LooseVersion
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
REQUESTS_IMP_ERR = None REQUESTS_IMP_ERR = None
try: try:

View File

@@ -0,0 +1,17 @@
# -*- coding: utf-8 -*-
# Copyright: (c) 2021, Felix Fontein <felix@fontein.de>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
"""Provide version object to compare version numbers."""
from __future__ import absolute_import, division, print_function
__metaclass__ = type
# Once we drop support for Ansible 2.9, ansible-base 2.10, and ansible-core 2.11, we can
# remove the _version.py file, and replace the following import by
#
# from ansible.module_utils.compat.version import LooseVersion
from ._version import LooseVersion

View File

@@ -120,7 +120,7 @@ __version__ = '${version}'
import os import os
import traceback import traceback
from distutils.version import LooseVersion from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
REQUESTS_IMP_ERR = None REQUESTS_IMP_ERR = None
try: try:

View File

@@ -161,7 +161,8 @@ __version__ = '${version}'
import json import json
import os import os
import traceback import traceback
from distutils.version import LooseVersion
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
REQUESTS_IMP_ERR = None REQUESTS_IMP_ERR = None
try: try:

View File

@@ -89,7 +89,8 @@ __version__ = '${version}'
import os import os
import traceback import traceback
from distutils.version import LooseVersion
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
REQUESTS_IMP_ERR = None REQUESTS_IMP_ERR = None
try: try:
@@ -132,8 +133,7 @@ class ClcBlueprintPackage:
self.module.fail_json(msg=missing_required_lib('clc-sdk'), exception=CLC_IMP_ERR) self.module.fail_json(msg=missing_required_lib('clc-sdk'), exception=CLC_IMP_ERR)
if not REQUESTS_FOUND: if not REQUESTS_FOUND:
self.module.fail_json(msg=missing_required_lib('requests'), exception=REQUESTS_IMP_ERR) self.module.fail_json(msg=missing_required_lib('requests'), exception=REQUESTS_IMP_ERR)
if requests.__version__ and LooseVersion( if requests.__version__ and LooseVersion(requests.__version__) < LooseVersion('2.5.0'):
requests.__version__) < LooseVersion('2.5.0'):
self.module.fail_json( self.module.fail_json(
msg='requests library version should be >= 2.5.0') msg='requests library version should be >= 2.5.0')

View File

@@ -162,7 +162,8 @@ import os
import traceback import traceback
from ansible.module_utils.six.moves.urllib.parse import urlparse from ansible.module_utils.six.moves.urllib.parse import urlparse
from time import sleep from time import sleep
from distutils.version import LooseVersion
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
REQUESTS_IMP_ERR = None REQUESTS_IMP_ERR = None
try: try:
@@ -203,8 +204,7 @@ class ClcFirewallPolicy:
self.module.fail_json(msg=missing_required_lib('clc-sdk'), exception=CLC_IMP_ERR) self.module.fail_json(msg=missing_required_lib('clc-sdk'), exception=CLC_IMP_ERR)
if not REQUESTS_FOUND: if not REQUESTS_FOUND:
self.module.fail_json(msg=missing_required_lib('requests'), exception=REQUESTS_IMP_ERR) self.module.fail_json(msg=missing_required_lib('requests'), exception=REQUESTS_IMP_ERR)
if requests.__version__ and LooseVersion( if requests.__version__ and LooseVersion(requests.__version__) < LooseVersion('2.5.0'):
requests.__version__) < LooseVersion('2.5.0'):
self.module.fail_json( self.module.fail_json(
msg='requests library version should be >= 2.5.0') msg='requests library version should be >= 2.5.0')

View File

@@ -207,7 +207,8 @@ __version__ = '${version}'
import os import os
import traceback import traceback
from distutils.version import LooseVersion
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
REQUESTS_IMP_ERR = None REQUESTS_IMP_ERR = None
try: try:

View File

@@ -210,7 +210,8 @@ import json
import os import os
import traceback import traceback
from time import sleep from time import sleep
from distutils.version import LooseVersion
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
REQUESTS_IMP_ERR = None REQUESTS_IMP_ERR = None
try: try:
@@ -255,8 +256,7 @@ class ClcLoadBalancer:
self.module.fail_json(msg=missing_required_lib('clc-sdk'), exception=CLC_IMP_ERR) self.module.fail_json(msg=missing_required_lib('clc-sdk'), exception=CLC_IMP_ERR)
if not REQUESTS_FOUND: if not REQUESTS_FOUND:
self.module.fail_json(msg=missing_required_lib('requests'), exception=REQUESTS_IMP_ERR) self.module.fail_json(msg=missing_required_lib('requests'), exception=REQUESTS_IMP_ERR)
if requests.__version__ and LooseVersion( if requests.__version__ and LooseVersion(requests.__version__) < LooseVersion('2.5.0'):
requests.__version__) < LooseVersion('2.5.0'):
self.module.fail_json( self.module.fail_json(
msg='requests library version should be >= 2.5.0') msg='requests library version should be >= 2.5.0')

View File

@@ -311,7 +311,8 @@ __version__ = '${version}'
import json import json
import os import os
import traceback import traceback
from distutils.version import LooseVersion
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
REQUESTS_IMP_ERR = None REQUESTS_IMP_ERR = None
try: try:
@@ -355,8 +356,7 @@ class ClcModifyServer:
self.module.fail_json(msg=missing_required_lib('clc-sdk'), exception=CLC_IMP_ERR) self.module.fail_json(msg=missing_required_lib('clc-sdk'), exception=CLC_IMP_ERR)
if not REQUESTS_FOUND: if not REQUESTS_FOUND:
self.module.fail_json(msg=missing_required_lib('requests'), exception=REQUESTS_IMP_ERR) self.module.fail_json(msg=missing_required_lib('requests'), exception=REQUESTS_IMP_ERR)
if requests.__version__ and LooseVersion( if requests.__version__ and LooseVersion(requests.__version__) < LooseVersion('2.5.0'):
requests.__version__) < LooseVersion('2.5.0'):
self.module.fail_json( self.module.fail_json(
msg='requests library version should be >= 2.5.0') msg='requests library version should be >= 2.5.0')

View File

@@ -117,7 +117,8 @@ __version__ = '${version}'
import os import os
import traceback import traceback
from distutils.version import LooseVersion
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
REQUESTS_IMP_ERR = None REQUESTS_IMP_ERR = None
try: try:

View File

@@ -433,7 +433,8 @@ import json
import os import os
import time import time
import traceback import traceback
from distutils.version import LooseVersion
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
REQUESTS_IMP_ERR = None REQUESTS_IMP_ERR = None
try: try:
@@ -478,8 +479,7 @@ class ClcServer:
self.module.fail_json(msg=missing_required_lib('clc-sdk'), exception=CLC_IMP_ERR) self.module.fail_json(msg=missing_required_lib('clc-sdk'), exception=CLC_IMP_ERR)
if not REQUESTS_FOUND: if not REQUESTS_FOUND:
self.module.fail_json(msg=missing_required_lib('requests'), exception=REQUESTS_IMP_ERR) self.module.fail_json(msg=missing_required_lib('requests'), exception=REQUESTS_IMP_ERR)
if requests.__version__ and LooseVersion( if requests.__version__ and LooseVersion(requests.__version__) < LooseVersion('2.5.0'):
requests.__version__) < LooseVersion('2.5.0'):
self.module.fail_json( self.module.fail_json(
msg='requests library version should be >= 2.5.0') msg='requests library version should be >= 2.5.0')

View File

@@ -101,7 +101,8 @@ __version__ = '${version}'
import os import os
import traceback import traceback
from distutils.version import LooseVersion
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
REQUESTS_IMP_ERR = None REQUESTS_IMP_ERR = None
try: try:
@@ -145,8 +146,7 @@ class ClcSnapshot:
self.module.fail_json(msg=missing_required_lib('clc-sdk'), exception=CLC_IMP_ERR) self.module.fail_json(msg=missing_required_lib('clc-sdk'), exception=CLC_IMP_ERR)
if not REQUESTS_FOUND: if not REQUESTS_FOUND:
self.module.fail_json(msg=missing_required_lib('requests'), exception=REQUESTS_IMP_ERR) self.module.fail_json(msg=missing_required_lib('requests'), exception=REQUESTS_IMP_ERR)
if requests.__version__ and LooseVersion( if requests.__version__ and LooseVersion(requests.__version__) < LooseVersion('2.5.0'):
requests.__version__) < LooseVersion('2.5.0'):
self.module.fail_json( self.module.fail_json(
msg='requests library version should be >= 2.5.0') msg='requests library version should be >= 2.5.0')

View File

@@ -363,7 +363,8 @@ EXAMPLES = r'''
import time import time
import traceback import traceback
from distutils.version import LooseVersion
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
try: try:
from proxmoxer import ProxmoxAPI from proxmoxer import ProxmoxAPI

View File

@@ -761,9 +761,10 @@ msg:
import re import re
import time import time
import traceback import traceback
from distutils.version import LooseVersion
from ansible.module_utils.six.moves.urllib.parse import quote from ansible.module_utils.six.moves.urllib.parse import quote
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
try: try:
from proxmoxer import ProxmoxAPI from proxmoxer import ProxmoxAPI
HAS_PROXMOXER = True HAS_PROXMOXER = True

View File

@@ -230,11 +230,12 @@ command:
import os import os
import json import json
import tempfile import tempfile
from distutils.version import LooseVersion
from ansible.module_utils.six.moves import shlex_quote from ansible.module_utils.six.moves import shlex_quote
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
module = None module = None

View File

@@ -97,7 +97,7 @@ EXAMPLES = '''
register: my_volume register: my_volume
''' '''
from distutils.version import LooseVersion from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
try: try:
import pyrax import pyrax

View File

@@ -75,7 +75,7 @@ def patch_user_data(compute_api, server_id, key, value):
compute_api.module.debug("Starting patching user_data attributes") compute_api.module.debug("Starting patching user_data attributes")
path = "servers/%s/user_data/%s" % (server_id, key) path = "servers/%s/user_data/%s" % (server_id, key)
response = compute_api.patch(path=path, data=value, headers={"Content-type": "text/plain"}) response = compute_api.patch(path=path, data=value, headers={"Content-Type": "text/plain"})
if not response.ok: if not response.ok:
msg = 'Error during user_data patching: %s %s' % (response.status_code, response.body) msg = 'Error during user_data patching: %s %s' % (response.status_code, response.body)
compute_api.module.fail_json(msg=msg) compute_api.module.fail_json(msg=msg)

View File

@@ -117,9 +117,10 @@ state:
''' '''
import os import os
from distutils.version import LooseVersion
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
PACKAGE_STATE_MAP = dict( PACKAGE_STATE_MAP = dict(
present="--install", present="--install",

View File

@@ -356,9 +356,10 @@ import os
import re import re
import traceback import traceback
from distutils.version import LooseVersion
from io import BytesIO from io import BytesIO
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
LXML_IMP_ERR = None LXML_IMP_ERR = None
try: try:
from lxml import etree, objectify from lxml import etree, objectify

View File

@@ -74,11 +74,12 @@ subca:
type: dict type: dict
''' '''
from distutils.version import LooseVersion
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.ipa import IPAClient, ipa_argument_spec from ansible_collections.community.general.plugins.module_utils.ipa import IPAClient, ipa_argument_spec
from ansible.module_utils.common.text.converters import to_native from ansible.module_utils.common.text.converters import to_native
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
class SubCAIPAClient(IPAClient): class SubCAIPAClient(IPAClient):
def __init__(self, module, host, port, protocol): def __init__(self, module, host, port, protocol):

View File

@@ -143,7 +143,8 @@ annotation:
import json import json
import time import time
import traceback import traceback
from distutils.version import LooseVersion
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
REQUESTS_IMP_ERR = None REQUESTS_IMP_ERR = None
try: try:

View File

@@ -146,9 +146,10 @@ EXAMPLES = '''
RETURN = r"""# """ RETURN = r"""# """
import traceback import traceback
from distutils.version import LooseVersion
import re import re
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
class DNSimpleV1(): class DNSimpleV1():
"""class which uses dnsimple-python < 2""" """class which uses dnsimple-python < 2"""

View File

@@ -124,7 +124,8 @@ import os
import ssl import ssl
import traceback import traceback
import platform import platform
from distutils.version import LooseVersion
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
HAS_PAHOMQTT = True HAS_PAHOMQTT = True
PAHOMQTT_IMP_ERR = None PAHOMQTT_IMP_ERR = None
@@ -207,7 +208,7 @@ def main():
if tls_version: if tls_version:
tls_version = tls_map.get(tls_version, ssl.PROTOCOL_SSLv23) tls_version = tls_map.get(tls_version, ssl.PROTOCOL_SSLv23)
else: else:
if LooseVersion(platform.python_version()) <= "3.5.2": if LooseVersion(platform.python_version()) <= LooseVersion("3.5.2"):
# Specifying `None` on later versions of python seems sufficient to # Specifying `None` on later versions of python seems sufficient to
# instruct python to autonegotiate the SSL/TLS connection. On versions # instruct python to autonegotiate the SSL/TLS connection. On versions
# 3.5.2 and lower though we need to specify the version. # 3.5.2 and lower though we need to specify the version.

View File

@@ -124,7 +124,7 @@ EXAMPLES = r'''
import os import os
import traceback import traceback
from distutils.version import LooseVersion from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
SENDGRID_IMP_ERR = None SENDGRID_IMP_ERR = None
try: try:

View File

@@ -346,7 +346,7 @@ def build_payload_for_slack(text, channel, thread_id, username, icon_url, icon_e
def get_slack_message(module, token, channel, ts): def get_slack_message(module, token, channel, ts):
headers = { headers = {
'Content-Type': 'application/json', 'Content-Type': 'application/json; charset=UTF-8',
'Accept': 'application/json', 'Accept': 'application/json',
'Authorization': 'Bearer ' + token 'Authorization': 'Bearer ' + token
} }
@@ -383,7 +383,7 @@ def do_notify_slack(module, domain, token, payload):
slack_uri = OLD_SLACK_INCOMING_WEBHOOK % (domain, token) slack_uri = OLD_SLACK_INCOMING_WEBHOOK % (domain, token)
headers = { headers = {
'Content-Type': 'application/json', 'Content-Type': 'application/json; charset=UTF-8',
'Accept': 'application/json', 'Accept': 'application/json',
} }
if use_webapi: if use_webapi:

View File

@@ -152,11 +152,11 @@ stdout:
sample: "org.gnome.Calendar/x86_64/stable\tcurrent\norg.gnome.gitg/x86_64/stable\tcurrent\n" sample: "org.gnome.Calendar/x86_64/stable\tcurrent\norg.gnome.gitg/x86_64/stable\tcurrent\n"
''' '''
from distutils.version import StrictVersion
from ansible.module_utils.six.moves.urllib.parse import urlparse from ansible.module_utils.six.moves.urllib.parse import urlparse
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
OUTDATED_FLATPAK_VERSION_ERROR_MESSAGE = "Unknown option --columns=application" OUTDATED_FLATPAK_VERSION_ERROR_MESSAGE = "Unknown option --columns=application"
@@ -172,7 +172,7 @@ def install_flat(module, binary, remote, names, method, no_dependencies):
id_names.append(name) id_names.append(name)
base_command = [binary, "install", "--{0}".format(method)] base_command = [binary, "install", "--{0}".format(method)]
flatpak_version = _flatpak_version(module, binary) flatpak_version = _flatpak_version(module, binary)
if StrictVersion(flatpak_version) < StrictVersion('1.1.3'): if LooseVersion(flatpak_version) < LooseVersion('1.1.3'):
base_command += ["-y"] base_command += ["-y"]
else: else:
base_command += ["--noninteractive"] base_command += ["--noninteractive"]
@@ -196,7 +196,7 @@ def uninstall_flat(module, binary, names, method):
] ]
command = [binary, "uninstall"] command = [binary, "uninstall"]
flatpak_version = _flatpak_version(module, binary) flatpak_version = _flatpak_version(module, binary)
if StrictVersion(flatpak_version) < StrictVersion('1.1.3'): if LooseVersion(flatpak_version) < LooseVersion('1.1.3'):
command += ["-y"] command += ["-y"]
else: else:
command += ["--noninteractive"] command += ["--noninteractive"]

View File

@@ -140,7 +140,8 @@ EXAMPLES = '''
import os import os
import re import re
import tempfile import tempfile
from distutils import version
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
from ansible.module_utils.common.text.converters import to_bytes from ansible.module_utils.common.text.converters import to_bytes
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
@@ -493,7 +494,7 @@ class HomebrewCask(object):
def _brew_cask_command_is_deprecated(self): def _brew_cask_command_is_deprecated(self):
# The `brew cask` replacements were fully available in 2.6.0 (https://brew.sh/2020/12/01/homebrew-2.6.0/) # The `brew cask` replacements were fully available in 2.6.0 (https://brew.sh/2020/12/01/homebrew-2.6.0/)
return version.LooseVersion(self._get_brew_version()) >= version.LooseVersion('2.6.0') return LooseVersion(self._get_brew_version()) >= LooseVersion('2.6.0')
# /checks ------------------------------------------------------ }}} # /checks ------------------------------------------------------ }}}
# commands ----------------------------------------------------- {{{ # commands ----------------------------------------------------- {{{

View File

@@ -97,9 +97,10 @@ RETURN = r''' # '''
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.common.text.converters import to_native from ansible.module_utils.common.text.converters import to_native
from distutils.version import StrictVersion
import os import os
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
class Mas(object): class Mas(object):
@@ -145,7 +146,7 @@ class Mas(object):
# Is the version recent enough? # Is the version recent enough?
rc, out, err = self.run(['version']) rc, out, err = self.run(['version'])
if rc != 0 or not out.strip() or StrictVersion(out.strip()) < StrictVersion('1.5.0'): if rc != 0 or not out.strip() or LooseVersion(out.strip()) < LooseVersion('1.5.0'):
self.module.fail_json(msg='`mas` tool in version 1.5.0+ needed, got ' + out.strip()) self.module.fail_json(msg='`mas` tool in version 1.5.0+ needed, got ' + out.strip())
def check_signin(self): def check_signin(self):

View File

@@ -135,10 +135,10 @@ import re
import shlex import shlex
import sqlite3 import sqlite3
from distutils.version import StrictVersion
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
# Function used for executing commands. # Function used for executing commands.
def execute_command(cmd, module): def execute_command(cmd, module):
@@ -435,7 +435,7 @@ def parse_package_name(names, pkg_spec, module):
if pkg_spec[name]['branch']: if pkg_spec[name]['branch']:
branch_release = "6.0" branch_release = "6.0"
if StrictVersion(platform.release()) < StrictVersion(branch_release): if LooseVersion(platform.release()) < LooseVersion(branch_release):
module.fail_json(msg="package name using 'branch' syntax requires at least OpenBSD %s: %s" % (branch_release, name)) module.fail_json(msg="package name using 'branch' syntax requires at least OpenBSD %s: %s" % (branch_release, name))
# Sanity check that there are no trailing dashes in flavor. # Sanity check that there are no trailing dashes in flavor.

View File

@@ -133,8 +133,6 @@ except ImportError:
XML_IMP_ERR = traceback.format_exc() XML_IMP_ERR = traceback.format_exc()
HAS_XML = False HAS_XML = False
from distutils.version import LooseVersion
from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils.urls import fetch_url from ansible.module_utils.urls import fetch_url
@@ -142,6 +140,8 @@ from ansible.module_utils.common.text.converters import to_text
from ansible.module_utils.six.moves import configparser, StringIO from ansible.module_utils.six.moves import configparser, StringIO
from io import open from io import open
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
REPO_OPTS = ['alias', 'name', 'priority', 'enabled', 'autorefresh', 'gpgcheck'] REPO_OPTS = ['alias', 'name', 'priority', 'enabled', 'autorefresh', 'gpgcheck']

View File

@@ -77,7 +77,8 @@ import traceback
from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils.api import basic_auth_argument_spec from ansible.module_utils.api import basic_auth_argument_spec
from distutils.version import LooseVersion
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
GITLAB_IMP_ERR = None GITLAB_IMP_ERR = None
try: try:

View File

@@ -104,7 +104,7 @@ def main():
# available alternatives # available alternatives
current_path_regex = re.compile(r'^\s*link currently points to (.*)$', current_path_regex = re.compile(r'^\s*link currently points to (.*)$',
re.MULTILINE) re.MULTILINE)
alternative_regex = re.compile(r'^(\/.*)\s-\spriority', re.MULTILINE) alternative_regex = re.compile(r'^(\/.*)\s-\s(?:family\s\S+\s)?priority', re.MULTILINE)
match = current_path_regex.search(display_output) match = current_path_regex.search(display_output)
if match: if match:

View File

@@ -158,11 +158,12 @@ diversion:
import re import re
import os import os
from distutils.version import LooseVersion
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.common.text.converters import to_bytes, to_native from ansible.module_utils.common.text.converters import to_bytes, to_native
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
def diversion_state(module, command, path): def diversion_state(module, command, path):
diversion = dict(path=path, state='absent', divert=None, holder=None) diversion = dict(path=path, state='absent', divert=None, holder=None)

View File

@@ -115,7 +115,6 @@ EXAMPLES = '''
fstype: vfat fstype: vfat
''' '''
from distutils.version import LooseVersion
import os import os
import platform import platform
import re import re
@@ -124,6 +123,8 @@ import stat
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.common.text.converters import to_native from ansible.module_utils.common.text.converters import to_native
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
class Device(object): class Device(object):
def __init__(self, module, path): def __init__(self, module, path):

View File

@@ -56,13 +56,14 @@ pids:
import abc import abc
import re import re
from distutils.version import LooseVersion
from os.path import basename from os.path import basename
from ansible.module_utils import six from ansible.module_utils import six
from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils.common.text.converters import to_native from ansible.module_utils.common.text.converters import to_native
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
try: try:
import psutil import psutil

View File

@@ -91,7 +91,7 @@ import operator
HAS_DISTUTILS = False HAS_DISTUTILS = False
try: try:
import pkg_resources import pkg_resources
from distutils.version import LooseVersion from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
HAS_DISTUTILS = True HAS_DISTUTILS = True
except ImportError: except ImportError:
pass pass

View File

@@ -95,10 +95,11 @@ EXAMPLES = """
import os import os
import tempfile import tempfile
import traceback import traceback
from distutils.version import LooseVersion
from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils.common.text.converters import to_native from ansible.module_utils.common.text.converters import to_native
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
PASSLIB_IMP_ERR = None PASSLIB_IMP_ERR = None
try: try:
from passlib.apache import HtpasswdFile, htpasswd_context from passlib.apache import HtpasswdFile, htpasswd_context

View File

@@ -669,7 +669,14 @@ class JIRA(StateModuleHelper):
try: try:
error = json.loads(info['body']) error = json.loads(info['body'])
except Exception: except Exception:
self.module.fail_json(msg=to_native(info['body']), exception=traceback.format_exc()) msg = 'The request "{method} {url}" returned the unexpected status code {status} {msg}\n{body}'.format(
status=info['status'],
msg=info['msg'],
body=info.get('body'),
url=url,
method=method,
)
self.module.fail_json(msg=to_native(msg), exception=traceback.format_exc())
if error: if error:
msg = [] msg = []
for key in ('errorMessages', 'errors'): for key in ('errorMessages', 'errors'):

View File

@@ -8,7 +8,7 @@
state: present state: present
# xfsprogs on OpenSUSE requires Python 3, skip this for our newer Py2 OpenSUSE builds # xfsprogs on OpenSUSE requires Python 3, skip this for our newer Py2 OpenSUSE builds
when: not (item == 'xfsprogs' and ansible_os_family == 'Suse' and ansible_python.version.major == 2 and ansible_distribution_major_version|int != 42) when: not (item == 'xfsprogs' and ansible_os_family == 'Suse' and ansible_python.version.major == 2 and ansible_distribution_major_version|int != 42)
with_items: loop:
- e2fsprogs - e2fsprogs
- xfsprogs - xfsprogs
@@ -32,12 +32,11 @@
- name: "Install btrfs progs (OpenSuse)" - name: "Install btrfs progs (OpenSuse)"
ansible.builtin.package: ansible.builtin.package:
name: '{{ item }}' name:
- python{{ ansible_python.version.major }}-xml
- btrfsprogs
state: present state: present
when: ansible_os_family == 'Suse' when: ansible_os_family == 'Suse'
with_items:
- python{{ ansible_python.version.major }}-xml
- btrfsprogs
- name: "Install reiserfs utils (Fedora)" - name: "Install reiserfs utils (Fedora)"
ansible.builtin.package: ansible.builtin.package:
@@ -46,9 +45,11 @@
when: when:
- ansible_distribution == 'Fedora' and (ansible_facts.distribution_major_version | int < 35) - ansible_distribution == 'Fedora' and (ansible_facts.distribution_major_version | int < 35)
- name: "Install reiserfs (OpenSuse)" - name: "Install reiserfs and util-linux-systemd (for findmnt) (OpenSuse)"
ansible.builtin.package: ansible.builtin.package:
name: reiserfs name:
- reiserfs
- util-linux-systemd
state: present state: present
when: when:
- ansible_os_family == 'Suse' - ansible_os_family == 'Suse'
@@ -100,10 +101,9 @@
- name: "Install dosfstools and lvm2 (Linux)" - name: "Install dosfstools and lvm2 (Linux)"
ansible.builtin.package: ansible.builtin.package:
name: '{{ item }}' name:
with_items: - dosfstools
- dosfstools - lvm2
- lvm2
when: ansible_system == 'Linux' when: ansible_system == 'Linux'
- name: "Install fatresize and get version" - name: "Install fatresize and get version"

View File

@@ -0,0 +1,3 @@
dependencies:
- setup_pkg_mgr
- setup_epel

View File

@@ -0,0 +1 @@
nothing.yml

View File

@@ -0,0 +1 @@
nothing.yml

View File

@@ -0,0 +1,23 @@
---
####################################################################
# WARNING: These are designed specifically for Ansible tests #
# and should not be used as examples of how to write Ansible roles #
####################################################################
- name: Print information on which we distinguish
debug:
msg: "Distribution '{{ ansible_facts.distribution }}', version '{{ ansible_facts.distribution_version }}', OS family '{{ ansible_facts.os_family }}'"
- name: Include distribution specific tasks
include_tasks: "{{ lookup('first_found', params) }}"
vars:
params:
files:
- "D-{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_version }}.yml"
- "D-{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_major_version }}.yml"
- "{{ ansible_facts.os_family }}-{{ ansible_facts.distribution_major_version }}.yml"
- "D-{{ ansible_facts.distribution }}.yml"
- "{{ ansible_facts.os_family }}.yml"
- "nothing.yml"
paths:
- "{{ role_path }}/tasks"

View File

@@ -1,3 +1,2 @@
dependencies: dependencies:
- setup_pkg_mgr - setup_snap
- setup_epel

View File

@@ -4,19 +4,6 @@
# and should not be used as examples of how to write Ansible roles # # and should not be used as examples of how to write Ansible roles #
#################################################################### ####################################################################
- name: Include distribution specific tasks
include_tasks: "{{ lookup('first_found', params) }}"
vars:
params:
files:
- "{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_major_version }}.yml"
- "{{ ansible_facts.os_family }}-{{ ansible_facts.distribution_major_version }}.yml"
- "{{ ansible_facts.distribution }}.yml"
- "{{ ansible_facts.os_family }}.yml"
- "nothing.yml"
paths:
- "{{ role_path }}/tasks"
- block: - block:
- name: Make sure package is not installed - name: Make sure package is not installed
community.general.snap: community.general.snap:

View File

@@ -56,7 +56,7 @@ FILENAME = '.github/BOTMETA.yml'
LIST_ENTRIES = frozenset(('supershipit', 'maintainers', 'labels', 'keywords', 'notify', 'ignore')) LIST_ENTRIES = frozenset(('supershipit', 'maintainers', 'labels', 'keywords', 'notify', 'ignore'))
AUTHOR_REGEX = re.compile(r'^\w.*\(@([\w-]+)\)(?![\w.])$') AUTHOR_REGEX = re.compile(r'^\w.*\(@([\w-]+)\)(?![\w.])')
def read_authors(filename): def read_authors(filename):

View File

@@ -17,6 +17,10 @@ fi
stage="${S:-prod}" stage="${S:-prod}"
provider="${P:-default}" provider="${P:-default}"
if [ "${platform}" == "rhel" ] && [[ "${version}" =~ ^8 ]]; then
echo "pynacl >= 1.4.0, < 1.5.0; python_version == '3.6'" >> tests/utils/constraints.txt
fi
# shellcheck disable=SC2086 # shellcheck disable=SC2086
ansible-test integration --color -v --retry-on-error "${target}" ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} ${UNSTABLE:+"$UNSTABLE"} \ ansible-test integration --color -v --retry-on-error "${target}" ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} ${UNSTABLE:+"$UNSTABLE"} \
--remote "${platform}/${version}" --remote-terminate always --remote-stage "${stage}" --remote-provider "${provider}" --remote "${platform}/${version}" --remote-terminate always --remote-stage "${stage}" --remote-provider "${provider}"

View File

@@ -22,7 +22,13 @@ esac
ansible-test env --timeout "${timeout}" --color -v ansible-test env --timeout "${timeout}" --color -v
if [ "$2" == "2.9" ]; then
# 1.5.0+ will not install for Python 3.6+ in the 2.9 setting (due to `enum` being installed)
echo "pynacl >= 1.4.0, < 1.5.0; python_version >= '3.6'" >> tests/unit/requirements.txt
fi
if [ "$2" == "2.10" ]; then if [ "$2" == "2.10" ]; then
sed -i -E 's/^redis($| .*)/redis < 4.1.0/g' tests/unit/requirements.txt
sed -i -E 's/^python-gitlab($| .*)/python-gitlab < 2.10.1 ; python_version >= '\'3.6\''/g' tests/unit/requirements.txt sed -i -E 's/^python-gitlab($| .*)/python-gitlab < 2.10.1 ; python_version >= '\'3.6\''/g' tests/unit/requirements.txt
echo "python-gitlab ; python_version < '3.6'" >> tests/unit/requirements.txt echo "python-gitlab ; python_version < '3.6'" >> tests/unit/requirements.txt
fi fi