ansible-core 2.17.3__py3-none-any.whl → 2.17.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ansible-core might be problematic. Click here for more details.
- ansible/config/base.yml +1 -1
- ansible/executor/task_executor.py +9 -5
- ansible/module_utils/ansible_release.py +1 -1
- ansible/module_utils/basic.py +5 -1
- ansible/parsing/dataloader.py +4 -5
- ansible/playbook/task.py +5 -0
- ansible/playbook/task_include.py +1 -1
- ansible/plugins/__init__.py +10 -3
- ansible/plugins/connection/psrp.py +22 -17
- ansible/plugins/connection/ssh.py +1 -1
- ansible/plugins/lookup/csvfile.py +20 -0
- ansible/plugins/shell/powershell.py +43 -8
- ansible/plugins/strategy/__init__.py +1 -5
- ansible/plugins/strategy/free.py +5 -1
- ansible/release.py +1 -1
- ansible/utils/version.py +1 -0
- {ansible_core-2.17.3.dist-info → ansible_core-2.17.4.dist-info}/METADATA +1 -1
- {ansible_core-2.17.3.dist-info → ansible_core-2.17.4.dist-info}/RECORD +24 -24
- ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +3 -1
- {ansible_core-2.17.3.data → ansible_core-2.17.4.data}/scripts/ansible-test +0 -0
- {ansible_core-2.17.3.dist-info → ansible_core-2.17.4.dist-info}/COPYING +0 -0
- {ansible_core-2.17.3.dist-info → ansible_core-2.17.4.dist-info}/WHEEL +0 -0
- {ansible_core-2.17.3.dist-info → ansible_core-2.17.4.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.17.3.dist-info → ansible_core-2.17.4.dist-info}/top_level.txt +0 -0
ansible/config/base.yml
CHANGED
|
@@ -948,7 +948,7 @@ DEFAULT_PRIVATE_ROLE_VARS:
|
|
|
948
948
|
- This was introduced as a way to reset role variables to default values if a role is used more than once
|
|
949
949
|
in a playbook.
|
|
950
950
|
- Starting in version '2.17' M(ansible.builtin.include_roles) and M(ansible.builtin.import_roles) can
|
|
951
|
-
|
|
951
|
+
individually override this via the C(public) parameter.
|
|
952
952
|
- Included roles only make their variables public at execution, unlike imported roles which happen at playbook compile time.
|
|
953
953
|
env: [{name: ANSIBLE_PRIVATE_ROLE_VARS}]
|
|
954
954
|
ini:
|
|
@@ -31,7 +31,7 @@ from ansible.utils.listify import listify_lookup_plugin_terms
|
|
|
31
31
|
from ansible.utils.unsafe_proxy import to_unsafe_text, wrap_var
|
|
32
32
|
from ansible.vars.clean import namespace_facts, clean_facts
|
|
33
33
|
from ansible.utils.display import Display
|
|
34
|
-
from ansible.utils.vars import combine_vars
|
|
34
|
+
from ansible.utils.vars import combine_vars
|
|
35
35
|
|
|
36
36
|
display = Display()
|
|
37
37
|
|
|
@@ -332,6 +332,13 @@ class TaskExecutor:
|
|
|
332
332
|
(self._task, tmp_task) = (tmp_task, self._task)
|
|
333
333
|
(self._play_context, tmp_play_context) = (tmp_play_context, self._play_context)
|
|
334
334
|
res = self._execute(variables=task_vars)
|
|
335
|
+
|
|
336
|
+
if self._task.register:
|
|
337
|
+
# Ensure per loop iteration results are registered in case `_execute()`
|
|
338
|
+
# returns early (when conditional, failure, ...).
|
|
339
|
+
# This is needed in case the registered variable is used in the loop label template.
|
|
340
|
+
task_vars[self._task.register] = res
|
|
341
|
+
|
|
335
342
|
task_fields = self._task.dump_attrs()
|
|
336
343
|
(self._task, tmp_task) = (tmp_task, self._task)
|
|
337
344
|
(self._play_context, tmp_play_context) = (tmp_play_context, self._play_context)
|
|
@@ -657,9 +664,6 @@ class TaskExecutor:
|
|
|
657
664
|
# update the local copy of vars with the registered value, if specified,
|
|
658
665
|
# or any facts which may have been generated by the module execution
|
|
659
666
|
if self._task.register:
|
|
660
|
-
if not isidentifier(self._task.register):
|
|
661
|
-
raise AnsibleError("Invalid variable name in 'register' specified: '%s'" % self._task.register)
|
|
662
|
-
|
|
663
667
|
vars_copy[self._task.register] = result
|
|
664
668
|
|
|
665
669
|
if self._task.async_val > 0:
|
|
@@ -1048,7 +1052,7 @@ class TaskExecutor:
|
|
|
1048
1052
|
# add extras if plugin supports them
|
|
1049
1053
|
if getattr(self._connection, 'allow_extras', False):
|
|
1050
1054
|
for k in variables:
|
|
1051
|
-
if k.startswith('ansible_%s_' % self._connection.
|
|
1055
|
+
if k.startswith('ansible_%s_' % self._connection.extras_prefix) and k not in options:
|
|
1052
1056
|
options['_extras'][k] = templar.template(variables[k])
|
|
1053
1057
|
|
|
1054
1058
|
task_keys = self._task.dump_attrs()
|
ansible/module_utils/basic.py
CHANGED
|
@@ -1686,8 +1686,12 @@ class AnsibleModule(object):
|
|
|
1686
1686
|
umask = os.umask(0)
|
|
1687
1687
|
os.umask(umask)
|
|
1688
1688
|
os.chmod(b_dest, S_IRWU_RWG_RWO & ~umask)
|
|
1689
|
+
dest_dir_stat = os.stat(os.path.dirname(b_dest))
|
|
1689
1690
|
try:
|
|
1690
|
-
|
|
1691
|
+
if dest_dir_stat.st_mode & stat.S_ISGID:
|
|
1692
|
+
os.chown(b_dest, os.geteuid(), dest_dir_stat.st_gid)
|
|
1693
|
+
else:
|
|
1694
|
+
os.chown(b_dest, os.geteuid(), os.getegid())
|
|
1691
1695
|
except OSError:
|
|
1692
1696
|
# We're okay with trying our best here. If the user is not
|
|
1693
1697
|
# root (or old Unices) they won't be able to chown.
|
ansible/parsing/dataloader.py
CHANGED
|
@@ -329,11 +329,10 @@ class DataLoader:
|
|
|
329
329
|
if (is_role or self._is_role(path)) and b_pb_base_dir.endswith(b'/tasks'):
|
|
330
330
|
search.append(os.path.join(os.path.dirname(b_pb_base_dir), b_dirname, b_source))
|
|
331
331
|
search.append(os.path.join(b_pb_base_dir, b_source))
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
search.append(os.path.join(b_upath, b_source))
|
|
332
|
+
# don't add dirname if user already is using it in source
|
|
333
|
+
if b_source.split(b'/')[0] != dirname:
|
|
334
|
+
search.append(os.path.join(b_upath, b_dirname, b_source))
|
|
335
|
+
search.append(os.path.join(b_upath, b_source))
|
|
337
336
|
|
|
338
337
|
# always append basedir as last resort
|
|
339
338
|
# don't add dirname if user already is using it in source
|
ansible/playbook/task.py
CHANGED
|
@@ -37,6 +37,7 @@ from ansible.playbook.taggable import Taggable
|
|
|
37
37
|
from ansible.utils.collection_loader import AnsibleCollectionConfig
|
|
38
38
|
from ansible.utils.display import Display
|
|
39
39
|
from ansible.utils.sentinel import Sentinel
|
|
40
|
+
from ansible.utils.vars import isidentifier
|
|
40
41
|
|
|
41
42
|
__all__ = ['Task']
|
|
42
43
|
|
|
@@ -274,6 +275,10 @@ class Task(Base, Conditional, Taggable, CollectionSearch, Notifiable, Delegatabl
|
|
|
274
275
|
if not isinstance(value, list):
|
|
275
276
|
setattr(self, name, [value])
|
|
276
277
|
|
|
278
|
+
def _validate_register(self, attr, name, value):
|
|
279
|
+
if value is not None and not isidentifier(value):
|
|
280
|
+
raise AnsibleParserError(f"Invalid variable name in 'register' specified: '{value}'")
|
|
281
|
+
|
|
277
282
|
def post_validate(self, templar):
|
|
278
283
|
'''
|
|
279
284
|
Override of base class post_validate, to also do final validation on
|
ansible/playbook/task_include.py
CHANGED
|
@@ -74,7 +74,7 @@ class TaskInclude(Task):
|
|
|
74
74
|
if not task.args.get('_raw_params'):
|
|
75
75
|
task.args['_raw_params'] = task.args.pop('file', None)
|
|
76
76
|
if not task.args['_raw_params']:
|
|
77
|
-
raise AnsibleParserError('No file specified for %s' % task.action)
|
|
77
|
+
raise AnsibleParserError('No file specified for %s' % task.action, obj=data)
|
|
78
78
|
|
|
79
79
|
apply_attrs = task.args.get('apply', {})
|
|
80
80
|
if apply_attrs and task.action not in C._ACTION_INCLUDE_TASKS:
|
ansible/plugins/__init__.py
CHANGED
|
@@ -50,16 +50,23 @@ def get_plugin_class(obj):
|
|
|
50
50
|
|
|
51
51
|
class AnsiblePlugin(ABC):
|
|
52
52
|
|
|
53
|
-
# allow extra passthrough parameters
|
|
54
|
-
allow_extras = False
|
|
55
|
-
|
|
56
53
|
# Set by plugin loader
|
|
57
54
|
_load_name: str
|
|
58
55
|
|
|
56
|
+
# allow extra passthrough parameters
|
|
57
|
+
allow_extras: bool = False
|
|
58
|
+
_extras_prefix: str | None = None
|
|
59
|
+
|
|
59
60
|
def __init__(self):
|
|
60
61
|
self._options = {}
|
|
61
62
|
self._defs = None
|
|
62
63
|
|
|
64
|
+
@property
|
|
65
|
+
def extras_prefix(self):
|
|
66
|
+
if not self._extras_prefix:
|
|
67
|
+
self._extras_prefix = self._load_name.split('.')[-1]
|
|
68
|
+
return self._extras_prefix
|
|
69
|
+
|
|
63
70
|
def matches_name(self, possible_names):
|
|
64
71
|
possible_fqcns = set()
|
|
65
72
|
for name in possible_names:
|
|
@@ -632,39 +632,41 @@ end {
|
|
|
632
632
|
buffer_size = max_b64_size - (max_b64_size % 1024)
|
|
633
633
|
|
|
634
634
|
# setup the file stream with read only mode
|
|
635
|
-
setup_script = '''$
|
|
636
|
-
$
|
|
635
|
+
setup_script = '''param([string]$Path)
|
|
636
|
+
$ErrorActionPreference = "Stop"
|
|
637
637
|
|
|
638
|
-
if (Test-Path -
|
|
638
|
+
if (Test-Path -LiteralPath $path -PathType Leaf) {
|
|
639
639
|
$fs = New-Object -TypeName System.IO.FileStream -ArgumentList @(
|
|
640
640
|
$path,
|
|
641
641
|
[System.IO.FileMode]::Open,
|
|
642
642
|
[System.IO.FileAccess]::Read,
|
|
643
643
|
[System.IO.FileShare]::Read
|
|
644
644
|
)
|
|
645
|
-
$buffer_size = %d
|
|
646
645
|
} elseif (Test-Path -Path $path -PathType Container) {
|
|
647
646
|
Write-Output -InputObject "[DIR]"
|
|
648
647
|
} else {
|
|
649
648
|
Write-Error -Message "$path does not exist"
|
|
650
649
|
$host.SetShouldExit(1)
|
|
651
|
-
}'''
|
|
650
|
+
}'''
|
|
652
651
|
|
|
653
652
|
# read the file stream at the offset and return the b64 string
|
|
654
|
-
read_script = '''$
|
|
655
|
-
$
|
|
656
|
-
$
|
|
657
|
-
$
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
653
|
+
read_script = '''param([int64]$Offset, [int]$BufferSize)
|
|
654
|
+
$ErrorActionPreference = "Stop"
|
|
655
|
+
$fs.Seek($Offset, [System.IO.SeekOrigin]::Begin) > $null
|
|
656
|
+
$buffer = New-Object -TypeName byte[] -ArgumentList $BufferSize
|
|
657
|
+
$read = $fs.Read($buffer, 0, $buffer.Length)
|
|
658
|
+
|
|
659
|
+
if ($read -gt 0) {
|
|
660
|
+
[System.Convert]::ToBase64String($buffer, 0, $read)
|
|
662
661
|
}'''
|
|
663
662
|
|
|
664
663
|
# need to run the setup script outside of the local scope so the
|
|
665
664
|
# file stream stays active between fetch operations
|
|
666
|
-
rc, stdout, stderr = self._exec_psrp_script(
|
|
667
|
-
|
|
665
|
+
rc, stdout, stderr = self._exec_psrp_script(
|
|
666
|
+
setup_script,
|
|
667
|
+
use_local_scope=False,
|
|
668
|
+
arguments=[in_path],
|
|
669
|
+
)
|
|
668
670
|
if rc != 0:
|
|
669
671
|
raise AnsibleError("failed to setup file stream for fetch '%s': %s"
|
|
670
672
|
% (out_path, to_native(stderr)))
|
|
@@ -679,7 +681,10 @@ if ($bytes_read -gt 0) {
|
|
|
679
681
|
while True:
|
|
680
682
|
display.vvvvv("PSRP FETCH %s to %s (offset=%d" %
|
|
681
683
|
(in_path, out_path, offset), host=self._psrp_host)
|
|
682
|
-
rc, stdout, stderr = self._exec_psrp_script(
|
|
684
|
+
rc, stdout, stderr = self._exec_psrp_script(
|
|
685
|
+
read_script,
|
|
686
|
+
arguments=[offset, buffer_size],
|
|
687
|
+
)
|
|
683
688
|
if rc != 0:
|
|
684
689
|
raise AnsibleError("failed to transfer file to '%s': %s"
|
|
685
690
|
% (out_path, to_native(stderr)))
|
|
@@ -813,7 +818,7 @@ if ($bytes_read -gt 0) {
|
|
|
813
818
|
script: str,
|
|
814
819
|
input_data: bytes | str | t.Iterable | None = None,
|
|
815
820
|
use_local_scope: bool = True,
|
|
816
|
-
arguments: t.Iterable[
|
|
821
|
+
arguments: t.Iterable[t.Any] | None = None,
|
|
817
822
|
) -> tuple[int, bytes, bytes]:
|
|
818
823
|
# Check if there's a command on the current pipeline that still needs to be closed.
|
|
819
824
|
if self._last_pipeline:
|
|
@@ -1250,7 +1250,7 @@ class Connection(ConnectionBase):
|
|
|
1250
1250
|
if sftp_action == 'get':
|
|
1251
1251
|
# we pass sudoable=False to disable pty allocation, which
|
|
1252
1252
|
# would end up mixing stdout/stderr and screwing with newlines
|
|
1253
|
-
(returncode, stdout, stderr) = self.exec_command('dd if=%s bs=%s' % (in_path, BUFSIZE), sudoable=False)
|
|
1253
|
+
(returncode, stdout, stderr) = self.exec_command('dd if=%s bs=%s' % (self._shell.quote(in_path), BUFSIZE), sudoable=False)
|
|
1254
1254
|
with open(to_bytes(out_path, errors='surrogate_or_strict'), 'wb+') as out_file:
|
|
1255
1255
|
out_file.write(stdout)
|
|
1256
1256
|
else:
|
|
@@ -12,6 +12,7 @@ DOCUMENTATION = r"""
|
|
|
12
12
|
- The csvfile lookup reads the contents of a file in CSV (comma-separated value) format.
|
|
13
13
|
The lookup looks for the row where the first column matches keyname (which can be multiple words)
|
|
14
14
|
and returns the value in the O(col) column (default 1, which indexed from 0 means the second column in the file).
|
|
15
|
+
- At least one keyname is required, provided as a positional argument(s) to the lookup.
|
|
15
16
|
options:
|
|
16
17
|
col:
|
|
17
18
|
description: column to return (0 indexed).
|
|
@@ -63,6 +64,22 @@ EXAMPLES = """
|
|
|
63
64
|
vars:
|
|
64
65
|
csvline: "{{ lookup('ansible.builtin.csvfile', bgp_neighbor_ip, file='bgp_neighbors.csv', delimiter=',') }}"
|
|
65
66
|
delegate_to: localhost
|
|
67
|
+
|
|
68
|
+
# Contents of debug.csv
|
|
69
|
+
# test1 ret1.1 ret2.1
|
|
70
|
+
# test2 ret1.2 ret2.2
|
|
71
|
+
# test3 ret1.3 ret2.3
|
|
72
|
+
|
|
73
|
+
- name: "Lookup multiple keynames in the first column (index 0), returning the values from the second column (index 1)"
|
|
74
|
+
debug:
|
|
75
|
+
msg: "{{ lookup('csvfile', 'test1', 'test2', file='debug.csv', delimiter=' ') }}"
|
|
76
|
+
|
|
77
|
+
- name: Lookup multiple keynames using old style syntax
|
|
78
|
+
debug:
|
|
79
|
+
msg: "{{ lookup('csvfile', term1, term2) }}"
|
|
80
|
+
vars:
|
|
81
|
+
term1: "test1 file=debug.csv delimiter=' '"
|
|
82
|
+
term2: "test2 file=debug.csv delimiter=' '"
|
|
66
83
|
"""
|
|
67
84
|
|
|
68
85
|
RETURN = """
|
|
@@ -150,6 +167,9 @@ class LookupModule(LookupBase):
|
|
|
150
167
|
# populate options
|
|
151
168
|
paramvals = self.get_options()
|
|
152
169
|
|
|
170
|
+
if not terms:
|
|
171
|
+
raise AnsibleError('Search key is required but was not found')
|
|
172
|
+
|
|
153
173
|
for term in terms:
|
|
154
174
|
kv = parse_kv(term)
|
|
155
175
|
|
|
@@ -25,35 +25,70 @@ import ntpath
|
|
|
25
25
|
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
|
26
26
|
from ansible.plugins.shell import ShellBase
|
|
27
27
|
|
|
28
|
+
# This is weird, we are matching on byte sequences that match the utf-16-be
|
|
29
|
+
# matches for '_x(a-fA-F0-9){4}_'. The \x00 and {8} will match the hex sequence
|
|
30
|
+
# when it is encoded as utf-16-be.
|
|
31
|
+
_STRING_DESERIAL_FIND = re.compile(rb"\x00_\x00x([\x00(a-fA-F0-9)]{8})\x00_")
|
|
28
32
|
|
|
29
33
|
_common_args = ['PowerShell', '-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Unrestricted']
|
|
30
34
|
|
|
31
35
|
|
|
32
|
-
def _parse_clixml(data, stream="Error"):
|
|
36
|
+
def _parse_clixml(data: bytes, stream: str = "Error") -> bytes:
|
|
33
37
|
"""
|
|
34
38
|
Takes a byte string like '#< CLIXML\r\n<Objs...' and extracts the stream
|
|
35
39
|
message encoded in the XML data. CLIXML is used by PowerShell to encode
|
|
36
40
|
multiple objects in stderr.
|
|
37
41
|
"""
|
|
38
|
-
lines = []
|
|
42
|
+
lines: list[str] = []
|
|
43
|
+
|
|
44
|
+
# A serialized string will serialize control chars and surrogate pairs as
|
|
45
|
+
# _xDDDD_ values where DDDD is the hex representation of a big endian
|
|
46
|
+
# UTF-16 code unit. As a surrogate pair uses 2 UTF-16 code units, we need
|
|
47
|
+
# to operate our text replacement on the utf-16-be byte encoding of the raw
|
|
48
|
+
# text. This allows us to replace the _xDDDD_ values with the actual byte
|
|
49
|
+
# values and then decode that back to a string from the utf-16-be bytes.
|
|
50
|
+
def rplcr(matchobj: re.Match) -> bytes:
|
|
51
|
+
match_hex = matchobj.group(1)
|
|
52
|
+
hex_string = match_hex.decode("utf-16-be")
|
|
53
|
+
return base64.b16decode(hex_string.upper())
|
|
39
54
|
|
|
40
55
|
# There are some scenarios where the stderr contains a nested CLIXML element like
|
|
41
56
|
# '<# CLIXML\r\n<# CLIXML\r\n<Objs>...</Objs><Objs>...</Objs>'.
|
|
42
57
|
# Parse each individual <Objs> element and add the error strings to our stderr list.
|
|
43
58
|
# https://github.com/ansible/ansible/issues/69550
|
|
44
59
|
while data:
|
|
45
|
-
|
|
46
|
-
|
|
60
|
+
start_idx = data.find(b"<Objs ")
|
|
61
|
+
end_idx = data.find(b"</Objs>")
|
|
62
|
+
if start_idx == -1 or end_idx == -1:
|
|
63
|
+
break
|
|
64
|
+
|
|
65
|
+
end_idx += 7
|
|
66
|
+
current_element = data[start_idx:end_idx]
|
|
47
67
|
data = data[end_idx:]
|
|
48
68
|
|
|
49
69
|
clixml = ET.fromstring(current_element)
|
|
50
70
|
namespace_match = re.match(r'{(.*)}', clixml.tag)
|
|
51
|
-
namespace = "{
|
|
71
|
+
namespace = f"{{{namespace_match.group(1)}}}" if namespace_match else ""
|
|
72
|
+
|
|
73
|
+
entries = clixml.findall("./%sS" % namespace)
|
|
74
|
+
if not entries:
|
|
75
|
+
continue
|
|
76
|
+
|
|
77
|
+
# If this is a new CLIXML element, add a newline to separate the messages.
|
|
78
|
+
if lines:
|
|
79
|
+
lines.append("\r\n")
|
|
80
|
+
|
|
81
|
+
for string_entry in entries:
|
|
82
|
+
actual_stream = string_entry.attrib.get('S', None)
|
|
83
|
+
if actual_stream != stream:
|
|
84
|
+
continue
|
|
85
|
+
|
|
86
|
+
b_line = (string_entry.text or "").encode("utf-16-be")
|
|
87
|
+
b_escaped = re.sub(_STRING_DESERIAL_FIND, rplcr, b_line)
|
|
52
88
|
|
|
53
|
-
|
|
54
|
-
lines.extend([e.text.replace('_x000D__x000A_', '') for e in strings if e.attrib.get('S') == stream])
|
|
89
|
+
lines.append(b_escaped.decode("utf-16-be", errors="surrogatepass"))
|
|
55
90
|
|
|
56
|
-
return to_bytes('
|
|
91
|
+
return to_bytes(''.join(lines), errors="surrogatepass")
|
|
57
92
|
|
|
58
93
|
|
|
59
94
|
class ShellModule(ShellBase):
|
|
@@ -54,7 +54,7 @@ from ansible.utils.display import Display
|
|
|
54
54
|
from ansible.utils.fqcn import add_internal_fqcns
|
|
55
55
|
from ansible.utils.unsafe_proxy import wrap_var
|
|
56
56
|
from ansible.utils.sentinel import Sentinel
|
|
57
|
-
from ansible.utils.vars import combine_vars
|
|
57
|
+
from ansible.utils.vars import combine_vars
|
|
58
58
|
from ansible.vars.clean import strip_internal_keys, module_response_deepcopy
|
|
59
59
|
|
|
60
60
|
display = Display()
|
|
@@ -766,10 +766,6 @@ class StrategyBase:
|
|
|
766
766
|
|
|
767
767
|
# register final results
|
|
768
768
|
if original_task.register:
|
|
769
|
-
|
|
770
|
-
if not isidentifier(original_task.register):
|
|
771
|
-
raise AnsibleError("Invalid variable name in 'register' specified: '%s'" % original_task.register)
|
|
772
|
-
|
|
773
769
|
host_list = self.get_task_hosts(iterator, original_host, original_task)
|
|
774
770
|
|
|
775
771
|
clean_copy = strip_internal_keys(module_response_deepcopy(task_result._result))
|
ansible/plugins/strategy/free.py
CHANGED
|
@@ -95,6 +95,7 @@ class StrategyModule(StrategyBase):
|
|
|
95
95
|
|
|
96
96
|
# try and find an unblocked host with a task to run
|
|
97
97
|
host_results = []
|
|
98
|
+
meta_task_dummy_results_count = 0
|
|
98
99
|
while True:
|
|
99
100
|
host = hosts_left[last_host]
|
|
100
101
|
display.debug("next free host: %s" % host)
|
|
@@ -181,6 +182,9 @@ class StrategyModule(StrategyBase):
|
|
|
181
182
|
continue
|
|
182
183
|
|
|
183
184
|
if task.action in C._ACTION_META:
|
|
185
|
+
if self._host_pinned:
|
|
186
|
+
meta_task_dummy_results_count += 1
|
|
187
|
+
workers_free -= 1
|
|
184
188
|
self._execute_meta(task, play_context, iterator, target_host=host)
|
|
185
189
|
self._blocked_hosts[host_name] = False
|
|
186
190
|
else:
|
|
@@ -220,7 +224,7 @@ class StrategyModule(StrategyBase):
|
|
|
220
224
|
host_results.extend(results)
|
|
221
225
|
|
|
222
226
|
# each result is counted as a worker being free again
|
|
223
|
-
workers_free += len(results)
|
|
227
|
+
workers_free += len(results) + meta_task_dummy_results_count
|
|
224
228
|
|
|
225
229
|
self.update_active_connections(results)
|
|
226
230
|
|
ansible/release.py
CHANGED
ansible/utils/version.py
CHANGED
|
@@ -190,6 +190,7 @@ class SemanticVersion(Version):
|
|
|
190
190
|
raise ValueError("invalid semantic version '%s'" % vstring)
|
|
191
191
|
|
|
192
192
|
(major, minor, patch, prerelease, buildmetadata) = match.group(1, 2, 3, 4, 5)
|
|
193
|
+
self.vstring = vstring
|
|
193
194
|
self.major = int(major)
|
|
194
195
|
self.minor = int(minor)
|
|
195
196
|
self.patch = int(patch)
|
|
@@ -3,7 +3,7 @@ ansible/__main__.py,sha256=EnLcULXNtSXkuJ8igEHPPLBTZKAwqXv4PvMEhvzp2Oo,1430
|
|
|
3
3
|
ansible/constants.py,sha256=vRwEcoynqtuKDPKsxKUY94XzrTSV3J0y1slb907DioU,9140
|
|
4
4
|
ansible/context.py,sha256=oKYyfjfWpy8vDeProtqfnqSmuij_t75_5e5t0U_hQ1g,1933
|
|
5
5
|
ansible/keyword_desc.yml,sha256=vE9joFgSeHR4Djl7Bd-HHVCrGByRCrTUmWYZ8LKPZKk,7412
|
|
6
|
-
ansible/release.py,sha256=
|
|
6
|
+
ansible/release.py,sha256=hJwAtpVj7TtTA5eJFPqdwBspCPNfXvjlgzBhCyVgQCg,832
|
|
7
7
|
ansible/_vendor/__init__.py,sha256=2QBeBwT7uG7M3Aw-pIdCpt6XPtHMCpbEKfACYKA7xIg,2033
|
|
8
8
|
ansible/cli/__init__.py,sha256=fzgR82NIGBH3GujIMehhAaP4KYszn4uztuCaFYRUpGk,28718
|
|
9
9
|
ansible/cli/adhoc.py,sha256=quJ9WzRzf3dz_dtDGmahNMffqyNVy1jzQCMo21YL5Qg,8194
|
|
@@ -26,7 +26,7 @@ ansible/compat/importlib_resources.py,sha256=oCjsu8foADOkMNwRuWiRCjQxO8zEOc-Olc2
|
|
|
26
26
|
ansible/compat/selectors.py,sha256=pbI2QH2fT2WAOtmEBbd6Cp2yXyCBbb5TLR7iitqnAkU,1002
|
|
27
27
|
ansible/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
28
|
ansible/config/ansible_builtin_runtime.yml,sha256=nwL_-rqEEmpuSHxZH70pJBiEosDKOPkYIboH3_7LVEY,376076
|
|
29
|
-
ansible/config/base.yml,sha256=
|
|
29
|
+
ansible/config/base.yml,sha256=4iotRTO8gAW_A19yBmYJAet1NIIulPbLA1b8TscyzbQ,85728
|
|
30
30
|
ansible/config/manager.py,sha256=MvNZnqHDtz9uda5_ryNvpCv2M3frAl81bvZvgS1lGko,25730
|
|
31
31
|
ansible/errors/__init__.py,sha256=pJ0Cd87ET5SNut851lrHH8EAoKEal2DdUJYl8yjRd8E,14739
|
|
32
32
|
ansible/errors/yaml_strings.py,sha256=fKfgD3rC017dyMackTpu-LkvbsdnsfBAKCxMH-fDtIg,3858
|
|
@@ -37,7 +37,7 @@ ansible/executor/module_common.py,sha256=4pVfjMgCle9ttAZTeuwSx3Kdi0rljagyHC11i4V
|
|
|
37
37
|
ansible/executor/play_iterator.py,sha256=FRzl8ELbICqzud-lT2KNuLmPoPntzayf2Y9DboEwso0,30427
|
|
38
38
|
ansible/executor/playbook_executor.py,sha256=S_dwBYqYTQtN32AMQXxQTOpVCczV4KJ8ezergt1nlmA,15014
|
|
39
39
|
ansible/executor/stats.py,sha256=gcBhJQrZTgE95737d6lArJ3FpTlbAfVt6GMhEqs5ZPU,3180
|
|
40
|
-
ansible/executor/task_executor.py,sha256=
|
|
40
|
+
ansible/executor/task_executor.py,sha256=Q9Puu6y0wczvnLMrHaNSeg4FkhFqs6c3Kj6X_RvhII4,60551
|
|
41
41
|
ansible/executor/task_queue_manager.py,sha256=wv19pq9LNHRABjvDYUZHQ9kmlO_ypA0r3aMaLnGxaCs,18640
|
|
42
42
|
ansible/executor/task_result.py,sha256=pnLu-f0tYaDmDXSQftCBChSt_Zx5pW0GeLYLvEHuHkA,5695
|
|
43
43
|
ansible/executor/discovery/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -140,9 +140,9 @@ ansible/inventory/host.py,sha256=PDb5OTplhfpUIvdHiP2BckUOB1gUl302N-3sW0_sTyg,503
|
|
|
140
140
|
ansible/inventory/manager.py,sha256=45mHgZTAkQ3IjAtrgsNzJXvynC-HIEor-JJE-V3xXN4,29454
|
|
141
141
|
ansible/module_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
142
142
|
ansible/module_utils/_text.py,sha256=VkWgAnSNVCbTQqZgllUObBFsH3uM4EUW5srl1UR9t1g,544
|
|
143
|
-
ansible/module_utils/ansible_release.py,sha256=
|
|
143
|
+
ansible/module_utils/ansible_release.py,sha256=hJwAtpVj7TtTA5eJFPqdwBspCPNfXvjlgzBhCyVgQCg,832
|
|
144
144
|
ansible/module_utils/api.py,sha256=DWIuLW5gDWuyyDHLLgGnub42Qa8kagDdkf1xDeLAFl4,5784
|
|
145
|
-
ansible/module_utils/basic.py,sha256=
|
|
145
|
+
ansible/module_utils/basic.py,sha256=G5gg2b4L6y8u4J7pCRkoAAsIz8rabuAPB4ThFu2wvaY,85920
|
|
146
146
|
ansible/module_utils/connection.py,sha256=q_BdUaST6E44ltHsWPOFOheXK9vKmzaJvP-eQOrOrmE,8394
|
|
147
147
|
ansible/module_utils/errors.py,sha256=cOVAUZaQTeYaSGhKnYsT3L8vshayQHbCXzkT6HIVi_o,3345
|
|
148
148
|
ansible/module_utils/json_utils.py,sha256=2WuR79zOoVVP4zo8iztwzE_k2JdXawpWh855YhdPIDU,3403
|
|
@@ -347,7 +347,7 @@ ansible/modules/wait_for_connection.py,sha256=lHgsuyw3oel1pqXlLCls7KSF1PJaSU0RKG
|
|
|
347
347
|
ansible/modules/yum_repository.py,sha256=v9nsLd5NLy33ygJ_6IYzknFDPnZaGvyKemWEL5843qk,24906
|
|
348
348
|
ansible/parsing/__init__.py,sha256=NMP9ZkK59SNdQktw76aWAXVAm5U2POXLgAK7wH-1h0g,742
|
|
349
349
|
ansible/parsing/ajson.py,sha256=wr13wRYyK_VPBVki-5hisJZZKwi1T4rSi37gWj7zrOU,1254
|
|
350
|
-
ansible/parsing/dataloader.py,sha256=
|
|
350
|
+
ansible/parsing/dataloader.py,sha256=ocwvS5dQo5ocJGO1JO5hz1DI_CNSX_cKFr_pKunaNyM,20915
|
|
351
351
|
ansible/parsing/mod_args.py,sha256=bDPfCFFYx9DwlJ16CHaIlWK8sXURqFSuJvXHtzcFxs0,14585
|
|
352
352
|
ansible/parsing/plugin_docs.py,sha256=XBpeEALC-eBOZJPM4jPPxbKu0dYDRDyUG4STDUsrf9o,8661
|
|
353
353
|
ansible/parsing/quoting.py,sha256=JokJozzFk7NDxDGTTZerfBntBls1NzNWyK7AQgsH5C8,1057
|
|
@@ -380,14 +380,14 @@ ansible/playbook/play_context.py,sha256=w5P-lAyN1cr01JgSLw8tnYy4QsSyDFLzbSy_ehuc
|
|
|
380
380
|
ansible/playbook/playbook_include.py,sha256=hr3N_yV4unjhiC2IIdchY0TPSARwlv0SXH9bIsIrbaA,7493
|
|
381
381
|
ansible/playbook/role_include.py,sha256=NCgDHtXlOltJ0XXSgGTTxDVrLC6IBe_d9SgNGXtsI20,7575
|
|
382
382
|
ansible/playbook/taggable.py,sha256=PfbiQhDDafwKja2yIknJTEAHPspb7tPmCRDEO_8gmvY,3165
|
|
383
|
-
ansible/playbook/task.py,sha256=
|
|
384
|
-
ansible/playbook/task_include.py,sha256=
|
|
383
|
+
ansible/playbook/task.py,sha256=VxFZY5gyAfhe40GTscpMy7f5Z6iLfTTCceGDUwpaKFU,21754
|
|
384
|
+
ansible/playbook/task_include.py,sha256=RHqzspHMA7wuIswDd6szZYCymXiVqWlF1Jil_2yRMz4,5244
|
|
385
385
|
ansible/playbook/role/__init__.py,sha256=HSvzDNMq8DtNG4jQvZe1UAkR42vyj8Qt1ScgRBZ2MYE,29697
|
|
386
386
|
ansible/playbook/role/definition.py,sha256=ZKs9FI3kqJETFHMh-8lOH6xGY_g2siuTxYgQj5VkcDk,9550
|
|
387
387
|
ansible/playbook/role/include.py,sha256=9e4IvnD3JXqJUV-hB7riGgq0SjrqQGQHDg-cuJ1vTlo,2342
|
|
388
388
|
ansible/playbook/role/metadata.py,sha256=HUuR5wCKAw-6urkAR4DKxUeOVsqFflSDHjZuWdBCmxo,5074
|
|
389
389
|
ansible/playbook/role/requirement.py,sha256=CNgLa0J6zZk2YQ_aeALnjQvehkkFXhrK8LQQZs7Ztzc,4173
|
|
390
|
-
ansible/plugins/__init__.py,sha256=
|
|
390
|
+
ansible/plugins/__init__.py,sha256=y4dYcAW6qvj2eaFQKxsJc2J5TXPPiXzXpVznk--Z0n0,5725
|
|
391
391
|
ansible/plugins/list.py,sha256=c2wWNt1LMQj9URWS4JAJVlyzJqAj3CxUrauozN75crM,8919
|
|
392
392
|
ansible/plugins/loader.py,sha256=BMUcCe2CltI95l3q56bEz_EjvaKLWB9XxthRCORFFJ0,75837
|
|
393
393
|
ansible/plugins/action/__init__.py,sha256=H7bcYPA8io7m4d0zSYPZo65c2xRf44YoJNvkS2H1RnI,69202
|
|
@@ -437,8 +437,8 @@ ansible/plugins/cliconf/__init__.py,sha256=NlIs8a21RJSPOmoO-fVSJtO4OGNPxCAMFntDZ
|
|
|
437
437
|
ansible/plugins/connection/__init__.py,sha256=7B9UmhcM4divUhg-RsurhOOGQiCVeLGGh0Zp_zCvK4w,17947
|
|
438
438
|
ansible/plugins/connection/local.py,sha256=A-XQy_wIky16xrgkm2KW2jyZLpzmcUPjNOPtoQQnDJg,8339
|
|
439
439
|
ansible/plugins/connection/paramiko_ssh.py,sha256=NnCHPiVZTzJVu0EQ4p4g0k0jxUgEHC9PHvuD6IFZ6O4,30045
|
|
440
|
-
ansible/plugins/connection/psrp.py,sha256=
|
|
441
|
-
ansible/plugins/connection/ssh.py,sha256=
|
|
440
|
+
ansible/plugins/connection/psrp.py,sha256=K3ZhDmpYcCI5CYtXBonD6hMb4QZe4GN6VZ6vKMPz4kk,36762
|
|
441
|
+
ansible/plugins/connection/ssh.py,sha256=zj_pSJk1SY3TVAXnYR6LMwmZvU5LWkTflXy_3SGG2Ag,62830
|
|
442
442
|
ansible/plugins/connection/winrm.py,sha256=x9FHPRkEyI_ua4PUPbYVb7_joyMJYEiGSv45jxxkNTQ,40599
|
|
443
443
|
ansible/plugins/doc_fragments/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
444
444
|
ansible/plugins/doc_fragments/action_common_attributes.py,sha256=OaP2is2r9wm_f8gbLZhDDDwccg1joXMvJM72vbgcbIo,2442
|
|
@@ -547,7 +547,7 @@ ansible/plugins/inventory/toml.py,sha256=VqNEJjr0I4qhNAdliW3doof01_DcfVSUbYpX5yk
|
|
|
547
547
|
ansible/plugins/inventory/yaml.py,sha256=bEvCjUdkDuMNE1N6o7_vTm-xmU6-SH2Jzmko4gUEq-0,7415
|
|
548
548
|
ansible/plugins/lookup/__init__.py,sha256=lUifYWnyaWPK-PcLGH65Qa0nkyF2sogY3GI2LHl0yLY,4680
|
|
549
549
|
ansible/plugins/lookup/config.py,sha256=ilQZ6AsZhk_Gc5MNGSPcj4dBf_EzEYf_9PwlgFHDz0c,6894
|
|
550
|
-
ansible/plugins/lookup/csvfile.py,sha256=
|
|
550
|
+
ansible/plugins/lookup/csvfile.py,sha256=3NDezWFG6syRg0HSaE_2iS1C_aMjgOv8l0htaGml7X0,7426
|
|
551
551
|
ansible/plugins/lookup/dict.py,sha256=Df0P5QgcIE1LwqDPbM0L8CwtBqJPVrqTHy3AudFvQ84,2198
|
|
552
552
|
ansible/plugins/lookup/env.py,sha256=MLMZNyzSuRLqBFYUjEhWa7exHJVnvqkgI4EmoYFS3iw,2646
|
|
553
553
|
ansible/plugins/lookup/file.py,sha256=El1j6qgZb2hdlVNusMGO6eaYkHadfum7kHQuD06ZU98,3271
|
|
@@ -574,11 +574,11 @@ ansible/plugins/lookup/vars.py,sha256=eXVZdwumdcp3ajaDX7JyIYeGvQ6L-HxHGfnob9Pnkg
|
|
|
574
574
|
ansible/plugins/netconf/__init__.py,sha256=50w1g2rhUo6L-xtiMT20jbR8WyOnhwNSRd2IRNSjNX4,17094
|
|
575
575
|
ansible/plugins/shell/__init__.py,sha256=rEwatHZ46LJuxMFANb6e__CTLkFWX6B0878eBaCXwqM,9286
|
|
576
576
|
ansible/plugins/shell/cmd.py,sha256=kPCSKrJJFH5XTkmteEI3P1Da6WfPSXxDnV39VFpgD-A,2170
|
|
577
|
-
ansible/plugins/shell/powershell.py,sha256=
|
|
577
|
+
ansible/plugins/shell/powershell.py,sha256=6_loE4nYiLjro8egODcsK4HmoPmAk9bd4YY961dXb2U,12880
|
|
578
578
|
ansible/plugins/shell/sh.py,sha256=wblaY2EGdA2O00gNuTVZVgVV08RH0e_g4V_AkE50Iws,3884
|
|
579
|
-
ansible/plugins/strategy/__init__.py,sha256=
|
|
579
|
+
ansible/plugins/strategy/__init__.py,sha256=UdcdFDk8cPjPxa6ZlXyIJUi7B0Pf5dEPCjm73plgcTE,57037
|
|
580
580
|
ansible/plugins/strategy/debug.py,sha256=yMmfT-lQHfR2y9bQcqrSPzqHuWZMo7V9y4ZWOXoboRE,1205
|
|
581
|
-
ansible/plugins/strategy/free.py,sha256=
|
|
581
|
+
ansible/plugins/strategy/free.py,sha256=WNrpfg2B8fVcYC5qvBhn4uEH0Cc1-UmFzBH6Hhs3u_I,16728
|
|
582
582
|
ansible/plugins/strategy/host_pinned.py,sha256=GrDDQCtohmmJn3t9VOPb0lUZK_nUWy0s__z5Tq_rHfI,1875
|
|
583
583
|
ansible/plugins/strategy/linear.py,sha256=no9JgVrgqoN3SphXE38y3DTK1P9FpB48Qn21ro2qFZU,18394
|
|
584
584
|
ansible/plugins/terminal/__init__.py,sha256=EqeJpMokRzuUMO66yYErPSyninjqNX0_5r55CEkTc4o,4420
|
|
@@ -666,7 +666,7 @@ ansible/utils/ssh_functions.py,sha256=DSxlfBO65EwnP18pmfNkJxx4sNRnPuj8tMP3X-Cjwp
|
|
|
666
666
|
ansible/utils/unicode.py,sha256=__zbdElrMS9Rrqo9H7tF8zkjKFQCFU8kTtj5cVIITxM,1100
|
|
667
667
|
ansible/utils/unsafe_proxy.py,sha256=RlAt3OHutmgYZD3dEqhqYjgPVLu7UzncnfhS6zJlwoM,12697
|
|
668
668
|
ansible/utils/vars.py,sha256=qMmRZJiUbmSWtmHd30jW7oxKr0sAq7_BzvIYglJ_T7g,9843
|
|
669
|
-
ansible/utils/version.py,sha256=
|
|
669
|
+
ansible/utils/version.py,sha256=AKu8wtymk6pGYQpWaZ7vvVc-5m-OQoDAwZcs9B-L9-c,7736
|
|
670
670
|
ansible/utils/collection_loader/__init__.py,sha256=ietIGihc75tjOuwbrk0keAi8RNLw2egfOCYrpQtckF4,1065
|
|
671
671
|
ansible/utils/collection_loader/_collection_config.py,sha256=LsGtKWY68PUExSMOLXW4qVfi50o7Fv62j2KPudyC3vA,3094
|
|
672
672
|
ansible/utils/collection_loader/_collection_finder.py,sha256=X4jKhMLld8RmpNgOVVv3nbuKsa6gAdDVyNwjHdk44MU,56584
|
|
@@ -678,7 +678,7 @@ ansible/vars/hostvars.py,sha256=ggUQ5luCajjX7sEvFCHpIuB_stWPRb089cZ3I1v1Vmo,5070
|
|
|
678
678
|
ansible/vars/manager.py,sha256=ujVDQXWvy8BihIxGzBPX6fMeUl2AlclkwadKMo6VjSk,38583
|
|
679
679
|
ansible/vars/plugins.py,sha256=RsRU9fiLcJwPIAyTYnmVZglsiEOMCIgQskflavE-XnE,4546
|
|
680
680
|
ansible/vars/reserved.py,sha256=kZiQMPvaFin35006gLwDpX16w-9xlu6EaL4LSTKP40U,2531
|
|
681
|
-
ansible_core-2.17.
|
|
681
|
+
ansible_core-2.17.4.data/scripts/ansible-test,sha256=dyY2HtRZotRQO3b89HGXY_KnJgBvgsm4eLIe4B2LUoA,1637
|
|
682
682
|
ansible_test/__init__.py,sha256=20VPOj11c6Ut1Av9RaurgwJvFhMqkWG3vAvcCbecNKw,66
|
|
683
683
|
ansible_test/_data/ansible.cfg,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
684
684
|
ansible_test/_data/coveragerc,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -906,7 +906,7 @@ ansible_test/_util/controller/sanity/code-smell/no-smart-quotes.py,sha256=4LFlim
|
|
|
906
906
|
ansible_test/_util/controller/sanity/code-smell/replace-urlopen.json,sha256=w9--s9c-2F26o7JBJbTJjVGPnvlwGNfSu7KNDSmL9Qw,179
|
|
907
907
|
ansible_test/_util/controller/sanity/code-smell/replace-urlopen.py,sha256=PSLEuYW5SBrcC7YIt8jdvJ3arxLL7SK7Mxbsvz1UfXc,624
|
|
908
908
|
ansible_test/_util/controller/sanity/code-smell/runtime-metadata.json,sha256=H2E2-01YXLlSWjvLJT5Vtj3Gn4zB6xhPXsDJh4a7EH0,225
|
|
909
|
-
ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py,sha256=
|
|
909
|
+
ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py,sha256=ozoaAQCTZM-0Hnl--jSUwbZS0mBrs6FGWbP6_esODzk,12233
|
|
910
910
|
ansible_test/_util/controller/sanity/code-smell/shebang.json,sha256=3vtNzoowM53gi2KZi9peIKVIU79ulQY3FE0jYcSP77M,63
|
|
911
911
|
ansible_test/_util/controller/sanity/code-smell/shebang.py,sha256=AKCti3RCgZy0GWB3bXgimr_OhqfVPOp_I7345UN_DV8,4672
|
|
912
912
|
ansible_test/_util/controller/sanity/code-smell/symlinks.json,sha256=JkalgX52aKGUKqjKG5P-68F0tXmUMgldPrNAknMN2Fk,96
|
|
@@ -979,9 +979,9 @@ ansible_test/config/cloud-config-vultr.ini.template,sha256=XLKHk3lg_8ReQMdWfZzhh
|
|
|
979
979
|
ansible_test/config/config.yml,sha256=wb3knoBmZewG3GWOMnRHoVPQWW4vPixKLPMNS6vJmTc,2620
|
|
980
980
|
ansible_test/config/inventory.networking.template,sha256=bFNSk8zNQOaZ_twaflrY0XZ9mLwUbRLuNT0BdIFwvn4,1335
|
|
981
981
|
ansible_test/config/inventory.winrm.template,sha256=1QU8W-GFLnYEw8yY9bVIvUAVvJYPM3hyoijf6-M7T00,1098
|
|
982
|
-
ansible_core-2.17.
|
|
983
|
-
ansible_core-2.17.
|
|
984
|
-
ansible_core-2.17.
|
|
985
|
-
ansible_core-2.17.
|
|
986
|
-
ansible_core-2.17.
|
|
987
|
-
ansible_core-2.17.
|
|
982
|
+
ansible_core-2.17.4.dist-info/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
983
|
+
ansible_core-2.17.4.dist-info/METADATA,sha256=w2THLrCDRKZHurp05qlD5ESg9vywW71t9td_zeh5A6M,6945
|
|
984
|
+
ansible_core-2.17.4.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
|
985
|
+
ansible_core-2.17.4.dist-info/entry_points.txt,sha256=0mpmsrIhODChxKl3eS-NcVQCaMetBn8KdPLtVxQgR64,453
|
|
986
|
+
ansible_core-2.17.4.dist-info/top_level.txt,sha256=IFbRLjAvih1DYzJWg3_F6t4sCzEMxRO7TOMNs6GkYHo,21
|
|
987
|
+
ansible_core-2.17.4.dist-info/RECORD,,
|
|
@@ -123,7 +123,9 @@ def get_collection_version():
|
|
|
123
123
|
# noinspection PyBroadException
|
|
124
124
|
try:
|
|
125
125
|
result = collection_detail.read_manifest_json('.') or collection_detail.read_galaxy_yml('.')
|
|
126
|
-
|
|
126
|
+
version = SemanticVersion()
|
|
127
|
+
version.parse(result['version'])
|
|
128
|
+
return version
|
|
127
129
|
except Exception: # pylint: disable=broad-except
|
|
128
130
|
# We do not care why it fails, in case we cannot get the version
|
|
129
131
|
# just return None to indicate "we don't know".
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|