ansible-core 2.17.6__py3-none-any.whl → 2.18.0__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/__main__.py +2 -17
- ansible/cli/__init__.py +3 -15
- ansible/cli/config.py +187 -24
- ansible/cli/console.py +1 -1
- ansible/cli/doc.py +38 -16
- ansible/cli/galaxy.py +3 -49
- ansible/cli/inventory.py +2 -2
- ansible/cli/pull.py +2 -2
- ansible/cli/scripts/ansible_connection_cli_stub.py +1 -10
- ansible/config/base.yml +127 -57
- ansible/config/manager.py +89 -11
- ansible/constants.py +32 -9
- ansible/errors/__init__.py +5 -0
- ansible/executor/interpreter_discovery.py +1 -1
- ansible/executor/play_iterator.py +16 -0
- ansible/executor/playbook_executor.py +1 -4
- ansible/executor/powershell/become_wrapper.ps1 +4 -5
- ansible/executor/powershell/bootstrap_wrapper.ps1 +2 -3
- ansible/executor/powershell/exec_wrapper.ps1 +1 -1
- ansible/executor/powershell/module_manifest.py +2 -2
- ansible/executor/task_executor.py +50 -39
- ansible/executor/task_queue_manager.py +1 -1
- ansible/executor/task_result.py +1 -1
- ansible/galaxy/api.py +3 -4
- ansible/galaxy/collection/__init__.py +21 -10
- ansible/galaxy/collection/concrete_artifact_manager.py +2 -2
- ansible/galaxy/collection/galaxy_api_proxy.py +10 -16
- ansible/galaxy/collection/gpg.py +17 -23
- ansible/galaxy/data/COPYING +7 -0
- ansible/galaxy/data/apb/Dockerfile.j2 +1 -0
- ansible/galaxy/data/apb/Makefile.j2 +1 -0
- ansible/galaxy/data/apb/README.md +7 -3
- ansible/galaxy/data/apb/apb.yml.j2 +1 -0
- ansible/galaxy/data/apb/defaults/main.yml.j2 +1 -0
- ansible/galaxy/data/apb/handlers/main.yml.j2 +1 -0
- ansible/galaxy/data/apb/meta/main.yml.j2 +1 -0
- ansible/galaxy/data/apb/playbooks/deprovision.yml.j2 +1 -0
- ansible/galaxy/data/apb/playbooks/provision.yml.j2 +1 -0
- ansible/galaxy/data/apb/tasks/main.yml.j2 +1 -0
- ansible/galaxy/data/apb/tests/ansible.cfg +1 -0
- ansible/galaxy/data/apb/tests/inventory +1 -0
- ansible/galaxy/data/apb/tests/test.yml.j2 +1 -0
- ansible/galaxy/data/apb/vars/main.yml.j2 +1 -0
- ansible/galaxy/data/collections_galaxy_meta.yml +1 -0
- ansible/galaxy/data/container/defaults/main.yml.j2 +1 -0
- ansible/galaxy/data/container/handlers/main.yml.j2 +1 -0
- ansible/galaxy/data/container/meta/container.yml.j2 +1 -0
- ansible/galaxy/data/container/meta/main.yml.j2 +1 -0
- ansible/galaxy/data/container/tasks/main.yml.j2 +1 -0
- ansible/galaxy/data/container/tests/ansible.cfg +1 -0
- ansible/galaxy/data/container/tests/inventory +1 -0
- ansible/galaxy/data/container/tests/test.yml.j2 +1 -0
- ansible/galaxy/data/container/vars/main.yml.j2 +1 -0
- ansible/galaxy/data/default/collection/README.md.j2 +1 -0
- ansible/galaxy/data/default/collection/galaxy.yml.j2 +1 -0
- ansible/galaxy/data/default/collection/meta/runtime.yml +1 -0
- ansible/galaxy/data/default/collection/plugins/README.md.j2 +1 -0
- ansible/galaxy/data/default/role/defaults/main.yml.j2 +1 -0
- ansible/galaxy/data/default/role/handlers/main.yml.j2 +1 -0
- ansible/galaxy/data/default/role/meta/main.yml.j2 +1 -0
- ansible/galaxy/data/default/role/tasks/main.yml.j2 +1 -0
- ansible/galaxy/data/default/role/tests/inventory +1 -0
- ansible/galaxy/data/default/role/tests/test.yml.j2 +1 -0
- ansible/galaxy/data/default/role/vars/main.yml.j2 +1 -0
- ansible/galaxy/data/network/cliconf_plugins/example.py.j2 +1 -0
- ansible/galaxy/data/network/defaults/main.yml.j2 +1 -0
- ansible/galaxy/data/network/library/example_command.py.j2 +1 -0
- ansible/galaxy/data/network/library/example_config.py.j2 +1 -0
- ansible/galaxy/data/network/library/example_facts.py.j2 +1 -0
- ansible/galaxy/data/network/meta/main.yml.j2 +1 -0
- ansible/galaxy/data/network/module_utils/example.py.j2 +1 -0
- ansible/galaxy/data/network/netconf_plugins/example.py.j2 +1 -0
- ansible/galaxy/data/network/tasks/main.yml.j2 +1 -0
- ansible/galaxy/data/network/terminal_plugins/example.py.j2 +1 -0
- ansible/galaxy/data/network/tests/inventory +1 -0
- ansible/galaxy/data/network/tests/test.yml.j2 +1 -0
- ansible/galaxy/data/network/vars/main.yml.j2 +1 -0
- ansible/galaxy/dependency_resolution/providers.py +3 -3
- ansible/galaxy/role.py +1 -1
- ansible/galaxy/token.py +20 -8
- ansible/keyword_desc.yml +1 -1
- ansible/module_utils/_internal/__init__.py +0 -0
- ansible/module_utils/_internal/_concurrent/__init__.py +0 -0
- ansible/module_utils/_internal/_concurrent/_daemon_threading.py +28 -0
- ansible/module_utils/_internal/_concurrent/_futures.py +21 -0
- ansible/module_utils/ansible_release.py +2 -2
- ansible/module_utils/api.py +2 -2
- ansible/module_utils/basic.py +8 -8
- ansible/module_utils/common/collections.py +1 -1
- ansible/module_utils/common/file.py +0 -6
- ansible/module_utils/common/process.py +22 -9
- ansible/module_utils/common/text/converters.py +5 -8
- ansible/module_utils/common/text/formatters.py +20 -4
- ansible/module_utils/common/validation.py +33 -25
- ansible/module_utils/compat/paramiko.py +6 -1
- ansible/module_utils/compat/selinux.py +2 -2
- ansible/module_utils/connection.py +8 -24
- ansible/module_utils/csharp/Ansible.Become.cs +14 -25
- ansible/module_utils/csharp/Ansible.Process.cs +1 -1
- ansible/module_utils/distro/__init__.py +1 -1
- ansible/module_utils/distro/_distro.py +8 -4
- ansible/module_utils/facts/collector.py +2 -0
- ansible/module_utils/facts/default_collectors.py +3 -1
- ansible/module_utils/facts/hardware/aix.py +54 -52
- ansible/module_utils/facts/hardware/darwin.py +37 -34
- ansible/module_utils/facts/hardware/freebsd.py +55 -15
- ansible/module_utils/facts/hardware/hpux.py +3 -0
- ansible/module_utils/facts/hardware/linux.py +101 -57
- ansible/module_utils/facts/hardware/netbsd.py +3 -0
- ansible/module_utils/facts/hardware/openbsd.py +4 -1
- ansible/module_utils/facts/hardware/sunos.py +7 -1
- ansible/module_utils/facts/network/aix.py +16 -17
- ansible/module_utils/facts/network/fc_wwn.py +4 -1
- ansible/module_utils/facts/network/hpux.py +21 -4
- ansible/module_utils/facts/network/iscsi.py +7 -8
- ansible/module_utils/facts/network/linux.py +0 -2
- ansible/module_utils/facts/other/facter.py +9 -4
- ansible/module_utils/facts/other/ohai.py +5 -5
- ansible/module_utils/facts/packages.py +49 -7
- ansible/module_utils/facts/sysctl.py +33 -31
- ansible/module_utils/facts/system/distribution.py +1 -1
- ansible/module_utils/facts/system/local.py +12 -22
- ansible/module_utils/facts/system/service_mgr.py +3 -1
- ansible/module_utils/facts/system/systemd.py +47 -0
- ansible/module_utils/powershell/Ansible.ModuleUtils.AddType.psm1 +1 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.CamelConversion.psm1 +1 -1
- ansible/module_utils/splitter.py +1 -1
- ansible/modules/add_host.py +1 -1
- ansible/modules/apt.py +43 -32
- ansible/modules/apt_key.py +6 -6
- ansible/modules/apt_repository.py +23 -14
- ansible/modules/assemble.py +7 -2
- ansible/modules/assert.py +4 -4
- ansible/modules/blockinfile.py +3 -6
- ansible/modules/command.py +1 -1
- ansible/modules/copy.py +4 -4
- ansible/modules/cron.py +13 -10
- ansible/modules/deb822_repository.py +16 -17
- ansible/modules/debconf.py +9 -9
- ansible/modules/debug.py +1 -1
- ansible/modules/dnf.py +79 -164
- ansible/modules/dnf5.py +54 -29
- ansible/modules/dpkg_selections.py +2 -2
- ansible/modules/expect.py +2 -2
- ansible/modules/fetch.py +2 -2
- ansible/modules/file.py +5 -3
- ansible/modules/find.py +40 -12
- ansible/modules/gather_facts.py +4 -2
- ansible/modules/get_url.py +29 -24
- ansible/modules/git.py +35 -35
- ansible/modules/group.py +71 -1
- ansible/modules/hostname.py +2 -4
- ansible/modules/include_vars.py +5 -5
- ansible/modules/iptables.py +13 -16
- ansible/modules/known_hosts.py +16 -13
- ansible/modules/lineinfile.py +1 -4
- ansible/modules/meta.py +6 -1
- ansible/modules/mount_facts.py +651 -0
- ansible/modules/package_facts.py +63 -80
- ansible/modules/pause.py +4 -3
- ansible/modules/pip.py +14 -14
- ansible/modules/replace.py +1 -4
- ansible/modules/rpm_key.py +31 -11
- ansible/modules/service.py +8 -8
- ansible/modules/service_facts.py +20 -5
- ansible/modules/set_stats.py +1 -1
- ansible/modules/setup.py +3 -3
- ansible/modules/stat.py +3 -3
- ansible/modules/subversion.py +1 -1
- ansible/modules/systemd.py +16 -10
- ansible/modules/systemd_service.py +16 -10
- ansible/modules/sysvinit.py +4 -4
- ansible/modules/unarchive.py +35 -22
- ansible/modules/uri.py +24 -18
- ansible/modules/user.py +145 -12
- ansible/modules/validate_argument_spec.py +3 -3
- ansible/modules/wait_for_connection.py +2 -1
- ansible/modules/yum_repository.py +136 -179
- ansible/parsing/dataloader.py +2 -2
- ansible/parsing/mod_args.py +11 -10
- ansible/parsing/vault/__init__.py +8 -3
- ansible/parsing/yaml/constructor.py +10 -8
- ansible/parsing/yaml/objects.py +1 -1
- ansible/playbook/base.py +12 -23
- ansible/playbook/helpers.py +4 -0
- ansible/playbook/loop_control.py +8 -0
- ansible/playbook/play.py +4 -22
- ansible/playbook/play_context.py +0 -16
- ansible/playbook/playbook_include.py +2 -2
- ansible/playbook/role/__init__.py +2 -2
- ansible/plugins/__init__.py +2 -0
- ansible/plugins/action/__init__.py +7 -9
- ansible/plugins/action/dnf.py +7 -5
- ansible/plugins/action/package.py +5 -4
- ansible/plugins/action/reboot.py +2 -2
- ansible/plugins/become/__init__.py +1 -1
- ansible/plugins/callback/__init__.py +44 -3
- ansible/plugins/callback/default.py +1 -1
- ansible/plugins/cliconf/__init__.py +1 -1
- ansible/plugins/connection/paramiko_ssh.py +2 -80
- ansible/plugins/connection/psrp.py +33 -82
- ansible/plugins/connection/ssh.py +0 -8
- ansible/plugins/connection/winrm.py +46 -1
- ansible/plugins/doc_fragments/connection_pipelining.py +2 -2
- ansible/plugins/doc_fragments/constructed.py +10 -10
- ansible/plugins/doc_fragments/default_callback.py +8 -8
- ansible/plugins/doc_fragments/files.py +5 -5
- ansible/plugins/doc_fragments/inventory_cache.py +2 -2
- ansible/plugins/doc_fragments/result_format_callback.py +6 -6
- ansible/plugins/doc_fragments/return_common.py +1 -1
- ansible/plugins/doc_fragments/shell_common.py +2 -10
- ansible/plugins/doc_fragments/shell_windows.py +0 -9
- ansible/plugins/doc_fragments/url.py +2 -2
- ansible/plugins/doc_fragments/url_windows.py +4 -5
- ansible/plugins/doc_fragments/validate.py +1 -1
- ansible/plugins/filter/core.py +2 -0
- ansible/plugins/filter/human_to_bytes.yml +9 -0
- ansible/plugins/filter/password_hash.yml +1 -1
- ansible/plugins/filter/strftime.yml +1 -1
- ansible/plugins/filter/to_nice_json.yml +7 -3
- ansible/plugins/filter/to_uuid.yml +1 -1
- ansible/plugins/inventory/script.py +1 -1
- ansible/plugins/list.py +1 -1
- ansible/plugins/loader.py +0 -11
- ansible/plugins/lookup/config.py +1 -1
- ansible/plugins/lookup/csvfile.py +21 -9
- ansible/plugins/lookup/env.py +8 -9
- ansible/plugins/lookup/ini.py +10 -1
- ansible/plugins/lookup/random_choice.py +2 -2
- ansible/plugins/lookup/url.py +7 -2
- ansible/plugins/shell/__init__.py +15 -20
- ansible/plugins/shell/powershell.py +9 -6
- ansible/plugins/strategy/__init__.py +16 -7
- ansible/plugins/test/core.py +23 -1
- ansible/plugins/test/issubset.yml +1 -1
- ansible/plugins/test/subset.yml +1 -1
- ansible/plugins/test/timedout.yml +20 -0
- ansible/plugins/test/vault_encrypted.yml +6 -6
- ansible/plugins/test/vaulted_file.yml +19 -0
- ansible/release.py +2 -2
- ansible/template/__init__.py +3 -8
- ansible/utils/collection_loader/_collection_finder.py +23 -55
- ansible/utils/display.py +44 -31
- ansible/utils/jsonrpc.py +1 -1
- ansible/utils/listify.py +1 -5
- ansible/utils/path.py +3 -0
- ansible/utils/vars.py +18 -27
- ansible/vars/manager.py +7 -150
- ansible/vars/plugins.py +1 -1
- ansible_core-2.18.0.dist-info/Apache-License.txt +202 -0
- {ansible_core-2.17.6.dist-info → ansible_core-2.18.0.dist-info}/METADATA +36 -23
- ansible_core-2.18.0.dist-info/MIT-license.txt +14 -0
- ansible_core-2.18.0.dist-info/PSF-license.txt +48 -0
- {ansible_core-2.17.6.dist-info → ansible_core-2.18.0.dist-info}/RECORD +316 -311
- {ansible_core-2.17.6.dist-info → ansible_core-2.18.0.dist-info}/entry_points.txt +1 -1
- ansible_core-2.18.0.dist-info/simplified_bsd.txt +8 -0
- ansible_test/_data/completion/docker.txt +7 -7
- ansible_test/_data/completion/remote.txt +5 -4
- ansible_test/_data/completion/windows.txt +4 -4
- ansible_test/_data/requirements/ansible-test.txt +1 -2
- ansible_test/_data/requirements/constraints.txt +1 -2
- ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
- ansible_test/_data/requirements/sanity.changelog.in +1 -1
- ansible_test/_data/requirements/sanity.changelog.txt +4 -4
- ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
- ansible_test/_data/requirements/sanity.import.txt +1 -1
- ansible_test/_data/requirements/sanity.integration-aliases.txt +1 -1
- ansible_test/_data/requirements/sanity.pep8.txt +1 -1
- ansible_test/_data/requirements/sanity.pylint.txt +6 -8
- ansible_test/_data/requirements/sanity.runtime-metadata.txt +2 -2
- ansible_test/_data/requirements/sanity.validate-modules.txt +3 -3
- ansible_test/_data/requirements/sanity.yamllint.in +1 -0
- ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
- ansible_test/_internal/ansible_util.py +8 -35
- ansible_test/_internal/ci/azp.py +1 -1
- ansible_test/_internal/classification/__init__.py +0 -2
- ansible_test/_internal/cli/parsers/key_value_parsers.py +3 -0
- ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -1
- ansible_test/_internal/commands/integration/cloud/httptester.py +1 -1
- ansible_test/_internal/commands/integration/cloud/nios.py +1 -1
- ansible_test/_internal/commands/sanity/__init__.py +96 -19
- ansible_test/_internal/commands/sanity/pylint.py +20 -24
- ansible_test/_internal/completion.py +2 -0
- ansible_test/_internal/constants.py +0 -1
- ansible_test/_internal/coverage_util.py +1 -2
- ansible_test/_internal/docker_util.py +1 -1
- ansible_test/_internal/encoding.py +4 -4
- ansible_test/_internal/host_configs.py +10 -0
- ansible_test/_internal/host_profiles.py +9 -13
- ansible_test/_internal/pypi_proxy.py +1 -1
- ansible_test/_internal/python_requirements.py +5 -14
- ansible_test/_internal/timeout.py +1 -1
- ansible_test/_internal/util.py +40 -0
- ansible_test/_internal/util_common.py +5 -1
- ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.json +3 -1
- ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +6 -3
- ansible_test/_util/controller/sanity/code-smell/empty-init.json +0 -2
- ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +5 -0
- ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +5 -0
- ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +5 -0
- ansible_test/_util/controller/sanity/pylint/config/collection.cfg +6 -0
- ansible_test/_util/controller/sanity/pylint/config/default.cfg +6 -0
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +1 -19
- ansible_test/_util/controller/sanity/shellcheck/exclude.txt +1 -0
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +67 -2
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +27 -5
- ansible_test/_util/target/cli/ansible_test_cli_stub.py +0 -0
- ansible_test/_util/target/common/constants.py +2 -2
- ansible_test/_util/target/injector/python.py +5 -0
- ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +6 -0
- ansible_test/_util/target/sanity/import/importer.py +1 -1
- ansible_test/_util/target/setup/bootstrap.sh +6 -17
- ansible_test/_util/target/setup/requirements.py +18 -24
- ansible_test/config/config.yml +1 -1
- ansible_core-2.17.6.data/scripts/ansible-test +0 -44
- ansible_test/_data/requirements/sanity.mypy.in +0 -10
- ansible_test/_data/requirements/sanity.mypy.txt +0 -18
- ansible_test/_internal/commands/sanity/mypy.py +0 -274
- ansible_test/_util/controller/sanity/mypy/ansible-core.ini +0 -116
- ansible_test/_util/controller/sanity/mypy/ansible-test.ini +0 -27
- ansible_test/_util/controller/sanity/mypy/modules.ini +0 -92
- ansible_test/_util/controller/sanity/mypy/packaging.ini +0 -20
- {ansible_core-2.17.6.dist-info → ansible_core-2.18.0.dist-info}/COPYING +0 -0
- {ansible_core-2.17.6.dist-info → ansible_core-2.18.0.dist-info}/WHEEL +0 -0
- {ansible_core-2.17.6.dist-info → ansible_core-2.18.0.dist-info}/top_level.txt +0 -0
|
@@ -8,7 +8,7 @@ import errno
|
|
|
8
8
|
import json
|
|
9
9
|
import os
|
|
10
10
|
import pkgutil
|
|
11
|
-
import
|
|
11
|
+
import secrets
|
|
12
12
|
import re
|
|
13
13
|
from importlib import import_module
|
|
14
14
|
|
|
@@ -318,7 +318,7 @@ def _create_powershell_wrapper(b_module_data, module_path, module_args,
|
|
|
318
318
|
|
|
319
319
|
exec_manifest["actions"].insert(0, 'async_watchdog')
|
|
320
320
|
exec_manifest["actions"].insert(0, 'async_wrapper')
|
|
321
|
-
exec_manifest["async_jid"] = f'j{
|
|
321
|
+
exec_manifest["async_jid"] = f'j{secrets.randbelow(999999999999)}'
|
|
322
322
|
exec_manifest["async_timeout_sec"] = async_timeout
|
|
323
323
|
exec_manifest["async_startup_timeout"] = C.config.get_config_value("WIN_ASYNC_STARTUP_TIMEOUT", variables=task_vars)
|
|
324
324
|
|
|
@@ -4,23 +4,24 @@
|
|
|
4
4
|
from __future__ import annotations
|
|
5
5
|
|
|
6
6
|
import os
|
|
7
|
-
import pty
|
|
8
7
|
import time
|
|
9
8
|
import json
|
|
9
|
+
import pathlib
|
|
10
10
|
import signal
|
|
11
11
|
import subprocess
|
|
12
12
|
import sys
|
|
13
|
-
import termios
|
|
14
13
|
import traceback
|
|
15
14
|
|
|
16
15
|
from ansible import constants as C
|
|
16
|
+
from ansible.cli import scripts
|
|
17
17
|
from ansible.errors import AnsibleError, AnsibleParserError, AnsibleUndefinedVariable, AnsibleConnectionFailure, AnsibleActionFail, AnsibleActionSkip
|
|
18
18
|
from ansible.executor.task_result import TaskResult
|
|
19
19
|
from ansible.executor.module_common import get_action_args_with_defaults
|
|
20
20
|
from ansible.module_utils.parsing.convert_bool import boolean
|
|
21
21
|
from ansible.module_utils.six import binary_type
|
|
22
22
|
from ansible.module_utils.common.text.converters import to_text, to_native
|
|
23
|
-
from ansible.module_utils.connection import
|
|
23
|
+
from ansible.module_utils.connection import write_to_stream
|
|
24
|
+
from ansible.module_utils.six import string_types
|
|
24
25
|
from ansible.playbook.conditional import Conditional
|
|
25
26
|
from ansible.playbook.task import Task
|
|
26
27
|
from ansible.plugins import get_plugin_class
|
|
@@ -42,11 +43,21 @@ __all__ = ['TaskExecutor']
|
|
|
42
43
|
|
|
43
44
|
|
|
44
45
|
class TaskTimeoutError(BaseException):
|
|
45
|
-
|
|
46
|
+
def __init__(self, message="", frame=None):
|
|
47
|
+
|
|
48
|
+
if frame is not None:
|
|
49
|
+
orig = frame
|
|
50
|
+
root = pathlib.Path(__file__).parent
|
|
51
|
+
while not pathlib.Path(frame.f_code.co_filename).is_relative_to(root):
|
|
52
|
+
frame = frame.f_back
|
|
53
|
+
|
|
54
|
+
self.frame = 'Interrupted at %s called from %s' % (orig, frame)
|
|
55
|
+
|
|
56
|
+
super(TaskTimeoutError, self).__init__(message)
|
|
46
57
|
|
|
47
58
|
|
|
48
59
|
def task_timeout(signum, frame):
|
|
49
|
-
raise TaskTimeoutError
|
|
60
|
+
raise TaskTimeoutError(frame=frame)
|
|
50
61
|
|
|
51
62
|
|
|
52
63
|
def remove_omit(task_args, omit_token):
|
|
@@ -369,12 +380,17 @@ class TaskExecutor:
|
|
|
369
380
|
'msg': 'Failed to template loop_control.label: %s' % to_text(e)
|
|
370
381
|
})
|
|
371
382
|
|
|
383
|
+
# if plugin is loaded, get resolved name, otherwise leave original task connection
|
|
384
|
+
if self._connection and not isinstance(self._connection, string_types):
|
|
385
|
+
task_fields['connection'] = getattr(self._connection, 'ansible_name')
|
|
386
|
+
|
|
372
387
|
tr = TaskResult(
|
|
373
388
|
self._host.name,
|
|
374
389
|
self._task._uuid,
|
|
375
390
|
res,
|
|
376
391
|
task_fields=task_fields,
|
|
377
392
|
)
|
|
393
|
+
|
|
378
394
|
if tr.is_failed() or tr.is_unreachable():
|
|
379
395
|
self._final_q.send_callback('v2_runner_item_on_failed', tr)
|
|
380
396
|
elif tr.is_skipped():
|
|
@@ -386,6 +402,19 @@ class TaskExecutor:
|
|
|
386
402
|
self._final_q.send_callback('v2_runner_item_on_ok', tr)
|
|
387
403
|
|
|
388
404
|
results.append(res)
|
|
405
|
+
|
|
406
|
+
# break loop if break_when conditions are met
|
|
407
|
+
if self._task.loop_control and self._task.loop_control.break_when:
|
|
408
|
+
cond = Conditional(loader=self._loader)
|
|
409
|
+
cond.when = self._task.loop_control.get_validated_value(
|
|
410
|
+
'break_when', self._task.loop_control.fattributes.get('break_when'), self._task.loop_control.break_when, templar
|
|
411
|
+
)
|
|
412
|
+
if cond.evaluate_conditional(templar, task_vars):
|
|
413
|
+
# delete loop vars before exiting loop
|
|
414
|
+
del task_vars[loop_var]
|
|
415
|
+
break
|
|
416
|
+
|
|
417
|
+
# done with loop var, remove for next iteration
|
|
389
418
|
del task_vars[loop_var]
|
|
390
419
|
|
|
391
420
|
# clear 'connection related' plugin variables for next iteration
|
|
@@ -647,7 +676,7 @@ class TaskExecutor:
|
|
|
647
676
|
return dict(unreachable=True, msg=to_text(e))
|
|
648
677
|
except TaskTimeoutError as e:
|
|
649
678
|
msg = 'The %s action failed to execute in the expected time frame (%d) and was terminated' % (self._task.action, self._task.timeout)
|
|
650
|
-
return dict(failed=True, msg=msg)
|
|
679
|
+
return dict(failed=True, msg=msg, timedout={'frame': e.frame, 'period': self._task.timeout})
|
|
651
680
|
finally:
|
|
652
681
|
if self._task.timeout:
|
|
653
682
|
signal.alarm(0)
|
|
@@ -1183,26 +1212,19 @@ class TaskExecutor:
|
|
|
1183
1212
|
return handler, module
|
|
1184
1213
|
|
|
1185
1214
|
|
|
1215
|
+
CLI_STUB_NAME = 'ansible_connection_cli_stub.py'
|
|
1216
|
+
|
|
1217
|
+
|
|
1186
1218
|
def start_connection(play_context, options, task_uuid):
|
|
1187
1219
|
'''
|
|
1188
1220
|
Starts the persistent connection
|
|
1189
1221
|
'''
|
|
1190
|
-
candidate_paths = [C.ANSIBLE_CONNECTION_PATH or os.path.dirname(sys.argv[0])]
|
|
1191
|
-
candidate_paths.extend(os.environ.get('PATH', '').split(os.pathsep))
|
|
1192
|
-
for dirname in candidate_paths:
|
|
1193
|
-
ansible_connection = os.path.join(dirname, 'ansible-connection')
|
|
1194
|
-
if os.path.isfile(ansible_connection):
|
|
1195
|
-
display.vvvv("Found ansible-connection at path {0}".format(ansible_connection))
|
|
1196
|
-
break
|
|
1197
|
-
else:
|
|
1198
|
-
raise AnsibleError("Unable to find location of 'ansible-connection'. "
|
|
1199
|
-
"Please set or check the value of ANSIBLE_CONNECTION_PATH")
|
|
1200
1222
|
|
|
1201
1223
|
env = os.environ.copy()
|
|
1202
1224
|
env.update({
|
|
1203
1225
|
# HACK; most of these paths may change during the controller's lifetime
|
|
1204
1226
|
# (eg, due to late dynamic role includes, multi-playbook execution), without a way
|
|
1205
|
-
# to invalidate/update,
|
|
1227
|
+
# to invalidate/update, the persistent connection helper won't always see the same plugins the controller
|
|
1206
1228
|
# can.
|
|
1207
1229
|
'ANSIBLE_BECOME_PLUGINS': become_loader.print_paths(),
|
|
1208
1230
|
'ANSIBLE_CLICONF_PLUGINS': cliconf_loader.print_paths(),
|
|
@@ -1215,30 +1237,19 @@ def start_connection(play_context, options, task_uuid):
|
|
|
1215
1237
|
verbosity = []
|
|
1216
1238
|
if display.verbosity:
|
|
1217
1239
|
verbosity.append('-%s' % ('v' * display.verbosity))
|
|
1218
|
-
|
|
1219
|
-
|
|
1240
|
+
|
|
1241
|
+
if not (cli_stub_path := C.config.get_config_value('_ANSIBLE_CONNECTION_PATH')):
|
|
1242
|
+
cli_stub_path = str(pathlib.Path(scripts.__file__).parent / CLI_STUB_NAME)
|
|
1243
|
+
|
|
1220
1244
|
p = subprocess.Popen(
|
|
1221
|
-
[
|
|
1222
|
-
stdin=
|
|
1245
|
+
[sys.executable, cli_stub_path, *verbosity, to_text(os.getppid()), to_text(task_uuid)],
|
|
1246
|
+
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env,
|
|
1223
1247
|
)
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
old = termios.tcgetattr(master)
|
|
1230
|
-
new = termios.tcgetattr(master)
|
|
1231
|
-
new[3] = new[3] & ~termios.ICANON
|
|
1232
|
-
|
|
1233
|
-
try:
|
|
1234
|
-
termios.tcsetattr(master, termios.TCSANOW, new)
|
|
1235
|
-
write_to_file_descriptor(master, options)
|
|
1236
|
-
write_to_file_descriptor(master, play_context.serialize())
|
|
1237
|
-
|
|
1238
|
-
(stdout, stderr) = p.communicate()
|
|
1239
|
-
finally:
|
|
1240
|
-
termios.tcsetattr(master, termios.TCSANOW, old)
|
|
1241
|
-
os.close(master)
|
|
1248
|
+
|
|
1249
|
+
write_to_stream(p.stdin, options)
|
|
1250
|
+
write_to_stream(p.stdin, play_context.serialize())
|
|
1251
|
+
|
|
1252
|
+
(stdout, stderr) = p.communicate()
|
|
1242
1253
|
|
|
1243
1254
|
if p.returncode == 0:
|
|
1244
1255
|
result = json.loads(to_text(stdout, errors='surrogate_then_replace'))
|
|
@@ -223,7 +223,7 @@ class TaskQueueManager:
|
|
|
223
223
|
callback_type = getattr(callback_plugin, 'CALLBACK_TYPE', '')
|
|
224
224
|
callback_needs_enabled = getattr(callback_plugin, 'CALLBACK_NEEDS_ENABLED', getattr(callback_plugin, 'CALLBACK_NEEDS_WHITELIST', False))
|
|
225
225
|
|
|
226
|
-
# try to get
|
|
226
|
+
# try to get collection world name first
|
|
227
227
|
cnames = getattr(callback_plugin, '_redirected_names', [])
|
|
228
228
|
if cnames:
|
|
229
229
|
# store the name the plugin was loaded as, as that's what we'll need to compare to the configured callback list later
|
ansible/executor/task_result.py
CHANGED
ansible/galaxy/api.py
CHANGED
|
@@ -62,8 +62,7 @@ def should_retry_error(exception):
|
|
|
62
62
|
if isinstance(orig_exc, URLError):
|
|
63
63
|
orig_exc = orig_exc.reason
|
|
64
64
|
|
|
65
|
-
# Handle common URL related errors
|
|
66
|
-
# Note: socket.timeout is only required for Py3.9
|
|
65
|
+
# Handle common URL related errors
|
|
67
66
|
if isinstance(orig_exc, (TimeoutError, BadStatusLine, IncompleteRead)):
|
|
68
67
|
return True
|
|
69
68
|
|
|
@@ -720,7 +719,7 @@ class GalaxyAPI:
|
|
|
720
719
|
|
|
721
720
|
display.display("Waiting until Galaxy import task %s has completed" % full_url)
|
|
722
721
|
start = time.time()
|
|
723
|
-
wait =
|
|
722
|
+
wait = C.GALAXY_COLLECTION_IMPORT_POLL_INTERVAL
|
|
724
723
|
|
|
725
724
|
while timeout == 0 or (time.time() - start) < timeout:
|
|
726
725
|
try:
|
|
@@ -744,7 +743,7 @@ class GalaxyAPI:
|
|
|
744
743
|
time.sleep(wait)
|
|
745
744
|
|
|
746
745
|
# poor man's exponential backoff algo so we don't flood the Galaxy API, cap at 30 seconds.
|
|
747
|
-
wait = min(30, wait *
|
|
746
|
+
wait = min(30, wait * C.GALAXY_COLLECTION_IMPORT_POLL_FACTOR)
|
|
748
747
|
if state == 'waiting':
|
|
749
748
|
raise AnsibleError("Timeout while waiting for the Galaxy import process to finish, check progress at '%s'"
|
|
750
749
|
% to_native(full_url))
|
|
@@ -8,6 +8,7 @@ from __future__ import annotations
|
|
|
8
8
|
import errno
|
|
9
9
|
import fnmatch
|
|
10
10
|
import functools
|
|
11
|
+
import glob
|
|
11
12
|
import inspect
|
|
12
13
|
import json
|
|
13
14
|
import os
|
|
@@ -1525,6 +1526,7 @@ def install(collection, path, artifacts_manager): # FIXME: mv to dataclasses?
|
|
|
1525
1526
|
artifacts_manager.required_successful_signature_count,
|
|
1526
1527
|
artifacts_manager.ignore_signature_errors,
|
|
1527
1528
|
)
|
|
1529
|
+
remove_source_metadata(collection, b_collection_path)
|
|
1528
1530
|
if (collection.is_online_index_pointer and isinstance(collection.src, GalaxyAPI)):
|
|
1529
1531
|
write_source_metadata(
|
|
1530
1532
|
collection,
|
|
@@ -1561,6 +1563,22 @@ def write_source_metadata(collection, b_collection_path, artifacts_manager):
|
|
|
1561
1563
|
raise
|
|
1562
1564
|
|
|
1563
1565
|
|
|
1566
|
+
def remove_source_metadata(collection, b_collection_path):
|
|
1567
|
+
pattern = f"{collection.namespace}.{collection.name}-*.info"
|
|
1568
|
+
info_path = os.path.join(
|
|
1569
|
+
b_collection_path,
|
|
1570
|
+
b'../../',
|
|
1571
|
+
to_bytes(pattern, errors='surrogate_or_strict')
|
|
1572
|
+
)
|
|
1573
|
+
if (outdated_info := glob.glob(info_path)):
|
|
1574
|
+
display.vvvv(f"Removing {pattern} metadata from previous installations")
|
|
1575
|
+
for info_dir in outdated_info:
|
|
1576
|
+
try:
|
|
1577
|
+
shutil.rmtree(info_dir)
|
|
1578
|
+
except Exception:
|
|
1579
|
+
pass
|
|
1580
|
+
|
|
1581
|
+
|
|
1564
1582
|
def verify_artifact_manifest(manifest_file, signatures, keyring, required_signature_count, ignore_signature_errors):
|
|
1565
1583
|
# type: (str, list[str], str, str, list[str]) -> None
|
|
1566
1584
|
failed_verify = False
|
|
@@ -1584,13 +1602,6 @@ def install_artifact(b_coll_targz_path, b_collection_path, b_temp_path, signatur
|
|
|
1584
1602
|
"""
|
|
1585
1603
|
try:
|
|
1586
1604
|
with tarfile.open(b_coll_targz_path, mode='r') as collection_tar:
|
|
1587
|
-
# Remove this once py3.11 is our controller minimum
|
|
1588
|
-
# Workaround for https://bugs.python.org/issue47231
|
|
1589
|
-
# See _extract_tar_dir
|
|
1590
|
-
collection_tar._ansible_normalized_cache = {
|
|
1591
|
-
m.name.removesuffix(os.path.sep): m for m in collection_tar.getmembers()
|
|
1592
|
-
} # deprecated: description='TarFile member index' core_version='2.18' python_version='3.11'
|
|
1593
|
-
|
|
1594
1605
|
# Verify the signature on the MANIFEST.json before extracting anything else
|
|
1595
1606
|
_extract_tar_file(collection_tar, MANIFEST_FILENAME, b_collection_path, b_temp_path)
|
|
1596
1607
|
|
|
@@ -1671,10 +1682,10 @@ def install_src(collection, b_collection_path, b_collection_output_path, artifac
|
|
|
1671
1682
|
|
|
1672
1683
|
def _extract_tar_dir(tar, dirname, b_dest):
|
|
1673
1684
|
""" Extracts a directory from a collection tar. """
|
|
1674
|
-
dirname = to_native(dirname, errors='surrogate_or_strict')
|
|
1685
|
+
dirname = to_native(dirname, errors='surrogate_or_strict')
|
|
1675
1686
|
|
|
1676
1687
|
try:
|
|
1677
|
-
tar_member = tar.
|
|
1688
|
+
tar_member = tar.getmember(dirname)
|
|
1678
1689
|
except KeyError:
|
|
1679
1690
|
raise AnsibleError("Unable to extract '%s' from collection" % dirname)
|
|
1680
1691
|
|
|
@@ -1896,7 +1907,7 @@ def _resolve_depenency_map(
|
|
|
1896
1907
|
|
|
1897
1908
|
for req in dep_exc.criterion.iter_requirement():
|
|
1898
1909
|
error_msg_lines.append(
|
|
1899
|
-
'* {req.fqcn!s}:{req.ver!s}'
|
|
1910
|
+
f'* {req.fqcn!s}:{req.ver!s}'
|
|
1900
1911
|
)
|
|
1901
1912
|
error_msg_lines.append(pre_release_hint)
|
|
1902
1913
|
|
|
@@ -63,7 +63,7 @@ class ConcreteArtifactsManager:
|
|
|
63
63
|
"""
|
|
64
64
|
def __init__(self, b_working_directory, validate_certs=True, keyring=None, timeout=60, required_signature_count=None, ignore_signature_errors=None):
|
|
65
65
|
# type: (bytes, bool, str, int, str, list[str]) -> None
|
|
66
|
-
"""Initialize ConcreteArtifactsManager caches and
|
|
66
|
+
"""Initialize ConcreteArtifactsManager caches and constraints."""
|
|
67
67
|
self._validate_certs = validate_certs # type: bool
|
|
68
68
|
self._artifact_cache = {} # type: dict[bytes, bytes]
|
|
69
69
|
self._galaxy_artifact_cache = {} # type: dict[Candidate | Requirement, bytes]
|
|
@@ -415,7 +415,7 @@ def _extract_collection_from_git(repo_url, coll_ver, b_path):
|
|
|
415
415
|
b_checkout_path = mkdtemp(
|
|
416
416
|
dir=b_path,
|
|
417
417
|
prefix=to_bytes(name, errors='surrogate_or_strict'),
|
|
418
|
-
)
|
|
418
|
+
)
|
|
419
419
|
|
|
420
420
|
try:
|
|
421
421
|
git_executable = get_bin_path('git')
|
|
@@ -27,8 +27,7 @@ display = Display()
|
|
|
27
27
|
class MultiGalaxyAPIProxy:
|
|
28
28
|
"""A proxy that abstracts talking to multiple Galaxy instances."""
|
|
29
29
|
|
|
30
|
-
def __init__(self, apis, concrete_artifacts_manager, offline=False):
|
|
31
|
-
# type: (t.Iterable[GalaxyAPI], ConcreteArtifactsManager, bool) -> None
|
|
30
|
+
def __init__(self, apis: t.Iterable[GalaxyAPI], concrete_artifacts_manager: ConcreteArtifactsManager, offline: bool = False) -> None:
|
|
32
31
|
"""Initialize the target APIs list."""
|
|
33
32
|
self._apis = apis
|
|
34
33
|
self._concrete_art_mgr = concrete_artifacts_manager
|
|
@@ -38,22 +37,21 @@ class MultiGalaxyAPIProxy:
|
|
|
38
37
|
def is_offline_mode_requested(self):
|
|
39
38
|
return self._offline
|
|
40
39
|
|
|
41
|
-
def _assert_that_offline_mode_is_not_requested(self)
|
|
40
|
+
def _assert_that_offline_mode_is_not_requested(self) -> None:
|
|
42
41
|
if self.is_offline_mode_requested:
|
|
43
42
|
raise NotImplementedError("The calling code is not supposed to be invoked in 'offline' mode.")
|
|
44
43
|
|
|
45
|
-
def _get_collection_versions(self, requirement):
|
|
46
|
-
# type: (Requirement) -> t.Iterator[tuple[GalaxyAPI, str]]
|
|
44
|
+
def _get_collection_versions(self, requirement: Requirement) -> t.Iterator[tuple[GalaxyAPI, str]]:
|
|
47
45
|
"""Helper for get_collection_versions.
|
|
48
46
|
|
|
49
47
|
Yield api, version pairs for all APIs,
|
|
50
48
|
and reraise the last error if no valid API was found.
|
|
51
49
|
"""
|
|
52
50
|
if self._offline:
|
|
53
|
-
return
|
|
51
|
+
return
|
|
54
52
|
|
|
55
53
|
found_api = False
|
|
56
|
-
last_error
|
|
54
|
+
last_error: Exception | None = None
|
|
57
55
|
|
|
58
56
|
api_lookup_order = (
|
|
59
57
|
(requirement.src, )
|
|
@@ -86,8 +84,7 @@ class MultiGalaxyAPIProxy:
|
|
|
86
84
|
if not found_api and last_error is not None:
|
|
87
85
|
raise last_error
|
|
88
86
|
|
|
89
|
-
def get_collection_versions(self, requirement):
|
|
90
|
-
# type: (Requirement) -> t.Iterable[tuple[str, GalaxyAPI]]
|
|
87
|
+
def get_collection_versions(self, requirement: Requirement) -> t.Iterable[tuple[str, GalaxyAPI]]:
|
|
91
88
|
"""Get a set of unique versions for FQCN on Galaxy servers."""
|
|
92
89
|
if requirement.is_concrete_artifact:
|
|
93
90
|
return {
|
|
@@ -110,8 +107,7 @@ class MultiGalaxyAPIProxy:
|
|
|
110
107
|
)
|
|
111
108
|
)
|
|
112
109
|
|
|
113
|
-
def get_collection_version_metadata(self, collection_candidate):
|
|
114
|
-
# type: (Candidate) -> CollectionVersionMetadata
|
|
110
|
+
def get_collection_version_metadata(self, collection_candidate: Candidate) -> CollectionVersionMetadata:
|
|
115
111
|
"""Retrieve collection metadata of a given candidate."""
|
|
116
112
|
self._assert_that_offline_mode_is_not_requested()
|
|
117
113
|
|
|
@@ -160,8 +156,7 @@ class MultiGalaxyAPIProxy:
|
|
|
160
156
|
|
|
161
157
|
raise last_err
|
|
162
158
|
|
|
163
|
-
def get_collection_dependencies(self, collection_candidate):
|
|
164
|
-
# type: (Candidate) -> dict[str, str]
|
|
159
|
+
def get_collection_dependencies(self, collection_candidate: Candidate) -> dict[str, str]:
|
|
165
160
|
# FIXME: return Requirement instances instead?
|
|
166
161
|
"""Retrieve collection dependencies of a given candidate."""
|
|
167
162
|
if collection_candidate.is_concrete_artifact:
|
|
@@ -177,13 +172,12 @@ class MultiGalaxyAPIProxy:
|
|
|
177
172
|
dependencies
|
|
178
173
|
)
|
|
179
174
|
|
|
180
|
-
def get_signatures(self, collection_candidate):
|
|
181
|
-
# type: (Candidate) -> list[str]
|
|
175
|
+
def get_signatures(self, collection_candidate: Candidate) -> list[str]:
|
|
182
176
|
self._assert_that_offline_mode_is_not_requested()
|
|
183
177
|
namespace = collection_candidate.namespace
|
|
184
178
|
name = collection_candidate.name
|
|
185
179
|
version = collection_candidate.ver
|
|
186
|
-
last_err
|
|
180
|
+
last_err: Exception | None = None
|
|
187
181
|
|
|
188
182
|
api_lookup_order = (
|
|
189
183
|
(collection_candidate.src, )
|
ansible/galaxy/collection/gpg.py
CHANGED
|
@@ -12,20 +12,14 @@ import contextlib
|
|
|
12
12
|
import inspect
|
|
13
13
|
import os
|
|
14
14
|
import subprocess
|
|
15
|
-
import sys
|
|
16
15
|
import typing as t
|
|
17
16
|
|
|
18
17
|
from dataclasses import dataclass, fields as dc_fields
|
|
19
|
-
from functools import partial
|
|
20
18
|
from urllib.error import HTTPError, URLError
|
|
21
19
|
|
|
22
20
|
if t.TYPE_CHECKING:
|
|
23
21
|
from ansible.utils.display import Display
|
|
24
22
|
|
|
25
|
-
IS_PY310_PLUS = sys.version_info[:2] >= (3, 10)
|
|
26
|
-
|
|
27
|
-
frozen_dataclass = partial(dataclass, frozen=True, **({'slots': True} if IS_PY310_PLUS else {}))
|
|
28
|
-
|
|
29
23
|
|
|
30
24
|
def get_signature_from_source(source, display=None): # type: (str, t.Optional[Display]) -> str
|
|
31
25
|
if display is not None:
|
|
@@ -128,7 +122,7 @@ def parse_gpg_errors(status_out): # type: (str) -> t.Iterator[GpgBaseError]
|
|
|
128
122
|
yield cls(*fields)
|
|
129
123
|
|
|
130
124
|
|
|
131
|
-
@
|
|
125
|
+
@dataclass(frozen=True, slots=True)
|
|
132
126
|
class GpgBaseError(Exception):
|
|
133
127
|
status: str
|
|
134
128
|
|
|
@@ -142,35 +136,35 @@ class GpgBaseError(Exception):
|
|
|
142
136
|
super(GpgBaseError, self).__setattr__(field_name, field_type(getattr(self, field_name)))
|
|
143
137
|
|
|
144
138
|
|
|
145
|
-
@
|
|
139
|
+
@dataclass(frozen=True, slots=True)
|
|
146
140
|
class GpgExpSig(GpgBaseError):
|
|
147
141
|
"""The signature with the keyid is good, but the signature is expired."""
|
|
148
142
|
keyid: str
|
|
149
143
|
username: str
|
|
150
144
|
|
|
151
145
|
|
|
152
|
-
@
|
|
146
|
+
@dataclass(frozen=True, slots=True)
|
|
153
147
|
class GpgExpKeySig(GpgBaseError):
|
|
154
148
|
"""The signature with the keyid is good, but the signature was made by an expired key."""
|
|
155
149
|
keyid: str
|
|
156
150
|
username: str
|
|
157
151
|
|
|
158
152
|
|
|
159
|
-
@
|
|
153
|
+
@dataclass(frozen=True, slots=True)
|
|
160
154
|
class GpgRevKeySig(GpgBaseError):
|
|
161
155
|
"""The signature with the keyid is good, but the signature was made by a revoked key."""
|
|
162
156
|
keyid: str
|
|
163
157
|
username: str
|
|
164
158
|
|
|
165
159
|
|
|
166
|
-
@
|
|
160
|
+
@dataclass(frozen=True, slots=True)
|
|
167
161
|
class GpgBadSig(GpgBaseError):
|
|
168
162
|
"""The signature with the keyid has not been verified okay."""
|
|
169
163
|
keyid: str
|
|
170
164
|
username: str
|
|
171
165
|
|
|
172
166
|
|
|
173
|
-
@
|
|
167
|
+
@dataclass(frozen=True, slots=True)
|
|
174
168
|
class GpgErrSig(GpgBaseError):
|
|
175
169
|
""""It was not possible to check the signature. This may be caused by
|
|
176
170
|
a missing public key or an unsupported algorithm. A RC of 4
|
|
@@ -186,24 +180,24 @@ class GpgErrSig(GpgBaseError):
|
|
|
186
180
|
fpr: str
|
|
187
181
|
|
|
188
182
|
|
|
189
|
-
@
|
|
183
|
+
@dataclass(frozen=True, slots=True)
|
|
190
184
|
class GpgNoPubkey(GpgBaseError):
|
|
191
185
|
"""The public key is not available."""
|
|
192
186
|
keyid: str
|
|
193
187
|
|
|
194
188
|
|
|
195
|
-
@
|
|
189
|
+
@dataclass(frozen=True, slots=True)
|
|
196
190
|
class GpgMissingPassPhrase(GpgBaseError):
|
|
197
191
|
"""No passphrase was supplied."""
|
|
198
192
|
|
|
199
193
|
|
|
200
|
-
@
|
|
194
|
+
@dataclass(frozen=True, slots=True)
|
|
201
195
|
class GpgBadPassphrase(GpgBaseError):
|
|
202
196
|
"""The supplied passphrase was wrong or not given."""
|
|
203
197
|
keyid: str
|
|
204
198
|
|
|
205
199
|
|
|
206
|
-
@
|
|
200
|
+
@dataclass(frozen=True, slots=True)
|
|
207
201
|
class GpgNoData(GpgBaseError):
|
|
208
202
|
"""No data has been found. Codes for WHAT are:
|
|
209
203
|
- 1 :: No armored data.
|
|
@@ -215,7 +209,7 @@ class GpgNoData(GpgBaseError):
|
|
|
215
209
|
what: str
|
|
216
210
|
|
|
217
211
|
|
|
218
|
-
@
|
|
212
|
+
@dataclass(frozen=True, slots=True)
|
|
219
213
|
class GpgUnexpected(GpgBaseError):
|
|
220
214
|
"""No data has been found. Codes for WHAT are:
|
|
221
215
|
- 1 :: No armored data.
|
|
@@ -227,7 +221,7 @@ class GpgUnexpected(GpgBaseError):
|
|
|
227
221
|
what: str
|
|
228
222
|
|
|
229
223
|
|
|
230
|
-
@
|
|
224
|
+
@dataclass(frozen=True, slots=True)
|
|
231
225
|
class GpgError(GpgBaseError):
|
|
232
226
|
"""This is a generic error status message, it might be followed by error location specific data."""
|
|
233
227
|
location: str
|
|
@@ -235,30 +229,30 @@ class GpgError(GpgBaseError):
|
|
|
235
229
|
more: str = ""
|
|
236
230
|
|
|
237
231
|
|
|
238
|
-
@
|
|
232
|
+
@dataclass(frozen=True, slots=True)
|
|
239
233
|
class GpgFailure(GpgBaseError):
|
|
240
234
|
"""This is the counterpart to SUCCESS and used to indicate a program failure."""
|
|
241
235
|
location: str
|
|
242
236
|
code: int
|
|
243
237
|
|
|
244
238
|
|
|
245
|
-
@
|
|
239
|
+
@dataclass(frozen=True, slots=True)
|
|
246
240
|
class GpgBadArmor(GpgBaseError):
|
|
247
241
|
"""The ASCII armor is corrupted."""
|
|
248
242
|
|
|
249
243
|
|
|
250
|
-
@
|
|
244
|
+
@dataclass(frozen=True, slots=True)
|
|
251
245
|
class GpgKeyExpired(GpgBaseError):
|
|
252
246
|
"""The key has expired."""
|
|
253
247
|
timestamp: int
|
|
254
248
|
|
|
255
249
|
|
|
256
|
-
@
|
|
250
|
+
@dataclass(frozen=True, slots=True)
|
|
257
251
|
class GpgKeyRevoked(GpgBaseError):
|
|
258
252
|
"""The used key has been revoked by its owner."""
|
|
259
253
|
|
|
260
254
|
|
|
261
|
-
@
|
|
255
|
+
@dataclass(frozen=True, slots=True)
|
|
262
256
|
class GpgNoSecKey(GpgBaseError):
|
|
263
257
|
"""The secret key is not available."""
|
|
264
258
|
keyid: str
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
All templates, files and files generated from them in the subdirectories of this one
|
|
2
|
+
are subject to the MIT license when applicable.
|
|
3
|
+
|
|
4
|
+
MIT License:
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -6,17 +6,21 @@ A brief description of the APB goes here.
|
|
|
6
6
|
Requirements
|
|
7
7
|
------------
|
|
8
8
|
|
|
9
|
-
Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here.
|
|
9
|
+
Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here.
|
|
10
|
+
For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
|
|
10
11
|
|
|
11
12
|
APB Variables
|
|
12
13
|
--------------
|
|
13
14
|
|
|
14
|
-
A description of the settable variables for this APB should go here, including any variables that are in defaults/main.yml, vars/main.yml, apb.yml, and
|
|
15
|
+
A description of the settable variables for this APB should go here, including any variables that are in defaults/main.yml, vars/main.yml, apb.yml, and
|
|
16
|
+
any variables that can/should be set via parameters to the role.
|
|
17
|
+
Any variables that are read from other roles and/or the global scope (i.e. hostvars, group vars, etc.) should be mentioned here as well.
|
|
15
18
|
|
|
16
19
|
Dependencies
|
|
17
20
|
------------
|
|
18
21
|
|
|
19
|
-
A list of other APBs/roles hosted on Galaxy should go here, plus any details in regards to
|
|
22
|
+
A list of other APBs/roles hosted on Galaxy should go here, plus any details in regards to
|
|
23
|
+
parameters that may need to be set for other roles, or variables that are used from other roles.
|
|
20
24
|
|
|
21
25
|
Example Playbook
|
|
22
26
|
----------------
|