ansible-core 2.16.6__py3-none-any.whl → 2.16.7__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.

@@ -429,13 +429,13 @@ class PlayIterator:
429
429
  # might be there from previous flush
430
430
  state.handlers = self.handlers[:]
431
431
  state.update_handlers = False
432
- state.cur_handlers_task = 0
433
432
 
434
433
  while True:
435
434
  try:
436
435
  task = state.handlers[state.cur_handlers_task]
437
436
  except IndexError:
438
437
  task = None
438
+ state.cur_handlers_task = 0
439
439
  state.run_state = state.pre_flushing_run_state
440
440
  state.update_handlers = True
441
441
  break
ansible/galaxy/role.py CHANGED
@@ -387,6 +387,8 @@ class GalaxyRole(object):
387
387
  else:
388
388
  os.makedirs(self.path)
389
389
 
390
+ resolved_archive = unfrackpath(archive_parent_dir, follow=False)
391
+
390
392
  # We strip off any higher-level directories for all of the files
391
393
  # contained within the tar file here. The default is 'github_repo-target'.
392
394
  # Gerrit instances, on the other hand, does not have a parent directory at all.
@@ -401,33 +403,29 @@ class GalaxyRole(object):
401
403
  if not (attr_value := getattr(member, attr, None)):
402
404
  continue
403
405
 
404
- if attr_value.startswith(os.sep) and not is_subpath(attr_value, archive_parent_dir):
405
- err = f"Invalid {attr} for tarfile member: path {attr_value} is not a subpath of the role {archive_parent_dir}"
406
- raise AnsibleError(err)
407
-
408
406
  if attr == 'linkname':
409
407
  # Symlinks are relative to the link
410
- relative_to_archive_dir = os.path.dirname(getattr(member, 'name', ''))
411
- archive_dir_path = os.path.join(archive_parent_dir, relative_to_archive_dir, attr_value)
408
+ relative_to = os.path.dirname(getattr(member, 'name', ''))
412
409
  else:
413
410
  # Normalize paths that start with the archive dir
414
411
  attr_value = attr_value.replace(archive_parent_dir, "", 1)
415
412
  attr_value = os.path.join(*attr_value.split(os.sep)) # remove leading os.sep
416
- archive_dir_path = os.path.join(archive_parent_dir, attr_value)
413
+ relative_to = ''
417
414
 
418
- resolved_archive = unfrackpath(archive_parent_dir)
419
- resolved_path = unfrackpath(archive_dir_path)
420
- if not is_subpath(resolved_path, resolved_archive):
421
- err = f"Invalid {attr} for tarfile member: path {resolved_path} is not a subpath of the role {resolved_archive}"
415
+ full_path = os.path.join(resolved_archive, relative_to, attr_value)
416
+ if not is_subpath(full_path, resolved_archive, real=True):
417
+ err = f"Invalid {attr} for tarfile member: path {full_path} is not a subpath of the role {resolved_archive}"
422
418
  raise AnsibleError(err)
423
419
 
424
- relative_path = os.path.join(*resolved_path.replace(resolved_archive, "", 1).split(os.sep)) or '.'
420
+ relative_path_dir = os.path.join(resolved_archive, relative_to)
421
+ relative_path = os.path.join(*full_path.replace(relative_path_dir, "", 1).split(os.sep))
425
422
  setattr(member, attr, relative_path)
426
423
 
427
424
  if _check_working_data_filter():
428
425
  # deprecated: description='extract fallback without filter' python_version='3.11'
429
426
  role_tar_file.extract(member, to_native(self.path), filter='data') # type: ignore[call-arg]
430
427
  else:
428
+ # Remove along with manual path filter once Python 3.12 is minimum supported version
431
429
  role_tar_file.extract(member, to_native(self.path))
432
430
 
433
431
  # write out the install info file for later use
@@ -19,6 +19,6 @@
19
19
  from __future__ import (absolute_import, division, print_function)
20
20
  __metaclass__ = type
21
21
 
22
- __version__ = '2.16.6'
22
+ __version__ = '2.16.7'
23
23
  __author__ = 'Ansible, Inc.'
24
24
  __codename__ = "All My Love"
ansible/modules/dnf.py CHANGED
@@ -380,7 +380,6 @@ EXAMPLES = '''
380
380
  '''
381
381
 
382
382
  import os
383
- import re
384
383
  import sys
385
384
 
386
385
  from ansible.module_utils.common.text.converters import to_native, to_text
@@ -482,94 +481,6 @@ class DnfModule(YumDnf):
482
481
 
483
482
  return result
484
483
 
