ansible-core 2.17.5__py3-none-any.whl → 2.17.6rc1__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.

@@ -447,6 +447,24 @@ class PlayIterator:
447
447
 
448
448
  # if something above set the task, break out of the loop now
449
449
  if task:
450
+ # skip implicit flush_handlers if there are no handlers notified
451
+ if (
452
+ task.implicit
453
+ and task.action in C._ACTION_META
454
+ and task.args.get('_raw_params', None) == 'flush_handlers'
455
+ and (
456
+ # the state store in the `state` variable could be a nested state,
457
+ # notifications are always stored in the top level state, get it here
458
+ not self.get_state_for_host(host.name).handler_notifications
459
+ # in case handlers notifying other handlers, the notifications are not
460
+ # saved in `handler_notifications` and handlers are notified directly
461
+ # to prevent duplicate handler runs, so check whether any handler
462
+ # is notified
463
+ and all(not h.notified_hosts for h in self.handlers)
464
+ )
465
+ ):
466
+ continue
467
+
450
468
  break
451
469
 
452
470
  return (state, task)
@@ -655,8 +655,8 @@ class TaskExecutor:
655
655
  self._handler.cleanup()
656
656
  display.debug("handler run complete")
657
657
 
658
- # preserve no log
659
- result["_ansible_no_log"] = no_log
658
+ # propagate no log to result- the action can set this, so only overwrite it with the task's value if missing or falsey
659
+ result["_ansible_no_log"] = bool(no_log or result.get('_ansible_no_log', False))
660
660
 
661
661
  if self._task.action not in C._ACTION_WITH_CLEAN_FACTS:
662
662
  result = wrap_var(result)
@@ -10,6 +10,7 @@ import os
10
10
  import tarfile
11
11
  import subprocess
12
12
  import typing as t
13
+ import yaml
13
14
 
14
15
  from contextlib import contextmanager
15
16
  from hashlib import sha256
@@ -24,6 +25,7 @@ if t.TYPE_CHECKING:
24
25
  )
25
26
  from ansible.galaxy.token import GalaxyToken
26
27
 
28
+ from ansible import context
27
29
  from ansible.errors import AnsibleError
28
30
  from ansible.galaxy import get_collections_galaxy_meta_info
29
31
  from ansible.galaxy.api import should_retry_error
@@ -38,7 +40,7 @@ from ansible.module_utils.urls import open_url
38
40
  from ansible.utils.display import Display
39
41
  from ansible.utils.sentinel import Sentinel
40
42
 
41
- import yaml
43
+ import ansible.constants as C
42
44
 
43
45
 
44
46
  display = Display()
@@ -425,11 +427,14 @@ def _extract_collection_from_git(repo_url, coll_ver, b_path):
425
427
 
426
428
  # Perform a shallow clone if simply cloning HEAD
427
429
  if version == 'HEAD':
428
- git_clone_cmd = git_executable, 'clone', '--depth=1', git_url, to_text(b_checkout_path)
430
+ git_clone_cmd = [git_executable, 'clone', '--depth=1', git_url, to_text(b_checkout_path)]
429
431
  else:
430
- git_clone_cmd = git_executable, 'clone', git_url, to_text(b_checkout_path)
432
+ git_clone_cmd = [git_executable, 'clone', git_url, to_text(b_checkout_path)]
431
433
  # FIXME: '--branch', version
432
434
 
435
+ if context.CLIARGS['ignore_certs'] or C.GALAXY_IGNORE_CERTS:
436
+ git_clone_cmd.extend(['-c', 'http.sslVerify=false'])
437
+
433
438
  try:
434
439
  subprocess.check_call(git_clone_cmd)
435
440
  except subprocess.CalledProcessError as proc_err:
@@ -17,6 +17,6 @@
17
17
 
18
18
  from __future__ import annotations
19
19
 
20
- __version__ = '2.17.5'
20
+ __version__ = '2.17.6rc1'
21
21
  __author__ = 'Ansible, Inc.'
22
22
  __codename__ = "Gallows Pole"
@@ -30,7 +30,7 @@ def get_uname(module, flags=('-v')):
30
30
 
31
31
  def _file_exists(path, allow_empty=False):
32
32
  # not finding the file, exit early
33
- if not os.path.exists(path):
33
+ if not os.path.isfile(path):
34
34
  return False
35
35
 
36
36
  # if just the path needs to exists (ie, it can be empty) we are done
@@ -48,7 +48,7 @@ def timeout(seconds=None, error_message="Timer expired"):
48
48
  return res.get(timeout_value)
49
49
  except multiprocessing.TimeoutError:
50
50
  # This is an ansible.module_utils.common.facts.timeout.TimeoutError
51
- raise TimeoutError('Timer expired after %s seconds' % timeout_value)
51
+ raise TimeoutError(f'{error_message} after {timeout_value} seconds')
52
52
  finally:
53
53
  pool.terminate()
54
54
 
@@ -134,21 +134,24 @@ def get_password_value(module, pkg, question, vtype):
134
134
  cmd = [getsel]
135
135
  rc, out, err = module.run_command(cmd)
136
136
  if rc != 0:
137
- module.fail_json(msg="Failed to get the value '%s' from '%s'" % (question, pkg))
137
+ module.fail_json(msg=f"Failed to get the value '{question}' from '{pkg}': {err}")
138
138
 
139
- desired_line = None
140
139
  for line in out.split("\n"):
