ansible-core 2.16.7__py3-none-any.whl → 2.17.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/__init__.py +1 -3
- ansible/__main__.py +1 -0
- ansible/_vendor/__init__.py +1 -2
- ansible/cli/__init__.py +7 -8
- ansible/cli/adhoc.py +1 -2
- ansible/cli/arguments/__init__.py +1 -2
- ansible/cli/arguments/option_helpers.py +1 -2
- ansible/cli/config.py +1 -2
- ansible/cli/console.py +1 -2
- ansible/cli/doc.py +326 -202
- ansible/cli/galaxy.py +9 -3
- ansible/cli/inventory.py +4 -6
- ansible/cli/playbook.py +1 -2
- ansible/cli/pull.py +4 -5
- ansible/cli/scripts/ansible_connection_cli_stub.py +1 -4
- ansible/cli/vault.py +1 -2
- ansible/collections/list.py +1 -0
- ansible/compat/__init__.py +1 -4
- ansible/compat/importlib_resources.py +1 -2
- ansible/compat/{selectors/__init__.py → selectors.py} +12 -12
- ansible/config/ansible_builtin_runtime.yml +2 -0
- ansible/config/base.yml +154 -149
- ansible/config/manager.py +33 -25
- ansible/constants.py +1 -2
- ansible/context.py +1 -4
- ansible/errors/__init__.py +1 -3
- ansible/errors/yaml_strings.py +1 -3
- ansible/executor/__init__.py +1 -3
- ansible/executor/discovery/python_target.py +1 -2
- ansible/executor/interpreter_discovery.py +9 -8
- ansible/executor/module_common.py +1 -3
- ansible/executor/play_iterator.py +1 -3
- ansible/executor/playbook_executor.py +1 -3
- ansible/executor/powershell/module_manifest.py +2 -3
- ansible/executor/process/__init__.py +1 -3
- ansible/executor/process/worker.py +1 -3
- ansible/executor/stats.py +1 -3
- ansible/executor/task_executor.py +2 -3
- ansible/executor/task_queue_manager.py +1 -3
- ansible/executor/task_result.py +2 -3
- ansible/galaxy/__init__.py +1 -2
- ansible/galaxy/api.py +10 -2
- ansible/galaxy/collection/__init__.py +38 -24
- ansible/galaxy/collection/concrete_artifact_manager.py +1 -2
- ansible/galaxy/collection/galaxy_api_proxy.py +1 -2
- ansible/galaxy/collection/gpg.py +4 -2
- ansible/galaxy/data/apb/meta/main.yml.j2 +0 -15
- ansible/galaxy/data/container/meta/main.yml.j2 +0 -18
- ansible/galaxy/data/default/role/meta/main.yml.j2 +0 -18
- ansible/galaxy/data/network/cliconf_plugins/example.py.j2 +1 -2
- ansible/galaxy/data/network/library/example_command.py.j2 +1 -2
- ansible/galaxy/data/network/library/example_config.py.j2 +1 -2
- ansible/galaxy/data/network/library/example_facts.py.j2 +1 -2
- ansible/galaxy/data/network/meta/main.yml.j2 +0 -15
- ansible/galaxy/data/network/module_utils/example.py.j2 +1 -2
- ansible/galaxy/data/network/netconf_plugins/example.py.j2 +1 -2
- ansible/galaxy/data/network/terminal_plugins/example.py.j2 +1 -2
- ansible/galaxy/dependency_resolution/__init__.py +1 -2
- ansible/galaxy/dependency_resolution/dataclasses.py +5 -6
- ansible/galaxy/dependency_resolution/errors.py +1 -2
- ansible/galaxy/dependency_resolution/providers.py +3 -4
- ansible/galaxy/dependency_resolution/reporters.py +2 -3
- ansible/galaxy/dependency_resolution/resolvers.py +1 -2
- ansible/galaxy/dependency_resolution/versioning.py +1 -2
- ansible/galaxy/role.py +2 -3
- ansible/galaxy/token.py +1 -2
- ansible/galaxy/user_agent.py +1 -2
- ansible/inventory/data.py +1 -2
- ansible/inventory/group.py +1 -2
- ansible/inventory/helpers.py +1 -2
- ansible/inventory/host.py +1 -3
- ansible/inventory/manager.py +1 -2
- ansible/module_utils/_text.py +1 -2
- ansible/module_utils/ansible_release.py +3 -5
- ansible/module_utils/api.py +1 -2
- ansible/module_utils/basic.py +113 -158
- ansible/module_utils/common/_collections_compat.py +1 -2
- ansible/module_utils/common/_utils.py +1 -3
- ansible/module_utils/common/arg_spec.py +1 -2
- ansible/module_utils/common/collections.py +1 -2
- ansible/module_utils/common/dict_transformations.py +1 -2
- ansible/module_utils/common/file.py +10 -5
- ansible/module_utils/common/json.py +1 -3
- ansible/module_utils/common/locale.py +1 -2
- ansible/module_utils/common/network.py +2 -3
- ansible/module_utils/common/parameters.py +9 -9
- ansible/module_utils/common/process.py +12 -5
- ansible/module_utils/common/respawn.py +2 -3
- ansible/module_utils/common/sys_info.py +1 -2
- ansible/module_utils/common/text/converters.py +1 -2
- ansible/module_utils/common/text/formatters.py +1 -2
- ansible/module_utils/common/validation.py +5 -6
- ansible/module_utils/common/warnings.py +1 -2
- ansible/module_utils/common/yaml.py +1 -2
- ansible/module_utils/compat/datetime.py +1 -3
- ansible/module_utils/compat/importlib.py +21 -13
- ansible/module_utils/compat/paramiko.py +1 -2
- ansible/module_utils/compat/selectors.py +10 -34
- ansible/module_utils/compat/selinux.py +1 -2
- ansible/module_utils/compat/typing.py +1 -2
- ansible/module_utils/compat/version.py +1 -2
- ansible/module_utils/connection.py +1 -2
- ansible/module_utils/csharp/Ansible.Basic.cs +20 -3
- ansible/module_utils/distro/__init__.py +3 -4
- ansible/module_utils/distro/_distro.py +230 -234
- ansible/module_utils/errors.py +1 -2
- ansible/module_utils/facts/__init__.py +1 -2
- ansible/module_utils/facts/ansible_collector.py +1 -2
- ansible/module_utils/facts/collector.py +1 -2
- ansible/module_utils/facts/compat.py +1 -2
- ansible/module_utils/facts/default_collectors.py +1 -2
- ansible/module_utils/facts/hardware/aix.py +1 -2
- ansible/module_utils/facts/hardware/base.py +1 -2
- ansible/module_utils/facts/hardware/darwin.py +1 -2
- ansible/module_utils/facts/hardware/dragonfly.py +1 -2
- ansible/module_utils/facts/hardware/freebsd.py +1 -2
- ansible/module_utils/facts/hardware/hpux.py +1 -2
- ansible/module_utils/facts/hardware/hurd.py +1 -2
- ansible/module_utils/facts/hardware/linux.py +8 -6
- ansible/module_utils/facts/hardware/netbsd.py +1 -2
- ansible/module_utils/facts/hardware/openbsd.py +1 -2
- ansible/module_utils/facts/hardware/sunos.py +2 -3
- ansible/module_utils/facts/namespace.py +1 -2
- ansible/module_utils/facts/network/aix.py +1 -2
- ansible/module_utils/facts/network/base.py +1 -2
- ansible/module_utils/facts/network/darwin.py +1 -2
- ansible/module_utils/facts/network/dragonfly.py +1 -2
- ansible/module_utils/facts/network/fc_wwn.py +1 -2
- ansible/module_utils/facts/network/freebsd.py +1 -2
- ansible/module_utils/facts/network/generic_bsd.py +1 -2
- ansible/module_utils/facts/network/hpux.py +1 -2
- ansible/module_utils/facts/network/hurd.py +1 -2
- ansible/module_utils/facts/network/iscsi.py +1 -2
- ansible/module_utils/facts/network/linux.py +1 -2
- ansible/module_utils/facts/network/netbsd.py +1 -2
- ansible/module_utils/facts/network/nvme.py +1 -2
- ansible/module_utils/facts/network/openbsd.py +1 -2
- ansible/module_utils/facts/network/sunos.py +1 -2
- ansible/module_utils/facts/other/facter.py +1 -2
- ansible/module_utils/facts/other/ohai.py +1 -2
- ansible/module_utils/facts/packages.py +1 -2
- ansible/module_utils/facts/sysctl.py +1 -2
- ansible/module_utils/facts/system/apparmor.py +1 -2
- ansible/module_utils/facts/system/caps.py +1 -2
- ansible/module_utils/facts/system/chroot.py +1 -2
- ansible/module_utils/facts/system/cmdline.py +1 -2
- ansible/module_utils/facts/system/date_time.py +1 -2
- ansible/module_utils/facts/system/distribution.py +4 -5
- ansible/module_utils/facts/system/dns.py +1 -2
- ansible/module_utils/facts/system/env.py +1 -2
- ansible/module_utils/facts/system/fips.py +1 -2
- ansible/module_utils/facts/system/loadavg.py +1 -2
- ansible/module_utils/facts/system/local.py +1 -2
- ansible/module_utils/facts/system/lsb.py +1 -2
- ansible/module_utils/facts/system/pkg_mgr.py +7 -30
- ansible/module_utils/facts/system/platform.py +1 -2
- ansible/module_utils/facts/system/python.py +1 -2
- ansible/module_utils/facts/system/selinux.py +1 -2
- ansible/module_utils/facts/system/service_mgr.py +1 -2
- ansible/module_utils/facts/system/ssh_pub_keys.py +1 -2
- ansible/module_utils/facts/system/user.py +1 -2
- ansible/module_utils/facts/timeout.py +1 -2
- ansible/module_utils/facts/utils.py +1 -2
- ansible/module_utils/facts/virtual/base.py +1 -2
- ansible/module_utils/facts/virtual/dragonfly.py +1 -2
- ansible/module_utils/facts/virtual/freebsd.py +1 -2
- ansible/module_utils/facts/virtual/hpux.py +1 -2
- ansible/module_utils/facts/virtual/linux.py +1 -2
- ansible/module_utils/facts/virtual/netbsd.py +1 -2
- ansible/module_utils/facts/virtual/openbsd.py +1 -2
- ansible/module_utils/facts/virtual/sunos.py +1 -2
- ansible/module_utils/facts/virtual/sysctl.py +1 -2
- ansible/module_utils/json_utils.py +1 -2
- ansible/module_utils/parsing/convert_bool.py +1 -2
- ansible/module_utils/powershell/Ansible.ModuleUtils.Legacy.psm1 +5 -2
- ansible/module_utils/powershell/Ansible.ModuleUtils.WebRequest.psm1 +1 -1
- ansible/module_utils/pycompat24.py +24 -4
- ansible/module_utils/service.py +31 -5
- ansible/module_utils/six/__init__.py +1 -1
- ansible/module_utils/splitter.py +1 -2
- ansible/module_utils/urls.py +335 -1052
- ansible/module_utils/yumdnf.py +13 -35
- ansible/modules/add_host.py +1 -2
- ansible/modules/apt.py +38 -22
- ansible/modules/apt_key.py +1 -2
- ansible/modules/apt_repository.py +18 -10
- ansible/modules/assemble.py +1 -2
- ansible/modules/assert.py +8 -4
- ansible/modules/async_status.py +17 -14
- ansible/modules/async_wrapper.py +11 -9
- ansible/modules/blockinfile.py +2 -3
- ansible/modules/command.py +1 -2
- ansible/modules/copy.py +4 -76
- ansible/modules/cron.py +3 -3
- ansible/modules/deb822_repository.py +5 -5
- ansible/modules/debconf.py +19 -8
- ansible/modules/debug.py +1 -2
- ansible/modules/dnf.py +39 -46
- ansible/modules/dnf5.py +28 -26
- ansible/modules/dpkg_selections.py +1 -2
- ansible/modules/expect.py +23 -15
- ansible/modules/fail.py +1 -2
- ansible/modules/fetch.py +1 -2
- ansible/modules/file.py +4 -3
- ansible/modules/find.py +18 -5
- ansible/modules/gather_facts.py +1 -2
- ansible/modules/get_url.py +2 -3
- ansible/modules/getent.py +2 -3
- ansible/modules/git.py +28 -17
- ansible/modules/group.py +1 -2
- ansible/modules/group_by.py +1 -2
- ansible/modules/hostname.py +2 -19
- ansible/modules/import_playbook.py +1 -2
- ansible/modules/import_role.py +9 -2
- ansible/modules/import_tasks.py +1 -2
- ansible/modules/include_role.py +1 -2
- ansible/modules/include_tasks.py +1 -2
- ansible/modules/include_vars.py +1 -2
- ansible/modules/iptables.py +38 -21
- ansible/modules/known_hosts.py +15 -8
- ansible/modules/lineinfile.py +1 -6
- ansible/modules/meta.py +3 -2
- ansible/modules/package.py +6 -5
- ansible/modules/package_facts.py +1 -2
- ansible/modules/pause.py +2 -3
- ansible/modules/ping.py +1 -2
- ansible/modules/pip.py +40 -20
- ansible/modules/raw.py +1 -2
- ansible/modules/reboot.py +1 -2
- ansible/modules/replace.py +7 -5
- ansible/modules/rpm_key.py +1 -2
- ansible/modules/script.py +1 -2
- ansible/modules/service.py +3 -21
- ansible/modules/service_facts.py +3 -12
- ansible/modules/set_fact.py +1 -2
- ansible/modules/set_stats.py +1 -2
- ansible/modules/setup.py +1 -2
- ansible/modules/shell.py +1 -2
- ansible/modules/slurp.py +1 -2
- ansible/modules/stat.py +1 -2
- ansible/modules/subversion.py +2 -3
- ansible/modules/systemd.py +12 -9
- ansible/modules/systemd_service.py +12 -9
- ansible/modules/sysvinit.py +7 -2
- ansible/modules/tempfile.py +7 -2
- ansible/modules/template.py +2 -3
- ansible/modules/unarchive.py +13 -3
- ansible/modules/uri.py +12 -15
- ansible/modules/user.py +11 -4
- ansible/modules/validate_argument_spec.py +15 -16
- ansible/modules/wait_for.py +1 -2
- ansible/modules/wait_for_connection.py +1 -2
- ansible/modules/yum_repository.py +2 -3
- ansible/parsing/__init__.py +1 -3
- ansible/parsing/ajson.py +1 -3
- ansible/parsing/dataloader.py +23 -12
- ansible/parsing/mod_args.py +6 -4
- ansible/parsing/plugin_docs.py +1 -2
- ansible/parsing/quoting.py +1 -3
- ansible/parsing/splitter.py +1 -3
- ansible/parsing/utils/__init__.py +1 -3
- ansible/parsing/utils/addresses.py +1 -3
- ansible/parsing/utils/jsonify.py +1 -3
- ansible/parsing/utils/yaml.py +1 -3
- ansible/parsing/vault/__init__.py +6 -8
- ansible/parsing/yaml/__init__.py +1 -3
- ansible/parsing/yaml/constructor.py +1 -3
- ansible/parsing/yaml/dumper.py +1 -3
- ansible/parsing/yaml/loader.py +1 -3
- ansible/parsing/yaml/objects.py +1 -3
- ansible/playbook/__init__.py +1 -3
- ansible/playbook/attribute.py +1 -3
- ansible/playbook/base.py +2 -3
- ansible/playbook/block.py +1 -3
- ansible/playbook/collectionsearch.py +1 -2
- ansible/playbook/conditional.py +1 -3
- ansible/playbook/delegatable.py +1 -0
- ansible/playbook/handler.py +2 -4
- ansible/playbook/handler_task_include.py +1 -3
- ansible/playbook/helpers.py +1 -4
- ansible/playbook/included_file.py +4 -4
- ansible/playbook/loop_control.py +1 -3
- ansible/playbook/notifiable.py +1 -0
- ansible/playbook/play.py +1 -3
- ansible/playbook/play_context.py +1 -3
- ansible/playbook/playbook_include.py +1 -3
- ansible/playbook/role/__init__.py +1 -3
- ansible/playbook/role/definition.py +1 -3
- ansible/playbook/role/include.py +1 -3
- ansible/playbook/role/metadata.py +1 -3
- ansible/playbook/role/requirement.py +1 -3
- ansible/playbook/role_include.py +2 -10
- ansible/playbook/taggable.py +1 -3
- ansible/playbook/task.py +2 -4
- ansible/playbook/task_include.py +1 -3
- ansible/plugins/__init__.py +4 -5
- ansible/plugins/action/__init__.py +19 -13
- ansible/plugins/action/add_host.py +2 -4
- ansible/plugins/action/assemble.py +2 -3
- ansible/plugins/action/assert.py +1 -2
- ansible/plugins/action/async_status.py +1 -2
- ansible/plugins/action/command.py +1 -2
- ansible/plugins/action/copy.py +12 -9
- ansible/plugins/action/debug.py +1 -2
- ansible/plugins/action/dnf.py +4 -4
- ansible/plugins/action/fail.py +1 -2
- ansible/plugins/action/fetch.py +2 -3
- ansible/plugins/action/gather_facts.py +3 -4
- ansible/plugins/action/group_by.py +1 -2
- ansible/plugins/action/include_vars.py +1 -2
- ansible/plugins/action/normal.py +1 -2
- ansible/plugins/action/package.py +36 -21
- ansible/plugins/action/pause.py +1 -2
- ansible/plugins/action/raw.py +2 -3
- ansible/plugins/action/reboot.py +30 -15
- ansible/plugins/action/script.py +3 -4
- ansible/plugins/action/service.py +1 -2
- ansible/plugins/action/set_fact.py +1 -2
- ansible/plugins/action/set_stats.py +1 -2
- ansible/plugins/action/shell.py +1 -2
- ansible/plugins/action/template.py +1 -2
- ansible/plugins/action/unarchive.py +1 -2
- ansible/plugins/action/uri.py +2 -3
- ansible/plugins/action/validate_argument_spec.py +1 -2
- ansible/plugins/action/wait_for_connection.py +2 -3
- ansible/plugins/become/__init__.py +1 -2
- ansible/plugins/become/runas.py +1 -2
- ansible/plugins/become/su.py +1 -2
- ansible/plugins/become/sudo.py +1 -2
- ansible/plugins/cache/__init__.py +3 -3
- ansible/plugins/cache/base.py +1 -2
- ansible/plugins/cache/jsonfile.py +1 -3
- ansible/plugins/cache/memory.py +1 -2
- ansible/plugins/callback/__init__.py +2 -4
- ansible/plugins/callback/default.py +2 -3
- ansible/plugins/callback/junit.py +1 -2
- ansible/plugins/callback/minimal.py +1 -3
- ansible/plugins/callback/oneline.py +1 -3
- ansible/plugins/callback/tree.py +1 -2
- ansible/plugins/cliconf/__init__.py +1 -2
- ansible/plugins/connection/__init__.py +4 -5
- ansible/plugins/connection/local.py +3 -4
- ansible/plugins/connection/paramiko_ssh.py +1 -2
- ansible/plugins/connection/psrp.py +1 -2
- ansible/plugins/connection/ssh.py +18 -54
- ansible/plugins/connection/winrm.py +3 -4
- ansible/plugins/doc_fragments/action_common_attributes.py +2 -3
- ansible/plugins/doc_fragments/action_core.py +3 -4
- ansible/plugins/doc_fragments/backup.py +1 -2
- ansible/plugins/doc_fragments/connection_pipelining.py +1 -2
- ansible/plugins/doc_fragments/constructed.py +1 -2
- ansible/plugins/doc_fragments/decrypt.py +2 -3
- ansible/plugins/doc_fragments/default_callback.py +1 -2
- ansible/plugins/doc_fragments/files.py +1 -2
- ansible/plugins/doc_fragments/inventory_cache.py +1 -2
- ansible/plugins/doc_fragments/result_format_callback.py +1 -2
- ansible/plugins/doc_fragments/return_common.py +1 -2
- ansible/plugins/doc_fragments/shell_common.py +1 -2
- ansible/plugins/doc_fragments/shell_windows.py +1 -2
- ansible/plugins/doc_fragments/template_common.py +1 -2
- ansible/plugins/doc_fragments/url.py +1 -2
- ansible/plugins/doc_fragments/url_windows.py +1 -2
- ansible/plugins/doc_fragments/validate.py +1 -2
- ansible/plugins/doc_fragments/vars_plugin_staging.py +1 -2
- ansible/plugins/filter/__init__.py +1 -2
- ansible/plugins/filter/b64decode.yml +8 -8
- ansible/plugins/filter/b64encode.yml +4 -4
- ansible/plugins/filter/comment.yml +1 -1
- ansible/plugins/filter/core.py +11 -9
- ansible/plugins/filter/encryption.py +1 -3
- ansible/plugins/filter/extract.yml +1 -1
- ansible/plugins/filter/from_yaml_all.yml +1 -1
- ansible/plugins/filter/human_readable.yml +3 -3
- ansible/plugins/filter/human_to_bytes.yml +2 -2
- ansible/plugins/filter/mandatory.yml +1 -1
- ansible/plugins/filter/mathstuff.py +2 -2
- ansible/plugins/filter/password_hash.yml +3 -2
- ansible/plugins/filter/regex_replace.yml +15 -0
- ansible/plugins/filter/regex_search.yml +12 -0
- ansible/plugins/filter/strftime.yml +2 -9
- ansible/plugins/filter/to_datetime.yml +17 -2
- ansible/plugins/filter/to_nice_json.yml +4 -0
- ansible/plugins/filter/union.yml +1 -1
- ansible/plugins/filter/urls.py +1 -2
- ansible/plugins/filter/urlsplit.py +1 -2
- ansible/plugins/filter/zip.yml +2 -2
- ansible/plugins/filter/zip_longest.yml +1 -1
- ansible/plugins/httpapi/__init__.py +1 -2
- ansible/plugins/inventory/__init__.py +2 -4
- ansible/plugins/inventory/advanced_host_list.py +1 -2
- ansible/plugins/inventory/auto.py +2 -3
- ansible/plugins/inventory/constructed.py +3 -2
- ansible/plugins/inventory/generator.py +1 -2
- ansible/plugins/inventory/host_list.py +1 -2
- ansible/plugins/inventory/ini.py +1 -2
- ansible/plugins/inventory/script.py +122 -3
- ansible/plugins/inventory/toml.py +1 -2
- ansible/plugins/inventory/yaml.py +3 -4
- ansible/plugins/list.py +2 -3
- ansible/plugins/loader.py +10 -11
- ansible/plugins/lookup/__init__.py +1 -3
- ansible/plugins/lookup/config.py +19 -15
- ansible/plugins/lookup/csvfile.py +16 -7
- ansible/plugins/lookup/dict.py +2 -3
- ansible/plugins/lookup/env.py +4 -4
- ansible/plugins/lookup/file.py +1 -2
- ansible/plugins/lookup/fileglob.py +1 -2
- ansible/plugins/lookup/first_found.py +8 -7
- ansible/plugins/lookup/indexed_items.py +1 -2
- ansible/plugins/lookup/ini.py +6 -3
- ansible/plugins/lookup/inventory_hostnames.py +1 -2
- ansible/plugins/lookup/items.py +1 -2
- ansible/plugins/lookup/lines.py +1 -2
- ansible/plugins/lookup/list.py +1 -3
- ansible/plugins/lookup/nested.py +1 -2
- ansible/plugins/lookup/password.py +16 -14
- ansible/plugins/lookup/pipe.py +1 -2
- ansible/plugins/lookup/random_choice.py +1 -2
- ansible/plugins/lookup/sequence.py +21 -52
- ansible/plugins/lookup/subelements.py +1 -2
- ansible/plugins/lookup/template.py +1 -2
- ansible/plugins/lookup/together.py +1 -2
- ansible/plugins/lookup/unvault.py +1 -2
- ansible/plugins/lookup/url.py +9 -11
- ansible/plugins/lookup/varnames.py +1 -2
- ansible/plugins/lookup/vars.py +1 -2
- ansible/plugins/netconf/__init__.py +1 -2
- ansible/plugins/shell/__init__.py +3 -4
- ansible/plugins/shell/cmd.py +1 -2
- ansible/plugins/shell/powershell.py +1 -2
- ansible/plugins/shell/sh.py +1 -2
- ansible/plugins/strategy/__init__.py +33 -21
- ansible/plugins/strategy/debug.py +1 -2
- ansible/plugins/strategy/free.py +17 -7
- ansible/plugins/strategy/host_pinned.py +1 -3
- ansible/plugins/strategy/linear.py +22 -22
- ansible/plugins/terminal/__init__.py +2 -3
- ansible/plugins/test/__init__.py +1 -2
- ansible/plugins/test/change.yml +1 -1
- ansible/plugins/test/changed.yml +1 -1
- ansible/plugins/test/contains.yml +1 -1
- ansible/plugins/test/core.py +2 -4
- ansible/plugins/test/exists.yml +1 -1
- ansible/plugins/test/failed.yml +1 -1
- ansible/plugins/test/failure.yml +1 -1
- ansible/plugins/test/files.py +1 -3
- ansible/plugins/test/finished.yml +3 -3
- ansible/plugins/test/issuperset.yml +1 -1
- ansible/plugins/test/match.yml +1 -1
- ansible/plugins/test/mathstuff.py +1 -2
- ansible/plugins/test/reachable.yml +1 -1
- ansible/plugins/test/regex.yml +1 -1
- ansible/plugins/test/search.yml +1 -1
- ansible/plugins/test/skip.yml +1 -1
- ansible/plugins/test/skipped.yml +1 -1
- ansible/plugins/test/started.yml +1 -1
- ansible/plugins/test/succeeded.yml +1 -1
- ansible/plugins/test/success.yml +1 -1
- ansible/plugins/test/successful.yml +1 -1
- ansible/plugins/test/superset.yml +1 -1
- ansible/plugins/test/unreachable.yml +1 -1
- ansible/plugins/test/uri.py +1 -3
- ansible/plugins/vars/__init__.py +1 -2
- ansible/plugins/vars/host_group_vars.py +2 -3
- ansible/release.py +3 -5
- ansible/template/__init__.py +14 -27
- ansible/template/native_helpers.py +1 -3
- ansible/template/template.py +1 -3
- ansible/template/vars.py +1 -0
- ansible/utils/__init__.py +1 -3
- ansible/utils/cmd_functions.py +1 -2
- ansible/utils/collection_loader/__init__.py +1 -2
- ansible/utils/collection_loader/_collection_config.py +1 -2
- ansible/utils/collection_loader/_collection_finder.py +1 -2
- ansible/utils/collection_loader/_collection_meta.py +1 -2
- ansible/utils/color.py +1 -2
- ansible/utils/context_objects.py +1 -4
- ansible/utils/display.py +89 -30
- ansible/utils/encrypt.py +4 -105
- ansible/utils/fqcn.py +1 -2
- ansible/utils/galaxy.py +1 -3
- ansible/utils/hashing.py +1 -3
- ansible/utils/helpers.py +1 -3
- ansible/utils/jsonrpc.py +1 -2
- ansible/utils/listify.py +1 -3
- ansible/utils/lock.py +1 -3
- ansible/utils/multiprocessing.py +1 -3
- ansible/utils/native_jinja.py +1 -3
- ansible/utils/path.py +1 -2
- ansible/utils/plugin_docs.py +7 -6
- ansible/utils/py3compat.py +17 -55
- ansible/utils/sentinel.py +1 -3
- ansible/utils/shlex.py +1 -3
- ansible/utils/singleton.py +1 -3
- ansible/utils/ssh_functions.py +1 -3
- ansible/utils/unicode.py +1 -3
- ansible/utils/unsafe_proxy.py +1 -2
- ansible/utils/vars.py +6 -8
- ansible/utils/version.py +1 -3
- ansible/vars/clean.py +1 -3
- ansible/vars/fact_cache.py +1 -2
- ansible/vars/hostvars.py +3 -7
- ansible/vars/manager.py +24 -6
- ansible/vars/reserved.py +1 -3
- {ansible_core-2.16.7.data → ansible_core-2.17.0.data}/scripts/ansible-test +1 -2
- {ansible_core-2.16.7.dist-info → ansible_core-2.17.0.dist-info}/METADATA +3 -3
- ansible_core-2.17.0.dist-info/RECORD +987 -0
- ansible_test/__init__.py +1 -2
- ansible_test/_data/completion/docker.txt +7 -9
- ansible_test/_data/completion/remote.txt +6 -7
- ansible_test/_data/requirements/ansible-test.txt +0 -2
- ansible_test/_data/requirements/constraints.txt +1 -6
- ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
- ansible_test/_data/requirements/sanity.changelog.txt +3 -3
- ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
- 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 +7 -7
- ansible_test/_data/requirements/sanity.runtime-metadata.txt +1 -1
- ansible_test/_data/requirements/sanity.validate-modules.txt +3 -3
- ansible_test/_data/requirements/sanity.yamllint.txt +2 -2
- ansible_test/_internal/bootstrap.py +2 -2
- ansible_test/_internal/classification/__init__.py +0 -5
- ansible_test/_internal/commands/integration/cloud/cs.py +1 -1
- ansible_test/_internal/commands/integration/cloud/nios.py +1 -1
- ansible_test/_internal/commands/sanity/__init__.py +1 -27
- ansible_test/_internal/commands/sanity/import.py +0 -18
- ansible_test/_internal/commands/sanity/mypy.py +7 -10
- ansible_test/_internal/commands/units/__init__.py +1 -1
- ansible_test/_internal/config.py +0 -1
- ansible_test/_internal/content_config.py +0 -5
- ansible_test/_internal/coverage_util.py +0 -1
- ansible_test/_internal/docker_util.py +1 -1
- ansible_test/_internal/host_profiles.py +5 -4
- ansible_test/_internal/pypi_proxy.py +1 -8
- ansible_test/_internal/python_requirements.py +1 -119
- ansible_test/_internal/ssh.py +1 -0
- ansible_test/_internal/util.py +1 -1
- ansible_test/_internal/util_common.py +1 -1
- ansible_test/_internal/venv.py +10 -108
- ansible_test/_util/__init__.py +1 -2
- ansible_test/_util/controller/sanity/mypy/ansible-core.ini +0 -6
- ansible_test/_util/controller/sanity/mypy/modules.ini +0 -6
- ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +0 -1
- ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +0 -1
- ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +0 -1
- ansible_test/_util/controller/sanity/pylint/config/collection.cfg +0 -1
- ansible_test/_util/controller/sanity/pylint/config/default.cfg +0 -1
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +1 -2
- ansible_test/_util/controller/sanity/shellcheck/exclude.txt +0 -1
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +31 -59
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +0 -7
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +10 -2
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -1
- ansible_test/_util/controller/sanity/yamllint/yamllinter.py +16 -4
- ansible_test/_util/target/__init__.py +1 -2
- ansible_test/_util/target/cli/ansible_test_cli_stub.py +1 -2
- ansible_test/_util/target/common/constants.py +1 -4
- ansible_test/_util/target/injector/python.py +4 -19
- ansible_test/_util/target/pytest/plugins/ansible_forked.py +2 -9
- ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py +1 -5
- ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +1 -2
- ansible_test/_util/target/sanity/compile/compile.py +3 -12
- ansible_test/_util/target/sanity/import/importer.py +1 -12
- ansible_test/_util/target/setup/bootstrap.sh +49 -105
- ansible_test/_util/target/setup/probe_cgroups.py +1 -2
- ansible_test/_util/target/setup/quiet_pip.py +1 -16
- ansible_test/_util/target/setup/requirements.py +9 -2
- ansible_test/_util/target/tools/virtualenvcheck.py +1 -2
- ansible_test/_util/target/tools/yamlcheck.py +1 -2
- ansible/module_utils/common/_json_compat.py +0 -16
- ansible/module_utils/compat/_selectors2.py +0 -655
- ansible/modules/yum.py +0 -1821
- ansible/plugins/action/yum.py +0 -111
- ansible_core-2.16.7.dist-info/RECORD +0 -1009
- ansible_test/_util/controller/sanity/code-smell/future-import-boilerplate.json +0 -7
- ansible_test/_util/controller/sanity/code-smell/future-import-boilerplate.py +0 -46
- ansible_test/_util/controller/sanity/code-smell/metaclass-boilerplate.json +0 -7
- ansible_test/_util/controller/sanity/code-smell/metaclass-boilerplate.py +0 -44
- ansible_test/_util/controller/sanity/code-smell/no-basestring.json +0 -7
- ansible_test/_util/controller/sanity/code-smell/no-basestring.py +0 -21
- ansible_test/_util/controller/sanity/code-smell/no-dict-iteritems.json +0 -7
- ansible_test/_util/controller/sanity/code-smell/no-dict-iteritems.py +0 -21
- ansible_test/_util/controller/sanity/code-smell/no-dict-iterkeys.json +0 -7
- ansible_test/_util/controller/sanity/code-smell/no-dict-iterkeys.py +0 -21
- ansible_test/_util/controller/sanity/code-smell/no-dict-itervalues.json +0 -7
- ansible_test/_util/controller/sanity/code-smell/no-dict-itervalues.py +0 -21
- ansible_test/_util/controller/sanity/code-smell/no-main-display.json +0 -10
- ansible_test/_util/controller/sanity/code-smell/no-main-display.py +0 -21
- ansible_test/_util/controller/sanity/code-smell/no-unicode-literals.json +0 -7
- ansible_test/_util/controller/sanity/code-smell/no-unicode-literals.py +0 -21
- ansible_test/_util/controller/tools/sslcheck.py +0 -22
- ansible_test/_util/target/common/__init__.py +0 -2
- {ansible_core-2.16.7.dist-info → ansible_core-2.17.0.dist-info}/COPYING +0 -0
- {ansible_core-2.16.7.dist-info → ansible_core-2.17.0.dist-info}/WHEEL +0 -0
- {ansible_core-2.16.7.dist-info → ansible_core-2.17.0.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.16.7.dist-info → ansible_core-2.17.0.dist-info}/top_level.txt +0 -0
|
@@ -30,6 +30,7 @@ Python 2.6 and removed in Python 3.8. Still, there are many cases in which
|
|
|
30
30
|
access to OS distribution information is needed. See `Python issue 1322
|
|
31
31
|
<https://bugs.python.org/issue1322>`_ for more information.
|
|
32
32
|
"""
|
|
33
|
+
from __future__ import annotations
|
|
33
34
|
|
|
34
35
|
import argparse
|
|
35
36
|
import json
|
|
@@ -40,40 +41,39 @@ import shlex
|
|
|
40
41
|
import subprocess
|
|
41
42
|
import sys
|
|
42
43
|
import warnings
|
|
44
|
+
from typing import (
|
|
45
|
+
Any,
|
|
46
|
+
Callable,
|
|
47
|
+
Dict,
|
|
48
|
+
Iterable,
|
|
49
|
+
Optional,
|
|
50
|
+
Sequence,
|
|
51
|
+
TextIO,
|
|
52
|
+
Tuple,
|
|
53
|
+
Type,
|
|
54
|
+
)
|
|
43
55
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
#
|
|
48
|
-
|
|
49
|
-
if False: # pragma: nocover
|
|
50
|
-
from typing import (
|
|
51
|
-
Any,
|
|
52
|
-
Callable,
|
|
53
|
-
Dict,
|
|
54
|
-
Iterable,
|
|
55
|
-
Optional,
|
|
56
|
-
Sequence,
|
|
57
|
-
TextIO,
|
|
58
|
-
Tuple,
|
|
59
|
-
Type,
|
|
60
|
-
TypedDict,
|
|
61
|
-
Union,
|
|
62
|
-
)
|
|
56
|
+
try:
|
|
57
|
+
from typing import TypedDict
|
|
58
|
+
except ImportError:
|
|
59
|
+
# Python 3.7
|
|
60
|
+
TypedDict = dict
|
|
63
61
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
62
|
+
__version__ = "1.8.0"
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class VersionDict(TypedDict):
|
|
66
|
+
major: str
|
|
67
|
+
minor: str
|
|
68
|
+
build_number: str
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class InfoDict(TypedDict):
|
|
72
|
+
id: str
|
|
73
|
+
version: str
|
|
74
|
+
version_parts: VersionDict
|
|
75
|
+
like: str
|
|
76
|
+
codename: str
|
|
77
77
|
|
|
78
78
|
|
|
79
79
|
_UNIXCONFDIR = os.environ.get("UNIXCONFDIR", "/etc")
|
|
@@ -126,6 +126,26 @@ _DISTRO_RELEASE_CONTENT_REVERSED_PATTERN = re.compile(
|
|
|
126
126
|
# Pattern for base file name of distro release file
|
|
127
127
|
_DISTRO_RELEASE_BASENAME_PATTERN = re.compile(r"(\w+)[-_](release|version)$")
|
|
128
128
|
|
|
129
|
+
# Base file names to be looked up for if _UNIXCONFDIR is not readable.
|
|
130
|
+
_DISTRO_RELEASE_BASENAMES = [
|
|
131
|
+
"SuSE-release",
|
|
132
|
+
"arch-release",
|
|
133
|
+
"base-release",
|
|
134
|
+
"centos-release",
|
|
135
|
+
"fedora-release",
|
|
136
|
+
"gentoo-release",
|
|
137
|
+
"mageia-release",
|
|
138
|
+
"mandrake-release",
|
|
139
|
+
"mandriva-release",
|
|
140
|
+
"mandrivalinux-release",
|
|
141
|
+
"manjaro-release",
|
|
142
|
+
"oracle-release",
|
|
143
|
+
"redhat-release",
|
|
144
|
+
"rocky-release",
|
|
145
|
+
"sl-release",
|
|
146
|
+
"slackware-version",
|
|
147
|
+
]
|
|
148
|
+
|
|
129
149
|
# Base file names to be ignored when searching for distro release file
|
|
130
150
|
_DISTRO_RELEASE_IGNORE_BASENAMES = (
|
|
131
151
|
"debian_version",
|
|
@@ -138,8 +158,7 @@ _DISTRO_RELEASE_IGNORE_BASENAMES = (
|
|
|
138
158
|
)
|
|
139
159
|
|
|
140
160
|
|
|
141
|
-
def linux_distribution(full_distribution_name=True):
|
|
142
|
-
# type: (bool) -> Tuple[str, str, str]
|
|
161
|
+
def linux_distribution(full_distribution_name: bool = True) -> Tuple[str, str, str]:
|
|
143
162
|
"""
|
|
144
163
|
.. deprecated:: 1.6.0
|
|
145
164
|
|
|
@@ -182,8 +201,7 @@ def linux_distribution(full_distribution_name=True):
|
|
|
182
201
|
return _distro.linux_distribution(full_distribution_name)
|
|
183
202
|
|
|
184
203
|
|
|
185
|
-
def id():
|
|
186
|
-
# type: () -> str
|
|
204
|
+
def id() -> str:
|
|
187
205
|
"""
|
|
188
206
|
Return the distro ID of the current distribution, as a
|
|
189
207
|
machine-readable string.
|
|
@@ -227,6 +245,7 @@ def id():
|
|
|
227
245
|
"freebsd" FreeBSD
|
|
228
246
|
"midnightbsd" MidnightBSD
|
|
229
247
|
"rocky" Rocky Linux
|
|
248
|
+
"aix" AIX
|
|
230
249
|
"guix" Guix System
|
|
231
250
|
============== =========================================
|
|
232
251
|
|
|
@@ -265,8 +284,7 @@ def id():
|
|
|
265
284
|
return _distro.id()
|
|
266
285
|
|
|
267
286
|
|
|
268
|
-
def name(pretty=False):
|
|
269
|
-
# type: (bool) -> str
|
|
287
|
+
def name(pretty: bool = False) -> str:
|
|
270
288
|
"""
|
|
271
289
|
Return the name of the current OS distribution, as a human-readable
|
|
272
290
|
string.
|
|
@@ -305,8 +323,7 @@ def name(pretty=False):
|
|
|
305
323
|
return _distro.name(pretty)
|
|
306
324
|
|
|
307
325
|
|
|
308
|
-
def version(pretty=False, best=False):
|
|
309
|
-
# type: (bool, bool) -> str
|
|
326
|
+
def version(pretty: bool = False, best: bool = False) -> str:
|
|
310
327
|
"""
|
|
311
328
|
Return the version of the current OS distribution, as a human-readable
|
|
312
329
|
string.
|
|
@@ -354,8 +371,7 @@ def version(pretty=False, best=False):
|
|
|
354
371
|
return _distro.version(pretty, best)
|
|
355
372
|
|
|
356
373
|
|
|
357
|
-
def version_parts(best=False):
|
|
358
|
-
# type: (bool) -> Tuple[str, str, str]
|
|
374
|
+
def version_parts(best: bool = False) -> Tuple[str, str, str]:
|
|
359
375
|
"""
|
|
360
376
|
Return the version of the current OS distribution as a tuple
|
|
361
377
|
``(major, minor, build_number)`` with items as follows:
|
|
@@ -372,8 +388,7 @@ def version_parts(best=False):
|
|
|
372
388
|
return _distro.version_parts(best)
|
|
373
389
|
|
|
374
390
|
|
|
375
|
-
def major_version(best=False):
|
|
376
|
-
# type: (bool) -> str
|
|
391
|
+
def major_version(best: bool = False) -> str:
|
|
377
392
|
"""
|
|
378
393
|
Return the major version of the current OS distribution, as a string,
|
|
379
394
|
if provided.
|
|
@@ -386,8 +401,7 @@ def major_version(best=False):
|
|
|
386
401
|
return _distro.major_version(best)
|
|
387
402
|
|
|
388
403
|
|
|
389
|
-
def minor_version(best=False):
|
|
390
|
-
# type: (bool) -> str
|
|
404
|
+
def minor_version(best: bool = False) -> str:
|
|
391
405
|
"""
|
|
392
406
|
Return the minor version of the current OS distribution, as a string,
|
|
393
407
|
if provided.
|
|
@@ -400,8 +414,7 @@ def minor_version(best=False):
|
|
|
400
414
|
return _distro.minor_version(best)
|
|
401
415
|
|
|
402
416
|
|
|
403
|
-
def build_number(best=False):
|
|
404
|
-
# type: (bool) -> str
|
|
417
|
+
def build_number(best: bool = False) -> str:
|
|
405
418
|
"""
|
|
406
419
|
Return the build number of the current OS distribution, as a string,
|
|
407
420
|
if provided.
|
|
@@ -414,8 +427,7 @@ def build_number(best=False):
|
|
|
414
427
|
return _distro.build_number(best)
|
|
415
428
|
|
|
416
429
|
|
|
417
|
-
def like():
|
|
418
|
-
# type: () -> str
|
|
430
|
+
def like() -> str:
|
|
419
431
|
"""
|
|
420
432
|
Return a space-separated list of distro IDs of distributions that are
|
|
421
433
|
closely related to the current OS distribution in regards to packaging
|
|
@@ -432,8 +444,7 @@ def like():
|
|
|
432
444
|
return _distro.like()
|
|
433
445
|
|
|
434
446
|
|
|
435
|
-
def codename():
|
|
436
|
-
# type: () -> str
|
|
447
|
+
def codename() -> str:
|
|
437
448
|
"""
|
|
438
449
|
Return the codename for the release of the current OS distribution,
|
|
439
450
|
as a string.
|
|
@@ -457,8 +468,7 @@ def codename():
|
|
|
457
468
|
return _distro.codename()
|
|
458
469
|
|
|
459
470
|
|
|
460
|
-
def info(pretty=False, best=False):
|
|
461
|
-
# type: (bool, bool) -> InfoDict
|
|
471
|
+
def info(pretty: bool = False, best: bool = False) -> InfoDict:
|
|
462
472
|
"""
|
|
463
473
|
Return certain machine-readable information items about the current OS
|
|
464
474
|
distribution in a dictionary, as shown in the following example:
|
|
@@ -502,8 +512,7 @@ def info(pretty=False, best=False):
|
|
|
502
512
|
return _distro.info(pretty, best)
|
|
503
513
|
|
|
504
514
|
|
|
505
|
-
def os_release_info():
|
|
506
|
-
# type: () -> Dict[str, str]
|
|
515
|
+
def os_release_info() -> Dict[str, str]:
|
|
507
516
|
"""
|
|
508
517
|
Return a dictionary containing key-value pairs for the information items
|
|
509
518
|
from the os-release file data source of the current OS distribution.
|
|
@@ -513,8 +522,7 @@ def os_release_info():
|
|
|
513
522
|
return _distro.os_release_info()
|
|
514
523
|
|
|
515
524
|
|
|
516
|
-
def lsb_release_info():
|
|
517
|
-
# type: () -> Dict[str, str]
|
|
525
|
+
def lsb_release_info() -> Dict[str, str]:
|
|
518
526
|
"""
|
|
519
527
|
Return a dictionary containing key-value pairs for the information items
|
|
520
528
|
from the lsb_release command data source of the current OS distribution.
|
|
@@ -525,8 +533,7 @@ def lsb_release_info():
|
|
|
525
533
|
return _distro.lsb_release_info()
|
|
526
534
|
|
|
527
535
|
|
|
528
|
-
def distro_release_info():
|
|
529
|
-
# type: () -> Dict[str, str]
|
|
536
|
+
def distro_release_info() -> Dict[str, str]:
|
|
530
537
|
"""
|
|
531
538
|
Return a dictionary containing key-value pairs for the information items
|
|
532
539
|
from the distro release file data source of the current OS distribution.
|
|
@@ -536,8 +543,7 @@ def distro_release_info():
|
|
|
536
543
|
return _distro.distro_release_info()
|
|
537
544
|
|
|
538
545
|
|
|
539
|
-
def uname_info():
|
|
540
|
-
# type: () -> Dict[str, str]
|
|
546
|
+
def uname_info() -> Dict[str, str]:
|
|
541
547
|
"""
|
|
542
548
|
Return a dictionary containing key-value pairs for the information items
|
|
543
549
|
from the distro release file data source of the current OS distribution.
|
|
@@ -545,8 +551,7 @@ def uname_info():
|
|
|
545
551
|
return _distro.uname_info()
|
|
546
552
|
|
|
547
553
|
|
|
548
|
-
def os_release_attr(attribute):
|
|
549
|
-
# type: (str) -> str
|
|
554
|
+
def os_release_attr(attribute: str) -> str:
|
|
550
555
|
"""
|
|
551
556
|
Return a single named information item from the os-release file data source
|
|
552
557
|
of the current OS distribution.
|
|
@@ -565,8 +570,7 @@ def os_release_attr(attribute):
|
|
|
565
570
|
return _distro.os_release_attr(attribute)
|
|
566
571
|
|
|
567
572
|
|
|
568
|
-
def lsb_release_attr(attribute):
|
|
569
|
-
# type: (str) -> str
|
|
573
|
+
def lsb_release_attr(attribute: str) -> str:
|
|
570
574
|
"""
|
|
571
575
|
Return a single named information item from the lsb_release command output
|
|
572
576
|
data source of the current OS distribution.
|
|
@@ -586,8 +590,7 @@ def lsb_release_attr(attribute):
|
|
|
586
590
|
return _distro.lsb_release_attr(attribute)
|
|
587
591
|
|
|
588
592
|
|
|
589
|
-
def distro_release_attr(attribute):
|
|
590
|
-
# type: (str) -> str
|
|
593
|
+
def distro_release_attr(attribute: str) -> str:
|
|
591
594
|
"""
|
|
592
595
|
Return a single named information item from the distro release file
|
|
593
596
|
data source of the current OS distribution.
|
|
@@ -606,8 +609,7 @@ def distro_release_attr(attribute):
|
|
|
606
609
|
return _distro.distro_release_attr(attribute)
|
|
607
610
|
|
|
608
611
|
|
|
609
|
-
def uname_attr(attribute):
|
|
610
|
-
# type: (str) -> str
|
|
612
|
+
def uname_attr(attribute: str) -> str:
|
|
611
613
|
"""
|
|
612
614
|
Return a single named information item from the distro release file
|
|
613
615
|
data source of the current OS distribution.
|
|
@@ -628,25 +630,23 @@ try:
|
|
|
628
630
|
from functools import cached_property
|
|
629
631
|
except ImportError:
|
|
630
632
|
# Python < 3.8
|
|
631
|
-
class cached_property
|
|
633
|
+
class cached_property: # type: ignore
|
|
632
634
|
"""A version of @property which caches the value. On access, it calls the
|
|
633
635
|
underlying function and sets the value in `__dict__` so future accesses
|
|
634
636
|
will not re-call the property.
|
|
635
637
|
"""
|
|
636
638
|
|
|
637
|
-
def __init__(self, f):
|
|
638
|
-
# type: (Callable[[Any], Any]) -> None
|
|
639
|
+
def __init__(self, f: Callable[[Any], Any]) -> None:
|
|
639
640
|
self._fname = f.__name__
|
|
640
641
|
self._f = f
|
|
641
642
|
|
|
642
|
-
def __get__(self, obj, owner):
|
|
643
|
-
|
|
644
|
-
assert obj is not None, "call {} on an instance".format(self._fname)
|
|
643
|
+
def __get__(self, obj: Any, owner: Type[Any]) -> Any:
|
|
644
|
+
assert obj is not None, f"call {self._fname} on an instance"
|
|
645
645
|
ret = obj.__dict__[self._fname] = self._f(obj)
|
|
646
646
|
return ret
|
|
647
647
|
|
|
648
648
|
|
|
649
|
-
class LinuxDistribution
|
|
649
|
+
class LinuxDistribution:
|
|
650
650
|
"""
|
|
651
651
|
Provides information about a OS distribution.
|
|
652
652
|
|
|
@@ -666,13 +666,13 @@ class LinuxDistribution(object):
|
|
|
666
666
|
|
|
667
667
|
def __init__(
|
|
668
668
|
self,
|
|
669
|
-
include_lsb=
|
|
670
|
-
os_release_file="",
|
|
671
|
-
distro_release_file="",
|
|
672
|
-
include_uname=
|
|
673
|
-
root_dir=None,
|
|
674
|
-
|
|
675
|
-
|
|
669
|
+
include_lsb: Optional[bool] = None,
|
|
670
|
+
os_release_file: str = "",
|
|
671
|
+
distro_release_file: str = "",
|
|
672
|
+
include_uname: Optional[bool] = None,
|
|
673
|
+
root_dir: Optional[str] = None,
|
|
674
|
+
include_oslevel: Optional[bool] = None,
|
|
675
|
+
) -> None:
|
|
676
676
|
"""
|
|
677
677
|
The initialization method of this class gathers information from the
|
|
678
678
|
available data sources, and stores that in private instance attributes.
|
|
@@ -712,7 +712,13 @@ class LinuxDistribution(object):
|
|
|
712
712
|
be empty.
|
|
713
713
|
|
|
714
714
|
* ``root_dir`` (string): The absolute path to the root directory to use
|
|
715
|
-
to find distro-related information files.
|
|
715
|
+
to find distro-related information files. Note that ``include_*``
|
|
716
|
+
parameters must not be enabled in combination with ``root_dir``.
|
|
717
|
+
|
|
718
|
+
* ``include_oslevel`` (bool): Controls whether (AIX) oslevel command
|
|
719
|
+
output is included as a data source. If the oslevel command is not
|
|
720
|
+
available in the program execution path the data source will be
|
|
721
|
+
empty.
|
|
716
722
|
|
|
717
723
|
Public instance attributes:
|
|
718
724
|
|
|
@@ -731,9 +737,20 @@ class LinuxDistribution(object):
|
|
|
731
737
|
parameter. This controls whether the uname information will
|
|
732
738
|
be loaded.
|
|
733
739
|
|
|
740
|
+
* ``include_oslevel`` (bool): The result of the ``include_oslevel``
|
|
741
|
+
parameter. This controls whether (AIX) oslevel information will be
|
|
742
|
+
loaded.
|
|
743
|
+
|
|
744
|
+
* ``root_dir`` (string): The result of the ``root_dir`` parameter.
|
|
745
|
+
The absolute path to the root directory to use to find distro-related
|
|
746
|
+
information files.
|
|
747
|
+
|
|
734
748
|
Raises:
|
|
735
749
|
|
|
736
|
-
* :py:exc:`
|
|
750
|
+
* :py:exc:`ValueError`: Initialization parameters combination is not
|
|
751
|
+
supported.
|
|
752
|
+
|
|
753
|
+
* :py:exc:`OSError`: Some I/O issue with an os-release file or distro
|
|
737
754
|
release file.
|
|
738
755
|
|
|
739
756
|
* :py:exc:`UnicodeError`: A data source has unexpected characters or
|
|
@@ -763,11 +780,24 @@ class LinuxDistribution(object):
|
|
|
763
780
|
self.os_release_file = usr_lib_os_release_file
|
|
764
781
|
|
|
765
782
|
self.distro_release_file = distro_release_file or "" # updated later
|
|
766
|
-
self.include_lsb = include_lsb
|
|
767
|
-
self.include_uname = include_uname
|
|
768
783
|
|
|
769
|
-
|
|
770
|
-
|
|
784
|
+
is_root_dir_defined = root_dir is not None
|
|
785
|
+
if is_root_dir_defined and (include_lsb or include_uname or include_oslevel):
|
|
786
|
+
raise ValueError(
|
|
787
|
+
"Including subprocess data sources from specific root_dir is disallowed"
|
|
788
|
+
" to prevent false information"
|
|
789
|
+
)
|
|
790
|
+
self.include_lsb = (
|
|
791
|
+
include_lsb if include_lsb is not None else not is_root_dir_defined
|
|
792
|
+
)
|
|
793
|
+
self.include_uname = (
|
|
794
|
+
include_uname if include_uname is not None else not is_root_dir_defined
|
|
795
|
+
)
|
|
796
|
+
self.include_oslevel = (
|
|
797
|
+
include_oslevel if include_oslevel is not None else not is_root_dir_defined
|
|
798
|
+
)
|
|
799
|
+
|
|
800
|
+
def __repr__(self) -> str:
|
|
771
801
|
"""Return repr of all info"""
|
|
772
802
|
return (
|
|
773
803
|
"LinuxDistribution("
|
|
@@ -775,14 +805,18 @@ class LinuxDistribution(object):
|
|
|
775
805
|
"distro_release_file={self.distro_release_file!r}, "
|
|
776
806
|
"include_lsb={self.include_lsb!r}, "
|
|
777
807
|
"include_uname={self.include_uname!r}, "
|
|
808
|
+
"include_oslevel={self.include_oslevel!r}, "
|
|
809
|
+
"root_dir={self.root_dir!r}, "
|
|
778
810
|
"_os_release_info={self._os_release_info!r}, "
|
|
779
811
|
"_lsb_release_info={self._lsb_release_info!r}, "
|
|
780
812
|
"_distro_release_info={self._distro_release_info!r}, "
|
|
781
|
-
"_uname_info={self._uname_info!r}
|
|
813
|
+
"_uname_info={self._uname_info!r}, "
|
|
814
|
+
"_oslevel_info={self._oslevel_info!r})".format(self=self)
|
|
782
815
|
)
|
|
783
816
|
|
|
784
|
-
def linux_distribution(
|
|
785
|
-
|
|
817
|
+
def linux_distribution(
|
|
818
|
+
self, full_distribution_name: bool = True
|
|
819
|
+
) -> Tuple[str, str, str]:
|
|
786
820
|
"""
|
|
787
821
|
Return information about the OS distribution that is compatible
|
|
788
822
|
with Python's :func:`platform.linux_distribution`, supporting a subset
|
|
@@ -796,15 +830,13 @@ class LinuxDistribution(object):
|
|
|
796
830
|
self._os_release_info.get("release_codename") or self.codename(),
|
|
797
831
|
)
|
|
798
832
|
|
|
799
|
-
def id(self):
|
|
800
|
-
# type: () -> str
|
|
833
|
+
def id(self) -> str:
|
|
801
834
|
"""Return the distro ID of the OS distribution, as a string.
|
|
802
835
|
|
|
803
836
|
For details, see :func:`distro.id`.
|
|
804
837
|
"""
|
|
805
838
|
|
|
806
|
-
def normalize(distro_id, table):
|
|
807
|
-
# type: (str, Dict[str, str]) -> str
|
|
839
|
+
def normalize(distro_id: str, table: Dict[str, str]) -> str:
|
|
808
840
|
distro_id = distro_id.lower().replace(" ", "_")
|
|
809
841
|
return table.get(distro_id, distro_id)
|
|
810
842
|
|
|
@@ -826,8 +858,7 @@ class LinuxDistribution(object):
|
|
|
826
858
|
|
|
827
859
|
return ""
|
|
828
860
|
|
|
829
|
-
def name(self, pretty=False):
|
|
830
|
-
# type: (bool) -> str
|
|
861
|
+
def name(self, pretty: bool = False) -> str:
|
|
831
862
|
"""
|
|
832
863
|
Return the name of the OS distribution, as a string.
|
|
833
864
|
|
|
@@ -847,11 +878,10 @@ class LinuxDistribution(object):
|
|
|
847
878
|
name = self.distro_release_attr("name") or self.uname_attr("name")
|
|
848
879
|
version = self.version(pretty=True)
|
|
849
880
|
if version:
|
|
850
|
-
name = name
|
|
881
|
+
name = f"{name} {version}"
|
|
851
882
|
return name or ""
|
|
852
883
|
|
|
853
|
-
def version(self, pretty=False, best=False):
|
|
854
|
-
# type: (bool, bool) -> str
|
|
884
|
+
def version(self, pretty: bool = False, best: bool = False) -> str:
|
|
855
885
|
"""
|
|
856
886
|
Return the version of the OS distribution, as a string.
|
|
857
887
|
|
|
@@ -869,7 +899,10 @@ class LinuxDistribution(object):
|
|
|
869
899
|
).get("version_id", ""),
|
|
870
900
|
self.uname_attr("release"),
|
|
871
901
|
]
|
|
872
|
-
if self.
|
|
902
|
+
if self.uname_attr("id").startswith("aix"):
|
|
903
|
+
# On AIX platforms, prefer oslevel command output.
|
|
904
|
+
versions.insert(0, self.oslevel_info())
|
|
905
|
+
elif self.id() == "debian" or "debian" in self.like().split():
|
|
873
906
|
# On Debian-like, add debian_version file content to candidates list.
|
|
874
907
|
versions.append(self._debian_version)
|
|
875
908
|
version = ""
|
|
@@ -887,11 +920,10 @@ class LinuxDistribution(object):
|
|
|
887
920
|
version = v
|
|
888
921
|
break
|
|
889
922
|
if pretty and version and self.codename():
|
|
890
|
-
version = "{
|
|
923
|
+
version = f"{version} ({self.codename()})"
|
|
891
924
|
return version
|
|
892
925
|
|
|
893
|
-
def version_parts(self, best=False):
|
|
894
|
-
# type: (bool) -> Tuple[str, str, str]
|
|
926
|
+
def version_parts(self, best: bool = False) -> Tuple[str, str, str]:
|
|
895
927
|
"""
|
|
896
928
|
Return the version of the OS distribution, as a tuple of version
|
|
897
929
|
numbers.
|
|
@@ -907,8 +939,7 @@ class LinuxDistribution(object):
|
|
|
907
939
|
return major, minor or "", build_number or ""
|
|
908
940
|
return "", "", ""
|
|
909
941
|
|
|
910
|
-
def major_version(self, best=False):
|
|
911
|
-
# type: (bool) -> str
|
|
942
|
+
def major_version(self, best: bool = False) -> str:
|
|
912
943
|
"""
|
|
913
944
|
Return the major version number of the current distribution.
|
|
914
945
|
|
|
@@ -916,8 +947,7 @@ class LinuxDistribution(object):
|
|
|
916
947
|
"""
|
|
917
948
|
return self.version_parts(best)[0]
|
|
918
949
|
|
|
919
|
-
def minor_version(self, best=False):
|
|
920
|
-
# type: (bool) -> str
|
|
950
|
+
def minor_version(self, best: bool = False) -> str:
|
|
921
951
|
"""
|
|
922
952
|
Return the minor version number of the current distribution.
|
|
923
953
|
|
|
@@ -925,8 +955,7 @@ class LinuxDistribution(object):
|
|
|
925
955
|
"""
|
|
926
956
|
return self.version_parts(best)[1]
|
|
927
957
|
|
|
928
|
-
def build_number(self, best=False):
|
|
929
|
-
# type: (bool) -> str
|
|
958
|
+
def build_number(self, best: bool = False) -> str:
|
|
930
959
|
"""
|
|
931
960
|
Return the build number of the current distribution.
|
|
932
961
|
|
|
@@ -934,8 +963,7 @@ class LinuxDistribution(object):
|
|
|
934
963
|
"""
|
|
935
964
|
return self.version_parts(best)[2]
|
|
936
965
|
|
|
937
|
-
def like(self):
|
|
938
|
-
# type: () -> str
|
|
966
|
+
def like(self) -> str:
|
|
939
967
|
"""
|
|
940
968
|
Return the IDs of distributions that are like the OS distribution.
|
|
941
969
|
|
|
@@ -943,8 +971,7 @@ class LinuxDistribution(object):
|
|
|
943
971
|
"""
|
|
944
972
|
return self.os_release_attr("id_like") or ""
|
|
945
973
|
|
|
946
|
-
def codename(self):
|
|
947
|
-
# type: () -> str
|
|
974
|
+
def codename(self) -> str:
|
|
948
975
|
"""
|
|
949
976
|
Return the codename of the OS distribution.
|
|
950
977
|
|
|
@@ -961,8 +988,7 @@ class LinuxDistribution(object):
|
|
|
961
988
|
or ""
|
|
962
989
|
)
|
|
963
990
|
|
|
964
|
-
def info(self, pretty=False, best=False):
|
|
965
|
-
# type: (bool, bool) -> InfoDict
|
|
991
|
+
def info(self, pretty: bool = False, best: bool = False) -> InfoDict:
|
|
966
992
|
"""
|
|
967
993
|
Return certain machine-readable information about the OS
|
|
968
994
|
distribution.
|
|
@@ -981,8 +1007,7 @@ class LinuxDistribution(object):
|
|
|
981
1007
|
codename=self.codename(),
|
|
982
1008
|
)
|
|
983
1009
|
|
|
984
|
-
def os_release_info(self):
|
|
985
|
-
# type: () -> Dict[str, str]
|
|
1010
|
+
def os_release_info(self) -> Dict[str, str]:
|
|
986
1011
|
"""
|
|
987
1012
|
Return a dictionary containing key-value pairs for the information
|
|
988
1013
|
items from the os-release file data source of the OS distribution.
|
|
@@ -991,8 +1016,7 @@ class LinuxDistribution(object):
|
|
|
991
1016
|
"""
|
|
992
1017
|
return self._os_release_info
|
|
993
1018
|
|
|
994
|
-
def lsb_release_info(self):
|
|
995
|
-
# type: () -> Dict[str, str]
|
|
1019
|
+
def lsb_release_info(self) -> Dict[str, str]:
|
|
996
1020
|
"""
|
|
997
1021
|
Return a dictionary containing key-value pairs for the information
|
|
998
1022
|
items from the lsb_release command data source of the OS
|
|
@@ -1002,8 +1026,7 @@ class LinuxDistribution(object):
|
|
|
1002
1026
|
"""
|
|
1003
1027
|
return self._lsb_release_info
|
|
1004
1028
|
|
|
1005
|
-
def distro_release_info(self):
|
|
1006
|
-
# type: () -> Dict[str, str]
|
|
1029
|
+
def distro_release_info(self) -> Dict[str, str]:
|
|
1007
1030
|
"""
|
|
1008
1031
|
Return a dictionary containing key-value pairs for the information
|
|
1009
1032
|
items from the distro release file data source of the OS
|
|
@@ -1013,8 +1036,7 @@ class LinuxDistribution(object):
|
|
|
1013
1036
|
"""
|
|
1014
1037
|
return self._distro_release_info
|
|
1015
1038
|
|
|
1016
|
-
def uname_info(self):
|
|
1017
|
-
# type: () -> Dict[str, str]
|
|
1039
|
+
def uname_info(self) -> Dict[str, str]:
|
|
1018
1040
|
"""
|
|
1019
1041
|
Return a dictionary containing key-value pairs for the information
|
|
1020
1042
|
items from the uname command data source of the OS distribution.
|
|
@@ -1023,8 +1045,13 @@ class LinuxDistribution(object):
|
|
|
1023
1045
|
"""
|
|
1024
1046
|
return self._uname_info
|
|
1025
1047
|
|
|
1026
|
-
def
|
|
1027
|
-
|
|
1048
|
+
def oslevel_info(self) -> str:
|
|
1049
|
+
"""
|
|
1050
|
+
Return AIX' oslevel command output.
|
|
1051
|
+
"""
|
|
1052
|
+
return self._oslevel_info
|
|
1053
|
+
|
|
1054
|
+
def os_release_attr(self, attribute: str) -> str:
|
|
1028
1055
|
"""
|
|
1029
1056
|
Return a single named information item from the os-release file data
|
|
1030
1057
|
source of the OS distribution.
|
|
@@ -1033,8 +1060,7 @@ class LinuxDistribution(object):
|
|
|
1033
1060
|
"""
|
|
1034
1061
|
return self._os_release_info.get(attribute, "")
|
|
1035
1062
|
|
|
1036
|
-
def lsb_release_attr(self, attribute):
|
|
1037
|
-
# type: (str) -> str
|
|
1063
|
+
def lsb_release_attr(self, attribute: str) -> str:
|
|
1038
1064
|
"""
|
|
1039
1065
|
Return a single named information item from the lsb_release command
|
|
1040
1066
|
output data source of the OS distribution.
|
|
@@ -1043,8 +1069,7 @@ class LinuxDistribution(object):
|
|
|
1043
1069
|
"""
|
|
1044
1070
|
return self._lsb_release_info.get(attribute, "")
|
|
1045
1071
|
|
|
1046
|
-
def distro_release_attr(self, attribute):
|
|
1047
|
-
# type: (str) -> str
|
|
1072
|
+
def distro_release_attr(self, attribute: str) -> str:
|
|
1048
1073
|
"""
|
|
1049
1074
|
Return a single named information item from the distro release file
|
|
1050
1075
|
data source of the OS distribution.
|
|
@@ -1053,8 +1078,7 @@ class LinuxDistribution(object):
|
|
|
1053
1078
|
"""
|
|
1054
1079
|
return self._distro_release_info.get(attribute, "")
|
|
1055
1080
|
|
|
1056
|
-
def uname_attr(self, attribute):
|
|
1057
|
-
# type: (str) -> str
|
|
1081
|
+
def uname_attr(self, attribute: str) -> str:
|
|
1058
1082
|
"""
|
|
1059
1083
|
Return a single named information item from the uname command
|
|
1060
1084
|
output data source of the OS distribution.
|
|
@@ -1064,8 +1088,7 @@ class LinuxDistribution(object):
|
|
|
1064
1088
|
return self._uname_info.get(attribute, "")
|
|
1065
1089
|
|
|
1066
1090
|
@cached_property
|
|
1067
|
-
def _os_release_info(self):
|
|
1068
|
-
# type: () -> Dict[str, str]
|
|
1091
|
+
def _os_release_info(self) -> Dict[str, str]:
|
|
1069
1092
|
"""
|
|
1070
1093
|
Get the information items from the specified os-release file.
|
|
1071
1094
|
|
|
@@ -1073,13 +1096,12 @@ class LinuxDistribution(object):
|
|
|
1073
1096
|
A dictionary containing all information items.
|
|
1074
1097
|
"""
|
|
1075
1098
|
if os.path.isfile(self.os_release_file):
|
|
1076
|
-
with open(self.os_release_file) as release_file:
|
|
1099
|
+
with open(self.os_release_file, encoding="utf-8") as release_file:
|
|
1077
1100
|
return self._parse_os_release_content(release_file)
|
|
1078
1101
|
return {}
|
|
1079
1102
|
|
|
1080
1103
|
@staticmethod
|
|
1081
|
-
def _parse_os_release_content(lines):
|
|
1082
|
-
# type: (TextIO) -> Dict[str, str]
|
|
1104
|
+
def _parse_os_release_content(lines: TextIO) -> Dict[str, str]:
|
|
1083
1105
|
"""
|
|
1084
1106
|
Parse the lines of an os-release file.
|
|
1085
1107
|
|
|
@@ -1096,16 +1118,6 @@ class LinuxDistribution(object):
|
|
|
1096
1118
|
lexer = shlex.shlex(lines, posix=True)
|
|
1097
1119
|
lexer.whitespace_split = True
|
|
1098
1120
|
|
|
1099
|
-
# The shlex module defines its `wordchars` variable using literals,
|
|
1100
|
-
# making it dependent on the encoding of the Python source file.
|
|
1101
|
-
# In Python 2.6 and 2.7, the shlex source file is encoded in
|
|
1102
|
-
# 'iso-8859-1', and the `wordchars` variable is defined as a byte
|
|
1103
|
-
# string. This causes a UnicodeDecodeError to be raised when the
|
|
1104
|
-
# parsed content is a unicode object. The following fix resolves that
|
|
1105
|
-
# (... but it should be fixed in shlex...):
|
|
1106
|
-
if sys.version_info[0] == 2 and isinstance(lexer.wordchars, bytes):
|
|
1107
|
-
lexer.wordchars = lexer.wordchars.decode("iso-8859-1")
|
|
1108
|
-
|
|
1109
1121
|
tokens = list(lexer)
|
|
1110
1122
|
for token in tokens:
|
|
1111
1123
|
# At this point, all shell-like parsing has been done (i.e.
|
|
@@ -1139,8 +1151,7 @@ class LinuxDistribution(object):
|
|
|
1139
1151
|
return props
|
|
1140
1152
|
|
|
1141
1153
|
@cached_property
|
|
1142
|
-
def _lsb_release_info(self):
|
|
1143
|
-
# type: () -> Dict[str, str]
|
|
1154
|
+
def _lsb_release_info(self) -> Dict[str, str]:
|
|
1144
1155
|
"""
|
|
1145
1156
|
Get the information items from the lsb_release command output.
|
|
1146
1157
|
|
|
@@ -1149,19 +1160,17 @@ class LinuxDistribution(object):
|
|
|
1149
1160
|
"""
|
|
1150
1161
|
if not self.include_lsb:
|
|
1151
1162
|
return {}
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
return {}
|
|
1163
|
+
try:
|
|
1164
|
+
cmd = ("lsb_release", "-a")
|
|
1165
|
+
stdout = subprocess.check_output(cmd, stderr=subprocess.DEVNULL)
|
|
1166
|
+
# Command not found or lsb_release returned error
|
|
1167
|
+
except (OSError, subprocess.CalledProcessError):
|
|
1168
|
+
return {}
|
|
1159
1169
|
content = self._to_str(stdout).splitlines()
|
|
1160
1170
|
return self._parse_lsb_release_content(content)
|
|
1161
1171
|
|
|
1162
1172
|
@staticmethod
|
|
1163
|
-
def _parse_lsb_release_content(lines):
|
|
1164
|
-
# type: (Iterable[str]) -> Dict[str, str]
|
|
1173
|
+
def _parse_lsb_release_content(lines: Iterable[str]) -> Dict[str, str]:
|
|
1165
1174
|
"""
|
|
1166
1175
|
Parse the output of the lsb_release command.
|
|
1167
1176
|
|
|
@@ -1185,31 +1194,39 @@ class LinuxDistribution(object):
|
|
|
1185
1194
|
return props
|
|
1186
1195
|
|
|
1187
1196
|
@cached_property
|
|
1188
|
-
def _uname_info(self):
|
|
1189
|
-
# type: () -> Dict[str, str]
|
|
1197
|
+
def _uname_info(self) -> Dict[str, str]:
|
|
1190
1198
|
if not self.include_uname:
|
|
1191
1199
|
return {}
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
return {}
|
|
1200
|
+
try:
|
|
1201
|
+
cmd = ("uname", "-rs")
|
|
1202
|
+
stdout = subprocess.check_output(cmd, stderr=subprocess.DEVNULL)
|
|
1203
|
+
except OSError:
|
|
1204
|
+
return {}
|
|
1198
1205
|
content = self._to_str(stdout).splitlines()
|
|
1199
1206
|
return self._parse_uname_content(content)
|
|
1200
1207
|
|
|
1201
1208
|
@cached_property
|
|
1202
|
-
def
|
|
1203
|
-
|
|
1209
|
+
def _oslevel_info(self) -> str:
|
|
1210
|
+
if not self.include_oslevel:
|
|
1211
|
+
return ""
|
|
1212
|
+
try:
|
|
1213
|
+
stdout = subprocess.check_output("oslevel", stderr=subprocess.DEVNULL)
|
|
1214
|
+
except (OSError, subprocess.CalledProcessError):
|
|
1215
|
+
return ""
|
|
1216
|
+
return self._to_str(stdout).strip()
|
|
1217
|
+
|
|
1218
|
+
@cached_property
|
|
1219
|
+
def _debian_version(self) -> str:
|
|
1204
1220
|
try:
|
|
1205
|
-
with open(
|
|
1221
|
+
with open(
|
|
1222
|
+
os.path.join(self.etc_dir, "debian_version"), encoding="ascii"
|
|
1223
|
+
) as fp:
|
|
1206
1224
|
return fp.readline().rstrip()
|
|
1207
|
-
except
|
|
1225
|
+
except FileNotFoundError:
|
|
1208
1226
|
return ""
|
|
1209
1227
|
|
|
1210
1228
|
@staticmethod
|
|
1211
|
-
def _parse_uname_content(lines):
|
|
1212
|
-
# type: (Sequence[str]) -> Dict[str, str]
|
|
1229
|
+
def _parse_uname_content(lines: Sequence[str]) -> Dict[str, str]:
|
|
1213
1230
|
if not lines:
|
|
1214
1231
|
return {}
|
|
1215
1232
|
props = {}
|
|
@@ -1228,23 +1245,12 @@ class LinuxDistribution(object):
|
|
|
1228
1245
|
return props
|
|
1229
1246
|
|
|
1230
1247
|
@staticmethod
|
|
1231
|
-
def _to_str(
|
|
1232
|
-
# type: (Union[bytes, str]) -> str
|
|
1248
|
+
def _to_str(bytestring: bytes) -> str:
|
|
1233
1249
|
encoding = sys.getfilesystemencoding()
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
if sys.version_info[0] >= 3:
|
|
1237
|
-
if isinstance(text, bytes):
|
|
1238
|
-
return text.decode(encoding)
|
|
1239
|
-
else:
|
|
1240
|
-
if isinstance(text, unicode): # noqa
|
|
1241
|
-
return text.encode(encoding)
|
|
1242
|
-
|
|
1243
|
-
return text
|
|
1250
|
+
return bytestring.decode(encoding)
|
|
1244
1251
|
|
|
1245
1252
|
@cached_property
|
|
1246
|
-
def _distro_release_info(self):
|
|
1247
|
-
# type: () -> Dict[str, str]
|
|
1253
|
+
def _distro_release_info(self) -> Dict[str, str]:
|
|
1248
1254
|
"""
|
|
1249
1255
|
Get the information items from the specified distro release file.
|
|
1250
1256
|
|
|
@@ -1261,14 +1267,14 @@ class LinuxDistribution(object):
|
|
|
1261
1267
|
# file), because we want to use what was specified as best as
|
|
1262
1268
|
# possible.
|
|
1263
1269
|
match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename)
|
|
1264
|
-
if "name" in distro_info and "cloudlinux" in distro_info["name"].lower():
|
|
1265
|
-
distro_info["id"] = "cloudlinux"
|
|
1266
|
-
elif match:
|
|
1267
|
-
distro_info["id"] = match.group(1)
|
|
1268
|
-
return distro_info
|
|
1269
1270
|
else:
|
|
1270
1271
|
try:
|
|
1271
|
-
basenames =
|
|
1272
|
+
basenames = [
|
|
1273
|
+
basename
|
|
1274
|
+
for basename in os.listdir(self.etc_dir)
|
|
1275
|
+
if basename not in _DISTRO_RELEASE_IGNORE_BASENAMES
|
|
1276
|
+
and os.path.isfile(os.path.join(self.etc_dir, basename))
|
|
1277
|
+
]
|
|
1272
1278
|
# We sort for repeatability in cases where there are multiple
|
|
1273
1279
|
# distro specific files; e.g. CentOS, Oracle, Enterprise all
|
|
1274
1280
|
# containing `redhat-release` on top of their own.
|
|
@@ -1278,42 +1284,31 @@ class LinuxDistribution(object):
|
|
|
1278
1284
|
# sure about the *-release files. Check common entries of
|
|
1279
1285
|
# /etc for information. If they turn out to not be there the
|
|
1280
1286
|
# error is handled in `_parse_distro_release_file()`.
|
|
1281
|
-
basenames =
|
|
1282
|
-
"SuSE-release",
|
|
1283
|
-
"arch-release",
|
|
1284
|
-
"base-release",
|
|
1285
|
-
"centos-release",
|
|
1286
|
-
"fedora-release",
|
|
1287
|
-
"gentoo-release",
|
|
1288
|
-
"mageia-release",
|
|
1289
|
-
"mandrake-release",
|
|
1290
|
-
"mandriva-release",
|
|
1291
|
-
"mandrivalinux-release",
|
|
1292
|
-
"manjaro-release",
|
|
1293
|
-
"oracle-release",
|
|
1294
|
-
"redhat-release",
|
|
1295
|
-
"rocky-release",
|
|
1296
|
-
"sl-release",
|
|
1297
|
-
"slackware-version",
|
|
1298
|
-
]
|
|
1287
|
+
basenames = _DISTRO_RELEASE_BASENAMES
|
|
1299
1288
|
for basename in basenames:
|
|
1300
|
-
if basename in _DISTRO_RELEASE_IGNORE_BASENAMES:
|
|
1301
|
-
continue
|
|
1302
1289
|
match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename)
|
|
1303
|
-
if match:
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1290
|
+
if match is None:
|
|
1291
|
+
continue
|
|
1292
|
+
filepath = os.path.join(self.etc_dir, basename)
|
|
1293
|
+
distro_info = self._parse_distro_release_file(filepath)
|
|
1294
|
+
# The name is always present if the pattern matches.
|
|
1295
|
+
if "name" not in distro_info:
|
|
1296
|
+
continue
|
|
1297
|
+
self.distro_release_file = filepath
|
|
1298
|
+
break
|
|
1299
|
+
else: # the loop didn't "break": no candidate.
|
|
1300
|
+
return {}
|
|
1301
|
+
|
|
1302
|
+
if match is not None:
|
|
1303
|
+
distro_info["id"] = match.group(1)
|
|
1304
|
+
|
|
1305
|
+
# CloudLinux < 7: manually enrich info with proper id.
|
|
1306
|
+
if "cloudlinux" in distro_info.get("name", "").lower():
|
|
1307
|
+
distro_info["id"] = "cloudlinux"
|
|
1308
|
+
|
|
1309
|
+
return distro_info
|
|
1314
1310
|
|
|
1315
|
-
def _parse_distro_release_file(self, filepath):
|
|
1316
|
-
# type: (str) -> Dict[str, str]
|
|
1311
|
+
def _parse_distro_release_file(self, filepath: str) -> Dict[str, str]:
|
|
1317
1312
|
"""
|
|
1318
1313
|
Parse a distro release file.
|
|
1319
1314
|
|
|
@@ -1325,19 +1320,18 @@ class LinuxDistribution(object):
|
|
|
1325
1320
|
A dictionary containing all information items.
|
|
1326
1321
|
"""
|
|
1327
1322
|
try:
|
|
1328
|
-
with open(filepath) as fp:
|
|
1323
|
+
with open(filepath, encoding="utf-8") as fp:
|
|
1329
1324
|
# Only parse the first line. For instance, on SLES there
|
|
1330
1325
|
# are multiple lines. We don't want them...
|
|
1331
1326
|
return self._parse_distro_release_content(fp.readline())
|
|
1332
|
-
except
|
|
1327
|
+
except OSError:
|
|
1333
1328
|
# Ignore not being able to read a specific, seemingly version
|
|
1334
1329
|
# related file.
|
|
1335
1330
|
# See https://github.com/python-distro/distro/issues/162
|
|
1336
1331
|
return {}
|
|
1337
1332
|
|
|
1338
1333
|
@staticmethod
|
|
1339
|
-
def _parse_distro_release_content(line):
|
|
1340
|
-
# type: (str) -> Dict[str, str]
|
|
1334
|
+
def _parse_distro_release_content(line: str) -> Dict[str, str]:
|
|
1341
1335
|
"""
|
|
1342
1336
|
Parse a line from a distro release file.
|
|
1343
1337
|
|
|
@@ -1365,8 +1359,7 @@ class LinuxDistribution(object):
|
|
|
1365
1359
|
_distro = LinuxDistribution()
|
|
1366
1360
|
|
|
1367
1361
|
|
|
1368
|
-
def main():
|
|
1369
|
-
# type: () -> None
|
|
1362
|
+
def main() -> None:
|
|
1370
1363
|
logger = logging.getLogger(__name__)
|
|
1371
1364
|
logger.setLevel(logging.DEBUG)
|
|
1372
1365
|
logger.addHandler(logging.StreamHandler(sys.stdout))
|
|
@@ -1388,7 +1381,10 @@ def main():
|
|
|
1388
1381
|
|
|
1389
1382
|
if args.root_dir:
|
|
1390
1383
|
dist = LinuxDistribution(
|
|
1391
|
-
include_lsb=False,
|
|
1384
|
+
include_lsb=False,
|
|
1385
|
+
include_uname=False,
|
|
1386
|
+
include_oslevel=False,
|
|
1387
|
+
root_dir=args.root_dir,
|
|
1392
1388
|
)
|
|
1393
1389
|
else:
|
|
1394
1390
|
dist = _distro
|