485
- def _split_package_arch(self, packagename):
486
- # This list was auto generated on a Fedora 28 system with the following one-liner
487
- # printf '[ '; for arch in $(ls /usr/lib/rpm/platform); do printf '"%s", ' ${arch%-linux}; done; printf ']\n'
488
- redhat_rpm_arches = [
489
- "aarch64", "alphaev56", "alphaev5", "alphaev67", "alphaev6", "alpha",
490
- "alphapca56", "amd64", "armv3l", "armv4b", "armv4l", "armv5tejl", "armv5tel",
491
- "armv5tl", "armv6hl", "armv6l", "armv7hl", "armv7hnl", "armv7l", "athlon",
492
- "geode", "i386", "i486", "i586", "i686", "ia32e", "ia64", "m68k", "mips64el",
493
- "mips64", "mips64r6el", "mips64r6", "mipsel", "mips", "mipsr6el", "mipsr6",
494
- "noarch", "pentium3", "pentium4", "ppc32dy4", "ppc64iseries", "ppc64le", "ppc64",
495
- "ppc64p7", "ppc64pseries", "ppc8260", "ppc8560", "ppciseries", "ppc", "ppcpseries",
496
- "riscv64", "s390", "s390x", "sh3", "sh4a", "sh4", "sh", "sparc64", "sparc64v",
497
- "sparc", "sparcv8", "sparcv9", "sparcv9v", "x86_64"
498
- ]
499
-
500
- name, delimiter, arch = packagename.rpartition('.')
501
- if name and arch and arch in redhat_rpm_arches:
502
- return name, arch
503
- return packagename, None
504
-
505
- def _packagename_dict(self, packagename):
506
- """
507
- Return a dictionary of information for a package name string or None
508
- if the package name doesn't contain at least all NVR elements
509
- """
510
-
511
- if packagename[-4:] == '.rpm':
512
- packagename = packagename[:-4]
513
-
514
- rpm_nevr_re = re.compile(r'(\S+)-(?:(\d*):)?(.*)-(~?\w+[\w.+]*)')
515
- try:
516
- arch = None
517
- nevr, arch = self._split_package_arch(packagename)
518
- if arch:
519
- packagename = nevr
520
- rpm_nevr_match = rpm_nevr_re.match(packagename)
521
- if rpm_nevr_match:
522
- name, epoch, version, release = rpm_nevr_re.match(packagename).groups()
523
- if not version or not version.split('.')[0].isdigit():
524
- return None
525
- else:
526
- return None
527
- except AttributeError as e:
528
- self.module.fail_json(
529
- msg='Error attempting to parse package: %s, %s' % (packagename, to_native(e)),
530
- rc=1,
531
- results=[]
532
- )
533
-
534
- if not epoch:
535
- epoch = "0"
536
-
537
- if ':' in name:
538
- epoch_name = name.split(":")
539
-
540
- epoch = epoch_name[0]
541
- name = ''.join(epoch_name[1:])
542
-
543
- result = {
544
- 'name': name,
545
- 'epoch': epoch,
546
- 'release': release,
547
- 'version': version,
548
- }
549
-
550
- return result
551
-
552
- # Original implementation from yum.rpmUtils.miscutils (GPLv2+)
553
- # http://yum.baseurl.org/gitweb?p=yum.git;a=blob;f=rpmUtils/miscutils.py
554
- def _compare_evr(self, e1, v1, r1, e2, v2, r2):
555
- # return 1: a is newer than b
556
- # 0: a and b are the same version
557
- # -1: b is newer than a
558
- if e1 is None:
559
- e1 = '0'
560
- else:
561
- e1 = str(e1)
562
- v1 = str(v1)
563
- r1 = str(r1)
564
- if e2 is None:
565
- e2 = '0'
566
- else:
567
- e2 = str(e2)
568
- v2 = str(v2)
569
- r2 = str(r2)
570
- rc = dnf.rpm.rpm.labelCompare((e1, v1, r1), (e2, v2, r2))
571
- return rc
572
-
573
484
  def _ensure_dnf(self):
574
485
  locale = get_best_parsable_locale(self.module)
575
486
  os.environ['LC_ALL'] = os.environ['LC_MESSAGES'] = locale
@@ -578,7 +489,6 @@ class DnfModule(YumDnf):
578
489
  global dnf
579
490
  try:
580
491
  import dnf
581
- import dnf.cli
582
492
  import dnf.const
583
493
  import dnf.exceptions
584
494
  import dnf.package
@@ -809,43 +719,22 @@ class DnfModule(YumDnf):
809
719
  self.module.exit_json(msg="", results=results)
810
720
 
811
721
  def _is_installed(self, pkg):
812
- installed = self.base.sack.query().installed()
813
-
814
- package_spec = {}
815
- name, arch = self._split_package_arch(pkg)
816
- if arch:
817
- package_spec['arch'] = arch
818
-
819
- package_details = self._packagename_dict(pkg)
820
- if package_details:
821
- package_details['epoch'] = int(package_details['epoch'])
822
- package_spec.update(package_details)
823
- else:
824
- package_spec['name'] = name
825
-
826
- return bool(installed.filter(**package_spec))
722
+ return bool(
723
+ dnf.subject.Subject(pkg).get_best_query(sack=self.base.sack).installed().run()
724
+ )
827
725
 
828
726
  def _is_newer_version_installed(self, pkg_name):
829
- candidate_pkg = self._packagename_dict(pkg_name)
830
- if not candidate_pkg:
831
- # The user didn't provide a versioned rpm, so version checking is
832
- # not required
833
- return False
834
-
835
- installed = self.base.sack.query().installed()
836
- installed_pkg = installed.filter(name=candidate_pkg['name']).run()
837
- if installed_pkg:
838
- installed_pkg = installed_pkg[0]
839
-
840
- # this looks weird but one is a dict and the other is a dnf.Package
841
- evr_cmp = self._compare_evr(
842
- installed_pkg.epoch, installed_pkg.version, installed_pkg.release,
843
- candidate_pkg['epoch'], candidate_pkg['version'], candidate_pkg['release'],
844
- )
845
-
846
- return evr_cmp == 1
847
- else:
727
+ try:
728
+ if isinstance(pkg_name, dnf.package.Package):
729
+ available = pkg_name
730
+ else:
731
+ available = sorted(
732
+ dnf.subject.Subject(pkg_name).get_best_query(sack=self.base.sack).available().run()
733
+ )[-1]
734
+ installed = sorted(self.base.sack.query().installed().filter(name=available.name).run())[-1]
735
+ except IndexError:
848
736
  return False
737
+ return installed > available
849
738
 
850
739
  def _mark_package_install(self, pkg_spec, upgrade=False):
851
740
  """Mark the package for install."""
@@ -917,17 +806,6 @@ class DnfModule(YumDnf):
917
806
  "results": []
918
807
  }
919
808
 
920
- def _whatprovides(self, filepath):
921
- self.base.read_all_repos()
922
- available = self.base.sack.query().available()
923
- # Search in file
924
- files_filter = available.filter(file=filepath)
925
- # And Search in provides
926
- pkg_spec = files_filter.union(available.filter(provides=filepath)).run()
927
-
928
- if pkg_spec:
929
- return pkg_spec[0].name
930
-
931
809
  def _parse_spec_group_file(self):
932
810
  pkg_specs, grp_specs, module_specs, filenames = [], [], [], []
933
811
  already_loaded_comps = False # Only load this if necessary, it's slow
@@ -939,11 +817,13 @@ class DnfModule(YumDnf):
939
817
  elif name.endswith(".rpm"):
940
818
  filenames.append(name)
941
819
  elif name.startswith('/'):
942
- # like "dnf install /usr/bin/vi"
943
- pkg_spec = self._whatprovides(name)
944
- if pkg_spec:
945
- pkg_specs.append(pkg_spec)
946
- continue
820
+ # dnf install /usr/bin/vi
821
+ installed = self.base.sack.query().filter(provides=name, file=name).installed().run()
822
+ if installed:
823
+ pkg_specs.append(installed[0].name) # should be only one?
824
+ elif not self.update_only:
825
+ # not installed, pass the filename for dnf to process
826
+ pkg_specs.append(name)
947
827
  elif name.startswith("@") or ('/' in name):
