ansible-core 2.15.4rc1__py3-none-any.whl → 2.16.0b2__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/cli/__init__.py +3 -3
- ansible/cli/adhoc.py +1 -1
- ansible/cli/arguments/option_helpers.py +15 -5
- ansible/cli/config.py +2 -2
- ansible/cli/console.py +21 -17
- ansible/cli/doc.py +8 -9
- ansible/cli/galaxy.py +60 -27
- ansible/cli/inventory.py +1 -1
- ansible/cli/playbook.py +1 -1
- ansible/cli/pull.py +2 -2
- ansible/cli/scripts/ansible_connection_cli_stub.py +1 -1
- ansible/cli/vault.py +11 -6
- ansible/collections/__init__.py +0 -29
- ansible/collections/list.py +23 -44
- ansible/config/ansible_builtin_runtime.yml +8 -4
- ansible/config/base.yml +34 -22
- ansible/config/manager.py +1 -1
- ansible/constants.py +3 -5
- ansible/errors/__init__.py +1 -1
- ansible/executor/interpreter_discovery.py +1 -1
- ansible/executor/module_common.py +39 -32
- ansible/executor/play_iterator.py +0 -15
- ansible/executor/playbook_executor.py +3 -3
- ansible/executor/powershell/module_manifest.py +1 -1
- ansible/executor/powershell/module_wrapper.ps1 +4 -1
- ansible/executor/process/worker.py +22 -7
- ansible/executor/task_executor.py +39 -40
- ansible/executor/task_queue_manager.py +8 -11
- ansible/galaxy/__init__.py +1 -1
- ansible/galaxy/api.py +8 -11
- ansible/galaxy/collection/__init__.py +17 -4
- ansible/galaxy/collection/concrete_artifact_manager.py +7 -2
- ansible/galaxy/collection/galaxy_api_proxy.py +1 -1
- ansible/galaxy/data/container/README.md +3 -5
- ansible/galaxy/dependency_resolution/__init__.py +1 -6
- ansible/galaxy/dependency_resolution/dataclasses.py +22 -1
- ansible/galaxy/dependency_resolution/providers.py +61 -69
- ansible/galaxy/role.py +31 -13
- ansible/galaxy/token.py +2 -2
- ansible/inventory/group.py +1 -1
- ansible/inventory/manager.py +1 -1
- ansible/module_utils/ansible_release.py +2 -2
- ansible/module_utils/basic.py +11 -41
- ansible/module_utils/common/file.py +0 -100
- ansible/module_utils/common/json.py +1 -1
- ansible/module_utils/common/locale.py +1 -1
- ansible/module_utils/common/text/converters.py +2 -2
- ansible/module_utils/common/validation.py +1 -1
- ansible/module_utils/compat/_selectors2.py +4 -4
- ansible/module_utils/compat/datetime.py +40 -0
- ansible/module_utils/compat/selinux.py +1 -1
- ansible/module_utils/compat/typing.py +1 -1
- ansible/module_utils/connection.py +1 -1
- ansible/module_utils/facts/hardware/linux.py +2 -2
- ansible/module_utils/facts/hardware/openbsd.py +1 -1
- ansible/module_utils/facts/network/linux.py +3 -3
- ansible/module_utils/facts/other/facter.py +8 -15
- ansible/module_utils/facts/sysctl.py +1 -1
- ansible/module_utils/facts/system/date_time.py +2 -2
- ansible/module_utils/facts/system/distribution.py +1 -1
- ansible/module_utils/facts/system/local.py +6 -2
- ansible/module_utils/facts/system/pkg_mgr.py +6 -1
- ansible/module_utils/facts/system/service_mgr.py +4 -2
- ansible/module_utils/parsing/convert_bool.py +1 -1
- ansible/module_utils/service.py +9 -6
- ansible/module_utils/urls.py +40 -22
- ansible/modules/add_host.py +2 -2
- ansible/modules/apt.py +48 -31
- ansible/modules/apt_key.py +4 -4
- ansible/modules/apt_repository.py +5 -5
- ansible/modules/assemble.py +7 -7
- ansible/modules/assert.py +1 -1
- ansible/modules/async_status.py +11 -7
- ansible/modules/async_wrapper.py +1 -1
- ansible/modules/blockinfile.py +60 -17
- ansible/modules/command.py +37 -15
- ansible/modules/copy.py +35 -30
- ansible/modules/cron.py +14 -14
- ansible/modules/deb822_repository.py +4 -3
- ansible/modules/debconf.py +35 -14
- ansible/modules/debug.py +1 -1
- ansible/modules/dnf.py +29 -27
- ansible/modules/dnf5.py +22 -22
- ansible/modules/dpkg_selections.py +9 -2
- ansible/modules/expect.py +4 -4
- ansible/modules/fetch.py +7 -7
- ansible/modules/file.py +30 -30
- ansible/modules/find.py +82 -22
- ansible/modules/gather_facts.py +6 -2
- ansible/modules/get_url.py +29 -29
- ansible/modules/getent.py +4 -4
- ansible/modules/git.py +27 -27
- ansible/modules/group.py +5 -12
- ansible/modules/hostname.py +21 -2
- ansible/modules/include_role.py +5 -5
- ansible/modules/include_tasks.py +2 -2
- ansible/modules/include_vars.py +5 -5
- ansible/modules/iptables.py +70 -65
- ansible/modules/known_hosts.py +7 -7
- ansible/modules/lineinfile.py +33 -33
- ansible/modules/meta.py +13 -13
- ansible/modules/package.py +8 -8
- ansible/modules/package_facts.py +3 -3
- ansible/modules/pause.py +2 -2
- ansible/modules/ping.py +5 -5
- ansible/modules/pip.py +80 -46
- ansible/modules/reboot.py +8 -4
- ansible/modules/replace.py +20 -15
- ansible/modules/rpm_key.py +2 -2
- ansible/modules/script.py +16 -10
- ansible/modules/service.py +26 -98
- ansible/modules/service_facts.py +36 -12
- ansible/modules/set_fact.py +2 -2
- ansible/modules/set_stats.py +2 -2
- ansible/modules/setup.py +18 -18
- ansible/modules/shell.py +3 -3
- ansible/modules/stat.py +9 -30
- ansible/modules/subversion.py +9 -9
- ansible/modules/systemd.py +20 -19
- ansible/modules/systemd_service.py +20 -19
- ansible/modules/sysvinit.py +26 -21
- ansible/modules/tempfile.py +5 -4
- ansible/modules/template.py +60 -6
- ansible/modules/unarchive.py +21 -18
- ansible/modules/uri.py +39 -39
- ansible/modules/user.py +81 -53
- ansible/modules/wait_for.py +22 -21
- ansible/modules/wait_for_connection.py +4 -4
- ansible/modules/yum.py +38 -38
- ansible/modules/yum_repository.py +58 -80
- ansible/parsing/dataloader.py +27 -27
- ansible/parsing/mod_args.py +1 -1
- ansible/parsing/plugin_docs.py +3 -3
- ansible/parsing/splitter.py +14 -16
- ansible/parsing/utils/yaml.py +1 -1
- ansible/parsing/vault/__init__.py +8 -6
- ansible/parsing/yaml/constructor.py +1 -1
- ansible/parsing/yaml/objects.py +1 -1
- ansible/playbook/__init__.py +1 -1
- ansible/playbook/base.py +2 -2
- ansible/playbook/block.py +0 -1
- ansible/playbook/conditional.py +40 -114
- ansible/playbook/helpers.py +5 -28
- ansible/playbook/included_file.py +8 -7
- ansible/playbook/play.py +1 -1
- ansible/playbook/play_context.py +2 -2
- ansible/playbook/playbook_include.py +2 -2
- ansible/playbook/role/__init__.py +1 -1
- ansible/playbook/role/include.py +1 -1
- ansible/playbook/role/metadata.py +1 -1
- ansible/playbook/role_include.py +1 -1
- ansible/playbook/task.py +2 -2
- ansible/playbook/task_include.py +1 -24
- ansible/plugins/__init__.py +13 -5
- ansible/plugins/action/__init__.py +17 -43
- ansible/plugins/action/add_host.py +2 -3
- ansible/plugins/action/assemble.py +1 -1
- ansible/plugins/action/assert.py +2 -1
- ansible/plugins/action/copy.py +2 -2
- ansible/plugins/action/debug.py +2 -1
- ansible/plugins/action/fail.py +1 -0
- ansible/plugins/action/fetch.py +3 -1
- ansible/plugins/action/gather_facts.py +37 -13
- ansible/plugins/action/group_by.py +1 -0
- ansible/plugins/action/include_vars.py +3 -2
- ansible/plugins/action/normal.py +3 -3
- ansible/plugins/action/pause.py +1 -1
- ansible/plugins/action/reboot.py +21 -16
- ansible/plugins/action/script.py +23 -8
- ansible/plugins/action/set_fact.py +1 -0
- ansible/plugins/action/set_stats.py +1 -0
- ansible/plugins/action/shell.py +6 -0
- ansible/plugins/action/template.py +1 -1
- ansible/plugins/action/unarchive.py +1 -1
- ansible/plugins/action/uri.py +1 -1
- ansible/plugins/action/validate_argument_spec.py +1 -0
- ansible/plugins/action/wait_for_connection.py +4 -4
- ansible/plugins/become/__init__.py +1 -1
- ansible/plugins/become/su.py +1 -1
- ansible/plugins/cache/__init__.py +1 -1
- ansible/plugins/callback/junit.py +1 -1
- ansible/plugins/callback/oneline.py +1 -1
- ansible/plugins/callback/tree.py +1 -1
- ansible/plugins/cliconf/__init__.py +2 -2
- ansible/plugins/connection/__init__.py +65 -37
- ansible/plugins/connection/local.py +9 -8
- ansible/plugins/connection/paramiko_ssh.py +34 -28
- ansible/plugins/connection/psrp.py +56 -43
- ansible/plugins/connection/ssh.py +67 -43
- ansible/plugins/connection/winrm.py +77 -30
- ansible/plugins/doc_fragments/constructed.py +4 -4
- ansible/plugins/doc_fragments/files.py +12 -12
- ansible/plugins/doc_fragments/inventory_cache.py +0 -6
- ansible/plugins/doc_fragments/result_format_callback.py +5 -5
- ansible/plugins/doc_fragments/shell_common.py +2 -2
- ansible/plugins/doc_fragments/shell_windows.py +1 -1
- ansible/plugins/doc_fragments/template_common.py +6 -6
- ansible/plugins/doc_fragments/url.py +10 -10
- ansible/plugins/doc_fragments/url_windows.py +15 -15
- ansible/plugins/doc_fragments/vars_plugin_staging.py +4 -4
- ansible/plugins/filter/b64decode.yml +1 -1
- ansible/plugins/filter/b64encode.yml +2 -2
- ansible/plugins/filter/bool.yml +5 -5
- ansible/plugins/filter/combine.yml +1 -1
- ansible/plugins/filter/commonpath.yml +2 -1
- ansible/plugins/filter/core.py +6 -8
- ansible/plugins/filter/dict2items.yml +11 -1
- ansible/plugins/filter/difference.yml +1 -0
- ansible/plugins/filter/encryption.py +1 -1
- ansible/plugins/filter/extract.yml +1 -1
- ansible/plugins/filter/flatten.yml +1 -1
- ansible/plugins/filter/from_yaml.yml +1 -1
- ansible/plugins/filter/from_yaml_all.yml +2 -2
- ansible/plugins/filter/hash.yml +1 -1
- ansible/plugins/filter/human_readable.yml +1 -1
- ansible/plugins/filter/human_to_bytes.yml +2 -2
- ansible/plugins/filter/intersect.yml +1 -0
- ansible/plugins/filter/mandatory.yml +7 -0
- ansible/plugins/filter/mathstuff.py +15 -17
- ansible/plugins/filter/normpath.yml +1 -1
- ansible/plugins/filter/path_join.yml +8 -1
- ansible/plugins/filter/realpath.yml +3 -2
- ansible/plugins/filter/regex_findall.yml +8 -2
- ansible/plugins/filter/regex_replace.yml +9 -3
- ansible/plugins/filter/regex_search.yml +8 -2
- ansible/plugins/filter/relpath.yml +2 -2
- ansible/plugins/filter/root.yml +1 -1
- ansible/plugins/filter/splitext.yml +1 -1
- ansible/plugins/filter/subelements.yml +2 -2
- ansible/plugins/filter/symmetric_difference.yml +1 -0
- ansible/plugins/filter/ternary.yml +5 -5
- ansible/plugins/filter/to_json.yml +7 -7
- ansible/plugins/filter/to_nice_json.yml +5 -5
- ansible/plugins/filter/to_yaml.yml +2 -2
- ansible/plugins/filter/type_debug.yml +1 -1
- ansible/plugins/filter/union.yml +1 -0
- ansible/plugins/filter/unvault.yml +2 -2
- ansible/plugins/filter/urldecode.yml +13 -32
- ansible/plugins/filter/urlsplit.py +1 -1
- ansible/plugins/filter/vault.yml +1 -1
- ansible/plugins/filter/zip.yml +1 -1
- ansible/plugins/filter/zip_longest.yml +1 -1
- ansible/plugins/inventory/__init__.py +1 -1
- ansible/plugins/inventory/advanced_host_list.py +1 -1
- ansible/plugins/inventory/constructed.py +2 -2
- ansible/plugins/inventory/host_list.py +1 -1
- ansible/plugins/inventory/ini.py +6 -3
- ansible/plugins/inventory/script.py +8 -2
- ansible/plugins/inventory/toml.py +1 -1
- ansible/plugins/inventory/yaml.py +1 -1
- ansible/plugins/list.py +21 -17
- ansible/plugins/loader.py +66 -88
- ansible/plugins/lookup/__init__.py +1 -1
- ansible/plugins/lookup/config.py +16 -6
- ansible/plugins/lookup/csvfile.py +7 -4
- ansible/plugins/lookup/env.py +1 -1
- ansible/plugins/lookup/file.py +5 -2
- ansible/plugins/lookup/fileglob.py +5 -2
- ansible/plugins/lookup/first_found.py +20 -14
- ansible/plugins/lookup/ini.py +6 -3
- ansible/plugins/lookup/lines.py +2 -1
- ansible/plugins/lookup/password.py +7 -7
- ansible/plugins/lookup/pipe.py +1 -0
- ansible/plugins/lookup/random_choice.py +2 -2
- ansible/plugins/lookup/sequence.py +1 -1
- ansible/plugins/lookup/subelements.py +2 -2
- ansible/plugins/lookup/template.py +4 -1
- ansible/plugins/lookup/unvault.py +4 -1
- ansible/plugins/lookup/url.py +6 -6
- ansible/plugins/lookup/varnames.py +1 -1
- ansible/plugins/netconf/__init__.py +3 -3
- ansible/plugins/shell/__init__.py +1 -1
- ansible/plugins/shell/cmd.py +7 -7
- ansible/plugins/shell/powershell.py +1 -1
- ansible/plugins/strategy/__init__.py +8 -10
- ansible/plugins/strategy/free.py +1 -1
- ansible/plugins/strategy/linear.py +3 -3
- ansible/plugins/terminal/__init__.py +2 -2
- ansible/plugins/test/abs.yml +1 -1
- ansible/plugins/test/all.yml +1 -1
- ansible/plugins/test/any.yml +1 -1
- ansible/plugins/test/change.yml +2 -2
- ansible/plugins/test/changed.yml +2 -2
- ansible/plugins/test/contains.yml +1 -1
- ansible/plugins/test/core.py +1 -1
- ansible/plugins/test/directory.yml +1 -1
- ansible/plugins/test/exists.yml +3 -2
- ansible/plugins/test/failed.yml +2 -2
- ansible/plugins/test/failure.yml +2 -2
- ansible/plugins/test/falsy.yml +2 -2
- ansible/plugins/test/file.yml +1 -1
- ansible/plugins/test/finished.yml +2 -2
- ansible/plugins/test/is_abs.yml +1 -1
- ansible/plugins/test/is_dir.yml +1 -1
- ansible/plugins/test/is_file.yml +1 -1
- ansible/plugins/test/is_link.yml +1 -1
- ansible/plugins/test/is_mount.yml +1 -1
- ansible/plugins/test/is_same_file.yml +1 -1
- ansible/plugins/test/isnan.yml +1 -1
- ansible/plugins/test/issubset.yml +1 -2
- ansible/plugins/test/issuperset.yml +1 -2
- ansible/plugins/test/link.yml +1 -1
- ansible/plugins/test/link_exists.yml +1 -1
- ansible/plugins/test/match.yml +2 -2
- ansible/plugins/test/mount.yml +1 -1
- ansible/plugins/test/nan.yml +1 -1
- ansible/plugins/test/reachable.yml +2 -2
- ansible/plugins/test/regex.yml +1 -1
- ansible/plugins/test/same_file.yml +1 -1
- ansible/plugins/test/search.yml +2 -2
- ansible/plugins/test/skip.yml +3 -3
- ansible/plugins/test/skipped.yml +3 -3
- ansible/plugins/test/started.yml +2 -2
- ansible/plugins/test/subset.yml +1 -2
- ansible/plugins/test/succeeded.yml +2 -2
- ansible/plugins/test/success.yml +2 -2
- ansible/plugins/test/successful.yml +2 -2
- ansible/plugins/test/superset.yml +1 -2
- ansible/plugins/test/truthy.yml +3 -3
- ansible/plugins/test/unreachable.yml +2 -2
- ansible/plugins/test/uri.yml +1 -1
- ansible/plugins/test/url.yml +1 -1
- ansible/plugins/test/urn.yml +1 -1
- ansible/plugins/test/vault_encrypted.yml +1 -1
- ansible/plugins/test/version.yml +7 -7
- ansible/plugins/test/version_compare.yml +7 -7
- ansible/plugins/vars/host_group_vars.py +1 -1
- ansible/release.py +2 -2
- ansible/template/__init__.py +24 -26
- ansible/template/native_helpers.py +1 -1
- ansible/template/vars.py +1 -1
- ansible/utils/_junit_xml.py +1 -1
- ansible/utils/cmd_functions.py +1 -1
- ansible/utils/collection_loader/_collection_finder.py +12 -1
- ansible/utils/display.py +113 -62
- ansible/utils/encrypt.py +11 -14
- ansible/utils/hashing.py +1 -1
- ansible/utils/jsonrpc.py +1 -1
- ansible/utils/path.py +1 -1
- ansible/utils/plugin_docs.py +1 -1
- ansible/utils/py3compat.py +1 -1
- ansible/utils/shlex.py +2 -10
- ansible/utils/ssh_functions.py +5 -4
- ansible/utils/unicode.py +1 -1
- ansible/utils/unsafe_proxy.py +1 -1
- ansible/utils/vars.py +4 -29
- ansible/vars/hostvars.py +1 -2
- ansible/vars/manager.py +13 -9
- ansible/vars/plugins.py +2 -2
- {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/COPYING +4 -5
- {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/METADATA +2 -4
- {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/RECORD +424 -425
- ansible_test/_data/completion/docker.txt +9 -9
- ansible_test/_data/completion/remote.txt +4 -7
- ansible_test/_data/completion/windows.txt +0 -2
- ansible_test/_data/requirements/ansible-test.txt +2 -1
- ansible_test/_data/requirements/ansible.txt +0 -3
- ansible_test/_data/requirements/constraints.txt +0 -2
- ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -5
- ansible_test/_data/requirements/sanity.changelog.in +1 -2
- ansible_test/_data/requirements/sanity.changelog.txt +4 -6
- ansible_test/_data/requirements/sanity.import.plugin.txt +2 -4
- ansible_test/_data/requirements/sanity.import.txt +1 -3
- ansible_test/_data/requirements/sanity.integration-aliases.txt +1 -3
- ansible_test/_data/requirements/sanity.mypy.txt +12 -12
- ansible_test/_data/requirements/sanity.pep8.txt +1 -1
- ansible_test/_data/requirements/sanity.pylint.txt +6 -12
- ansible_test/_data/requirements/sanity.runtime-metadata.txt +1 -3
- ansible_test/_data/requirements/sanity.validate-modules.in +1 -1
- ansible_test/_data/requirements/sanity.validate-modules.txt +3 -5
- ansible_test/_data/requirements/sanity.yamllint.txt +3 -5
- ansible_test/_data/requirements/units.txt +0 -1
- ansible_test/_internal/ci/azp.py +4 -4
- ansible_test/_internal/cli/environments.py +0 -13
- ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +4 -4
- ansible_test/_internal/commands/coverage/combine.py +1 -1
- ansible_test/_internal/commands/integration/cloud/acme.py +6 -8
- ansible_test/_internal/commands/integration/cloud/cs.py +4 -9
- ansible_test/_internal/commands/integration/cloud/galaxy.py +103 -96
- ansible_test/_internal/commands/integration/cloud/httptester.py +0 -3
- ansible_test/_internal/commands/integration/cloud/nios.py +7 -9
- ansible_test/_internal/commands/integration/cloud/openshift.py +2 -7
- ansible_test/_internal/commands/integration/cloud/vcenter.py +11 -95
- ansible_test/_internal/commands/sanity/__init__.py +10 -0
- ansible_test/_internal/commands/sanity/import.py +8 -2
- ansible_test/_internal/commands/sanity/pylint.py +27 -1
- ansible_test/_internal/commands/units/__init__.py +2 -1
- ansible_test/_internal/config.py +0 -7
- ansible_test/_internal/containers.py +11 -56
- ansible_test/_internal/core_ci.py +0 -7
- ansible_test/_internal/coverage_util.py +8 -3
- ansible_test/_internal/delegation.py +0 -1
- ansible_test/_internal/diff.py +1 -1
- ansible_test/_internal/docker_util.py +9 -2
- ansible_test/_internal/host_profiles.py +6 -6
- ansible_test/_internal/http.py +1 -1
- ansible_test/_internal/junit_xml.py +1 -1
- ansible_test/_internal/pypi_proxy.py +1 -1
- ansible_test/_internal/python_requirements.py +3 -8
- ansible_test/_internal/util.py +1 -6
- ansible_test/_util/controller/sanity/code-smell/no-get-exception.json +4 -0
- ansible_test/_util/controller/sanity/code-smell/replace-urlopen.json +4 -0
- ansible_test/_util/controller/sanity/code-smell/use-compat-six.json +4 -0
- ansible_test/_util/controller/sanity/mypy/ansible-core.ini +3 -0
- ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +2 -0
- ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +0 -1
- ansible_test/_util/controller/sanity/pylint/config/collection.cfg +1 -0
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +172 -10
- ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +13 -2
- ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +7 -1
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +6 -6
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +1 -1
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -1
- ansible_test/_util/controller/sanity/yamllint/yamllinter.py +3 -3
- ansible_test/_util/controller/tools/collection_detail.py +2 -2
- ansible_test/_util/target/common/constants.py +2 -2
- ansible_test/_util/target/pytest/plugins/ansible_forked.py +103 -0
- ansible_test/_util/target/sanity/import/importer.py +0 -8
- ansible_test/_util/target/setup/bootstrap.sh +36 -16
- ansible_test/_util/target/setup/quiet_pip.py +0 -4
- ansible/modules/_include.py +0 -80
- ansible_test/_internal/commands/integration/cloud/foreman.py +0 -102
- ansible_test/_util/target/setup/ConfigureRemotingForAnsible.ps1 +0 -435
- {ansible_core-2.15.4rc1.data → ansible_core-2.16.0b2.data}/scripts/ansible-test +0 -0
- {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/WHEEL +0 -0
- {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/top_level.txt +0 -0
|
@@ -51,7 +51,6 @@ class CollectionDependencyProviderBase(AbstractProvider):
|
|
|
51
51
|
self, # type: CollectionDependencyProviderBase
|
|
52
52
|
apis, # type: MultiGalaxyAPIProxy
|
|
53
53
|
concrete_artifacts_manager=None, # type: ConcreteArtifactsManager
|
|
54
|
-
user_requirements=None, # type: t.Iterable[Requirement]
|
|
55
54
|
preferred_candidates=None, # type: t.Iterable[Candidate]
|
|
56
55
|
with_deps=True, # type: bool
|
|
57
56
|
with_pre_releases=False, # type: bool
|
|
@@ -87,58 +86,12 @@ class CollectionDependencyProviderBase(AbstractProvider):
|
|
|
87
86
|
Requirement.from_requirement_dict,
|
|
88
87
|
art_mgr=concrete_artifacts_manager,
|
|
89
88
|
)
|
|
90
|
-
self._pinned_candidate_requests = set(
|
|
91
|
-
# NOTE: User-provided signatures are supplemental, so signatures
|
|
92
|
-
# NOTE: are not used to determine if a candidate is user-requested
|
|
93
|
-
Candidate(req.fqcn, req.ver, req.src, req.type, None)
|
|
94
|
-
for req in (user_requirements or ())
|
|
95
|
-
if req.is_concrete_artifact or (
|
|
96
|
-
req.ver != '*' and
|
|
97
|
-
not req.ver.startswith(('<', '>', '!='))
|
|
98
|
-
)
|
|
99
|
-
)
|
|
100
89
|
self._preferred_candidates = set(preferred_candidates or ())
|
|
101
90
|
self._with_deps = with_deps
|
|
102
91
|
self._with_pre_releases = with_pre_releases
|
|
103
92
|
self._upgrade = upgrade
|
|
104
93
|
self._include_signatures = include_signatures
|
|
105
94
|
|
|
106
|
-
def _is_user_requested(self, candidate): # type: (Candidate) -> bool
|
|
107
|
-
"""Check if the candidate is requested by the user."""
|
|
108
|
-
if candidate in self._pinned_candidate_requests:
|
|
109
|
-
return True
|
|
110
|
-
|
|
111
|
-
if candidate.is_online_index_pointer and candidate.src is not None:
|
|
112
|
-
# NOTE: Candidate is a namedtuple, it has a source server set
|
|
113
|
-
# NOTE: to a specific GalaxyAPI instance or `None`. When the
|
|
114
|
-
# NOTE: user runs
|
|
115
|
-
# NOTE:
|
|
116
|
-
# NOTE: $ ansible-galaxy collection install ns.coll
|
|
117
|
-
# NOTE:
|
|
118
|
-
# NOTE: then it's saved in `self._pinned_candidate_requests`
|
|
119
|
-
# NOTE: as `('ns.coll', '*', None, 'galaxy')` but then
|
|
120
|
-
# NOTE: `self.find_matches()` calls `self.is_satisfied_by()`
|
|
121
|
-
# NOTE: with Candidate instances bound to each specific
|
|
122
|
-
# NOTE: server available, those look like
|
|
123
|
-
# NOTE: `('ns.coll', '*', GalaxyAPI(...), 'galaxy')` and
|
|
124
|
-
# NOTE: wouldn't match the user requests saved in
|
|
125
|
-
# NOTE: `self._pinned_candidate_requests`. This is why we
|
|
126
|
-
# NOTE: normalize the collection to have `src=None` and try
|
|
127
|
-
# NOTE: again.
|
|
128
|
-
# NOTE:
|
|
129
|
-
# NOTE: When the user request comes from `requirements.yml`
|
|
130
|
-
# NOTE: with the `source:` set, it'll match the first check
|
|
131
|
-
# NOTE: but it still can have entries with `src=None` so this
|
|
132
|
-
# NOTE: normalized check is still necessary.
|
|
133
|
-
# NOTE:
|
|
134
|
-
# NOTE: User-provided signatures are supplemental, so signatures
|
|
135
|
-
# NOTE: are not used to determine if a candidate is user-requested
|
|
136
|
-
return Candidate(
|
|
137
|
-
candidate.fqcn, candidate.ver, None, candidate.type, None
|
|
138
|
-
) in self._pinned_candidate_requests
|
|
139
|
-
|
|
140
|
-
return False
|
|
141
|
-
|
|
142
95
|
def identify(self, requirement_or_candidate):
|
|
143
96
|
# type: (t.Union[Candidate, Requirement]) -> str
|
|
144
97
|
"""Given requirement or candidate, return an identifier for it.
|
|
@@ -342,25 +295,79 @@ class CollectionDependencyProviderBase(AbstractProvider):
|
|
|
342
295
|
latest_matches = []
|
|
343
296
|
signatures = []
|
|
344
297
|
extra_signature_sources = [] # type: list[str]
|
|
298
|
+
|
|
299
|
+
discarding_pre_releases_acceptable = any(
|
|
300
|
+
not is_pre_release(candidate_version)
|
|
301
|
+
for candidate_version, _src_server in coll_versions
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
# NOTE: The optimization of conditionally looping over the requirements
|
|
305
|
+
# NOTE: is used to skip having to compute the pinned status of all
|
|
306
|
+
# NOTE: requirements and apply version normalization to the found ones.
|
|
307
|
+
all_pinned_requirement_version_numbers = {
|
|
308
|
+
# NOTE: Pinned versions can start with a number, but also with an
|
|
309
|
+
# NOTE: equals sign. Stripping it at the beginning should be
|
|
310
|
+
# NOTE: enough. If there's a space after equals, the second strip
|
|
311
|
+
# NOTE: will take care of it.
|
|
312
|
+
# NOTE: Without this conversion, requirements versions like
|
|
313
|
+
# NOTE: '1.2.3-alpha.4' work, but '=1.2.3-alpha.4' don't.
|
|
314
|
+
requirement.ver.lstrip('=').strip()
|
|
315
|
+
for requirement in requirements
|
|
316
|
+
if requirement.is_pinned
|
|
317
|
+
} if discarding_pre_releases_acceptable else set()
|
|
318
|
+
|
|
345
319
|
for version, src_server in coll_versions:
|
|
346
320
|
tmp_candidate = Candidate(fqcn, version, src_server, 'galaxy', None)
|
|
347
321
|
|
|
348
|
-
unsatisfied = False
|
|
349
322
|
for requirement in requirements:
|
|
350
|
-
|
|
323
|
+
candidate_satisfies_requirement = self.is_satisfied_by(
|
|
324
|
+
requirement, tmp_candidate,
|
|
325
|
+
)
|
|
326
|
+
if not candidate_satisfies_requirement:
|
|
327
|
+
break
|
|
328
|
+
|
|
329
|
+
should_disregard_pre_release_candidate = (
|
|
330
|
+
# NOTE: Do not discard pre-release candidates in the
|
|
331
|
+
# NOTE: following cases:
|
|
332
|
+
# NOTE: * the end-user requested pre-releases explicitly;
|
|
333
|
+
# NOTE: * the candidate is a concrete artifact (e.g. a
|
|
334
|
+
# NOTE: Git repository, subdirs, a tarball URL, or a
|
|
335
|
+
# NOTE: local dir or file etc.);
|
|
336
|
+
# NOTE: * the candidate's pre-release version exactly
|
|
337
|
+
# NOTE: matches a version specifically requested by one
|
|
338
|
+
# NOTE: of the requirements in the current match
|
|
339
|
+
# NOTE: discovery round (i.e. matching a requirement
|
|
340
|
+
# NOTE: that is not a range but an explicit specific
|
|
341
|
+
# NOTE: version pin). This works when some requirements
|
|
342
|
+
# NOTE: request version ranges but others (possibly on
|
|
343
|
+
# NOTE: different dependency tree level depths) demand
|
|
344
|
+
# NOTE: pre-release dependency versions, even if those
|
|
345
|
+
# NOTE: dependencies are transitive.
|
|
346
|
+
is_pre_release(tmp_candidate.ver)
|
|
347
|
+
and discarding_pre_releases_acceptable
|
|
348
|
+
and not (
|
|
349
|
+
self._with_pre_releases
|
|
350
|
+
or tmp_candidate.is_concrete_artifact
|
|
351
|
+
or version in all_pinned_requirement_version_numbers
|
|
352
|
+
)
|
|
353
|
+
)
|
|
354
|
+
if should_disregard_pre_release_candidate:
|
|
355
|
+
break
|
|
356
|
+
|
|
351
357
|
# FIXME
|
|
352
|
-
#
|
|
353
|
-
# requirement.src is None
|
|
358
|
+
# candidate_is_from_requested_source = (
|
|
359
|
+
# requirement.src is None # if this is true for some candidates but not all it will break key param - Nonetype can't be compared to str
|
|
354
360
|
# or requirement.src == candidate.src
|
|
355
361
|
# )
|
|
356
|
-
if
|
|
357
|
-
|
|
362
|
+
# if not candidate_is_from_requested_source:
|
|
363
|
+
# break
|
|
364
|
+
|
|
358
365
|
if not self._include_signatures:
|
|
359
366
|
continue
|
|
360
367
|
|
|
361
368
|
extra_signature_sources.extend(requirement.signature_sources or [])
|
|
362
369
|
|
|
363
|
-
|
|
370
|
+
else: # candidate satisfies requirements, `break` never happened
|
|
364
371
|
if self._include_signatures:
|
|
365
372
|
for extra_source in extra_signature_sources:
|
|
366
373
|
signatures.append(get_signature_from_source(extra_source))
|
|
@@ -405,21 +412,6 @@ class CollectionDependencyProviderBase(AbstractProvider):
|
|
|
405
412
|
:returns: Indication whether the `candidate` is a viable \
|
|
406
413
|
solution to the `requirement`.
|
|
407
414
|
"""
|
|
408
|
-
# NOTE: Only allow pre-release candidates if we want pre-releases
|
|
409
|
-
# NOTE: or the req ver was an exact match with the pre-release
|
|
410
|
-
# NOTE: version. Another case where we'd want to allow
|
|
411
|
-
# NOTE: pre-releases is when there are several user requirements
|
|
412
|
-
# NOTE: and one of them is a pre-release that also matches a
|
|
413
|
-
# NOTE: transitive dependency of another requirement.
|
|
414
|
-
allow_pre_release = self._with_pre_releases or not (
|
|
415
|
-
requirement.ver == '*' or
|
|
416
|
-
requirement.ver.startswith('<') or
|
|
417
|
-
requirement.ver.startswith('>') or
|
|
418
|
-
requirement.ver.startswith('!=')
|
|
419
|
-
) or self._is_user_requested(candidate)
|
|
420
|
-
if is_pre_release(candidate.ver) and not allow_pre_release:
|
|
421
|
-
return False
|
|
422
|
-
|
|
423
415
|
# NOTE: This is a set of Pipenv-inspired optimizations. Ref:
|
|
424
416
|
# https://github.com/sarugaku/passa/blob/2ac00f1/src/passa/models/providers.py#L58-L74
|
|
425
417
|
if (
|
ansible/galaxy/role.py
CHANGED
|
@@ -36,7 +36,7 @@ from ansible import context
|
|
|
36
36
|
from ansible.errors import AnsibleError, AnsibleParserError
|
|
37
37
|
from ansible.galaxy.api import GalaxyAPI
|
|
38
38
|
from ansible.galaxy.user_agent import user_agent
|
|
39
|
-
from ansible.module_utils.
|
|
39
|
+
from ansible.module_utils.common.text.converters import to_native, to_text
|
|
40
40
|
from ansible.module_utils.common.yaml import yaml_dump, yaml_load
|
|
41
41
|
from ansible.module_utils.compat.version import LooseVersion
|
|
42
42
|
from ansible.module_utils.urls import open_url
|
|
@@ -211,7 +211,7 @@ class GalaxyRole(object):
|
|
|
211
211
|
|
|
212
212
|
info = dict(
|
|
213
213
|
version=self.version,
|
|
214
|
-
install_date=datetime.datetime.
|
|
214
|
+
install_date=datetime.datetime.now(datetime.timezone.utc).strftime("%c"),
|
|
215
215
|
)
|
|
216
216
|
if not os.path.exists(os.path.join(self.path, 'meta')):
|
|
217
217
|
os.makedirs(os.path.join(self.path, 'meta'))
|
|
@@ -394,18 +394,36 @@ class GalaxyRole(object):
|
|
|
394
394
|
# bits that might be in the file for security purposes
|
|
395
395
|
# and drop any containing directory, as mentioned above
|
|
396
396
|
if member.isreg() or member.issym():
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
397
|
+
for attr in ('name', 'linkname'):
|
|
398
|
+
attr_value = getattr(member, attr, None)
|
|
399
|
+
if not attr_value:
|
|
400
|
+
continue
|
|
401
|
+
n_attr_value = to_native(attr_value)
|
|
402
|
+
n_archive_parent_dir = to_native(archive_parent_dir)
|
|
403
|
+
n_parts = n_attr_value.replace(n_archive_parent_dir, "", 1).split(os.sep)
|
|
404
|
+
n_final_parts = []
|
|
405
|
+
for n_part in n_parts:
|
|
406
|
+
# TODO if the condition triggers it produces a broken installation.
|
|
407
|
+
# It will create the parent directory as an empty file and will
|
|
408
|
+
# explode if the directory contains valid files.
|
|
409
|
+
# Leaving this as is since the whole module needs a rewrite.
|
|
410
|
+
#
|
|
411
|
+
# Check if we have any files with illegal names,
|
|
412
|
+
# and display a warning if so. This could help users
|
|
413
|
+
# to debug a broken installation.
|
|
414
|
+
if not n_part:
|
|
415
|
+
continue
|
|
416
|
+
if n_part == '..':
|
|
417
|
+
display.warning(f"Illegal filename '{n_part}': '..' is not allowed")
|
|
418
|
+
continue
|
|
419
|
+
if n_part.startswith('~'):
|
|
420
|
+
display.warning(f"Illegal filename '{n_part}': names cannot start with '~'")
|
|
421
|
+
continue
|
|
422
|
+
if '$' in n_part:
|
|
423
|
+
display.warning(f"Illegal filename '{n_part}': names cannot contain '$'")
|
|
424
|
+
continue
|
|
407
425
|
n_final_parts.append(n_part)
|
|
408
|
-
|
|
426
|
+
setattr(member, attr, os.path.join(*n_final_parts))
|
|
409
427
|
|
|
410
428
|
if _check_working_data_filter():
|
|
411
429
|
# deprecated: description='extract fallback without filter' python_version='3.11'
|
ansible/galaxy/token.py
CHANGED
|
@@ -28,7 +28,7 @@ from stat import S_IRUSR, S_IWUSR
|
|
|
28
28
|
|
|
29
29
|
from ansible import constants as C
|
|
30
30
|
from ansible.galaxy.user_agent import user_agent
|
|
31
|
-
from ansible.module_utils.
|
|
31
|
+
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
|
32
32
|
from ansible.module_utils.common.yaml import yaml_dump, yaml_load
|
|
33
33
|
from ansible.module_utils.urls import open_url
|
|
34
34
|
from ansible.utils.display import Display
|
|
@@ -69,7 +69,7 @@ class KeycloakToken(object):
|
|
|
69
69
|
|
|
70
70
|
# - build a request to POST to auth_url
|
|
71
71
|
# - body is form encoded
|
|
72
|
-
# - '
|
|
72
|
+
# - 'refresh_token' is the offline token stored in ansible.cfg
|
|
73
73
|
# - 'grant_type' is 'refresh_token'
|
|
74
74
|
# - 'client_id' is 'cloud-services'
|
|
75
75
|
# - should probably be based on the contents of the
|
ansible/inventory/group.py
CHANGED
|
@@ -22,7 +22,7 @@ from itertools import chain
|
|
|
22
22
|
|
|
23
23
|
from ansible import constants as C
|
|
24
24
|
from ansible.errors import AnsibleError
|
|
25
|
-
from ansible.module_utils.
|
|
25
|
+
from ansible.module_utils.common.text.converters import to_native, to_text
|
|
26
26
|
from ansible.utils.display import Display
|
|
27
27
|
from ansible.utils.vars import combine_vars
|
|
28
28
|
|
ansible/inventory/manager.py
CHANGED
|
@@ -33,7 +33,7 @@ from ansible import constants as C
|
|
|
33
33
|
from ansible.errors import AnsibleError, AnsibleOptionsError, AnsibleParserError
|
|
34
34
|
from ansible.inventory.data import InventoryData
|
|
35
35
|
from ansible.module_utils.six import string_types
|
|
36
|
-
from ansible.module_utils.
|
|
36
|
+
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
|
37
37
|
from ansible.parsing.utils.addresses import parse_address
|
|
38
38
|
from ansible.plugins.loader import inventory_loader
|
|
39
39
|
from ansible.utils.helpers import deduplicate_list
|
ansible/module_utils/basic.py
CHANGED
|
@@ -9,40 +9,17 @@ import sys
|
|
|
9
9
|
|
|
10
10
|
# Used for determining if the system is running a new enough python version
|
|
11
11
|
# and should only restrict on our documented minimum versions
|
|
12
|
-
_PY3_MIN = sys.version_info >= (3,
|
|
12
|
+
_PY3_MIN = sys.version_info >= (3, 6)
|
|
13
13
|
_PY2_MIN = (2, 7) <= sys.version_info < (3,)
|
|
14
14
|
_PY_MIN = _PY3_MIN or _PY2_MIN
|
|
15
15
|
|
|
16
16
|
if not _PY_MIN:
|
|
17
17
|
print(
|
|
18
18
|
'\n{"failed": true, '
|
|
19
|
-
'"msg": "ansible-core requires a minimum of Python2 version 2.7 or Python3 version 3.
|
|
19
|
+
'"msg": "ansible-core requires a minimum of Python2 version 2.7 or Python3 version 3.6. Current version: %s"}' % ''.join(sys.version.splitlines())
|
|
20
20
|
)
|
|
21
21
|
sys.exit(1)
|
|
22
22
|
|
|
23
|
-
FILE_ATTRIBUTES = {
|
|
24
|
-
'A': 'noatime',
|
|
25
|
-
'a': 'append',
|
|
26
|
-
'c': 'compressed',
|
|
27
|
-
'C': 'nocow',
|
|
28
|
-
'd': 'nodump',
|
|
29
|
-
'D': 'dirsync',
|
|
30
|
-
'e': 'extents',
|
|
31
|
-
'E': 'encrypted',
|
|
32
|
-
'h': 'blocksize',
|
|
33
|
-
'i': 'immutable',
|
|
34
|
-
'I': 'indexed',
|
|
35
|
-
'j': 'journalled',
|
|
36
|
-
'N': 'inline',
|
|
37
|
-
's': 'zero',
|
|
38
|
-
'S': 'synchronous',
|
|
39
|
-
't': 'notail',
|
|
40
|
-
'T': 'blockroot',
|
|
41
|
-
'u': 'undelete',
|
|
42
|
-
'X': 'compressedraw',
|
|
43
|
-
'Z': 'compresseddirty',
|
|
44
|
-
}
|
|
45
|
-
|
|
46
23
|
# Ansible modules can be written in any language.
|
|
47
24
|
# The functions available here can be used to do many common tasks,
|
|
48
25
|
# to simplify development of Python modules.
|
|
@@ -172,6 +149,7 @@ from ansible.module_utils.common.file import (
|
|
|
172
149
|
is_executable,
|
|
173
150
|
format_attributes,
|
|
174
151
|
get_flags_from_attributes,
|
|
152
|
+
FILE_ATTRIBUTES,
|
|
175
153
|
)
|
|
176
154
|
from ansible.module_utils.common.sys_info import (
|
|
177
155
|
get_distribution,
|
|
@@ -265,8 +243,8 @@ PASSWD_ARG_RE = re.compile(r'^[-]{0,2}pass[-]?(word|wd)?')
|
|
|
265
243
|
|
|
266
244
|
# Used for parsing symbolic file perms
|
|
267
245
|
MODE_OPERATOR_RE = re.compile(r'[+=-]')
|
|
268
|
-
USERS_RE = re.compile(r'[
|
|
269
|
-
PERMS_RE = re.compile(r'[
|
|
246
|
+
USERS_RE = re.compile(r'^[ugo]+$')
|
|
247
|
+
PERMS_RE = re.compile(r'^[rwxXstugo]*$')
|
|
270
248
|
|
|
271
249
|
|
|
272
250
|
#
|
|
@@ -1063,18 +1041,18 @@ class AnsibleModule(object):
|
|
|
1063
1041
|
|
|
1064
1042
|
# Check if there are illegal characters in the user list
|
|
1065
1043
|
# They can end up in 'users' because they are not split
|
|
1066
|
-
if USERS_RE.match(users):
|
|
1044
|
+
if not USERS_RE.match(users):
|
|
1067
1045
|
raise ValueError("bad symbolic permission for mode: %s" % mode)
|
|
1068
1046
|
|
|
1069
1047
|
# Now we have two list of equal length, one contains the requested
|
|
1070
1048
|
# permissions and one with the corresponding operators.
|
|
1071
1049
|
for idx, perms in enumerate(permlist):
|
|
1072
1050
|
# Check if there are illegal characters in the permissions
|
|
1073
|
-
if PERMS_RE.match(perms):
|
|
1051
|
+
if not PERMS_RE.match(perms):
|
|
1074
1052
|
raise ValueError("bad symbolic permission for mode: %s" % mode)
|
|
1075
1053
|
|
|
1076
1054
|
for user in users:
|
|
1077
|
-
mode_to_apply = cls._get_octal_mode_from_symbolic_perms(path_stat, user, perms, use_umask)
|
|
1055
|
+
mode_to_apply = cls._get_octal_mode_from_symbolic_perms(path_stat, user, perms, use_umask, new_mode)
|
|
1078
1056
|
new_mode = cls._apply_operation_to_mode(user, opers[idx], mode_to_apply, new_mode)
|
|
1079
1057
|
|
|
1080
1058
|
return new_mode
|
|
@@ -1099,9 +1077,9 @@ class AnsibleModule(object):
|
|
|
1099
1077
|
return new_mode
|
|
1100
1078
|
|
|
1101
1079
|
@staticmethod
|
|
1102
|
-
def _get_octal_mode_from_symbolic_perms(path_stat, user, perms, use_umask):
|
|
1103
|
-
prev_mode
|
|
1104
|
-
|
|
1080
|
+
def _get_octal_mode_from_symbolic_perms(path_stat, user, perms, use_umask, prev_mode=None):
|
|
1081
|
+
if prev_mode is None:
|
|
1082
|
+
prev_mode = stat.S_IMODE(path_stat.st_mode)
|
|
1105
1083
|
is_directory = stat.S_ISDIR(path_stat.st_mode)
|
|
1106
1084
|
has_x_permissions = (prev_mode & EXEC_PERM_BITS) > 0
|
|
1107
1085
|
apply_X_permission = is_directory or has_x_permissions
|
|
@@ -1715,14 +1693,6 @@ class AnsibleModule(object):
|
|
|
1715
1693
|
tmp_dest_fd, tmp_dest_name = tempfile.mkstemp(prefix=b'.ansible_tmp', dir=b_dest_dir, suffix=b_suffix)
|
|
1716
1694
|
except (OSError, IOError) as e:
|
|
1717
1695
|
error_msg = 'The destination directory (%s) is not writable by the current user. Error was: %s' % (os.path.dirname(dest), to_native(e))
|
|
1718
|
-
except TypeError:
|
|
1719
|
-
# We expect that this is happening because python3.4.x and
|
|
1720
|
-
# below can't handle byte strings in mkstemp().
|
|
1721
|
-
# Traceback would end in something like:
|
|
1722
|
-
# file = _os.path.join(dir, pre + name + suf)
|
|
1723
|
-
# TypeError: can't concat bytes to str
|
|
1724
|
-
error_msg = ('Failed creating tmp file for atomic move. This usually happens when using Python3 less than Python3.5. '
|
|
1725
|
-
'Please use Python2.x or Python3.5 or greater.')
|
|
1726
1696
|
finally:
|
|
1727
1697
|
if error_msg:
|
|
1728
1698
|
if unsafe_writes:
|
|
@@ -7,12 +7,6 @@ __metaclass__ = type
|
|
|
7
7
|
import os
|
|
8
8
|
import stat
|
|
9
9
|
import re
|
|
10
|
-
import time
|
|
11
|
-
import fcntl
|
|
12
|
-
import sys
|
|
13
|
-
|
|
14
|
-
from contextlib import contextmanager
|
|
15
|
-
from ansible.module_utils.common.warnings import deprecate
|
|
16
10
|
|
|
17
11
|
try:
|
|
18
12
|
import selinux # pylint: disable=unused-import
|
|
@@ -102,97 +96,3 @@ def get_file_arg_spec():
|
|
|
102
96
|
attributes=dict(aliases=['attr']),
|
|
103
97
|
)
|
|
104
98
|
return arg_spec
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
class LockTimeout(Exception):
|
|
108
|
-
pass
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
class FileLock:
|
|
112
|
-
'''
|
|
113
|
-
Currently FileLock is implemented via fcntl.flock on a lock file, however this
|
|
114
|
-
behaviour may change in the future. Avoid mixing lock types fcntl.flock,
|
|
115
|
-
fcntl.lockf and module_utils.common.file.FileLock as it will certainly cause
|
|
116
|
-
unwanted and/or unexpected behaviour
|
|
117
|
-
'''
|
|
118
|
-
def __init__(self):
|
|
119
|
-
deprecate("FileLock is not reliable and has never been used in core for that reason. There is no current alternative that works across POSIX targets",
|
|
120
|
-
version='2.16')
|
|
121
|
-
self.lockfd = None
|
|
122
|
-
|
|
123
|
-
@contextmanager
|
|
124
|
-
def lock_file(self, path, tmpdir, lock_timeout=None):
|
|
125
|
-
'''
|
|
126
|
-
Context for lock acquisition
|
|
127
|
-
'''
|
|
128
|
-
try:
|
|
129
|
-
self.set_lock(path, tmpdir, lock_timeout)
|
|
130
|
-
yield
|
|
131
|
-
finally:
|
|
132
|
-
self.unlock()
|
|
133
|
-
|
|
134
|
-
def set_lock(self, path, tmpdir, lock_timeout=None):
|
|
135
|
-
'''
|
|
136
|
-
Create a lock file based on path with flock to prevent other processes
|
|
137
|
-
using given path.
|
|
138
|
-
Please note that currently file locking only works when it's executed by
|
|
139
|
-
the same user, I.E single user scenarios
|
|
140
|
-
|
|
141
|
-
:kw path: Path (file) to lock
|
|
142
|
-
:kw tmpdir: Path where to place the temporary .lock file
|
|
143
|
-
:kw lock_timeout:
|
|
144
|
-
Wait n seconds for lock acquisition, fail if timeout is reached.
|
|
145
|
-
0 = Do not wait, fail if lock cannot be acquired immediately,
|
|
146
|
-
Default is None, wait indefinitely until lock is released.
|
|
147
|
-
:returns: True
|
|
148
|
-
'''
|
|
149
|
-
lock_path = os.path.join(tmpdir, 'ansible-{0}.lock'.format(os.path.basename(path)))
|
|
150
|
-
l_wait = 0.1
|
|
151
|
-
r_exception = IOError
|
|
152
|
-
if sys.version_info[0] == 3:
|
|
153
|
-
r_exception = BlockingIOError
|
|
154
|
-
|
|
155
|
-
self.lockfd = open(lock_path, 'w')
|
|
156
|
-
|
|
157
|
-
if lock_timeout <= 0:
|
|
158
|
-
fcntl.flock(self.lockfd, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
|
159
|
-
os.chmod(lock_path, stat.S_IWRITE | stat.S_IREAD)
|
|
160
|
-
return True
|
|
161
|
-
|
|
162
|
-
if lock_timeout:
|
|
163
|
-
e_secs = 0
|
|
164
|
-
while e_secs < lock_timeout:
|
|
165
|
-
try:
|
|
166
|
-
fcntl.flock(self.lockfd, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
|
167
|
-
os.chmod(lock_path, stat.S_IWRITE | stat.S_IREAD)
|
|
168
|
-
return True
|
|
169
|
-
except r_exception:
|
|
170
|
-
time.sleep(l_wait)
|
|
171
|
-
e_secs += l_wait
|
|
172
|
-
continue
|
|
173
|
-
|
|
174
|
-
self.lockfd.close()
|
|
175
|
-
raise LockTimeout('{0} sec'.format(lock_timeout))
|
|
176
|
-
|
|
177
|
-
fcntl.flock(self.lockfd, fcntl.LOCK_EX)
|
|
178
|
-
os.chmod(lock_path, stat.S_IWRITE | stat.S_IREAD)
|
|
179
|
-
|
|
180
|
-
return True
|
|
181
|
-
|
|
182
|
-
def unlock(self):
|
|
183
|
-
'''
|
|
184
|
-
Make sure lock file is available for everyone and Unlock the file descriptor
|
|
185
|
-
locked by set_lock
|
|
186
|
-
|
|
187
|
-
:returns: True
|
|
188
|
-
'''
|
|
189
|
-
if not self.lockfd:
|
|
190
|
-
return True
|
|
191
|
-
|
|
192
|
-
try:
|
|
193
|
-
fcntl.flock(self.lockfd, fcntl.LOCK_UN)
|
|
194
|
-
self.lockfd.close()
|
|
195
|
-
except ValueError: # file wasn't opened, let context manager fail gracefully
|
|
196
|
-
pass
|
|
197
|
-
|
|
198
|
-
return True
|
|
@@ -10,7 +10,7 @@ import json
|
|
|
10
10
|
|
|
11
11
|
import datetime
|
|
12
12
|
|
|
13
|
-
from ansible.module_utils.
|
|
13
|
+
from ansible.module_utils.common.text.converters import to_text
|
|
14
14
|
from ansible.module_utils.six.moves.collections_abc import Mapping
|
|
15
15
|
from ansible.module_utils.common.collections import is_sequence
|
|
16
16
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
from __future__ import absolute_import, division, print_function
|
|
5
5
|
__metaclass__ = type
|
|
6
6
|
|
|
7
|
-
from ansible.module_utils.
|
|
7
|
+
from ansible.module_utils.common.text.converters import to_native
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def get_best_parsable_locale(module, preferences=None, raise_on_locale=False):
|
|
@@ -168,7 +168,7 @@ def to_text(obj, encoding='utf-8', errors=None, nonstring='simplerepr'):
|
|
|
168
168
|
handler, otherwise it will use replace.
|
|
169
169
|
:surrogate_then_replace: Does the same as surrogate_or_replace but
|
|
170
170
|
`was added for symmetry with the error handlers in
|
|
171
|
-
:func:`ansible.module_utils.
|
|
171
|
+
:func:`ansible.module_utils.common.text.converters.to_bytes` (Added in Ansible 2.3)
|
|
172
172
|
|
|
173
173
|
Because surrogateescape was added in Python3 this usually means that
|
|
174
174
|
Python3 will use `surrogateescape` and Python2 will use the fallback
|
|
@@ -179,7 +179,7 @@ def to_text(obj, encoding='utf-8', errors=None, nonstring='simplerepr'):
|
|
|
179
179
|
|
|
180
180
|
The default until Ansible-2.2 was `surrogate_or_replace`
|
|
181
181
|
In Ansible-2.3 this defaults to `surrogate_then_replace` for symmetry
|
|
182
|
-
with :func:`ansible.module_utils.
|
|
182
|
+
with :func:`ansible.module_utils.common.text.converters.to_bytes` .
|
|
183
183
|
:kwarg nonstring: The strategy to use if a nonstring is specified in
|
|
184
184
|
``obj``. Default is 'simplerepr'. Valid values are:
|
|
185
185
|
|
|
@@ -9,7 +9,7 @@ import os
|
|
|
9
9
|
import re
|
|
10
10
|
|
|
11
11
|
from ast import literal_eval
|
|
12
|
-
from ansible.module_utils.
|
|
12
|
+
from ansible.module_utils.common.text.converters import to_native
|
|
13
13
|
from ansible.module_utils.common._json_compat import json
|
|
14
14
|
from ansible.module_utils.common.collections import is_iterable
|
|
15
15
|
from ansible.module_utils.common.text.converters import jsonify
|
|
@@ -81,7 +81,7 @@ def _fileobj_to_fd(fileobj):
|
|
|
81
81
|
|
|
82
82
|
# Python 3.5 uses a more direct route to wrap system calls to increase speed.
|
|
83
83
|
if sys.version_info >= (3, 5):
|
|
84
|
-
def _syscall_wrapper(func,
|
|
84
|
+
def _syscall_wrapper(func, dummy, *args, **kwargs):
|
|
85
85
|
""" This is the short-circuit version of the below logic
|
|
86
86
|
because in Python 3.5+ all selectors restart system calls. """
|
|
87
87
|
try:
|
|
@@ -342,8 +342,8 @@ if hasattr(select, "select"):
|
|
|
342
342
|
|
|
343
343
|
timeout = None if timeout is None else max(timeout, 0.0)
|
|
344
344
|
ready = []
|
|
345
|
-
r, w,
|
|
346
|
-
|
|
345
|
+
r, w, dummy = _syscall_wrapper(self._select, True, self._readers,
|
|
346
|
+
self._writers, timeout=timeout)
|
|
347
347
|
r = set(r)
|
|
348
348
|
w = set(w)
|
|
349
349
|
for fd in r | w:
|
|
@@ -649,7 +649,7 @@ elif 'PollSelector' in globals(): # Platform-specific: Linux
|
|
|
649
649
|
elif 'SelectSelector' in globals(): # Platform-specific: Windows
|
|
650
650
|
DefaultSelector = SelectSelector
|
|
651
651
|
else: # Platform-specific: AppEngine
|
|
652
|
-
def no_selector(
|
|
652
|
+
def no_selector(dummy):
|
|
653
653
|
raise ValueError("Platform does not have a selector")
|
|
654
654
|
DefaultSelector = no_selector
|
|
655
655
|
HAS_SELECT = False
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Copyright (c) 2023 Ansible
|
|
2
|
+
# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
|
|
3
|
+
|
|
4
|
+
# Make coding more python3-ish
|
|
5
|
+
from __future__ import (absolute_import, division, print_function)
|
|
6
|
+
__metaclass__ = type
|
|
7
|
+
|
|
8
|
+
from ansible.module_utils.six import PY3
|
|
9
|
+
|
|
10
|
+
import datetime
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
if PY3:
|
|
14
|
+
UTC = datetime.timezone.utc
|
|
15
|
+
else:
|
|
16
|
+
_ZERO = datetime.timedelta(0)
|
|
17
|
+
|
|
18
|
+
class _UTC(datetime.tzinfo):
|
|
19
|
+
__slots__ = ()
|
|
20
|
+
|
|
21
|
+
def utcoffset(self, dt):
|
|
22
|
+
return _ZERO
|
|
23
|
+
|
|
24
|
+
def dst(self, dt):
|
|
25
|
+
return _ZERO
|
|
26
|
+
|
|
27
|
+
def tzname(self, dt):
|
|
28
|
+
return "UTC"
|
|
29
|
+
|
|
30
|
+
UTC = _UTC()
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def utcfromtimestamp(timestamp): # type: (float) -> datetime.datetime
|
|
34
|
+
"""Construct an aware UTC datetime from a POSIX timestamp."""
|
|
35
|
+
return datetime.datetime.fromtimestamp(timestamp, UTC)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def utcnow(): # type: () -> datetime.datetime
|
|
39
|
+
"""Construct an aware UTC datetime from time.time()."""
|
|
40
|
+
return datetime.datetime.now(UTC)
|
|
@@ -62,7 +62,7 @@ def _module_setup():
|
|
|
62
62
|
fn.restype = cfg.get('restype', c_int)
|
|
63
63
|
|
|
64
64
|
# just patch simple directly callable functions directly onto the module
|
|
65
|
-
if not fn.argtypes or not any(argtype for argtype in fn.argtypes if type(argtype)
|
|
65
|
+
if not fn.argtypes or not any(argtype for argtype in fn.argtypes if type(argtype) is base_ptr_type):
|
|
66
66
|
setattr(_thismod, fname, fn)
|
|
67
67
|
continue
|
|
68
68
|
|
|
@@ -38,7 +38,7 @@ import traceback
|
|
|
38
38
|
import uuid
|
|
39
39
|
|
|
40
40
|
from functools import partial
|
|
41
|
-
from ansible.module_utils.
|
|
41
|
+
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
|
42
42
|
from ansible.module_utils.common.json import AnsibleJSONEncoder
|
|
43
43
|
from ansible.module_utils.six import iteritems
|
|
44
44
|
from ansible.module_utils.six.moves import cPickle
|