141
- if line.startswith(pkg):
142
- desired_line = line
143
- break
144
-
145
- if not desired_line:
146
- module.fail_json(msg="Failed to find the value '%s' from '%s'" % (question, pkg))
147
-
148
- (dpkg, dquestion, dvtype, dvalue) = desired_line.split()
149
- if dquestion == question and dvtype == vtype:
150
- return dvalue
151
- return ''
140
+ if not line.startswith(pkg):
141
+ continue
142
+
143
+ # line is a collection of tab separated values
144
+ fields = line.split('\t')
145
+ if len(fields) <= 3:
146
+ # No password found, return a blank password
147
+ return ''
148
+ try:
149
+ if fields[1] == question and fields[2] == vtype:
150
+ # If correct question and question type found, return password value
151
+ return fields[3]
152
+ except IndexError:
153
+ # Fail safe
154
+ return ''
152
155
 
153
156
 
154
157
  def get_selections(module, pkg):
ansible/modules/user.py CHANGED
@@ -1167,9 +1167,11 @@ class User(object):
1167
1167
  overwrite = None
1168
1168
  try:
1169
1169
  ssh_key_file = self.get_ssh_key_path()
1170
+ pub_file = f'{ssh_key_file}.pub'
1170
1171
  except Exception as e:
1171
1172
  return (1, '', to_native(e))
1172
1173
  ssh_dir = os.path.dirname(ssh_key_file)
1174
+
1173
1175
  if not os.path.exists(ssh_dir):
1174
1176
  if self.module.check_mode:
1175
1177
  return (0, '', '')
@@ -1178,12 +1180,23 @@ class User(object):
1178
1180
  os.chown(ssh_dir, info[2], info[3])
1179
1181
  except OSError as e:
1180
1182
  return (1, '', 'Failed to create %s: %s' % (ssh_dir, to_native(e)))
1183
+
1181
1184
  if os.path.exists(ssh_key_file):
1182
1185
  if self.force:
1183
- # ssh-keygen doesn't support overwriting the key interactively, so send 'y' to confirm
1186
+ self.module.warn(f'Overwriting existing ssh key private file "{ssh_key_file}"')
1184
1187
  overwrite = 'y'
1185
1188
  else:
1189
+ self.module.warn(f'Found existing ssh key private file "{ssh_key_file}", no force, so skipping ssh-keygen generation')
1186
1190
  return (None, 'Key already exists, use "force: yes" to overwrite', '')
1191
+
1192
+ if os.path.exists(pub_file):
1193
+ if self.force:
1194
+ self.module.warn(f'Overwriting existing ssh key public file "{pub_file}"')
1195
+ os.unlink(pub_file)
1196
+ else:
1197
+ self.module.warn(f'Found existing ssh key public file "{pub_file}", no force, so skipping ssh-keygen generation')
1198
+ return (None, 'Public key already exists, use "force: yes" to overwrite', '')
1199
+
1187
1200
  cmd = [self.module.get_bin_path('ssh-keygen', True)]
1188
1201
  cmd.append('-t')
1189
1202
  cmd.append(self.ssh_type)
@@ -1250,7 +1263,7 @@ class User(object):
1250
1263
  # If the keys were successfully created, we should be able
1251
1264
  # to tweak ownership.
1252
1265
  os.chown(ssh_key_file, info[2], info[3])
1253
- os.chown('%s.pub' % ssh_key_file, info[2], info[3])
1266
+ os.chown(pub_file, info[2], info[3])
1254
1267
  return (rc, out, err)
1255
1268
 
1256
1269
  def ssh_key_fingerprint(self):
@@ -1322,7 +1335,9 @@ class User(object):
1322
1335
  for d in dirs:
1323
1336
  os.chown(os.path.join(root, d), uid, gid)
1324
1337
  for f in files:
1325
- os.chown(os.path.join(root, f), uid, gid)
1338
+ full_path = os.path.join(root, f)
1339
+ if not os.path.islink(full_path):
1340
+ os.chown(full_path, uid, gid)
1326
1341
  except OSError as e:
1327
1342
  self.module.exit_json(failed=True, msg="%s" % to_native(e))
1328
1343
 
@@ -237,7 +237,8 @@ class ActionModule(ActionBase):
237
237
  b_data, show_content = self._loader._get_file_contents(filename)
238
238
  data = to_text(b_data, errors='surrogate_or_strict')
239
239
 
240
- self.show_content = show_content
240
+ self.show_content &= show_content # mask all results if any file was encrypted
241
+
241
242
  data = self._loader.load(data, file_name=filename, show_content=show_content)
242
243
  if not data:
243
244
  data = dict()
@@ -10,6 +10,13 @@ DOCUMENTATION:
10
10
  description: A list.
11
11
  type: list
12
12
  required: true
13
+ case_sensitive:
14
+ description: Whether to consider case when comparing elements.
15
+ default: false
16
+ type: bool
17
+ attribute:
18
+ description: Filter objects with unique values for this attribute.
19
+ type: str
13
20
  seealso:
14
21
  - plugin_type: filter
15
22
  plugin: ansible.builtin.difference
@@ -24,6 +31,27 @@ EXAMPLES: |
24
31
  # list1: [1, 2, 5, 1, 3, 4, 10]
25
32
  {{ list1 | unique }}
26
33
  # => [1, 2, 5, 3, 4, 10]
34
+
35
+ # return case sensitive unique elements
36
+ {{ ['a', 'A', 'a'] | unique(case_sensitive='true') }}
37
+ # => ['a', 'A']
38
+
39
+ # return case insensitive unique elements
40
+ {{ ['b', 'B', 'b'] | unique() }}
41
+ # => ['b']
42
+
43
+ # return unique elements of list based on attribute
44
+ # => [{"age": 12, "name": "a" }, { "age": 14, "name": "b"}]
45
+ - debug:
46
+ msg: "{{ sample | unique(attribute='age') }}"
47
+ vars:
48
+ sample:
49
+ - name: a
50
+ age: 12
51
+ - name: b
52
+ age: 14
53
+ - name: c
54
+ age: 14
27
55
  RETURN:
28
56
  _value:
29
57
  description: A list with unique elements, also known as a set.
@@ -926,6 +926,8 @@ class StrategyBase:
926
926
  meta_action = task.args.get('_raw_params')
927
927
 
928
928
  def _evaluate_conditional(h):
929
+ if not task.when:
930
+ return True
929
931
  all_vars = self._variable_manager.get_vars(play=iterator._play, host=h, task=task,
930
932
  _hosts=self._hosts_cache, _hosts_all=self._hosts_cache_all)
931
933
  templar = Templar(loader=self._loader, variables=all_vars)
@@ -34,7 +34,6 @@ from ansible.errors import AnsibleError, AnsibleAssertionError, AnsibleParserErr
34
34
  from ansible.module_utils.common.text.converters import to_text
35
35
  from ansible.playbook.handler import Handler
36
36
  from ansible.playbook.included_file import IncludedFile
37
- from ansible.playbook.task import Task
38
37
  from ansible.plugins.loader import action_loader
39
38
  from ansible.plugins.strategy import StrategyBase
40
39
  from ansible.template import Templar
@@ -51,12 +50,6 @@ class StrategyModule(StrategyBase):
51
50
  be a noop task to keep the iterator in lock step across
52
51
  all hosts.
53
52
  '''
54
- noop_task = Task()
55
- noop_task.action = 'meta'
56
- noop_task.args['_raw_params'] = 'noop'
57
- noop_task.implicit = True
58
- noop_task.set_loader(iterator._play._loader)
59
-
60
53
  state_task_per_host = {}
61
54
  for host in hosts:
62
55
  state, task = iterator.get_next_task_for_host(host, peek=True)
@@ -64,7 +57,7 @@ class StrategyModule(StrategyBase):
64
57
  state_task_per_host[host] = state, task
65
58
 
66
59
  if not state_task_per_host:
67
- return [(h, None) for h in hosts]
60
+ return []
68
61
 
69
62
  task_uuids = {t._uuid for s, t in state_task_per_host.values()}
70
63
  _loop_cnt = 0
@@ -90,8 +83,6 @@ class StrategyModule(StrategyBase):
90
83
  if cur_task._uuid == task._uuid:
91
84
  iterator.set_state_for_host(host.name, state)
92
85
  host_tasks.append((host, task))
93
- else:
94
- host_tasks.append((host, noop_task))
95
86
 
96
87
  if cur_task.action in C._ACTION_META and cur_task.args.get('_raw_params') == 'flush_handlers':
97
88
  iterator.all_tasks[iterator.cur_task:iterator.cur_task] = [h for b in iterator._play.handlers for h in b.block]
@@ -133,9 +124,6 @@ class StrategyModule(StrategyBase):
133
124
 
134
125
  results = []
135
126
  for (host, task) in host_tasks:
136
- if not task:
137
- continue
138
-
139
127
  if self._tqm._terminated:
140
128
  break
141
129
 
ansible/release.py CHANGED
@@ -17,6 +17,6 @@
17
17
 
18
18
  from __future__ import annotations
19
19
 
20
- __version__ = '2.17.5'
20
+ __version__ = '2.17.6rc1'
21
21
  __author__ = 'Ansible, Inc.'
22
22
  __codename__ = "Gallows Pole"
ansible/utils/galaxy.py CHANGED
@@ -64,7 +64,7 @@ def scm_archive_resource(src, scm='git', name=None, version='HEAD', keep_scm_met
64
64
  clone_cmd = [scm_path, 'clone']
65
65
 
66
66
  # Add specific options for ignoring certificates if requested
67
- ignore_certs = context.CLIARGS['ignore_certs']
67
+ ignore_certs = context.CLIARGS['ignore_certs'] or C.GALAXY_IGNORE_CERTS
68
68
 
69
69
  if ignore_certs:
70
70
  if scm == 'git':
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ansible-core
3
- Version: 2.17.5
3
+ Version: 2.17.6rc1
4
4
  Summary: Radically simple IT automation
5
5
  Home-page: https://ansible.com/
6
6
  Author: Ansible, Inc.
@@ -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=_XGtKRjcMh1__Vz9z-VsGT0sUQ9UlzMetagFX-lsShk,832
6
+ ansible/release.py,sha256=L5LFpIiGyePLM1o5ej00AA_uTPzhtrXceQcejEIHh7k,835
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
@@ -34,10 +34,10 @@ ansible/executor/__init__.py,sha256=mRvbCJPA-_veSG5ka3v04G5vsarLVDeB3EWFsu6geSI,
34
34
  ansible/executor/action_write_locks.py,sha256=Up2n3cwFCr4T4IvttHpe3QOxRBF_9NgWJ1tFm9CHpfM,1915
35
35
  ansible/executor/interpreter_discovery.py,sha256=i9BS5Rw0TWC_32zqRO3KTURjn1J6CugrVxKKqhvmn-k,9974
36
36
  ansible/executor/module_common.py,sha256=4pVfjMgCle9ttAZTeuwSx3Kdi0rljagyHC11i4VnCl4,65755
37
- ansible/executor/play_iterator.py,sha256=FRzl8ELbICqzud-lT2KNuLmPoPntzayf2Y9DboEwso0,30427
37
+ ansible/executor/play_iterator.py,sha256=mrGK7INCfE6L2Gt0X7S0hm0Srtw4T-PYwJVi77BAxls,31457
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=Q9Puu6y0wczvnLMrHaNSeg4FkhFqs6c3Kj6X_RvhII4,60551
40
+ ansible/executor/task_executor.py,sha256=T1f5RrzIUULNpH2dYXftm47165FrtiwVR3hzxQEJBXc,60698
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
@@ -61,7 +61,7 @@ ansible/galaxy/role.py,sha256=yPLmpm1wESUHqmIRYJ9aLlfs-7TBOHwksa4W286SqGs,21120
61
61
  ansible/galaxy/token.py,sha256=Skm_MSpUgn7_SXeGHzdPEPR06kVZ-2dJgYGjm89c8MY,6131
62
62
  ansible/galaxy/user_agent.py,sha256=_Vr4ZJV8HNXhSbhw_dvUr378OjFdyhtLRHyywCjGU6g,760
63
63
  ansible/galaxy/collection/__init__.py,sha256=DBZFQRFQUA7jQknzOXAJbJezXeMNbGpgZpvtBzw3ZJg,78889
64
- ansible/galaxy/collection/concrete_artifact_manager.py,sha256=3i3sSzewQjheGQr_1k0vv8a2ttqdIJ2yxbXfI1Adfl4,29301
64
+ ansible/galaxy/collection/concrete_artifact_manager.py,sha256=fl4Opym_yhPgC2z-rG6WAKeW_qXUx_g42Pq--XtyFO0,29490
65
65
  ansible/galaxy/collection/galaxy_api_proxy.py,sha256=eukJ-rzlQ5eqM9tFb_41PcTigJ6BLmpY5Jhx1JXjZx8,7936
66
66
  ansible/galaxy/collection/gpg.py,sha256=PmsUTfZTLZxwCwA42rPHKI0xBzxmawDKXPazYinbPr0,7422
67
67
  ansible/galaxy/data/collections_galaxy_meta.yml,sha256=UNkGJWZEWSRbyiPbpoqLQdBR4DbAg9DeIB38HSZycoI,4018
@@ -140,7 +140,7 @@ 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=_XGtKRjcMh1__Vz9z-VsGT0sUQ9UlzMetagFX-lsShk,832
143
+ ansible/module_utils/ansible_release.py,sha256=L5LFpIiGyePLM1o5ej00AA_uTPzhtrXceQcejEIHh7k,835
144
144
  ansible/module_utils/api.py,sha256=DWIuLW5gDWuyyDHLLgGnub42Qa8kagDdkf1xDeLAFl4,5784
145
145
  ansible/module_utils/basic.py,sha256=UcDamm_6bkL3HXxKvQcSUlzDOHkIlvd8AYGuqJNmZeI,86113
146
146
  ansible/module_utils/connection.py,sha256=q_BdUaST6E44ltHsWPOFOheXK9vKmzaJvP-eQOrOrmE,8394
@@ -195,7 +195,7 @@ ansible/module_utils/facts/default_collectors.py,sha256=HuBVKiKn9omZI9yzQhfAKZEt
195
195
  ansible/module_utils/facts/namespace.py,sha256=EAzWToQ7tP54GodzmFdtEvzyQrc-2deWhOUQ5lGsoCk,2313
196
196
  ansible/module_utils/facts/packages.py,sha256=f3LXG6NHFW5vJGqu-vz8j39Czevfd8U3bLbHQjXQ6GY,2604
197
197
  ansible/module_utils/facts/sysctl.py,sha256=wkYfbNpHR23ZCgicGe72zXU_Cig1exkHqSwyWZznuug,1895
198
- ansible/module_utils/facts/timeout.py,sha256=LLO9h5wr-2Cf7PB9T_859BOI04dfQktlOJsidMLhCpE,2453
198
+ ansible/module_utils/facts/timeout.py,sha256=rGOnkMaLIvrCDKfCJeQ8ref9jah4tsDzd24KZ-BFPS8,2453
199
199
  ansible/module_utils/facts/utils.py,sha256=cKka93JV5LdMQ_Uec77p7DzyPfSBhitX1AfR0m5v7Dk,3419
200
200
  ansible/module_utils/facts/hardware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
201
201
  ansible/module_utils/facts/hardware/aix.py,sha256=VDGCCFmftjVJQZUf7g3FKVjCGhO7b9JzzuaJfnzn0NA,10453
@@ -234,7 +234,7 @@ ansible/module_utils/facts/system/caps.py,sha256=ymoLYx8RFh75dX4ODEcd5aGcpQhYcWj
234
234
  ansible/module_utils/facts/system/chroot.py,sha256=KBBOXOZOAvsXLCAYiD24k2vKv8x-vRPYHAFH8Km-bdQ,1517
235
235
  ansible/module_utils/facts/system/cmdline.py,sha256=rStcOy2NX5as62oRlwU-OS0QGWC-a1iDLJNJwuDmFWk,2637
236
236
  ansible/module_utils/facts/system/date_time.py,sha256=oDeUy493BIQzp3JVBkoD1DHtu_m-oTWKdxcR4C_db-Q,3125
237
- ansible/module_utils/facts/system/distribution.py,sha256=U3Voxd9-Ui1LY36Nrq1fTlT_iMwgD8Yg79Ifd6oVfnA,32747
237
+ ansible/module_utils/facts/system/distribution.py,sha256=-RvC2N81r2H7zXm-yyIxoQ1_apmoPB69EZNXwbvLsJ4,32747
238
238
  ansible/module_utils/facts/system/dns.py,sha256=_UaIcGLEaSt5Dd51O-JTR82ST1exgTm_DppCaZJnhSc,2692
239
239
  ansible/module_utils/facts/system/env.py,sha256=LPPTxo46aaf30o-uMGetD19v6XWsaPJJgGWwxijn2rc,1185
240
240
  ansible/module_utils/facts/system/fips.py,sha256=g9gbq_bHg25kbvRLewOn1boxXsb5newi_Hhj-D2KZv4,1353
@@ -287,7 +287,7 @@ ansible/modules/command.py,sha256=t0VvOXUwlgO_5Jv7A0TcrG0O-jIlkfdwEJXsc_S5q8A,13
287
287
  ansible/modules/copy.py,sha256=FE1jKP-VVBTrV_eX2td7FHNhEh-ed_KPGCyrAW1N_gA,32102
288
288
  ansible/modules/cron.py,sha256=beuuoj80saY3B7Gtj7wDYLdFuGnxc94iBczakBZhsKY,26198
289
289
  ansible/modules/deb822_repository.py,sha256=CWgVVSuq45dkHrozG2Yk229FdIdGfaFSmBFBQ3ymANs,15741
290
- ansible/modules/debconf.py,sha256=XUVgx2Bfxjkeyw15_lYzfqA2EnVOqR2d-i5mfnP7udg,9172
290
+ ansible/modules/debconf.py,sha256=sL3QKn3fg6bnifY7J3mvbeF7aUoUx7t0H-RL-ByIm4k,9323
291
291
  ansible/modules/debug.py,sha256=jqFvwGzDkB5NlcxR8vXhHjaakv9Ib_GjGdT2GbKhMhE,2907
292
292
  ansible/modules/dnf.py,sha256=uuOAjuUen70MR2j3CwuVzy-NWJnGHoPukHyuo3Dtqvs,56095
293
293
  ansible/modules/dnf5.py,sha256=bbPlc-K-I0NZzCwn3Ke12FUcQu-A8H4S7_gmlxXDgZg,26793
@@ -340,7 +340,7 @@ ansible/modules/tempfile.py,sha256=lA9e8lyFXf9J5ud0R6Jkt8sIFyRcOwzhc9Jz-5_HOZQ,3
340
340
  ansible/modules/template.py,sha256=D1sm36GB_mEimH0CfWq1cJ4w1eRvpcsHwZ-ufVzC_Gs,4537
341
341
  ansible/modules/unarchive.py,sha256=hlRAn2Ma36rmeQ4-OldGLPnHu3w8rlxlvLovQ2pYg5c,44880
342
342
  ansible/modules/uri.py,sha256=WgJA04YvgKTpQsMJFWAg9ITbj8cpIYwZD_tPlD_hcz4,28203
343
- ansible/modules/user.py,sha256=W53gNWD8ymV5o7j80-ROHMfkwG4IPVLuQ2r5Efk98_U,118055
343
+ ansible/modules/user.py,sha256=WXKZLfqFzs-CRzz3HKU2BSWosU_1rb3gAaMtbrO9P8o,118750
344
344
  ansible/modules/validate_argument_spec.py,sha256=epLh4EUaoDLvhdVszRM68Q2QdicK-3jxhMA530dQaIE,3044
345
345
  ansible/modules/wait_for.py,sha256=VXFFcYG88EJVXnrJfa0fzh9rD_2luSty__qdzRuTAQE,27322
346
346
  ansible/modules/wait_for_connection.py,sha256=lHgsuyw3oel1pqXlLCls7KSF1PJaSU0RKGGE6ewbQQY,3326
@@ -403,7 +403,7 @@ ansible/plugins/action/fail.py,sha256=_1JuS0Z8Y8EB4FKG1u7KdP6xMuLobRHJsmtzmvN2Ck
403
403
  ansible/plugins/action/fetch.py,sha256=cQAmUWEGMDjfVfHGviNtsT4i06rnoubL3EgrOlUZbLw,10188
404
404
  ansible/plugins/action/gather_facts.py,sha256=JFkrn3_78A7eUw0I3DsfUoe3Pu3wVLkhLUiOJ7Oyk0A,7863
405
405
  ansible/plugins/action/group_by.py,sha256=97d4TF9o7vS5y0s1HfGgvh70l2gkQ2uUGxy0knlok5Y,1894
406
- ansible/plugins/action/include_vars.py,sha256=XnX2mgcZpK4NHn7Bktc8IUjzRkVbjA4xHsiJ_vap9U0,11525
406
+ ansible/plugins/action/include_vars.py,sha256=_xPrP_BeGqbhvpJYQFDUkREL9UzZ6Y4q_AnCshvsn1A,11573
407
407
  ansible/plugins/action/normal.py,sha256=cCHrZ3z2kB_wnnSNkmJHJWcJNRgdoxnLUNeHex-P8DE,1854
408
408
  ansible/plugins/action/package.py,sha256=pEQ9Wg6Ik3-7nazy1pawlECdKa7-PjMC9xfRzqovvlg,4883
409
409
  ansible/plugins/action/pause.py,sha256=A_U8FhGeFdaOXUadEM-Mv42v9lwsjnxPOE7ExvEfl1s,5674
@@ -523,7 +523,7 @@ ansible/plugins/filter/to_uuid.yml,sha256=ApwjBOSjeHuL5p_zLuFKxhhbYN2ZR1IJ3795sS
523
523
  ansible/plugins/filter/to_yaml.yml,sha256=F4f1WmvPNrBtgG7JzrvW7WNP-uml_f_tAj7RXITSPtM,1672
524
524
  ansible/plugins/filter/type_debug.yml,sha256=xrs13AsR9lV9hRmqsUg4U6zApJpYGCMspUI3or2AdYk,508
525
525
  ansible/plugins/filter/union.yml,sha256=qBIbwRisbsImGixrLj6YDYXJSUGziZkjt_4aJsbhcj0,1018
526
- ansible/plugins/filter/unique.yml,sha256=ZII1RymJplBWxzNOXmpDltqfAvhi8EEbLy0hIrNNzgo,839
526
+ ansible/plugins/filter/unique.yml,sha256=aip4HWd5ZCgg7wYFB6CUqLK0ldrY7qd2Wb_MlTtee3M,1592
527
527
  ansible/plugins/filter/unvault.yml,sha256=GBpNWkLs5sg66PHmrEAR_NsMphuxsWm8dgeVUchbZPI,1069
528
528
  ansible/plugins/filter/urldecode.yml,sha256=zPEvZ6HGc59figLfFMJHISqKCgR1ymdsNYe_nZjTJ_k,716
529
529
  ansible/plugins/filter/urls.py,sha256=b2Zmy1iQuDc4ybU4QqRRAw2HL5xeG5D2kQrT2bybiPM,457
@@ -576,11 +576,11 @@ ansible/plugins/shell/__init__.py,sha256=rEwatHZ46LJuxMFANb6e__CTLkFWX6B0878eBaC
576
576
  ansible/plugins/shell/cmd.py,sha256=kPCSKrJJFH5XTkmteEI3P1Da6WfPSXxDnV39VFpgD-A,2170
577
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=UdcdFDk8cPjPxa6ZlXyIJUi7B0Pf5dEPCjm73plgcTE,57037
579
+ ansible/plugins/strategy/__init__.py,sha256=EtxIpgZMoYM3Me3Cj7t0oys48JJMyCj9u4nK5gz35FI,57095
580
580
  ansible/plugins/strategy/debug.py,sha256=yMmfT-lQHfR2y9bQcqrSPzqHuWZMo7V9y4ZWOXoboRE,1205
581
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
- ansible/plugins/strategy/linear.py,sha256=no9JgVrgqoN3SphXE38y3DTK1P9FpB48Qn21ro2qFZU,18394
583
+ ansible/plugins/strategy/linear.py,sha256=syZPVmCr2hlHBAzdpUtoajIz4Zs3ycXzcvlUGyQl5_0,17997
584
584
  ansible/plugins/terminal/__init__.py,sha256=EqeJpMokRzuUMO66yYErPSyninjqNX0_5r55CEkTc4o,4420
585
585
  ansible/plugins/test/__init__.py,sha256=m-XTUgWU-qSLJoZvHN3A85igElMjhaBJrzCTDrU7zhs,418
586
586
  ansible/plugins/test/abs.yml,sha256=lZA0XP1oBNg___Du6SqNOkDeQC9xIcZpROYV5XJG9bg,764
@@ -648,7 +648,7 @@ ansible/utils/context_objects.py,sha256=vYulSJkzR3zxsQF_6_AqbPCCMy8WGC5dSqLFXJZq
648
648
  ansible/utils/display.py,sha256=Ld3dNZTvvLRZmPCq191Iu-t4EIzoIP1fY_-X7qcoSts,32094
649
649
  ansible/utils/encrypt.py,sha256=MU0teLATt7qtTwk-y809H5HApafSl2QMW1INWIUL3T4,7221
650
650
  ansible/utils/fqcn.py,sha256=Jx5SwYzlbMZ-SlkjyKkM4pCe5jIyXeeo62BU1msUunU,1215
651
- ansible/utils/galaxy.py,sha256=wQ3s8Mr7Ib0C2ou1SloA76ZOraJr48ADZZf_6vaNYdg,3830
651
+ ansible/utils/galaxy.py,sha256=Un3XgXhx8FoC6tkp1cZ33rmiAaRg634exKruwOVhtdQ,3855
652
652
  ansible/utils/hashing.py,sha256=RKJSXjZ5dgnTdqC4NOqOKYm_r7F4vw5ToW9YgxIt8QU,2837
653
653
  ansible/utils/helpers.py,sha256=GECErEAio6-mOcUrMtPWRvegTNfCBToBdmHXrGXYBbc,1759
654
654
  ansible/utils/jsonrpc.py,sha256=Wn7KuzRwN1FFOgGpCzgX3ORWHkxYWX_Z_3Tt1Larp18,3792
@@ -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.5.data/scripts/ansible-test,sha256=dyY2HtRZotRQO3b89HGXY_KnJgBvgsm4eLIe4B2LUoA,1637
681
+ ansible_core-2.17.6rc1.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
@@ -745,7 +745,7 @@ ansible_test/_internal/coverage_util.py,sha256=p8zcoN6DyyNcLWHzAOtGMeN_6BHTCD1jR
745
745
  ansible_test/_internal/data.py,sha256=OFDpRa47yqBqQO1aSvTZVQQpScHvBHsr861586MQEUI,11184
746
746
  ansible_test/_internal/delegation.py,sha256=D8hluDQf_YN3DtVG_8HW0iumRBY3gjp_zP-rlc3VNY4,13418
747
747
  ansible_test/_internal/diff.py,sha256=qfzSL7BtoW7bLLgzF0-m--jthVDpUQSr9aBw1fCMIHk,7310
748
- ansible_test/_internal/docker_util.py,sha256=tSB5fUPzdxsxo9igkowE2X7z4_Y3eTYc51Pfe6562vY,37901
748
+ ansible_test/_internal/docker_util.py,sha256=xpsOEbCBTL1l4q4vUvGC3AqFVs7-VQ9ZDw_hPBoYQoY,38220
749
749
  ansible_test/_internal/encoding.py,sha256=E61EfXbQw0uQoFhbN3SYx3Oy_1tAMCPAAvY9hkEcSSo,1367
750
750
  ansible_test/_internal/executor.py,sha256=KW5yI-f-giErQ077MTj707fTtFkf_Kr8IV_Nr36NNmc,2959
751
751
  ansible_test/_internal/git.py,sha256=njtciWq2DlzZ1DAkQi08HRRP-TgH0mgeGZsWcsJGctI,4366
@@ -767,7 +767,7 @@ ansible_test/_internal/target.py,sha256=Whtb_n0jn4zbiMmX7je5jewgzsRczfXRm_ndYtjT
767
767
  ansible_test/_internal/test.py,sha256=znQmGjKACqDU8T0EAPqcv2qyy0J7M2w4OmyYhwHLqT0,14515
768
768
  ansible_test/_internal/thread.py,sha256=WQoZ2q2ljmEkKHRDkIqwxW7eZbkCKDrG3YZfcaxHzHw,2596
769
769
  ansible_test/_internal/timeout.py,sha256=hT-LirImhAh1iCGIh8JpmECXsiGu6Zetw8BWl1iBIC8,4050
770
- ansible_test/_internal/util.py,sha256=eVRJTt5rWcOf-Yi8UnQVwU_EvK9i2Ktrg9NYGDM24FI,37567
770
+ ansible_test/_internal/util.py,sha256=NAeVlq-vOwwZzIaFOxnjsFwdibSp_9k1ay8YkChGCxU,37792
771
771
  ansible_test/_internal/util_common.py,sha256=W5mkR0sevcyMWsMPYcpxRN-b8It8N9g6PqkophHCI9U,17385
772
772
  ansible_test/_internal/venv.py,sha256=k7L9_Ocpsdwp4kQFLF59BVguymd2nqJ-bLHH1NlMET0,5521
773
773
  ansible_test/_internal/ci/__init__.py,sha256=QOaC_8_wUzqFEbsFCXYAnElWoUo6gB40CXvP9RJ-Iyo,7738
@@ -930,7 +930,7 @@ ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg,sha256=SFagBky
930
930
  ansible_test/_util/controller/sanity/pylint/config/collection.cfg,sha256=m2cplKx5iPLUbEizDOflMKU_5QR2HPe_gTxEeMqOWPQ,4373
931
931
  ansible_test/_util/controller/sanity/pylint/config/default.cfg,sha256=cFHZCDu6yeqPaZkUrxMhK3_Cp5Q-UKjVdE3M6XiH-xY,3879
932
932
  ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py,sha256=UVsdv1MtIcydrKDYJxgyeNRbmMvDv0jw9FGpW7cXUO0,18615
933
- ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py,sha256=HU4zOeVgNcr_xtz9f7OFSCiT9gB2oRC1Nc8v-5CSk4E,894
933
+ ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py,sha256=Fua0oKX3ONMELx4UrmWDJOx-KBP9ZkvuSq-EgqHedtE,835
934
934
  ansible_test/_util/controller/sanity/pylint/plugins/string_format.py,sha256=hAX_9P0VR5ngilRKxN5NOgS4vJmoeGCgLJ2mMI8IliA,2626
935
935
  ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py,sha256=9ZS9CiTARriKsHw807pO4Wp9FGg01xQqWJXwD9MeiJ8,9061
936
936
  ansible_test/_util/controller/sanity/shellcheck/exclude.txt,sha256=fKw7FyFVyQ2Er9GViQj_1ccQpWh7NhbL2ok8G9I3XGU,14
@@ -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.5.dist-info/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
983
- ansible_core-2.17.5.dist-info/METADATA,sha256=bpWsSr2R2RLt-a1eFmzwx9mKKGG2xFii9spybVSQxmg,6945
984
- ansible_core-2.17.5.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
985
- ansible_core-2.17.5.dist-info/entry_points.txt,sha256=0mpmsrIhODChxKl3eS-NcVQCaMetBn8KdPLtVxQgR64,453
986
- ansible_core-2.17.5.dist-info/top_level.txt,sha256=IFbRLjAvih1DYzJWg3_F6t4sCzEMxRO7TOMNs6GkYHo,21
987
- ansible_core-2.17.5.dist-info/RECORD,,
982
+ ansible_core-2.17.6rc1.dist-info/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
983
+ ansible_core-2.17.6rc1.dist-info/METADATA,sha256=IwaRh7UlvEK8CN4UUaEhQrEliddnWsCs3Tu_SIL--yo,6948
984
+ ansible_core-2.17.6rc1.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
985
+ ansible_core-2.17.6rc1.dist-info/entry_points.txt,sha256=0mpmsrIhODChxKl3eS-NcVQCaMetBn8KdPLtVxQgR64,453
986
+ ansible_core-2.17.6rc1.dist-info/top_level.txt,sha256=IFbRLjAvih1DYzJWg3_F6t4sCzEMxRO7TOMNs6GkYHo,21
987
+ ansible_core-2.17.6rc1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.1.0)
2
+ Generator: setuptools (75.3.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -20,6 +20,8 @@ from .util import (
20
20
  SubprocessError,
21
21
  cache,
22
22
  OutputStream,
23
+ InternalError,
24
+ format_command_output,
23
25
  )
24
26
 
25
27
  from .util_common import (
@@ -300,7 +302,7 @@ def detect_host_properties(args: CommonConfig) -> ContainerHostProperties:
300
302
  options = ['--volume', '/sys/fs/cgroup:/probe:ro']
301
303
  cmd = ['sh', '-c', ' && echo "-" && '.join(multi_line_commands)]
302
304
 
303
- stdout = run_utility_container(args, 'ansible-test-probe', cmd, options)[0]
305
+ stdout, stderr = run_utility_container(args, 'ansible-test-probe', cmd, options)
304
306
 
305
307
  if args.explain:
306
308
  return ContainerHostProperties(
@@ -313,6 +315,12 @@ def detect_host_properties(args: CommonConfig) -> ContainerHostProperties:
313
315
 
314
316
  blocks = stdout.split('\n-\n')
315
317
 
318
+ if len(blocks) != len(multi_line_commands):
319
+ message = f'Unexpected probe output. Expected {len(multi_line_commands)} blocks but found {len(blocks)}.\n'
320
+ message += format_command_output(stdout, stderr)
321
+
322
+ raise InternalError(message.strip())
323
+
316
324
  values = blocks[0].split('\n')
317
325
 
318
326
  audit_parts = values[0].split(' ', 1)
@@ -930,14 +930,7 @@ class SubprocessError(ApplicationError):
930
930
  error_callback: t.Optional[c.Callable[[SubprocessError], None]] = None,
931
931
  ) -> None:
932
932
  message = 'Command "%s" returned exit status %s.\n' % (shlex.join(cmd), status)
933
-
934
- if stderr:
935
- message += '>>> Standard Error\n'
936
- message += '%s%s\n' % (stderr.strip(), Display.clear)
937
-
938
- if stdout:
939
- message += '>>> Standard Output\n'
940
- message += '%s%s\n' % (stdout.strip(), Display.clear)
933
+ message += format_command_output(stdout, stderr)
941
934
 
942
935
  self.cmd = cmd
943
936
  self.message = message
@@ -981,6 +974,21 @@ class HostConnectionError(ApplicationError):
981
974
  self._callback()
982
975
 
983
976
 
977
+ def format_command_output(stdout: str, stderr: str) -> str:
978
+ """Return a formatted string containing the given stdout and stderr (if any)."""
979
+ message = ''
980
+
981
+ if stderr := stderr.strip():
982
+ message += '>>> Standard Error\n'
983
+ message += f'{stderr}{Display.clear}\n'
984
+
985
+ if stdout := stdout.strip():
986
+ message += '>>> Standard Output\n'
987
+ message += f'{stdout}{Display.clear}\n'
988
+
989
+ return message
990
+
991
+
984
992
  def retry(func: t.Callable[..., TValue], ex_type: t.Type[BaseException] = SubprocessError, sleep: int = 10, attempts: int = 10, warn: bool = True) -> TValue:
985
993
  """Retry the specified function on failure."""
986
994
  for dummy in range(1, attempts):
@@ -1,4 +1,4 @@
1
- """Temporary plugin to prevent stdout noise pollution from finalization of abandoned generators under Python 3.12"""
1
+ """Temporary plugin to prevent stdout noise pollution from finalization of abandoned generators."""
2
2
  from __future__ import annotations
3
3
 
4
4
  import sys
@@ -10,7 +10,7 @@ if t.TYPE_CHECKING:
10
10
 
11
11
  def _mask_finalizer_valueerror(ur: t.Any) -> None:
12
12
  """Mask only ValueErrors from finalizing abandoned generators; delegate everything else"""
13
- # work around Py3.12 finalizer changes that sometimes spews this error message to stdout
13
+ # work around Python finalizer issue that sometimes spews this error message to stdout
14
14
  # see https://github.com/pylint-dev/pylint/issues/9138
15
15
  if ur.exc_type is ValueError and 'generator already executing' in str(ur.exc_value):
16
16
  return
@@ -20,5 +20,4 @@ def _mask_finalizer_valueerror(ur: t.Any) -> None:
20
20
 
21
21
  def register(linter: PyLinter) -> None: # pylint: disable=unused-argument
22
22
  """PyLint plugin registration entrypoint"""
23
- if sys.version_info >= (3, 12):
24
- sys.unraisablehook = _mask_finalizer_valueerror
23
+ sys.unraisablehook = _mask_finalizer_valueerror