948
828
  if not already_loaded_comps:
949
829
  self.base.read_comps()
@@ -1005,7 +885,7 @@ class DnfModule(YumDnf):
1005
885
  else:
1006
886
  for pkg in pkgs:
1007
887
  try:
1008
- if self._is_newer_version_installed(self._package_dict(pkg)['nevra']):
888
+ if self._is_newer_version_installed(pkg):
1009
889
  if self.allow_downgrade:
1010
890
  self.base.package_install(pkg, strict=self.base.conf.strict)
1011
891
  else:
ansible/modules/dnf5.py CHANGED
@@ -361,19 +361,37 @@ def is_newer_version_installed(base, spec):
361
361
  spec_nevra = next(iter(libdnf5.rpm.Nevra.parse(spec)))
362
362
  except RuntimeError:
363
363
  return False
364
- spec_name = spec_nevra.get_name()
365
- v = spec_nevra.get_version()
366
- r = spec_nevra.get_release()
367
- if not v or not r:
364
+
365
+ spec_version = spec_nevra.get_version()
366
+ if not spec_version:
368
367
  return False
369
- spec_evr = "{}:{}-{}".format(spec_nevra.get_epoch() or "0", v, r)
370
368
 
371
- query = libdnf5.rpm.PackageQuery(base)
372
- query.filter_installed()
373
- query.filter_name([spec_name])
374
- query.filter_evr([spec_evr], libdnf5.common.QueryCmp_GT)
369
+ installed = libdnf5.rpm.PackageQuery(base)
370
+ installed.filter_installed()
371
+ installed.filter_name([spec_nevra.get_name()])
372
+ installed.filter_latest_evr()
373
+ try:
374
+ installed_package = list(installed)[-1]
375
+ except IndexError:
376
+ return False
375
377
 
376
- return query.size() > 0
378
+ target = libdnf5.rpm.PackageQuery(base)
379
+ target.filter_name([spec_nevra.get_name()])
380
+ target.filter_version([spec_version])
381
+ spec_release = spec_nevra.get_release()
382
+ if spec_release:
383
+ target.filter_release([spec_release])
384
+ spec_epoch = spec_nevra.get_epoch()
385
+ if spec_epoch:
386
+ target.filter_epoch([spec_epoch])
387
+ target.filter_latest_evr()
388
+ try:
389
+ target_package = list(target)[-1]
390
+ except IndexError:
391
+ return False
392
+
393
+ # FIXME https://github.com/rpm-software-management/dnf5/issues/1104
394
+ return libdnf5.rpm.rpmvercmp(installed_package.get_evr(), target_package.get_evr()) == 1
377
395
 
378
396
 
379
397
  def package_to_dict(package):
@@ -606,13 +624,7 @@ class Dnf5Module(YumDnf):
606
624
  for spec in self.names:
607
625
  if is_newer_version_installed(base, spec):
608
626
  if self.allow_downgrade:
609
- if upgrade:
610
- if is_installed(base, spec):
611
- goal.add_upgrade(spec, settings)
612
- else:
613
- goal.add_install(spec, settings)
614
- else:
615
- goal.add_install(spec, settings)
627
+ goal.add_install(spec, settings)
616
628
  elif is_installed(base, spec):
617
629
  if upgrade:
618
630
  goal.add_upgrade(spec, settings)
ansible/modules/uri.py CHANGED
@@ -108,14 +108,15 @@ options:
108
108
  default: no
109
109
  follow_redirects:
110
110
  description:
111
- - Whether or not the URI module should follow redirects. V(all) will follow all redirects.
112
- V(safe) will follow only "safe" redirects, where "safe" means that the client is only
113
- doing a GET or HEAD on the URI to which it is being redirected. V(none) will not follow
114
- any redirects. Note that V(true) and V(false) choices are accepted for backwards compatibility,
115
- where V(true) is the equivalent of V(all) and V(false) is the equivalent of V(safe). V(true) and V(false)
116
- are deprecated and will be removed in some future version of Ansible.
111
+ - Whether or not the URI module should follow redirects.
112
+ - V(all) Will follow all redirects.
113
+ - V(none) Will not follow any redirects.
114
+ - V(safe) Only redirects doing GET or HEAD requests will be followed.
115
+ - V(urllib2) Defer to urllib2 behavior (As of writing this follows HTTP redirects).
116
+ - V('no') (DEPRECATED, will be removed in the future version) alias of V(none).
117
+ - V('yes') (DEPRECATED, will be removed in the future version) alias of V(all).
118
+ choices: ['all', 'none', 'safe', 'urllib2', 'yes', 'no']
117
119
  type: str
118
- choices: ['all', 'no', 'none', 'safe', 'urllib2', 'yes']
119
120
  default: safe
120
121
  creates:
121
122
  description:
ansible/modules/user.py CHANGED
@@ -1063,12 +1063,6 @@ class User(object):
1063
1063
  exists = True
1064
1064
  break
1065
1065
 
1066
- if not exists:
1067
- self.module.warn(
1068
- "'local: true' specified and user '{name}' was not found in {file}. "
1069
- "The local user account may already exist if the local account database exists "
1070
- "somewhere other than {file}.".format(file=self.PASSWORDFILE, name=self.name))
1071
-
1072
1066
  return exists
1073
1067
 
1074
1068
  else:
@@ -48,7 +48,6 @@ RAW_PARAM_MODULES = FREEFORM_ACTIONS.union(add_internal_fqcns((
48
48
 
49
49
  BUILTIN_TASKS = frozenset(add_internal_fqcns((
50
50
  'meta',
51
- 'include',
52
51
  'include_tasks',
53
52
  'include_role',
54
53
  'import_tasks',
@@ -304,9 +303,14 @@ class ModuleArgsParser:
304
303
  elif skip_action_validation:
305
304
  is_action_candidate = True
306
305
  else:
307
- context = action_loader.find_plugin_with_context(item, collection_list=self._collection_list)
308
- if not context.resolved:
309
- context = module_loader.find_plugin_with_context(item, collection_list=self._collection_list)
306
+ try:
307
+ context = action_loader.find_plugin_with_context(item, collection_list=self._collection_list)
308
+ if not context.resolved:
309
+ context = module_loader.find_plugin_with_context(item, collection_list=self._collection_list)
310
+ except AnsibleError as e:
311
+ if e.obj is None:
312
+ e.obj = self._task_ds
313
+ raise e
310
314
 
311
315
  is_action_candidate = context.resolved and bool(context.redirect_list)
312
316
 
@@ -1339,7 +1339,7 @@ class ActionBase(ABC):
1339
1339
  display.debug(u"_low_level_execute_command() done: rc=%d, stdout=%s, stderr=%s" % (rc, out, err))
1340
1340
  return dict(rc=rc, stdout=out, stdout_lines=out.splitlines(), stderr=err, stderr_lines=err.splitlines())
1341
1341
 
1342
- def _get_diff_data(self, destination, source, task_vars, content, source_file=True):
1342
+ def _get_diff_data(self, destination, source, task_vars, content=None, source_file=True):
1343
1343
 
1344
1344
  # Note: Since we do not diff the source and destination before we transform from bytes into
1345
1345
  # text the diff between source and destination may not be accurate. To fix this, we'd need
@@ -14,7 +14,7 @@ description:
14
14
  underlying transport but instead runs in a PowerShell interpreter.
15
15
  version_added: "2.7"
16
16
  requirements:
17
- - pypsrp>=0.4.0 (Python library)
17
+ - pypsrp>=0.4.0, <1.0.0 (Python library)
18
18
  extends_documentation_fragment:
19
19
  - connection_pipelining
20
20
  options:
@@ -88,7 +88,14 @@ options:
88
88
  - section: url_lookup
89
89
  key: force_basic_auth
90
90
  follow_redirects:
91
- description: String of urllib2, all/yes, safe, none to determine how redirects are followed, see RedirectHandlerFactory for more information
91
+ description:
92
+ - String of urllib2, all/yes, safe, none to determine how redirects are followed, see RedirectHandlerFactory for more information.
93
+ - V(all) Will follow all redirects.
94
+ - V(none) Will not follow any redirects.
95
+ - V(safe) Only redirects doing GET or HEAD requests will be followed.
96
+ - V(urllib2) Defer to urllib2 behavior (As of writing this follows HTTP redirects).
97
+ - V('no') (DEPRECATED, will be removed in the future version) alias of V(none).
98
+ - V('yes') (DEPRECATED, will be removed in the future version) alias of V(all).
92
99
  type: string
93
100
  version_added: "2.10"
94
101
  default: 'urllib2'
@@ -99,6 +106,7 @@ options:
99
106
  ini:
100
107
  - section: url_lookup
101
108
  key: follow_redirects
109
+ choices: ['all', 'none', 'safe', 'urllib2', 'yes', 'no']
102
110
  use_gssapi:
103
111
  description:
104
112
  - Use GSSAPI handler of requests
ansible/release.py CHANGED
@@ -19,6 +19,6 @@
19
19
  from __future__ import (absolute_import, division, print_function)
20
20
  __metaclass__ = type
21
21
 
22
- __version__ = '2.16.6'
22
+ __version__ = '2.16.7'
23
23
  __author__ = 'Ansible, Inc.'
24
24
  __codename__ = "All My Love"
@@ -86,26 +86,26 @@ def generate_ansible_template_vars(path, fullpath=None, dest_path=None):
86
86
  template_uid = os.stat(b_path).st_uid
87
87
 
88
88
  temp_vars = {
89
- 'template_host': to_text(os.uname()[1]),
90
- 'template_path': path,
89
+ 'template_host': to_unsafe_text(os.uname()[1]),
90
+ 'template_path': to_unsafe_text(path),
91
91
  'template_mtime': datetime.datetime.fromtimestamp(os.path.getmtime(b_path)),
92
- 'template_uid': to_text(template_uid),
92
+ 'template_uid': to_unsafe_text(template_uid),
93
93
  'template_run_date': datetime.datetime.now(),
94
- 'template_destpath': to_native(dest_path) if dest_path else None,
94
+ 'template_destpath': wrap_var(to_native(dest_path)) if dest_path else None,
95
95
  }
96
96
 
97
97
  if fullpath is None:
98
- temp_vars['template_fullpath'] = os.path.abspath(path)
98
+ temp_vars['template_fullpath'] = wrap_var(os.path.abspath(path))
99
99
  else:
100
- temp_vars['template_fullpath'] = fullpath
100
+ temp_vars['template_fullpath'] = wrap_var(fullpath)
101
101
 
102
102
  managed_default = C.DEFAULT_MANAGED_STR
103
103
  managed_str = managed_default.format(
104
- host=temp_vars['template_host'],
105
- uid=temp_vars['template_uid'],
106
- file=temp_vars['template_path'].replace('%', '%%'),
104
+ host="{{ template_host }}",
105
+ uid="{{ template_uid }}",
106
+ file="{{ template_path }}"
107
107
  )
108
- temp_vars['ansible_managed'] = to_unsafe_text(time.strftime(to_native(managed_str), time.localtime(os.path.getmtime(b_path))))
108
+ temp_vars['ansible_managed'] = time.strftime(to_native(managed_str), time.localtime(os.path.getmtime(b_path)))
109
109
 
110
110
  return temp_vars
111
111
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ansible-core
3
- Version: 2.16.6
3
+ Version: 2.16.7
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=IvyRvY64pT0on94qCLibxgDJ0-7_2CRoaZ5kfGOl54Q,1395
3
3
  ansible/constants.py,sha256=FvX7PDG0GWV91Vszb5-DFKvkR8O2OTpBmIbQk-d51sc,9193
4
4
  ansible/context.py,sha256=OzSlaA_GgGRyyf5I209sy19_eGOX6HXn441W9w_FcvU,2018
5
5
  ansible/keyword_desc.yml,sha256=vE9joFgSeHR4Djl7Bd-HHVCrGByRCrTUmWYZ8LKPZKk,7412
6
- ansible/release.py,sha256=J0fxbJGiPqQTdDQmUq028tdtlSwGKMYrmscShbhHe2U,915
6
+ ansible/release.py,sha256=yCaE8NXeZ8dXAHkgxe7eU4U1rgrGOZGMo-FSHm2VL0I,915
7
7
  ansible/_vendor/__init__.py,sha256=wJRKH7kI9OzYVY9hgSchOsTNTmTnugpPLGYj9Y5akX0,2086
8
8
  ansible/cli/__init__.py,sha256=6jaX6SS-UBM7pjiUlDsC0y07k3klUjxTR5ZEnDiCmP8,28706
9
9
  ansible/cli/adhoc.py,sha256=suzo4QnsaMjJBk5JlAUd-cpQLs8Ckj6A55CiG9Y8Gns,8247
@@ -34,7 +34,7 @@ ansible/executor/__init__.py,sha256=1lMXN1i2fFqslda4BmeI5tpYMFP95D5Wpr1AjDJi-SQ,
34
34
  ansible/executor/action_write_locks.py,sha256=Up2n3cwFCr4T4IvttHpe3QOxRBF_9NgWJ1tFm9CHpfM,1915
35
35
  ansible/executor/interpreter_discovery.py,sha256=0n3JAD8LfYBjnyNnj-JbWH8tb1jy23dwX7f5QvlyrFY,9943
36
36
  ansible/executor/module_common.py,sha256=GjRWM0L9Y4iDPa3ffhxjpy07i9e6ozpvvPnSLxZF_y8,65839
37
- ansible/executor/play_iterator.py,sha256=6Sf7im1-6rZjzF6ewQJNONkIVfv8VkIZy4jPvVfK9jc,30507
37
+ ansible/executor/play_iterator.py,sha256=7Lk3Zxh3gAzLR8cyHmmFbbbT0C-JyeCK-vquKZyPBY0,30511
38
38
  ansible/executor/playbook_executor.py,sha256=RYYgI82wviDOE1o8zrIB5WWsSEg13KdxEVMXLGPKK7A,15098
39
39
  ansible/executor/stats.py,sha256=757UK8wDzLCXq4ltI9PqpoMNAdtRsd9D9-GS-5Al_Hs,3264
40
40
  ansible/executor/task_executor.py,sha256=uarhaFNWGboyKO2AegjEp-KQSr9BMlF2PnmOdYwkmD0,60445
@@ -57,7 +57,7 @@ ansible/executor/process/__init__.py,sha256=1lMXN1i2fFqslda4BmeI5tpYMFP95D5Wpr1A
57
57
  ansible/executor/process/worker.py,sha256=rTLNZeKhW91zlx9izZlPkAn6afsSj6rdKm1xIj78LGI,10125
58
58
  ansible/galaxy/__init__.py,sha256=E80kenF78N0K9cKZybnGMMjgG_kFlITuhxFf8gyBfAU,2550
59
59
  ansible/galaxy/api.py,sha256=mGsxCKWvUF5wheObXtdMR-xHNVrs7J3AZ9_97XZuL1w,39789
60
- ansible/galaxy/role.py,sha256=lLeqwV82-Zin-JoUqpqZZB8WWxLJfXsHZAWiiigVsFU,21414
60
+ ansible/galaxy/role.py,sha256=83LHaufePRCUR1rT5peqSRE_-9Dl-JtoruB3x3oE1Io,21139
61
61
  ansible/galaxy/token.py,sha256=X21edFoqAq4DyA6Xm8MaVu-PNYhVjw-yWkFRxRdWZOw,6184
62
62
  ansible/galaxy/user_agent.py,sha256=x7cJzzpnTngHcwqSUd2hg0i28Dv0tbAyBdke5CSiNhM,813
63
63
  ansible/galaxy/collection/__init__.py,sha256=4tljAb0RxxglfHDbQpWZfHkYc__KsogyETCDTCW3BdI,78192
@@ -140,7 +140,7 @@ ansible/inventory/host.py,sha256=7RZjLiB7M74bejFRflOTa8XPHxMC334qhSo_5VmZrKI,512
140
140
  ansible/inventory/manager.py,sha256=ZwmEF3E2BKOJi9SMVQNz83A2f3raQn6Nyo-rfSNMn2k,29507
141
141
  ansible/module_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
142
142
  ansible/module_utils/_text.py,sha256=F_YfeaxhwmTI16HICAzQS9ZmlKgBDdQ4mqR-Kh--okg,597
143
- ansible/module_utils/ansible_release.py,sha256=J0fxbJGiPqQTdDQmUq028tdtlSwGKMYrmscShbhHe2U,915
143
+ ansible/module_utils/ansible_release.py,sha256=yCaE8NXeZ8dXAHkgxe7eU4U1rgrGOZGMo-FSHm2VL0I,915
144
144
  ansible/module_utils/api.py,sha256=BTo7stVOANbtd-ngZslaqx70r9t5gfvo44cKyu5SFjU,5837
145
145
  ansible/module_utils/basic.py,sha256=7xL3IsZK68gyyYm2x8yB2s1V7Sx77-vK3rkXmp2mlCM,87489
146
146
  ansible/module_utils/connection.py,sha256=9Us-d-y1bhC3zNnziQxvYNT4umIaN0OYv8zPaUSdEf0,8447
@@ -291,8 +291,8 @@ ansible/modules/cron.py,sha256=HlokG4Pcx219oksqbZRLXC61SlpbZSpCFVG-uRL_Qz4,26189
291
291
  ansible/modules/deb822_repository.py,sha256=rZzJzyl7TfVKrcICzYOBJISTrqRYGq8AoWNLwyl6eb0,15693
292
292
  ansible/modules/debconf.py,sha256=dqW8NQtQom64KUjre6liHNzT5oqyuEumyRQpyEfD9RE,8452
293
293
  ansible/modules/debug.py,sha256=eAQPIQ_LKHy718uD175T22nTrv7_8OlHjwO0ekKBQMU,2958
294
- ansible/modules/dnf.py,sha256=OJBLow95N31inSg0pHdj7Ux08nCsV_1hJGdP5JqeKR4,60173
295
- ansible/modules/dnf5.py,sha256=5IUzioKKT6ueDUM2GlkOL7acLVWtT1hsQtY3XDWKlCk,26019
294
+ ansible/modules/dnf.py,sha256=O55N-PlXOTLaPby10KiWd95GQJYKOt01yqyBBVsQHvg,55876
295
+ ansible/modules/dnf5.py,sha256=kwscsR4SVsBR3U5EXBg3TQ02_TVTASOqAUaKy6HjZ0s,26309
296
296
  ansible/modules/dpkg_selections.py,sha256=NBiePEQRamuOO5ncxt6mBbvlWihhMFwMmqiql7zZU34,2833
297
297
  ansible/modules/expect.py,sha256=C7t85H_TV9Y10wLVx0ok6qvYk4Lb6n6xT2qu3DSMBKE,9067
298
298
  ansible/modules/fail.py,sha256=AI4gNQC7E5U2Vs7QiIlFk7PcWozN0tXtiVPa_LJrQpk,1710
@@ -341,8 +341,8 @@ ansible/modules/sysvinit.py,sha256=MS_Hus1xvXSn_jF-o6mYbK7duIsOT0mi6UPMoC8YvYY,1
341
341
  ansible/modules/tempfile.py,sha256=5QDq5jiUcIlhTQnZmAuoyUMwtd13sIgcIAMoEcKdVyI,3539
342
342
  ansible/modules/template.py,sha256=E3GB8_LZNSu_64hzFKQD6Ov7HTfrkzsaJ3Xl4IOrL8A,4586
343
343
  ansible/modules/unarchive.py,sha256=6szHhYTZo4IQoXNNaF43TZbUIVvsM0VgefroScs4wDM,44451
344
- ansible/modules/uri.py,sha256=3vrPsO-q2JJ7JOaJA0GIJMS5gikO0USZRH7z6wrIlCk,28521
345
- ansible/modules/user.py,sha256=3yOjzB_9Dgj2nS-CMb3X3J3ATFisCUnG6crO_8QEB8I,118135
344
+ ansible/modules/uri.py,sha256=xzruu2NYOW0K2MAI0rBlSNA6OU4zNPav1m4wfAGH4OM,28428
345
+ ansible/modules/user.py,sha256=ACDk1KTJqnf1usB0LHavD2CMG3IUjVZKs7wEP61iGvs,117783
346
346
  ansible/modules/validate_argument_spec.py,sha256=wbFJ6zNUOcRBtmES7rYBqt_Cqior9CKVBNem5k6jvsk,3128
347
347
  ansible/modules/wait_for.py,sha256=VxgBrnnxjhfi5VkP6T_ElE5oVrr1rEJXuidQfwkHFz4,27373
348
348
  ansible/modules/wait_for_connection.py,sha256=EjxPKKwc1LNoKfQ7g0g-citLSZfhqNgpTeJTnO6_fB0,3377
@@ -351,7 +351,7 @@ ansible/modules/yum_repository.py,sha256=36uZERU09bfvTTsmr3Qx4p1TWZ8V4fQ64LLLOlx
351
351
  ansible/parsing/__init__.py,sha256=fPEa2N1Z4mjQHwps752TC-vhKA1CkCoEcAjh0YkfM5Y,826
352
352
  ansible/parsing/ajson.py,sha256=CZ3s2arKLvMWz5rzRIhzutRGSx73aS6fDg4C94HAHVA,1338
353
353
  ansible/parsing/dataloader.py,sha256=1T_DGy16iZoQzoIdv57HCGLv9AuPB_W2oJ_T1UlJQE0,20466
354
- ansible/parsing/mod_args.py,sha256=Igbiz-QAA1lLu8U3-fC27p4HphUZ1iHHKeH2xq1mZvc,13720
354
+ ansible/parsing/mod_args.py,sha256=LOnMmK5Twr99HVoRItYjUKAjFWF9Jp7xpzgXtnVT8yk,13892
355
355
  ansible/parsing/plugin_docs.py,sha256=JdK4OiFa7lSu9_-ztKQ7RPJs2FrmZejhE3YLESe-41Y,8714
356
356
  ansible/parsing/quoting.py,sha256=OsrBXkTzgn8PHH7VGA0kqnz6jBejdoQymDqsOYxTF-M,1141
357
357
  ansible/parsing/splitter.py,sha256=4rFm0Kr9QDv4VYw6uO2IaUzU52qAf7j8gsvVSDYRbAQ,11105
@@ -393,7 +393,7 @@ ansible/playbook/role/requirement.py,sha256=T_PljD0hgVstV325iALyCUKkAZxzLLlcQjpp
393
393
  ansible/plugins/__init__.py,sha256=OsNLvhmwNm7W9JFwLUmr3vAW5lby-Jp2wC2sDbZjzik,5371
394
394
  ansible/plugins/list.py,sha256=r_ai9G1ERwTigM2ZyhLtJK8BYRh4_hUNvAuqDlVS5ZI,8979
395
395
  ansible/plugins/loader.py,sha256=A_8sGZYgDLY-7fq4PjLC-dfcZrrdG5Xj290mTLy5htk,75723
396
- ansible/plugins/action/__init__.py,sha256=2objnMPfbxEC_2ahVxXU9sDZxO5cPflseK4HraGb5gY,68692
396
+ ansible/plugins/action/__init__.py,sha256=G6IVJe6hA6oJyOLN-0pCPc1A1GtRQ6WMBrqg-BflDdo,68697
397
397
  ansible/plugins/action/add_host.py,sha256=ZWrTsEVdAiOotHQL3Mb6FjzO8EzOsxy1MAg3sf7ndIE,3662
398
398
  ansible/plugins/action/assemble.py,sha256=EFWmRj9-0sur73__x2GosRavjLgwsjaamVSy0SavVvk,6590
399
399
  ansible/plugins/action/assert.py,sha256=r3mzC0-ZBj5qafDCK0uvew2fY4yGI7tvlffJ0s9YG_s,5156
@@ -441,7 +441,7 @@ ansible/plugins/cliconf/__init__.py,sha256=hjwVXkBPenYCSCF5-7HmylUFFO1L2itrvwpKX
441
441
  ansible/plugins/connection/__init__.py,sha256=87RA8bIaaS0LGZCZQpdJJEgAjDd2DPJgXebCMjYrTxE,18011
442
442
  ansible/plugins/connection/local.py,sha256=RFIZEyZjXQ_AcynPiYfmgZbHDNpgV6GiKb9qeXGxwoA,8437
443
443
  ansible/plugins/connection/paramiko_ssh.py,sha256=gMaVa1GqhymC7EHdtvp_rBN7MilHGDLYAgxs-l1_AAc,30111
444
- ansible/plugins/connection/psrp.py,sha256=MmhZ2aDpB4eT5BfHXguuNhO-7-9wDXNbxgg27-5wLuQ,36798
444
+ ansible/plugins/connection/psrp.py,sha256=di5R8Ijc0CHeCmWGXUdqf8kR2CaCFmmMzveS1VYKJY4,36806
445
445
  ansible/plugins/connection/ssh.py,sha256=ISeEuEPTxkgZEChz562155tDNk6A3d9kUnbvrzZITWU,64393
446
446
  ansible/plugins/connection/winrm.py,sha256=xk7IGA9rnhlg8gwiUI7FK19UFut_KzqKS6glRPJJFFA,40666
447
447
  ansible/plugins/doc_fragments/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -572,7 +572,7 @@ ansible/plugins/lookup/subelements.py,sha256=48w16cC8VVAxFm8FLSUzOFzP_Ub06IhZl7t
572
572
  ansible/plugins/lookup/template.py,sha256=rF36kU4fKTuyM70p-YmeJ_9ZOfXrWpjZgT2zWUavZIc,7165
573
573
  ansible/plugins/lookup/together.py,sha256=WHPggvxSXhQEqN0mbYLzEixazGrDkS6UALLVEiS7K9U,2163
574
574
  ansible/plugins/lookup/unvault.py,sha256=x-IFOIWlp2b6evZKigKFaIgMmn4TlHC-GY7TYfZHaSk,2102
575
- ansible/plugins/lookup/url.py,sha256=PpqwbagdJZ8XHiZu6hN8Sf32OJ6tCaDm8R00tpvg7QM,9064
575
+ ansible/plugins/lookup/url.py,sha256=xfxjuL_MijSjqToyJFffrQOf7UA3sSRv3hfuCZsqPtU,9561
576
576
  ansible/plugins/lookup/varnames.py,sha256=-QmnjyNg1sHSyKH_DTqzPh0HS4FgpXmPl7dFIycDUWA,2383
577
577
  ansible/plugins/lookup/vars.py,sha256=3YJ6wGXkOa4Of_0ngL-2_ZMOG7lG_f0ozpkgFs57WIs,3477
578
578
  ansible/plugins/netconf/__init__.py,sha256=yNiWM9PZHi2h2jJ0oV4QD6GuUvz-60_rcqsfefZEz7k,17147
@@ -640,7 +640,7 @@ ansible/plugins/test/version.yml,sha256=2d55HZGIniPu53z6_bV4C26_1sqRAHJqCwesOU3m
640
640
  ansible/plugins/test/version_compare.yml,sha256=2d55HZGIniPu53z6_bV4C26_1sqRAHJqCwesOU3ma38,3283
641
641
  ansible/plugins/vars/__init__.py,sha256=gfNJZDMgLDlH3d0Uzw_rzgqLGZPJtwpeMxkcsDi2jTk,1384
642
642
  ansible/plugins/vars/host_group_vars.py,sha256=DVv-2ku5ea41iZUyjqOFutCqh2VF4lgDKa0fDVjRZpM,6336
643
- ansible/template/__init__.py,sha256=S6zoqHCJ717If79PSomoOZEm6aeAUJB-sWHAW9JB5cQ,41465
643
+ ansible/template/__init__.py,sha256=orkAzf7KwC-UawteDcj8oaGBmmz3kHcbKW3uaVs36g4,41474
644
644
  ansible/template/native_helpers.py,sha256=-2P4gTC_-3JcEFw4R9SmFrRNUkoWoSlOVLxaPLjCcjY,4417
645
645
  ansible/template/template.py,sha256=synOxn1MzR7aNcIUanEsrtasK-jFlzvyJdUcqBdidGw,1667
646
646
  ansible/template/vars.py,sha256=Wl-suFtu88AHRCcIqqR7-lLY_KTlXZTE6D4z_oDLwXM,2819
@@ -682,7 +682,7 @@ ansible/vars/hostvars.py,sha256=px4HRxotkuXedT6pbLTa6TyptNwRp5ttzVUgBjm0LRI,4896
682
682
  ansible/vars/manager.py,sha256=lIfISTPyRcNfJVWJhhNof36Zmk6xSMUkf9sFxrzCzcI,38180
683
683
  ansible/vars/plugins.py,sha256=RsRU9fiLcJwPIAyTYnmVZglsiEOMCIgQskflavE-XnE,4546
684
684
  ansible/vars/reserved.py,sha256=FBD7n2dnA0CW4I0J1LtWwk2hQqvGW0KTRPcxaRtMKWo,2615
685
- ansible_core-2.16.6.data/scripts/ansible-test,sha256=CYIYL99IxWdVTtDIj3avilIJXhGAmtjuKPPWNuLWuc8,1690
685
+ ansible_core-2.16.7.data/scripts/ansible-test,sha256=CYIYL99IxWdVTtDIj3avilIJXhGAmtjuKPPWNuLWuc8,1690
686
686
  ansible_test/__init__.py,sha256=6e721yAyyyocRKzbCKtQXloAfFP7Aqv0L3zG70uh-4A,190
687
687
  ansible_test/_data/ansible.cfg,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
688
688
  ansible_test/_data/coveragerc,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -706,7 +706,7 @@ ansible_test/_data/pytest/config/default.ini,sha256=3f5D0MA9l2RafBBriLaG2eH3ePHP
706
706
  ansible_test/_data/pytest/config/legacy.ini,sha256=WBpVsIeHL2szv5oFznM2WXYizBgYhBrivpvQliYUKTw,85
707
707
  ansible_test/_data/requirements/ansible-test.txt,sha256=7lUJeoB76W4kmFa6P7G-cyJouIYrKWUtY-uIjXrEGkE,377
708
708
  ansible_test/_data/requirements/ansible.txt,sha256=SoGhVAYgDYWYKwMSH0g8WsCQczVft6Obb5ePPMQPRTU,838
709
- ansible_test/_data/requirements/constraints.txt,sha256=PiFo21efTtdKHwfhzmNIPA6B5H3_OUh_boakiWlWUDU,1327
709
+ ansible_test/_data/requirements/constraints.txt,sha256=vUOJauD7mv-0X_ZcDkUaHXY2joJxZCT0EfSAql4tSnU,1399
710
710
  ansible_test/_data/requirements/sanity.ansible-doc.in,sha256=9KRJJ-n37IMHpLJLv_VmFOhYF8Y3Vnk6eRyhwVKzC8A,108
711
711
  ansible_test/_data/requirements/sanity.ansible-doc.txt,sha256=cEdRsJvYL6u2C-dsZinArt_5cYHhwmFl5PReUuRPfcw,169
712
712
  ansible_test/_data/requirements/sanity.changelog.in,sha256=gWVsUch6Jxrq55MEutB-b9GB6Pp2PL-FqM84v-aI4Ng,78
@@ -764,7 +764,7 @@ ansible_test/_internal/locale_util.py,sha256=tjRbwKmgMQc1ysIhvP8yBhFcNA-2UCaWfQB
764
764
  ansible_test/_internal/metadata.py,sha256=c9ThXPUlgeKYhaTUmfCSS4INRNQ1JhN2KEOVaX3m1Gk,4791
765
765
  ansible_test/_internal/payload.py,sha256=1Pw05OEHvP3LMQnoLXch8631c94YMklWlpDn0CvQECw,8012
766
766
  ansible_test/_internal/provisioning.py,sha256=9Zl3xQqljx0MGDTp55Q4LZPWQ7Afj5K87cGsXzPGS5Y,7320
767
- ansible_test/_internal/pypi_proxy.py,sha256=C_AppiOKHtTfQPMYOSJQJyPB01K9UQ1-bUTOBcnO11E,6019
767
+ ansible_test/_internal/pypi_proxy.py,sha256=HyHZDMzVq4RoTczFhpBI0-TbUqQX7ttW0Ph6klCohYM,6203
768
768
  ansible_test/_internal/python_requirements.py,sha256=WgL1U-kw554JDxqi9xiD7mxoJAI5qHLiF_yqgfoKinc,20236
769
769
  ansible_test/_internal/ssh.py,sha256=2bS-DkcMJcBr3NExF2Y_htJVye_glKXir1NmLF05VR8,10662
770
770
  ansible_test/_internal/target.py,sha256=Whtb_n0jn4zbiMmX7je5jewgzsRczfXRm_ndYtjTSTQ,25320
@@ -1001,9 +1001,9 @@ ansible_test/config/cloud-config-vultr.ini.template,sha256=XLKHk3lg_8ReQMdWfZzhh
1001
1001
  ansible_test/config/config.yml,sha256=wb3knoBmZewG3GWOMnRHoVPQWW4vPixKLPMNS6vJmTc,2620
1002
1002
  ansible_test/config/inventory.networking.template,sha256=bFNSk8zNQOaZ_twaflrY0XZ9mLwUbRLuNT0BdIFwvn4,1335
1003
1003
  ansible_test/config/inventory.winrm.template,sha256=1QU8W-GFLnYEw8yY9bVIvUAVvJYPM3hyoijf6-M7T00,1098
1004
- ansible_core-2.16.6.dist-info/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
1005
- ansible_core-2.16.6.dist-info/METADATA,sha256=eET8TIMyKgKybojZroQ311uHSS8TPbvSw-CIDjwQlio,6905
1006
- ansible_core-2.16.6.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
1007
- ansible_core-2.16.6.dist-info/entry_points.txt,sha256=0mpmsrIhODChxKl3eS-NcVQCaMetBn8KdPLtVxQgR64,453
1008
- ansible_core-2.16.6.dist-info/top_level.txt,sha256=IFbRLjAvih1DYzJWg3_F6t4sCzEMxRO7TOMNs6GkYHo,21
1009
- ansible_core-2.16.6.dist-info/RECORD,,
1004
+ ansible_core-2.16.7.dist-info/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
1005
+ ansible_core-2.16.7.dist-info/METADATA,sha256=CZg7Zb3SVTQUVQTRGWH1Ze_n99Mad0hupzX44L02aJM,6905
1006
+ ansible_core-2.16.7.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
1007
+ ansible_core-2.16.7.dist-info/entry_points.txt,sha256=0mpmsrIhODChxKl3eS-NcVQCaMetBn8KdPLtVxQgR64,453
1008
+ ansible_core-2.16.7.dist-info/top_level.txt,sha256=IFbRLjAvih1DYzJWg3_F6t4sCzEMxRO7TOMNs6GkYHo,21
1009
+ ansible_core-2.16.7.dist-info/RECORD,,
@@ -1,6 +1,7 @@
1
1
  # do not add a cryptography or pyopenssl constraint to this file, they require special handling, see get_cryptography_requirements in python_requirements.py
2
2
  # do not add a coverage constraint to this file, it is handled internally by ansible-test
3
3
  packaging < 21.0 ; python_version < '3.6' # packaging 21.0 requires Python 3.6 or newer
4
+ pypsrp < 1.0.0 # in case the next major version is too big of a change
4
5
  pywinrm >= 0.3.0 ; python_version < '3.11' # message encryption support
5
6
  pywinrm >= 0.4.3 ; python_version >= '3.11' # support for Python 3.11
6
7
  pytest < 5.0.0, >= 4.5.0 ; python_version == '2.7' # pytest 5.0.0 and later will no longer support python 2.7
@@ -14,6 +14,7 @@ from .config import (
14
14
 
15
15
  from .host_configs import (
16
16
  PosixConfig,
17
+ DockerConfig,
17
18
  )
18
19
 
19
20
  from .util import (
@@ -55,8 +56,14 @@ def run_pypi_proxy(args: EnvironmentConfig, targets_use_pypi: bool) -> None:
55
56
  return # user has overridden the proxy endpoint, there is nothing to provision
56
57
 
57
58
  versions_needing_proxy: tuple[str, ...] = tuple() # preserved for future use, no versions currently require this
59
+ containers_needing_proxy: set[str] = {'centos7'}
58
60
  posix_targets = [target for target in args.targets if isinstance(target, PosixConfig)]
59
- need_proxy = targets_use_pypi and any(target.python.version in versions_needing_proxy for target in posix_targets)
61
+ need_proxy = targets_use_pypi and any(
62
+ target.python.version in versions_needing_proxy or
63
+ (isinstance(target, DockerConfig) and target.name in containers_needing_proxy)
64
+ for target in posix_targets
65
+ )
66
+
60
67
  use_proxy = args.pypi_proxy or need_proxy
61
68
 
62
69
  if not use_proxy: