Prepare 5.0.0 (#1123)

* Bump version to 5.0.0-a1.

* Drop support for ansible-core 2.15 and 2.16.

* Remove Python 2 and early Python 3 compatibility.
This commit is contained in:
Felix Fontein 2025-10-05 20:22:50 +02:00 committed by GitHub
parent b9cf9015c4
commit 1f2817fa20
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
133 changed files with 278 additions and 893 deletions

View File

@ -1,18 +0,0 @@
Copyright (c) 2010-2024 Benjamin Peterson
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,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
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.

View File

@ -38,7 +38,7 @@ For more information about communication, see the [Ansible communication guide](
## Tested with Ansible ## Tested with Ansible
Tested with the current ansible-core 2.15, ansible-core 2.16, ansible-core 2.17, ansible-core 2.18, and ansible-core 2.19 releases, and the current development version of ansible-core. Ansible/ansible-base versions before 2.15.0 are not supported. Tested with the current ansible-core 2.17, ansible-core 2.18, and ansible-core 2.19 releases, and the current development version of ansible-core. Ansible/ansible-base versions before 2.17.0 are not supported.
## External requirements ## External requirements
@ -160,6 +160,5 @@ This collection is primarily licensed and distributed as a whole under the GNU G
See [LICENSES/GPL-3.0-or-later.txt](https://github.com/ansible-collections/community.docker/blob/main/COPYING) for the full text. See [LICENSES/GPL-3.0-or-later.txt](https://github.com/ansible-collections/community.docker/blob/main/COPYING) for the full text.
Parts of the collection are licensed under the [Apache 2.0 license](https://github.com/ansible-collections/community.docker/blob/main/LICENSES/Apache-2.0.txt). This mostly applies to files vendored from the [Docker SDK for Python](https://github.com/docker/docker-py/). Parts of the collection are licensed under the [Apache 2.0 license](https://github.com/ansible-collections/community.docker/blob/main/LICENSES/Apache-2.0.txt). This mostly applies to files vendored from the [Docker SDK for Python](https://github.com/docker/docker-py/).
Also `plugins/module_utils/_six.py` is licensed under the [MIT license](https://github.com/ansible-collections/community.dns/blob/main/LICENSES/MIT.txt).
All files have a machine readable `SDPX-License-Identifier:` comment denoting its respective license(s) or an equivalent entry in an accompanying `.license` file. Only changelog fragments (which will not be part of a release) are covered by a blanket statement in `REUSE.toml`. This conforms to the [REUSE specification](https://reuse.software/spec/). All files have a machine readable `SDPX-License-Identifier:` comment denoting its respective license(s) or an equivalent entry in an accompanying `.license` file. Only changelog fragments (which will not be part of a release) are covered by a blanket statement in `REUSE.toml`. This conforms to the [REUSE specification](https://reuse.software/spec/).

View File

@ -8,16 +8,6 @@
"community.internal_test_tools" = "git+https://github.com/ansible-collections/community.internal_test_tools.git,main" "community.internal_test_tools" = "git+https://github.com/ansible-collections/community.internal_test_tools.git,main"
"community.library_inventory_filtering_v1" = "git+https://github.com/ansible-collections/community.library_inventory_filtering.git,stable-1" "community.library_inventory_filtering_v1" = "git+https://github.com/ansible-collections/community.library_inventory_filtering.git,stable-1"
[collection_sources_per_ansible.'2.15']
# community.crypto's main branch needs ansible-core >= 2.17
"community.crypto" = "git+https://github.com/ansible-collections/community.crypto.git,stable-2"
# community.general's main branch needs ansible-core >= 2.16
"community.general" = "git+https://github.com/ansible-collections/community.general.git,stable-10"
[collection_sources_per_ansible.'2.16']
# community.crypto's main branch needs ansible-core >= 2.17
"community.crypto" = "git+https://github.com/ansible-collections/community.crypto.git,stable-2"
[vcs] [vcs]
vcs = "git" vcs = "git"
development_branch = "main" development_branch = "main"
@ -94,45 +84,6 @@ force_docker_sdk_for_python_pypi = { type = "value", value = false, template_val
################################################################################################## ##################################################################################################
# Ansible-core 2.15:
[[sessions.ansible_test_integration.groups]]
session_name = "ansible-test-integration-2.15"
description = "Meta session for running all ansible-test-integration-2.15-* sessions."
[[sessions.ansible_test_integration.groups.sessions]]
ansible_core = "2.15"
target = [ "azp/4/", "azp/5/" ]
docker = [ "fedora37" ]
[[sessions.ansible_test_integration.groups.sessions]]
ansible_core = "2.15"
target = [ "azp/1/", "azp/2/", "azp/3/", "azp/4/", "azp/5/" ]
remote = [ "rhel/9.1", "rhel/8.7", "rhel/7.9" ]
# Ansible-core 2.16:
[[sessions.ansible_test_integration.groups]]
session_name = "ansible-test-integration-2.16"
description = "Meta session for running all ansible-test-integration-2.16-* sessions."
[[sessions.ansible_test_integration.groups.sessions]]
ansible_core = "2.16"
target = [ "azp/4/", "azp/5/" ]
docker = [ "fedora38", "opensuse15", "alpine3" ]
[[sessions.ansible_test_integration.groups.sessions]]
ansible_core = "2.16"
target = [ "azp/4/", "azp/5/" ]
docker = [ "centos7" ]
# "centos7" does not work in GHA:
tags = [ "no-gha" ]
[[sessions.ansible_test_integration.groups.sessions]]
ansible_core = "2.16"
target = [ "azp/1/", "azp/2/", "azp/3/", "azp/4/", "azp/5/" ]
remote = [ "rhel/8.8", "rhel/7.9" ]
# Ansible-core 2.17: # Ansible-core 2.17:
[[sessions.ansible_test_integration.groups]] [[sessions.ansible_test_integration.groups]]
@ -254,12 +205,14 @@ runtime_container_options = [
] ]
[[sessions.ee_check.execution_environments]] [[sessions.ee_check.execution_environments]]
name = "2.15-rocky-9" name = "2.17-rocky-9"
description = "ansible-core 2.15 @ Rocky Linux 9" description = "ansible-core 2.17 @ Rocky Linux 9"
test_playbooks = ["tests/ee/all.yml"] test_playbooks = ["tests/ee/all.yml"]
config.images.base_image.name = "quay.io/rockylinux/rockylinux:9" config.images.base_image.name = "quay.io/rockylinux/rockylinux:9"
config.dependencies.ansible_core.package_pip = "https://github.com/ansible/ansible/archive/stable-2.15.tar.gz" config.dependencies.ansible_core.package_pip = "https://github.com/ansible/ansible/archive/stable-2.17.tar.gz"
config.dependencies.ansible_runner.package_pip = "ansible-runner" config.dependencies.ansible_runner.package_pip = "ansible-runner"
config.dependencies.python_interpreter.package_system = "python3.11 python3.11-pip python3.11-wheel python3.11-cryptography"
config.dependencies.python_interpreter.python_path = "/usr/bin/python3.11"
runtime_environment = {"ANSIBLE_PRIVATE_ROLE_VARS" = "true"} runtime_environment = {"ANSIBLE_PRIVATE_ROLE_VARS" = "true"}
runtime_container_options = [ runtime_container_options = [
# Mount Docker socket into the container so we can talk to Docker outside the container # Mount Docker socket into the container so we can talk to Docker outside the container

View File

@ -0,0 +1,5 @@
removed_features:
- The collection no longer supports ansible-core 2.15 and 2.16.
You need ansible-core 2.17.0 or newer to use community.docker 5.x.y (https://github.com/ansible-collections/community.docker/pull/1123).
- The collection no longer supports Python 3.6 and before.
Note that this coincides with the Python requirements of ansible-core 2.17+ (https://github.com/ansible-collections/community.docker/pull/1123).

View File

@ -7,7 +7,7 @@
namespace: community namespace: community
name: docker name: docker
version: 4.8.1 version: 5.0.0-a1
readme: README.md readme: README.md
authors: authors:
- Ansible Docker Working Group - Ansible Docker Working Group
@ -15,7 +15,6 @@ description: Modules and plugins for working with Docker
license: license:
- GPL-3.0-or-later - GPL-3.0-or-later
- Apache-2.0 - Apache-2.0
- MIT
# license_file: COPYING # license_file: COPYING
tags: tags:
- docker - docker

View File

@ -3,7 +3,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
requires_ansible: '>=2.15.0' requires_ansible: '>=2.17.0'
action_groups: action_groups:
docker: docker:
- docker_compose_v2 - docker_compose_v2

View File

@ -2,8 +2,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
import base64 import base64

View File

@ -7,8 +7,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""
author: author:
@ -115,9 +114,10 @@ options:
import fcntl import fcntl
import os import os
import os.path import os.path
import selectors
import subprocess import subprocess
import re import re
from shlex import quote as shlex_quote from shlex import quote
from ansible.errors import AnsibleError, AnsibleFileNotFound, AnsibleConnectionFailure from ansible.errors import AnsibleError, AnsibleFileNotFound, AnsibleConnectionFailure
from ansible.module_utils.common.process import get_bin_path from ansible.module_utils.common.process import get_bin_path
@ -125,7 +125,6 @@ from ansible.module_utils.common.text.converters import to_bytes, to_native, to_
from ansible.plugins.connection import ConnectionBase, BUFSIZE from ansible.plugins.connection import ConnectionBase, BUFSIZE
from ansible.utils.display import Display from ansible.utils.display import Display
from ansible_collections.community.docker.plugins.module_utils.selectors import selectors
from ansible_collections.community.docker.plugins.module_utils.version import LooseVersion from ansible_collections.community.docker.plugins.module_utils.version import LooseVersion
display = Display() display = Display()
@ -433,7 +432,7 @@ class Connection(ConnectionBase):
raise AnsibleFileNotFound( raise AnsibleFileNotFound(
"file or module does not exist: %s" % to_native(in_path)) "file or module does not exist: %s" % to_native(in_path))
out_path = shlex_quote(out_path) out_path = quote(out_path)
# Older docker does not have native support for copying files into # Older docker does not have native support for copying files into
# running containers, so we use docker exec to implement this # running containers, so we use docker exec to implement this
# Although docker version 1.8 and later provide support, the # Although docker version 1.8 and later provide support, the

View File

@ -2,8 +2,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""
author: author:

View File

@ -5,8 +5,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""
name: nsenter name: nsenter
@ -42,6 +41,7 @@ notes:
import os import os
import pty import pty
import selectors
import subprocess import subprocess
import fcntl import fcntl
@ -52,8 +52,6 @@ from ansible.plugins.connection import ConnectionBase
from ansible.utils.display import Display from ansible.utils.display import Display
from ansible.utils.path import unfrackpath from ansible.utils.path import unfrackpath
from ansible_collections.community.docker.plugins.module_utils.selectors import selectors
display = Display() display = Display()

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
class ModuleDocFragment(object): class ModuleDocFragment(object):

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
class ModuleDocFragment(object): class ModuleDocFragment(object):

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
class ModuleDocFragment(object): class ModuleDocFragment(object):
@ -303,7 +302,6 @@ requirements:
- pywin32 (when using named pipes on Windows 32) - pywin32 (when using named pipes on Windows 32)
- paramiko (when using SSH with O(use_ssh_client=false)) - paramiko (when using SSH with O(use_ssh_client=false))
- pyOpenSSL (when using TLS) - pyOpenSSL (when using TLS)
- backports.ssl_match_hostname (when using TLS on Python 2)
''' '''
# Docker doc fragment when using the Docker CLI # Docker doc fragment when using the Docker CLI

View File

@ -7,9 +7,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""

View File

@ -3,8 +3,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""
name: docker_machine name: docker_machine

View File

@ -4,9 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""
name: docker_swarm name: docker_swarm
@ -14,7 +12,6 @@ author:
- Stefan Heitmüller (@morph027) <stefan.heitmueller@gmx.com> - Stefan Heitmüller (@morph027) <stefan.heitmueller@gmx.com>
short_description: Ansible dynamic inventory plugin for Docker swarm nodes short_description: Ansible dynamic inventory plugin for Docker swarm nodes
requirements: requirements:
- python >= 2.7
- L(Docker SDK for Python,https://docker-py.readthedocs.io/en/stable/) >= 1.10.0 - L(Docker SDK for Python,https://docker-py.readthedocs.io/en/stable/) >= 1.10.0
extends_documentation_fragment: extends_documentation_fragment:
- ansible.builtin.constructed - ansible.builtin.constructed

View File

@ -7,17 +7,13 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import traceback import traceback
from ansible_collections.community.docker.plugins.module_utils._six import PY2
REQUESTS_IMPORT_ERROR = None REQUESTS_IMPORT_ERROR = None
URLLIB3_IMPORT_ERROR = None URLLIB3_IMPORT_ERROR = None
BACKPORTS_SSL_MATCH_HOSTNAME_IMPORT_ERROR = None
try: try:
@ -41,11 +37,11 @@ except ImportError:
try: try:
from requests.packages import urllib3 from requests.packages import urllib3 # pylint: disable=unused-import
from requests.packages.urllib3 import connection as urllib3_connection # pylint: disable=unused-import from requests.packages.urllib3 import connection as urllib3_connection # pylint: disable=unused-import
except ImportError: except ImportError:
try: try:
import urllib3 import urllib3 # pylint: disable=unused-import
from urllib3 import connection as urllib3_connection # pylint: disable=unused-import from urllib3 import connection as urllib3_connection # pylint: disable=unused-import
except ImportError: except ImportError:
URLLIB3_IMPORT_ERROR = traceback.format_exc() URLLIB3_IMPORT_ERROR = traceback.format_exc()
@ -76,16 +72,6 @@ except ImportError:
urllib3_connection = FakeURLLIB3Connection() urllib3_connection = FakeURLLIB3Connection()
# Monkey-patching match_hostname with a version that supports
# IP-address checking. Not necessary for Python 3.5 and above
if PY2:
try:
from backports.ssl_match_hostname import match_hostname
urllib3.connection.match_hostname = match_hostname
except ImportError:
BACKPORTS_SSL_MATCH_HOSTNAME_IMPORT_ERROR = traceback.format_exc()
def fail_on_missing_imports(): def fail_on_missing_imports():
if REQUESTS_IMPORT_ERROR is not None: if REQUESTS_IMPORT_ERROR is not None:
from .errors import MissingRequirementException from .errors import MissingRequirementException
@ -99,9 +85,3 @@ def fail_on_missing_imports():
raise MissingRequirementException( raise MissingRequirementException(
'You have to install urllib3', 'You have to install urllib3',
'urllib3', URLLIB3_IMPORT_ERROR) 'urllib3', URLLIB3_IMPORT_ERROR)
if BACKPORTS_SSL_MATCH_HOSTNAME_IMPORT_ERROR is not None:
from .errors import MissingRequirementException
raise MissingRequirementException(
'You have to install backports.ssl-match-hostname',
'backports.ssl-match-hostname', BACKPORTS_SSL_MATCH_HOSTNAME_IMPORT_ERROR)

View File

@ -7,15 +7,13 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import json import json
import logging import logging
import struct import struct
from functools import partial from functools import partial
from urllib.parse import quote
from ansible_collections.community.docker.plugins.module_utils._six import PY3, binary_type, iteritems, string_types, raise_from, quote
from .. import auth from .. import auth
from .._import_helper import fail_on_missing_imports from .._import_helper import fail_on_missing_imports
@ -183,11 +181,11 @@ class APIClient(
self.base_url = base_url self.base_url = base_url
# version detection needs to be after unix adapter mounting # version detection needs to be after unix adapter mounting
if version is None or (isinstance(version, string_types) and version.lower() == 'auto'): if version is None or (isinstance(version, str) and version.lower() == 'auto'):
self._version = self._retrieve_server_version() self._version = self._retrieve_server_version()
else: else:
self._version = version self._version = version
if not isinstance(self._version, string_types): if not isinstance(self._version, str):
raise DockerException( raise DockerException(
'Version parameter must be a string or None. Found {0}'.format( 'Version parameter must be a string or None. Found {0}'.format(
type(version).__name__ type(version).__name__
@ -247,7 +245,7 @@ class APIClient(
def _url(self, pathfmt, *args, **kwargs): def _url(self, pathfmt, *args, **kwargs):
for arg in args: for arg in args:
if not isinstance(arg, string_types): if not isinstance(arg, str):
raise ValueError( raise ValueError(
'Expected a string but found {0} ({1}) ' 'Expected a string but found {0} ({1}) '
'instead'.format(arg, type(arg)) 'instead'.format(arg, type(arg))
@ -268,7 +266,7 @@ class APIClient(
try: try:
response.raise_for_status() response.raise_for_status()
except _HTTPError as e: except _HTTPError as e:
raise_from(create_api_error_from_http_exception(e), e) create_api_error_from_http_exception(e)
def _result(self, response, json=False, binary=False): def _result(self, response, json=False, binary=False):
if json and binary: if json and binary:
@ -286,7 +284,7 @@ class APIClient(
# so we do this disgusting thing here. # so we do this disgusting thing here.
data2 = {} data2 = {}
if data is not None and isinstance(data, dict): if data is not None and isinstance(data, dict):
for k, v in iteritems(data): for k, v in data.items():
if v is not None: if v is not None:
data2[k] = v data2[k] = v
elif data is not None: elif data is not None:
@ -310,12 +308,10 @@ class APIClient(
sock = response.raw._fp.fp.raw.sock sock = response.raw._fp.fp.raw.sock
elif self.base_url.startswith('http+docker://ssh'): elif self.base_url.startswith('http+docker://ssh'):
sock = response.raw._fp.fp.channel sock = response.raw._fp.fp.channel
elif PY3: else:
sock = response.raw._fp.fp.raw sock = response.raw._fp.fp.raw
if self.base_url.startswith("https://"): if self.base_url.startswith("https://"):
sock = sock._sock sock = sock._sock
else:
sock = response.raw._fp.fp._sock
try: try:
# Keep a reference to the response to stop it being garbage # Keep a reference to the response to stop it being garbage
# collected. If the response is garbage collected, it will # collected. If the response is garbage collected, it will
@ -333,8 +329,7 @@ class APIClient(
if response.raw._fp.chunked: if response.raw._fp.chunked:
if decode: if decode:
for chunk in json_stream.json_stream(self._stream_helper(response, False)): yield from json_stream.json_stream(self._stream_helper(response, False))
yield chunk
else: else:
reader = response.raw reader = response.raw
while not reader.closed: while not reader.closed:
@ -396,8 +391,7 @@ class APIClient(
socket = self._get_raw_response_socket(response) socket = self._get_raw_response_socket(response)
self._disable_socket_timeout(socket) self._disable_socket_timeout(socket)
for out in response.iter_content(chunk_size, decode): yield from response.iter_content(chunk_size, decode)
yield out
def _read_from_socket(self, response, stream, tty=True, demux=False): def _read_from_socket(self, response, stream, tty=True, demux=False):
"""Consume all data from the socket, close the response and return the """Consume all data from the socket, close the response and return the
@ -468,7 +462,7 @@ class APIClient(
self._result(res, binary=True) self._result(res, binary=True)
self._raise_for_status(res) self._raise_for_status(res)
sep = binary_type() sep = b''
if stream: if stream:
return self._multiplexed_response_stream_helper(res) return self._multiplexed_response_stream_helper(res)
else: else:

View File

@ -7,8 +7,7 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import os import os

View File

@ -7,15 +7,12 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import base64 import base64
import json import json
import logging import logging
from ansible_collections.community.docker.plugins.module_utils._six import iteritems, string_types
from . import errors from . import errors
from .credentials.store import Store from .credentials.store import Store
from .credentials.errors import StoreError, CredentialsNotFound from .credentials.errors import StoreError, CredentialsNotFound
@ -111,7 +108,7 @@ class AuthConfig(dict):
""" """
conf = {} conf = {}
for registry, entry in iteritems(entries): for registry, entry in entries.items():
if not isinstance(entry, dict): if not isinstance(entry, dict):
log.debug('Config entry for key %s is not auth config', registry) log.debug('Config entry for key %s is not auth config', registry)
# We sometimes fall back to parsing the whole config as if it # We sometimes fall back to parsing the whole config as if it
@ -242,7 +239,7 @@ class AuthConfig(dict):
log.debug("Found %s", repr(registry)) log.debug("Found %s", repr(registry))
return self.auths[registry] return self.auths[registry]
for key, conf in iteritems(self.auths): for key, conf in self.auths.items():
if resolve_index_name(key) == registry: if resolve_index_name(key) == registry:
log.debug("Found %s", repr(key)) log.debug("Found %s", repr(key))
return conf return conf
@ -326,7 +323,7 @@ def convert_to_hostname(url):
def decode_auth(auth): def decode_auth(auth):
if isinstance(auth, string_types): if isinstance(auth, str):
auth = auth.encode('ascii') auth = auth.encode('ascii')
s = base64.b64decode(auth) s = base64.b64decode(auth)
login, pwd = s.split(b':', 1) login, pwd = s.split(b':', 1)

View File

@ -7,8 +7,7 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import sys import sys

View File

@ -7,14 +7,11 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import json import json
import os import os
from ansible_collections.community.docker.plugins.module_utils._six import raise_from
from .. import errors from .. import errors
from .config import ( from .config import (
@ -148,9 +145,9 @@ class ContextAPI(object):
raise ValueError('"default" is a reserved context name') raise ValueError('"default" is a reserved context name')
names.append(name) names.append(name)
except Exception as e: except Exception as e:
raise_from(errors.ContextException( raise errors.ContextException(
"Failed to load metafile {filepath}: {e}".format(filepath=filepath, e=e), "Failed to load metafile {filepath}: {e}".format(filepath=filepath, e=e),
), e) ) from e
contexts = [cls.get_default_context()] contexts = [cls.get_default_context()]
for name in names: for name in names:

View File

@ -7,8 +7,7 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import hashlib import hashlib
import json import json

View File

@ -7,15 +7,12 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import json import json
import os import os
from shutil import copyfile, rmtree from shutil import copyfile, rmtree
from ansible_collections.community.docker.plugins.module_utils._six import raise_from
from ..errors import ContextException from ..errors import ContextException
from ..tls import TLSConfig from ..tls import TLSConfig
@ -120,9 +117,9 @@ class Context(object):
metadata = json.load(f) metadata = json.load(f)
except (OSError, KeyError, ValueError) as e: except (OSError, KeyError, ValueError) as e:
# unknown format # unknown format
raise_from(Exception( raise Exception(
"Detected corrupted meta file for context {name} : {e}".format(name=name, e=e) "Detected corrupted meta file for context {name} : {e}".format(name=name, e=e)
), e) ) from e
# for docker endpoints, set defaults for # for docker endpoints, set defaults for
# Host and SkipTLSVerify fields # Host and SkipTLSVerify fields

View File

@ -7,8 +7,7 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
PROGRAM_PREFIX = 'docker-credential-' PROGRAM_PREFIX = 'docker-credential-'
DEFAULT_LINUX_STORE = 'secretservice' DEFAULT_LINUX_STORE = 'secretservice'

View File

@ -7,8 +7,7 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
class StoreError(RuntimeError): class StoreError(RuntimeError):

View File

@ -7,15 +7,12 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import errno import errno
import json import json
import subprocess import subprocess
from ansible_collections.community.docker.plugins.module_utils._six import PY3, binary_type
from . import constants from . import constants
from . import errors from . import errors
from .utils import create_environment_dict from .utils import create_environment_dict
@ -42,7 +39,7 @@ class Store(object):
""" Retrieve credentials for `server`. If no credentials are found, """ Retrieve credentials for `server`. If no credentials are found,
a `StoreError` will be raised. a `StoreError` will be raised.
""" """
if not isinstance(server, binary_type): if not isinstance(server, bytes):
server = server.encode('utf-8') server = server.encode('utf-8')
data = self._execute('get', server) data = self._execute('get', server)
result = json.loads(data.decode('utf-8')) result = json.loads(data.decode('utf-8'))
@ -73,7 +70,7 @@ class Store(object):
""" Erase credentials for `server`. Raises a `StoreError` if an error """ Erase credentials for `server`. Raises a `StoreError` if an error
occurs. occurs.
""" """
if not isinstance(server, binary_type): if not isinstance(server, bytes):
server = server.encode('utf-8') server = server.encode('utf-8')
self._execute('erase', server) self._execute('erase', server)
@ -87,20 +84,9 @@ class Store(object):
output = None output = None
env = create_environment_dict(self.environment) env = create_environment_dict(self.environment)
try: try:
if PY3: output = subprocess.check_output(
output = subprocess.check_output( [self.exe, subcmd], input=data_input, env=env,
[self.exe, subcmd], input=data_input, env=env, )
)
else:
process = subprocess.Popen(
[self.exe, subcmd], stdin=subprocess.PIPE,
stdout=subprocess.PIPE, env=env,
)
output, dummy = process.communicate(data_input)
if process.returncode != 0:
raise subprocess.CalledProcessError(
returncode=process.returncode, cmd='', output=output
)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
raise errors.process_store_error(e, self.program) raise errors.process_store_error(e, self.program)
except OSError as e: except OSError as e:

View File

@ -7,18 +7,11 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import os import os
import sys
from ansible_collections.community.docker.plugins.module_utils._six import PY2 from shutil import which
if PY2:
from distutils.spawn import find_executable as which
else:
from shutil import which
def find_executable(executable, path=None): def find_executable(executable, path=None):
@ -26,31 +19,10 @@ def find_executable(executable, path=None):
As distutils.spawn.find_executable, but on Windows, look up As distutils.spawn.find_executable, but on Windows, look up
every extension declared in PATHEXT instead of just `.exe` every extension declared in PATHEXT instead of just `.exe`
""" """
if not PY2: # shutil.which() already uses PATHEXT on Windows, so on
# shutil.which() already uses PATHEXT on Windows, so on # Python 3 we can simply use shutil.which() in all cases.
# Python 3 we can simply use shutil.which() in all cases. # (https://github.com/docker/docker-py/commit/42789818bed5d86b487a030e2e60b02bf0cfa284)
# (https://github.com/docker/docker-py/commit/42789818bed5d86b487a030e2e60b02bf0cfa284) return which(executable, path=path)
return which(executable, path=path)
if sys.platform != 'win32':
return which(executable, path)
if path is None:
path = os.environ['PATH']
paths = path.split(os.pathsep)
extensions = os.environ.get('PATHEXT', '.exe').split(os.pathsep)
base, ext = os.path.splitext(executable)
if not os.path.isfile(executable):
for p in paths:
for ext in extensions:
f = os.path.join(p, base + ext)
if os.path.isfile(f):
return f
return None
else:
return executable
def create_environment_dict(overrides): def create_environment_dict(overrides):

View File

@ -7,13 +7,11 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
from ._import_helper import HTTPError as _HTTPError from ._import_helper import HTTPError as _HTTPError
from ansible.module_utils.common.text.converters import to_native from ansible.module_utils.common.text.converters import to_native
from ansible_collections.community.docker.plugins.module_utils._six import raise_from
class DockerException(Exception): class DockerException(Exception):
@ -43,7 +41,7 @@ def create_api_error_from_http_exception(e):
cls = ImageNotFound cls = ImageNotFound
else: else:
cls = NotFound cls = NotFound
raise_from(cls(e, response=response, explanation=explanation), e) raise cls(e, response=response, explanation=explanation) from e
class APIError(_HTTPError, DockerException): class APIError(_HTTPError, DockerException):

View File

@ -7,12 +7,10 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import os import os
import ssl import ssl
import sys
from . import errors from . import errors
from .transport.ssladapter import SSLHTTPAdapter from .transport.ssladapter import SSLHTTPAdapter
@ -51,22 +49,6 @@ class TLSConfig(object):
# If the user provides an SSL version, we should use their preference # If the user provides an SSL version, we should use their preference
if ssl_version: if ssl_version:
self.ssl_version = ssl_version self.ssl_version = ssl_version
elif (sys.version_info.major, sys.version_info.minor) < (3, 6):
# If the user provides no ssl version, we should default to
# TLSv1_2. This option is the most secure, and will work for the
# majority of users with reasonably up-to-date software. However,
# before doing so, detect openssl version to ensure we can support
# it.
if ssl.OPENSSL_VERSION_INFO[:3] >= (1, 0, 1) and hasattr(
ssl, 'PROTOCOL_TLSv1_2'):
# If the OpenSSL version is high enough to support TLSv1_2,
# then we should use it.
self.ssl_version = getattr(ssl, 'PROTOCOL_TLSv1_2')
else:
# Otherwise, TLS v1.0 seems to be the safest default;
# SSLv23 fails in mysterious ways:
# https://github.com/docker/docker-py/issues/963
self.ssl_version = ssl.PROTOCOL_TLSv1
else: else:
self.ssl_version = ssl.PROTOCOL_TLS_CLIENT self.ssl_version = ssl.PROTOCOL_TLS_CLIENT

View File

@ -7,8 +7,7 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
from .._import_helper import HTTPAdapter as _HTTPAdapter from .._import_helper import HTTPAdapter as _HTTPAdapter

View File

@ -7,10 +7,9 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
from ansible_collections.community.docker.plugins.module_utils._six import Empty from queue import Empty
from .. import constants from .. import constants
from .._import_helper import HTTPAdapter, urllib3, urllib3_connection from .._import_helper import HTTPAdapter, urllib3, urllib3_connection

View File

@ -7,16 +7,13 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import functools import functools
import io import io
import time import time
import traceback import traceback
from ansible_collections.community.docker.plugins.module_utils._six import PY2
PYWIN32_IMPORT_ERROR = None PYWIN32_IMPORT_ERROR = None
try: try:
import win32file import win32file
@ -152,9 +149,6 @@ class NpipeSocket(object):
@check_closed @check_closed
def recv_into(self, buf, nbytes=0): def recv_into(self, buf, nbytes=0):
if PY2:
return self._recv_into_py2(buf, nbytes)
readbuf = buf readbuf = buf
if not isinstance(buf, memoryview): if not isinstance(buf, memoryview):
readbuf = memoryview(buf) readbuf = memoryview(buf)
@ -176,12 +170,6 @@ class NpipeSocket(object):
finally: finally:
win32api.CloseHandle(event) win32api.CloseHandle(event)
def _recv_into_py2(self, buf, nbytes):
err, data = win32file.ReadFile(self._handle, nbytes or len(buf))
n = len(data)
buf[:n] = data
return n
@check_closed @check_closed
def send(self, string, flags=0): def send(self, string, flags=0):
event = win32event.CreateEvent(None, True, True, None) event = win32event.CreateEvent(None, True, True, None)

View File

@ -7,8 +7,7 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import logging import logging
import os import os
@ -16,8 +15,8 @@ import signal
import socket import socket
import subprocess import subprocess
import traceback import traceback
from queue import Empty
from ansible_collections.community.docker.plugins.module_utils._six import PY3, Empty, urlparse from urllib.parse import urlparse
from .basehttpadapter import BaseHTTPAdapter from .basehttpadapter import BaseHTTPAdapter
from .. import constants from .. import constants
@ -100,8 +99,7 @@ class SSHSocket(socket.socket):
def makefile(self, mode): def makefile(self, mode):
if not self.proc: if not self.proc:
self.connect() self.connect()
if PY3: self.proc.stdout.channel = self
self.proc.stdout.channel = self
return self.proc.stdout return self.proc.stdout

View File

@ -7,8 +7,7 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
""" Resolves OpenSSL issues in some servers: """ Resolves OpenSSL issues in some servers:
https://lukasa.co.uk/2013/01/Choosing_SSL_Version_In_Requests/ https://lukasa.co.uk/2013/01/Choosing_SSL_Version_In_Requests/

View File

@ -7,13 +7,10 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import socket import socket
from ansible_collections.community.docker.plugins.module_utils._six import PY2
from .basehttpadapter import BaseHTTPAdapter from .basehttpadapter import BaseHTTPAdapter
from .. import constants from .. import constants
@ -46,12 +43,9 @@ class UnixHTTPConnection(urllib3_connection.HTTPConnection, object):
self.disable_buffering = True self.disable_buffering = True
def response_class(self, sock, *args, **kwargs): def response_class(self, sock, *args, **kwargs):
if PY2: # FIXME: We may need to disable buffering on Py3,
# FIXME: We may need to disable buffering on Py3 as well, # but there's no clear way to do it at the moment. See:
# but there's no clear way to do it at the moment. See: # https://github.com/docker/docker-py/issues/1799
# https://github.com/docker/docker-py/issues/1799
kwargs['buffering'] = not self.disable_buffering
return super(UnixHTTPConnection, self).response_class(sock, *args, **kwargs) return super(UnixHTTPConnection, self).response_class(sock, *args, **kwargs)

View File

@ -7,8 +7,7 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import socket import socket

View File

@ -7,8 +7,7 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import io import io
import os import os
@ -17,8 +16,6 @@ import re
import tarfile import tarfile
import tempfile import tempfile
from ansible_collections.community.docker.plugins.module_utils._six import PY3
from . import fnmatch from . import fnmatch
from ..constants import IS_WINDOWS_PLATFORM, WINDOWS_LONGPATH_PREFIX from ..constants import IS_WINDOWS_PLATFORM, WINDOWS_LONGPATH_PREFIX
@ -131,13 +128,7 @@ def mkbuildcontext(dockerfile):
f = tempfile.NamedTemporaryFile() f = tempfile.NamedTemporaryFile()
t = tarfile.open(mode='w', fileobj=f) t = tarfile.open(mode='w', fileobj=f)
if isinstance(dockerfile, io.StringIO): if isinstance(dockerfile, io.StringIO):
dfinfo = tarfile.TarInfo('Dockerfile') raise TypeError('Please use io.BytesIO to create in-memory Dockerfiles')
if PY3:
raise TypeError('Please use io.BytesIO to create in-memory '
'Dockerfiles with Python 3')
else:
dfinfo.size = len(dockerfile.getvalue())
dockerfile.seek(0)
elif isinstance(dockerfile, io.BytesIO): elif isinstance(dockerfile, io.BytesIO):
dfinfo = tarfile.TarInfo('Dockerfile') dfinfo = tarfile.TarInfo('Dockerfile')
dfinfo.size = len(dockerfile.getvalue()) dfinfo.size = len(dockerfile.getvalue())
@ -225,8 +216,7 @@ class PatternMatcher(object):
break break
if skip: if skip:
continue continue
for sub in rec_walk(cur): yield from rec_walk(cur)
yield sub
return rec_walk(root) return rec_walk(root)

View File

@ -7,8 +7,7 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import json import json
import logging import logging

View File

@ -7,8 +7,7 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import functools import functools

View File

@ -7,8 +7,7 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
"""Filename matching with shell patterns. """Filename matching with shell patterns.

View File

@ -7,14 +7,11 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import json import json
import json.decoder import json.decoder
from ansible_collections.community.docker.plugins.module_utils._six import text_type
from ..errors import StreamParseError from ..errors import StreamParseError
@ -29,7 +26,7 @@ def stream_as_text(stream):
instead of byte streams. instead of byte streams.
""" """
for data in stream: for data in stream:
if not isinstance(data, text_type): if not isinstance(data, str):
data = data.decode('utf-8', 'replace') data = data.decode('utf-8', 'replace')
yield data yield data
@ -56,7 +53,7 @@ def json_stream(stream):
def line_splitter(buffer, separator=u'\n'): def line_splitter(buffer, separator=u'\n'):
index = buffer.find(text_type(separator)) index = buffer.find(str(separator))
if index == -1: if index == -1:
return None return None
return buffer[:index + 1], buffer[index + 1:] return buffer[:index + 1], buffer[index + 1:]
@ -70,7 +67,7 @@ def split_buffer(stream, splitter=None, decoder=lambda a: a):
of the input. of the input.
""" """
splitter = splitter or line_splitter splitter = splitter or line_splitter
buffered = text_type('') buffered = ''
for data in stream_as_text(stream): for data in stream_as_text(stream):
buffered += data buffered += data

View File

@ -7,8 +7,7 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import re import re

View File

@ -7,8 +7,7 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
from .utils import format_environment from .utils import format_environment

View File

@ -7,8 +7,7 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import errno import errno
import os import os
@ -16,8 +15,6 @@ import select
import socket as pysocket import socket as pysocket
import struct import struct
from ansible_collections.community.docker.plugins.module_utils._six import PY3, binary_type
from ..transport.npipesocket import NpipeSocket from ..transport.npipesocket import NpipeSocket
@ -41,7 +38,7 @@ def read(socket, n=4096):
recoverable_errors = (errno.EINTR, errno.EDEADLK, errno.EWOULDBLOCK) recoverable_errors = (errno.EINTR, errno.EDEADLK, errno.EWOULDBLOCK)
if PY3 and not isinstance(socket, NpipeSocket): if not isinstance(socket, NpipeSocket):
if not hasattr(select, "poll"): if not hasattr(select, "poll"):
# Limited to 1024 # Limited to 1024
select.select([socket], [], []) select.select([socket], [], [])
@ -53,7 +50,7 @@ def read(socket, n=4096):
try: try:
if hasattr(socket, 'recv'): if hasattr(socket, 'recv'):
return socket.recv(n) return socket.recv(n)
if PY3 and isinstance(socket, getattr(pysocket, 'SocketIO')): if isinstance(socket, getattr(pysocket, 'SocketIO')):
return socket.read(n) return socket.read(n)
return os.read(socket.fileno(), n) return os.read(socket.fileno(), n)
except EnvironmentError as e: except EnvironmentError as e:
@ -75,7 +72,7 @@ def read_exactly(socket, n):
Reads exactly n bytes from socket Reads exactly n bytes from socket
Raises SocketError if there is not enough data Raises SocketError if there is not enough data
""" """
data = binary_type() data = b''
while len(data) < n: while len(data) < n:
next_data = read(socket, n - len(data)) next_data = read(socket, n - len(data))
if not next_data: if not next_data:
@ -163,7 +160,7 @@ def consume_socket_output(frames, demux=False):
if demux is False: if demux is False:
# If the streams are multiplexed, the generator returns strings, that # If the streams are multiplexed, the generator returns strings, that
# we just need to concatenate. # we just need to concatenate.
return binary_type().join(frames) return b''.join(frames)
# If the streams are demultiplexed, the generator yields tuples # If the streams are demultiplexed, the generator yields tuples
# (stdout, stderr) # (stdout, stderr)

View File

@ -7,8 +7,7 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import base64 import base64
import collections import collections
@ -19,8 +18,6 @@ import shlex
import string import string
from ansible_collections.community.docker.plugins.module_utils.version import StrictVersion from ansible_collections.community.docker.plugins.module_utils.version import StrictVersion
from ansible_collections.community.docker.plugins.module_utils._six import PY2, PY3, binary_type, integer_types, iteritems, string_types, text_type
from .. import errors from .. import errors
from ..constants import DEFAULT_HTTP_HOST from ..constants import DEFAULT_HTTP_HOST
from ..constants import DEFAULT_UNIX_SOCKET from ..constants import DEFAULT_UNIX_SOCKET
@ -28,10 +25,7 @@ from ..constants import DEFAULT_NPIPE
from ..constants import BYTE_UNITS from ..constants import BYTE_UNITS
from ..tls import TLSConfig from ..tls import TLSConfig
if PY2: from urllib.parse import urlparse, urlunparse
from urlparse import urlparse, urlunparse
else:
from urllib.parse import urlparse, urlunparse
URLComponents = collections.namedtuple( URLComponents = collections.namedtuple(
@ -55,9 +49,7 @@ def create_ipam_config(*args, **kwargs):
def decode_json_header(header): def decode_json_header(header):
data = base64.b64decode(header) data = base64.b64decode(header).decode('utf-8')
if PY3:
data = data.decode('utf-8')
return json.loads(data) return json.loads(data)
@ -97,7 +89,7 @@ def _convert_port_binding(binding):
if len(binding) == 2: if len(binding) == 2:
result['HostPort'] = binding[1] result['HostPort'] = binding[1]
result['HostIp'] = binding[0] result['HostIp'] = binding[0]
elif isinstance(binding[0], string_types): elif isinstance(binding[0], str):
result['HostIp'] = binding[0] result['HostIp'] = binding[0]
else: else:
result['HostPort'] = binding[0] result['HostPort'] = binding[0]
@ -121,7 +113,7 @@ def _convert_port_binding(binding):
def convert_port_bindings(port_bindings): def convert_port_bindings(port_bindings):
result = {} result = {}
for k, v in iteritems(port_bindings): for k, v in port_bindings.items():
key = str(k) key = str(k)
if '/' not in key: if '/' not in key:
key += '/tcp' key += '/tcp'
@ -138,7 +130,7 @@ def convert_volume_binds(binds):
result = [] result = []
for k, v in binds.items(): for k, v in binds.items():
if isinstance(k, binary_type): if isinstance(k, bytes):
k = k.decode('utf-8') k = k.decode('utf-8')
if isinstance(v, dict): if isinstance(v, dict):
@ -149,7 +141,7 @@ def convert_volume_binds(binds):
) )
bind = v['bind'] bind = v['bind']
if isinstance(bind, binary_type): if isinstance(bind, bytes):
bind = bind.decode('utf-8') bind = bind.decode('utf-8')
if 'ro' in v: if 'ro' in v:
@ -175,15 +167,11 @@ def convert_volume_binds(binds):
else: else:
mode = v['propagation'] mode = v['propagation']
result.append( result.append('{0}:{1}:{2}'.format(k, bind, mode))
text_type('{0}:{1}:{2}').format(k, bind, mode)
)
else: else:
if isinstance(v, binary_type): if isinstance(v, bytes):
v = v.decode('utf-8') v = v.decode('utf-8')
result.append( result.append('{0}:{1}:rw'.format(k, v))
text_type('{0}:{1}:rw').format(k, v)
)
return result return result
@ -199,7 +187,7 @@ def convert_tmpfs_mounts(tmpfs):
result = {} result = {}
for mount in tmpfs: for mount in tmpfs:
if isinstance(mount, string_types): if isinstance(mount, str):
if ":" in mount: if ":" in mount:
name, options = mount.split(":", 1) name, options = mount.split(":", 1)
else: else:
@ -224,7 +212,7 @@ def convert_service_networks(networks):
result = [] result = []
for n in networks: for n in networks:
if isinstance(n, string_types): if isinstance(n, str):
n = {'Target': n} n = {'Target': n}
result.append(n) result.append(n)
return result return result
@ -333,7 +321,7 @@ def parse_devices(devices):
if isinstance(device, dict): if isinstance(device, dict):
device_list.append(device) device_list.append(device)
continue continue
if not isinstance(device, string_types): if not isinstance(device, str):
raise errors.DockerException( raise errors.DockerException(
'Invalid device type {0}'.format(type(device)) 'Invalid device type {0}'.format(type(device))
) )
@ -403,20 +391,20 @@ def kwargs_from_env(ssl_version=None, assert_hostname=None, environment=None):
def convert_filters(filters): def convert_filters(filters):
result = {} result = {}
for k, v in iteritems(filters): for k, v in filters.items():
if isinstance(v, bool): if isinstance(v, bool):
v = 'true' if v else 'false' v = 'true' if v else 'false'
if not isinstance(v, list): if not isinstance(v, list):
v = [v, ] v = [v, ]
result[k] = [ result[k] = [
str(item) if not isinstance(item, string_types) else item str(item) if not isinstance(item, str) else item
for item in v for item in v
] ]
return json.dumps(result) return json.dumps(result)
def parse_bytes(s): def parse_bytes(s):
if isinstance(s, integer_types + (float,)): if isinstance(s, (int, float)):
return s return s
if len(s) == 0: if len(s) == 0:
return 0 return 0
@ -458,7 +446,7 @@ def parse_bytes(s):
def normalize_links(links): def normalize_links(links):
if isinstance(links, dict): if isinstance(links, dict):
links = iteritems(links) links = links.items()
return ['{0}:{1}'.format(k, v) if v else k for k, v in sorted(links)] return ['{0}:{1}'.format(k, v) if v else k for k, v in sorted(links)]
@ -493,8 +481,6 @@ def parse_env_file(env_file):
def split_command(command): def split_command(command):
if PY2 and not isinstance(command, binary_type):
command = command.encode('utf-8')
return shlex.split(command) return shlex.split(command)
@ -502,22 +488,22 @@ def format_environment(environment):
def format_env(key, value): def format_env(key, value):
if value is None: if value is None:
return key return key
if isinstance(value, binary_type): if isinstance(value, bytes):
value = value.decode('utf-8') value = value.decode('utf-8')
return u'{key}={value}'.format(key=key, value=value) return u'{key}={value}'.format(key=key, value=value)
return [format_env(*var) for var in iteritems(environment)] return [format_env(*var) for var in environment.items()]
def format_extra_hosts(extra_hosts, task=False): def format_extra_hosts(extra_hosts, task=False):
# Use format dictated by Swarm API if container is part of a task # Use format dictated by Swarm API if container is part of a task
if task: if task:
return [ return [
'{0} {1}'.format(v, k) for k, v in sorted(iteritems(extra_hosts)) '{0} {1}'.format(v, k) for k, v in sorted(extra_hosts.items())
] ]
return [ return [
'{0}:{1}'.format(k, v) for k, v in sorted(iteritems(extra_hosts)) '{0}:{1}'.format(k, v) for k, v in sorted(extra_hosts.items())
] ]

View File

@ -8,8 +8,7 @@ Parse go logfmt messages.
See https://pkg.go.dev/github.com/kr/logfmt?utm_source=godoc for information on the format. See https://pkg.go.dev/github.com/kr/logfmt?utm_source=godoc for information on the format.
""" """
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
# The format is defined in https://pkg.go.dev/github.com/kr/logfmt?utm_source=godoc # The format is defined in https://pkg.go.dev/github.com/kr/logfmt?utm_source=godoc

View File

@ -8,8 +8,7 @@
# It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection) # It is licensed under the Apache 2.0 license (see LICENSES/Apache-2.0.txt in this collection)
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import re import re

View File

@ -2,14 +2,12 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import base64 import base64
import random import random
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
from ansible_collections.community.docker.plugins.module_utils._six import PY2
def generate_insecure_key(): def generate_insecure_key():
@ -17,10 +15,7 @@ def generate_insecure_key():
while True: while True:
# Generate a one-byte key. Right now the functions below do not use more # Generate a one-byte key. Right now the functions below do not use more
# than one byte, so this is sufficient. # than one byte, so this is sufficient.
if PY2: key = bytes([random.randint(0, 255)])
key = chr(random.randint(0, 255))
else:
key = bytes([random.randint(0, 255)])
# Return anything that is not zero # Return anything that is not zero
if key != b'\x00': if key != b'\x00':
return key return key
@ -31,12 +26,8 @@ def scramble(value, key):
if len(key) < 1: if len(key) < 1:
raise ValueError('Key must be at least one byte') raise ValueError('Key must be at least one byte')
value = to_bytes(value) value = to_bytes(value)
if PY2: k = key[0]
k = ord(key[0]) value = bytes([k ^ b for b in value])
value = b''.join([chr(k ^ ord(b)) for b in value])
else:
k = key[0]
value = bytes([k ^ b for b in value])
return '=S=' + to_native(base64.b64encode(value)) return '=S=' + to_native(base64.b64encode(value))
@ -47,10 +38,6 @@ def unscramble(value, key):
if not value.startswith(u'=S='): if not value.startswith(u'=S='):
raise ValueError('Value does not start with indicator') raise ValueError('Value does not start with indicator')
value = base64.b64decode(value[3:]) value = base64.b64decode(value[3:])
if PY2: k = key[0]
k = ord(key[0]) value = bytes([k ^ b for b in value])
value = b''.join([chr(k ^ ord(b)) for b in value])
else:
k = key[0]
value = bytes([k ^ b for b in value])
return to_text(value) return to_text(value)

View File

@ -1,98 +0,0 @@
# This code is strewn with things that are not defined on Python3 (unicode,
# long, etc) but they are all shielded by version checks. This is also an
# upstream vendored file that we're not going to modify on our own
# pylint: disable=undefined-variable
#
# Copyright (c) 2010-2024 Benjamin Peterson
#
# 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, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# 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.
# Extracted from https://github.com/benjaminp/six/blob/7d2a0e96602b83cd082896c8c224a87f1efe2111/six.py
# SPDX-License-Identifier: MIT
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import sys as _sys
# Useful for very coarse version differentiation.
PY2 = _sys.version_info[0] == 2
PY3 = _sys.version_info[0] > 2
if PY3:
string_types = (str,)
integer_types = (int,)
binary_type = bytes
text_type = str
def iteritems(d):
return d.items()
from shlex import quote as shlex_quote # pylint: disable=unused-import
from collections.abc import Mapping, Sequence # pylint: disable=unused-import
from queue import Empty # pylint: disable=unused-import
from urllib.parse import quote, urlparse # pylint: disable=unused-import
else:
string_types = (basestring,) # noqa: F821, pylint: disable=undefined-variable
integer_types = (int, long) # noqa: F821, pylint: disable=undefined-variable
binary_type = str
text_type = unicode # noqa: F821, pylint: disable=undefined-variable
def iteritems(d):
return d.iteritems()
from pipes import quote as shlex_quote
from collections import Mapping, Sequence
from Queue import Empty
from urllib import quote
from urlparse import urlparse
if PY3:
import builtins as _builtins
getattr(_builtins, "exec")("""def raise_from(value, from_value):
try:
raise value from from_value
finally:
value = None
""")
else:
def raise_from(value, from_value):
raise value
def add_metaclass(metaclass):
"""Class decorator for creating a class with a metaclass."""
def wrapper(cls):
orig_vars = cls.__dict__.copy()
slots = orig_vars.get('__slots__')
if slots is not None:
if isinstance(slots, str):
slots = [slots]
for slots_var in slots:
orig_vars.pop(slots_var)
orig_vars.pop('__dict__', None)
orig_vars.pop('__weakref__', None)
if hasattr(cls, '__qualname__'):
orig_vars['__qualname__'] = cls.__qualname__
return metaclass(cls.__name__, cls.__bases__, orig_vars)
return wrapper

View File

@ -2,8 +2,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import abc import abc
@ -12,9 +11,9 @@ import platform
import re import re
import sys import sys
import traceback import traceback
from collections.abc import Mapping, Sequence
from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible_collections.community.docker.plugins.module_utils._six import Mapping, Sequence, string_types
from ansible.module_utils.parsing.convert_bool import BOOLEANS_TRUE, BOOLEANS_FALSE from ansible.module_utils.parsing.convert_bool import BOOLEANS_TRUE, BOOLEANS_FALSE
from ansible_collections.community.docker.plugins.module_utils.version import LooseVersion from ansible_collections.community.docker.plugins.module_utils.version import LooseVersion
@ -209,10 +208,8 @@ class AnsibleDockerClientBase(Client):
"state." % (platform.node(), sys.executable)) "state." % (platform.node(), sys.executable))
if not HAS_DOCKER_PY: if not HAS_DOCKER_PY:
msg = missing_required_lib("Docker SDK for Python: docker>=5.0.0 (Python >= 3.6) or " msg = missing_required_lib("Docker SDK for Python: docker>=5.0.0")
"docker<5.0.0 (Python 2.7)") msg = msg + ", for example via `pip install docker`. The error was: %s"
msg = msg + ", for example via `pip install docker` (Python >= 3.6) or " \
+ "`pip install docker==4.4.4` (Python 2.7). The error was: %s"
self.fail(msg % HAS_DOCKER_ERROR, exception=HAS_DOCKER_TRACEBACK) self.fail(msg % HAS_DOCKER_ERROR, exception=HAS_DOCKER_TRACEBACK)
if self.docker_py_version < LooseVersion(min_docker_version): if self.docker_py_version < LooseVersion(min_docker_version):
@ -695,5 +692,5 @@ class AnsibleDockerClient(AnsibleDockerClientBase):
if isinstance(result, Sequence): if isinstance(result, Sequence):
for warning in result: for warning in result:
self.module.warn('Docker warning: {0}'.format(warning)) self.module.warn('Docker warning: {0}'.format(warning))
elif isinstance(result, string_types) and result: elif isinstance(result, str) and result:
self.module.warn('Docker warning: {0}'.format(result)) self.module.warn('Docker warning: {0}'.format(result))

View File

@ -3,16 +3,15 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import abc import abc
import os import os
import re import re
from collections.abc import Mapping, Sequence
from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible_collections.community.docker.plugins.module_utils._six import Mapping, Sequence, string_types
from ansible.module_utils.parsing.convert_bool import BOOLEANS_TRUE, BOOLEANS_FALSE from ansible.module_utils.parsing.convert_bool import BOOLEANS_TRUE, BOOLEANS_FALSE
from ansible_collections.community.docker.plugins.module_utils.version import LooseVersion from ansible_collections.community.docker.plugins.module_utils.version import LooseVersion
@ -579,5 +578,5 @@ class AnsibleDockerClient(AnsibleDockerClientBase):
if isinstance(result, Sequence): if isinstance(result, Sequence):
for warning in result: for warning in result:
self.module.warn('Docker warning: {0}'.format(warning)) self.module.warn('Docker warning: {0}'.format(warning))
elif isinstance(result, string_types) and result: elif isinstance(result, str) and result:
self.module.warn('Docker warning: {0}'.format(result)) self.module.warn('Docker warning: {0}'.format(result))

View File

@ -2,8 +2,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import abc import abc
@ -13,7 +12,6 @@ import shlex
from ansible.module_utils.basic import AnsibleModule, env_fallback from ansible.module_utils.basic import AnsibleModule, env_fallback
from ansible.module_utils.common.process import get_bin_path from ansible.module_utils.common.process import get_bin_path
from ansible.module_utils.common.text.converters import to_native from ansible.module_utils.common.text.converters import to_native
from ansible_collections.community.docker.plugins.module_utils._six import string_types
from ansible_collections.community.docker.plugins.module_utils.version import LooseVersion from ansible_collections.community.docker.plugins.module_utils.version import LooseVersion
@ -86,7 +84,7 @@ class AnsibleDockerClientBase(object):
self._info = None self._info = None
if needs_api_version: if needs_api_version:
if not isinstance(self._version.get('Server'), dict) or not isinstance(self._version['Server'].get('ApiVersion'), string_types): if not isinstance(self._version.get('Server'), dict) or not isinstance(self._version['Server'].get('ApiVersion'), str):
self.fail('Cannot determine Docker Daemon information. Are you maybe using podman instead of docker?') self.fail('Cannot determine Docker Daemon information. Are you maybe using podman instead of docker?')
self.docker_api_version_str = to_native(self._version['Server']['ApiVersion']) self.docker_api_version_str = to_native(self._version['Server']['ApiVersion'])
self.docker_api_version = LooseVersion(self.docker_api_version_str) self.docker_api_version = LooseVersion(self.docker_api_version_str)
@ -118,9 +116,7 @@ class AnsibleDockerClientBase(object):
return ' '.join(shlex.quote(a) for a in self._compose_cmd(args)) return ' '.join(shlex.quote(a) for a in self._compose_cmd(args))
@abc.abstractmethod @abc.abstractmethod
# def call_cli(self, *args, check_rc=False, data=None, cwd=None, environ_update=None): def call_cli(self, *args, check_rc=False, data=None, cwd=None, environ_update=None):
def call_cli(self, *args, **kwargs):
# Python 2.7 does not like anything than '**kwargs' after '*args', so we have to do this manually...
pass pass
# def call_cli_json(self, *args, check_rc=False, data=None, cwd=None, environ_update=None, warn_on_stderr=False): # def call_cli_json(self, *args, check_rc=False, data=None, cwd=None, environ_update=None, warn_on_stderr=False):
@ -320,16 +316,7 @@ class AnsibleModuleDockerClient(AnsibleDockerClientBase):
common_args, min_docker_api_version=min_docker_api_version, needs_api_version=needs_api_version, common_args, min_docker_api_version=min_docker_api_version, needs_api_version=needs_api_version,
) )
# def call_cli(self, *args, check_rc=False, data=None, cwd=None, environ_update=None): def call_cli(self, *args, check_rc=False, data=None, cwd=None, environ_update=None):
def call_cli(self, *args, **kwargs):
# Python 2.7 does not like anything than '**kwargs' after '*args', so we have to do this manually...
check_rc = kwargs.pop('check_rc', False)
data = kwargs.pop('data', None)
cwd = kwargs.pop('cwd', None)
environ_update = kwargs.pop('environ_update', None)
if kwargs:
raise TypeError("call_cli() got an unexpected keyword argument '%s'" % list(kwargs)[0])
environment = self._environment.copy() environment = self._environment.copy()
if environ_update: if environ_update:
environment.update(environ_update) environment.update(environ_update)

View File

@ -3,8 +3,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import json import json
@ -14,10 +13,10 @@ import shutil
import tempfile import tempfile
import traceback import traceback
from collections import namedtuple from collections import namedtuple
from shlex import quote
from ansible.module_utils.basic import missing_required_lib from ansible.module_utils.basic import missing_required_lib
from ansible.module_utils.common.text.converters import to_native from ansible.module_utils.common.text.converters import to_native
from ansible_collections.community.docker.plugins.module_utils._six import shlex_quote, string_types
from ansible_collections.community.docker.plugins.module_utils.util import DockerBaseClass from ansible_collections.community.docker.plugins.module_utils.util import DockerBaseClass
from ansible_collections.community.docker.plugins.module_utils.version import LooseVersion from ansible_collections.community.docker.plugins.module_utils.version import LooseVersion
@ -461,7 +460,7 @@ def parse_json_events(stderr, warn_function=None):
elif text in DOCKER_PULL_PROGRESS_DONE or line_data.get('text') in DOCKER_PULL_PROGRESS_WORKING: elif text in DOCKER_PULL_PROGRESS_DONE or line_data.get('text') in DOCKER_PULL_PROGRESS_WORKING:
resource_type = ResourceType.IMAGE_LAYER resource_type = ResourceType.IMAGE_LAYER
status, text = text, status status, text = text, status
elif status is None and isinstance(text, string_types) and text.startswith('Skipped - '): elif status is None and isinstance(text, str) and text.startswith('Skipped - '):
status, text = text.split(' - ', 1) status, text = text.split(' - ', 1)
elif line_data.get('level') in _JSON_LEVEL_TO_STATUS_MAP and 'msg' in line_data: elif line_data.get('level') in _JSON_LEVEL_TO_STATUS_MAP and 'msg' in line_data:
status = _JSON_LEVEL_TO_STATUS_MAP[line_data['level']] status = _JSON_LEVEL_TO_STATUS_MAP[line_data['level']]
@ -629,7 +628,7 @@ def update_failed(result, events, args, stdout, stderr, rc, cli):
errors.append('Return code {code} is non-zero'.format(code=rc)) errors.append('Return code {code} is non-zero'.format(code=rc))
result['failed'] = True result['failed'] = True
result['msg'] = '\n'.join(errors) result['msg'] = '\n'.join(errors)
result['cmd'] = ' '.join(shlex_quote(arg) for arg in [cli] + args) result['cmd'] = ' '.join(quote(arg) for arg in [cli] + args)
result['stdout'] = to_native(stdout) result['stdout'] = to_native(stdout)
result['stderr'] = to_native(stderr) result['stderr'] = to_native(stderr)
result['rc'] = rc result['rc'] = rc

View File

@ -2,8 +2,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import base64 import base64
import datetime import datetime
@ -16,7 +15,6 @@ import stat
import tarfile import tarfile
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
from ansible_collections.community.docker.plugins.module_utils._six import raise_from
from ansible_collections.community.docker.plugins.module_utils._api.errors import APIError, NotFound from ansible_collections.community.docker.plugins.module_utils._api.errors import APIError, NotFound
@ -126,12 +124,7 @@ def _regular_content_tar_generator(content, out_file, user_id, group_id, mode, u
tarinfo.uid = user_id tarinfo.uid = user_id
tarinfo.gid = group_id tarinfo.gid = group_id
tarinfo.size = len(content) tarinfo.size = len(content)
try: tarinfo.mtime = int(datetime.datetime.now().timestamp())
tarinfo.mtime = int(datetime.datetime.now().timestamp())
except AttributeError:
# Python 2 (or more precisely: Python < 3.3) has no timestamp(). Use the following
# expression for Python 2:
tarinfo.mtime = int((datetime.datetime.utcnow() - datetime.datetime(1970, 1, 1)).total_seconds())
tarinfo.type = tarfile.REGTYPE tarinfo.type = tarfile.REGTYPE
tarinfo.linkname = '' tarinfo.linkname = ''
if user_name: if user_name:
@ -346,9 +339,9 @@ def fetch_file(client, container, in_path, out_path, follow_links=False, log=Non
if not follow_links and os.path.exists(b_out_path): if not follow_links and os.path.exists(b_out_path):
os.unlink(b_out_path) os.unlink(b_out_path)
in_f = tar.extractfile(member) # in Python 2, this *cannot* be used in `with`... with tar.extractfile(member) as in_f:
with open(b_out_path, 'wb') as out_f: with open(b_out_path, 'wb') as out_f:
shutil.copyfileobj(in_f, out_f) shutil.copyfileobj(in_f, out_f)
return in_path return in_path
def process_symlink(in_path, member): def process_symlink(in_path, member):
@ -385,16 +378,10 @@ def _execute_command(client, container, command, log=None, check_rc=False):
try: try:
exec_data = client.post_json_to_json('/containers/{0}/exec', container, data=data) exec_data = client.post_json_to_json('/containers/{0}/exec', container, data=data)
except NotFound as e: except NotFound as e:
raise_from( raise DockerFileCopyError('Could not find container "{container}"'.format(container=container)) from e
DockerFileCopyError('Could not find container "{container}"'.format(container=container)),
e,
)
except APIError as e: except APIError as e:
if e.response is not None and e.response.status_code == 409: if e.response is not None and e.response.status_code == 409:
raise_from( raise DockerFileCopyError('Cannot execute command in paused container "{container}"'.format(container=container)) from e
DockerFileCopyError('Cannot execute command in paused container "{container}"'.format(container=container)),
e,
)
raise raise
exec_id = exec_data['Id'] exec_id = exec_data['Id']

View File

@ -2,8 +2,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import json import json
import os import os
@ -31,18 +30,7 @@ class ImageArchiveManifestSummary(object):
class ImageArchiveInvalidException(Exception): class ImageArchiveInvalidException(Exception):
def __init__(self, message, cause): pass
'''
:param message: Exception message
:type message: str
:param cause: Inner exception that this exception wraps
:type cause: Exception | None
'''
super(ImageArchiveInvalidException, self).__init__(message)
# Python 2 does not support causes
self.cause = cause
def api_image_id(archive_image_id): def api_image_id(archive_image_id):
@ -84,26 +72,19 @@ def load_archived_image_manifest(archive_path):
if not os.path.isfile(archive_path): if not os.path.isfile(archive_path):
return None return None
tf = tarfile.open(archive_path, 'r') with tarfile.open(archive_path, 'r') as tf:
try:
try: try:
ef = tf.extractfile('manifest.json')
try: try:
text = ef.read().decode('utf-8') with tf.extractfile('manifest.json') as ef:
manifest = json.loads(text) manifest = json.load(ef)
except Exception as exc: except Exception as exc:
raise ImageArchiveInvalidException( raise ImageArchiveInvalidException(
"Failed to decode and deserialize manifest.json: %s" % to_native(exc), "Failed to decode and deserialize manifest.json: %s" % to_native(exc)
exc ) from exc
)
finally:
# In Python 2.6, this does not have __exit__
ef.close()
if len(manifest) == 0: if len(manifest) == 0:
raise ImageArchiveInvalidException( raise ImageArchiveInvalidException(
"Expected to have at least one entry in manifest.json but found none", "Expected to have at least one entry in manifest.json but found none"
None
) )
result = [] result = []
@ -112,9 +93,8 @@ def load_archived_image_manifest(archive_path):
config_file = meta['Config'] config_file = meta['Config']
except KeyError as exc: except KeyError as exc:
raise ImageArchiveInvalidException( raise ImageArchiveInvalidException(
"Failed to get Config entry from {0}th manifest in manifest.json: {1}".format(index + 1, to_native(exc)), "Failed to get Config entry from {0}th manifest in manifest.json: {1}".format(index + 1, to_native(exc))
exc ) from exc
)
# Extracts hash without 'sha256:' prefix # Extracts hash without 'sha256:' prefix
try: try:
@ -122,9 +102,8 @@ def load_archived_image_manifest(archive_path):
image_id = os.path.splitext(config_file)[0] image_id = os.path.splitext(config_file)[0]
except Exception as exc: except Exception as exc:
raise ImageArchiveInvalidException( raise ImageArchiveInvalidException(
"Failed to extract image id from config file name %s: %s" % (config_file, to_native(exc)), "Failed to extract image id from config file name %s: %s" % (config_file, to_native(exc))
exc ) from exc
)
for prefix in ( for prefix in (
'blobs/sha256/', # Moby 25.0.0, Docker API 1.44 'blobs/sha256/', # Moby 25.0.0, Docker API 1.44
@ -136,9 +115,8 @@ def load_archived_image_manifest(archive_path):
repo_tags = meta['RepoTags'] repo_tags = meta['RepoTags']
except KeyError as exc: except KeyError as exc:
raise ImageArchiveInvalidException( raise ImageArchiveInvalidException(
"Failed to get RepoTags entry from {0}th manifest in manifest.json: {1}".format(index + 1, to_native(exc)), "Failed to get RepoTags entry from {0}th manifest in manifest.json: {1}".format(index + 1, to_native(exc))
exc ) from exc
)
result.append(ImageArchiveManifestSummary( result.append(ImageArchiveManifestSummary(
image_id=image_id, image_id=image_id,
@ -150,18 +128,13 @@ def load_archived_image_manifest(archive_path):
raise raise
except Exception as exc: except Exception as exc:
raise ImageArchiveInvalidException( raise ImageArchiveInvalidException(
"Failed to extract manifest.json from tar file %s: %s" % (archive_path, to_native(exc)), "Failed to extract manifest.json from tar file %s: %s" % (archive_path, to_native(exc))
exc ) from exc
)
finally:
# In Python 2.6, TarFile does not have __exit__
tf.close()
except ImageArchiveInvalidException: except ImageArchiveInvalidException:
raise raise
except Exception as exc: except Exception as exc:
raise ImageArchiveInvalidException("Failed to open tar file %s: %s" % (archive_path, to_native(exc)), exc) raise ImageArchiveInvalidException("Failed to open tar file %s: %s" % (archive_path, to_native(exc))) from exc
def archived_image_manifest(archive_path): def archived_image_manifest(archive_path):
@ -189,6 +162,5 @@ def archived_image_manifest(archive_path):
if len(results) == 1: if len(results) == 1:
return results[0] return results[0]
raise ImageArchiveInvalidException( raise ImageArchiveInvalidException(
"Expected to have one entry in manifest.json but found %s" % len(results), "Expected to have one entry in manifest.json but found %s" % len(results)
None
) )

View File

@ -3,8 +3,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
import abc import abc
import os import os
@ -15,7 +14,6 @@ from functools import partial
from ansible.module_utils.common.text.converters import to_native, to_text from ansible.module_utils.common.text.converters import to_native, to_text
from ansible.module_utils.common.text.formatters import human_to_bytes from ansible.module_utils.common.text.formatters import human_to_bytes
from ansible_collections.community.docker.plugins.module_utils._six import string_types
from ansible_collections.community.docker.plugins.module_utils.util import ( from ansible_collections.community.docker.plugins.module_utils.util import (
clean_dict_booleans_for_docker_api, clean_dict_booleans_for_docker_api,
@ -461,7 +459,7 @@ def _preprocess_env(module, values):
final_env[name] = to_text(value, errors='surrogate_or_strict') final_env[name] = to_text(value, errors='surrogate_or_strict')
if 'env' in values: if 'env' in values:
for name, value in values['env'].items(): for name, value in values['env'].items():
if not isinstance(value, string_types): if not isinstance(value, str):
module.fail_json(msg='Non-string value found for env option. Ambiguous env options must be ' module.fail_json(msg='Non-string value found for env option. Ambiguous env options must be '
'wrapped in quotes to avoid them being interpreted. Key: %s' % (name, )) 'wrapped in quotes to avoid them being interpreted. Key: %s' % (name, ))
final_env[name] = to_text(value, errors='surrogate_or_strict') final_env[name] = to_text(value, errors='surrogate_or_strict')
@ -695,7 +693,7 @@ def _preprocess_log(module, values):
if 'log_options' in values: if 'log_options' in values:
options = {} options = {}
for k, v in values['log_options'].items(): for k, v in values['log_options'].items():
if not isinstance(v, string_types): if not isinstance(v, str):
module.warn( module.warn(
"Non-string value found for log_options option '%s'. The value is automatically converted to '%s'. " "Non-string value found for log_options option '%s'. The value is automatically converted to '%s'. "
"If this is not correct, or you want to avoid such warnings, please quote the value." % ( "If this is not correct, or you want to avoid such warnings, please quote the value." % (
@ -780,7 +778,7 @@ def _preprocess_ports(module, values):
# Any published port should also be exposed # Any published port should also be exposed
for publish_port in values['published_ports']: for publish_port in values['published_ports']:
match = False match = False
if isinstance(publish_port, string_types) and '/' in publish_port: if isinstance(publish_port, str) and '/' in publish_port:
port, protocol = publish_port.split('/') port, protocol = publish_port.split('/')
port = int(port) port = int(port)
else: else:
@ -789,7 +787,7 @@ def _preprocess_ports(module, values):
for exposed_port in exposed: for exposed_port in exposed:
if exposed_port[1] != protocol: if exposed_port[1] != protocol:
continue continue
if isinstance(exposed_port[0], string_types) and '-' in exposed_port[0]: if isinstance(exposed_port[0], str) and '-' in exposed_port[0]:
start_port, end_port = exposed_port[0].split('-') start_port, end_port = exposed_port[0].split('-')
if int(start_port) <= port <= int(end_port): if int(start_port) <= port <= int(end_port):
match = True match = True

View File

@ -3,8 +3,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
import json import json
import traceback import traceback

View File

@ -3,8 +3,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
import re import re
from time import sleep from time import sleep

View File

@ -6,16 +6,7 @@
"""Provide selectors import.""" """Provide selectors import."""
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
# Once we drop support for ansible-core 2.16, we can remove the try/except. import selectors # noqa: F401, pylint: disable=unused-import
from sys import version_info as _python_version_info
if _python_version_info < (3, 4):
from ansible.module_utils.compat import selectors # noqa: F401, pylint: disable=unused-import
else:
import selectors # noqa: F401, pylint: disable=unused-import

View File

@ -2,8 +2,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import os import os
@ -11,8 +10,6 @@ import os.path
import socket as pysocket import socket as pysocket
import struct import struct
from ansible_collections.community.docker.plugins.module_utils._six import PY2
from ansible_collections.community.docker.plugins.module_utils._api.utils import socket as docker_socket from ansible_collections.community.docker.plugins.module_utils._api.utils import socket as docker_socket
from ansible_collections.community.docker.plugins.module_utils.socket_helper import ( from ansible_collections.community.docker.plugins.module_utils.socket_helper import (
@ -85,7 +82,7 @@ class DockerSocketHandlerBase(object):
return return
else: else:
raise raise
elif not PY2 and isinstance(self._sock, getattr(pysocket, 'SocketIO')): elif isinstance(self._sock, getattr(pysocket, 'SocketIO')):
data = self._sock.read() data = self._sock.read()
else: else:
data = os.read(self._sock.fileno()) data = os.read(self._sock.fileno())

View File

@ -2,8 +2,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import fcntl import fcntl
@ -11,8 +10,6 @@ import os
import os.path import os.path
import socket as pysocket import socket as pysocket
from ansible_collections.community.docker.plugins.module_utils._six import PY2
def make_file_unblocking(file): def make_file_unblocking(file):
fcntl.fcntl(file.fileno(), fcntl.F_SETFL, fcntl.fcntl(file.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK) fcntl.fcntl(file.fileno(), fcntl.F_SETFL, fcntl.fcntl(file.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK)
@ -49,7 +46,7 @@ def shutdown_writing(sock, log=_empty_writer):
# probably: "TypeError: shutdown() takes 1 positional argument but 2 were given" # probably: "TypeError: shutdown() takes 1 positional argument but 2 were given"
log('Shutting down for writing not possible; trying shutdown instead: {0}'.format(e)) log('Shutting down for writing not possible; trying shutdown instead: {0}'.format(e))
sock.shutdown() sock.shutdown()
elif not PY2 and isinstance(sock, getattr(pysocket, 'SocketIO')): elif isinstance(sock, getattr(pysocket, 'SocketIO')):
sock._sock.shutdown(pysocket.SHUT_WR) sock._sock.shutdown(pysocket.SHUT_WR)
else: else:
log('No idea how to signal end of writing') log('No idea how to signal end of writing')

View File

@ -3,8 +3,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import json import json

View File

@ -2,17 +2,16 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
import json import json
import re import re
from datetime import timedelta from datetime import timedelta
from urllib.parse import urlparse
from ansible.module_utils.basic import env_fallback from ansible.module_utils.basic import env_fallback
from ansible.module_utils.common.collections import is_sequence from ansible.module_utils.common.collections import is_sequence
from ansible_collections.community.docker.plugins.module_utils._six import string_types, urlparse
from ansible.module_utils.common.text.converters import to_text from ansible.module_utils.common.text.converters import to_text
@ -289,7 +288,7 @@ def sanitize_labels(labels, labels_field, client=None, module=None):
if labels is None: if labels is None:
return return
for k, v in list(labels.items()): for k, v in list(labels.items()):
if not isinstance(k, string_types): if not isinstance(k, str):
fail( fail(
"The key {key!r} of {field} is not a string!".format( "The key {key!r} of {field} is not a string!".format(
field=labels_field, key=k)) field=labels_field, key=k))

View File

@ -6,8 +6,7 @@
"""Provide version object to compare version numbers.""" """Provide version object to compare version numbers."""
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
from ansible.module_utils.compat.version import LooseVersion, StrictVersion # noqa: F401, pylint: disable=unused-import from ansible.module_utils.compat.version import LooseVersion, StrictVersion # noqa: F401, pylint: disable=unused-import

View File

@ -5,8 +5,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""

View File

@ -6,8 +6,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""
@ -441,7 +440,6 @@ import traceback
from ansible.module_utils.common.validation import check_type_int from ansible.module_utils.common.validation import check_type_int
from ansible.module_utils.common.text.converters import to_native from ansible.module_utils.common.text.converters import to_native
from ansible_collections.community.docker.plugins.module_utils._six import string_types
from ansible_collections.community.docker.plugins.module_utils.common_cli import ( from ansible_collections.community.docker.plugins.module_utils.common_cli import (
AnsibleModuleDockerClient, AnsibleModuleDockerClient,
@ -482,7 +480,7 @@ class ServicesManager(BaseComposeManager):
self.fail('assume_yes=true needs Docker Compose 2.32.0 or newer, not version %s' % (self.compose_version, )) self.fail('assume_yes=true needs Docker Compose 2.32.0 or newer, not version %s' % (self.compose_version, ))
for key, value in self.scale.items(): for key, value in self.scale.items():
if not isinstance(key, string_types): if not isinstance(key, str):
self.fail('The key %s for `scale` is not a string' % repr(key)) self.fail('The key %s for `scale` is not a string' % repr(key))
try: try:
value = check_type_int(value) value = check_type_int(value)

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""
@ -169,7 +168,6 @@ import shlex
import traceback import traceback
from ansible.module_utils.common.text.converters import to_text, to_native from ansible.module_utils.common.text.converters import to_text, to_native
from ansible_collections.community.docker.plugins.module_utils._six import string_types
from ansible_collections.community.docker.plugins.module_utils.common_cli import ( from ansible_collections.community.docker.plugins.module_utils.common_cli import (
AnsibleModuleDockerClient, AnsibleModuleDockerClient,
@ -210,7 +208,7 @@ class ExecManager(BaseComposeManager):
if self.env is not None: if self.env is not None:
for name, value in list(self.env.items()): for name, value in list(self.env.items()):
if not isinstance(value, string_types): if not isinstance(value, str):
self.fail( self.fail(
"Non-string value found for env option. Ambiguous env options must be " "Non-string value found for env option. Ambiguous env options must be "
"wrapped in quotes to avoid them being interpreted. Key: %s" % (name, ) "wrapped in quotes to avoid them being interpreted. Key: %s" % (name, )

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""
@ -242,7 +241,6 @@ import shlex
import traceback import traceback
from ansible.module_utils.common.text.converters import to_text, to_native from ansible.module_utils.common.text.converters import to_text, to_native
from ansible_collections.community.docker.plugins.module_utils._six import string_types
from ansible_collections.community.docker.plugins.module_utils.common_cli import ( from ansible_collections.community.docker.plugins.module_utils.common_cli import (
AnsibleModuleDockerClient, AnsibleModuleDockerClient,
@ -296,7 +294,7 @@ class ExecManager(BaseComposeManager):
if self.env is not None: if self.env is not None:
for name, value in list(self.env.items()): for name, value in list(self.env.items()):
if not isinstance(value, string_types): if not isinstance(value, str):
self.fail( self.fail(
"Non-string value found for env option. Ambiguous env options must be " "Non-string value found for env option. Ambiguous env options must be "
"wrapped in quotes to avoid them being interpreted. Key: %s" % (name, ) "wrapped in quotes to avoid them being interpreted. Key: %s" % (name, )

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""
@ -173,7 +172,6 @@ import traceback
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
from ansible.module_utils.common.validation import check_type_int from ansible.module_utils.common.validation import check_type_int
from ansible_collections.community.docker.plugins.module_utils._six import integer_types, string_types
from ansible_collections.community.docker.plugins.module_utils._api.errors import APIError, DockerException, NotFound from ansible_collections.community.docker.plugins.module_utils._api.errors import APIError, DockerException, NotFound
@ -421,8 +419,9 @@ def add_diff_dst_from_regular_member(diff, max_file_size_for_diff, container_pat
diff['dst_larger'] = max_file_size_for_diff diff['dst_larger'] = max_file_size_for_diff
return return
tar_f = tar.extractfile(member) # in Python 2, this *cannot* be used in `with`... with tar.extractfile(member) as tar_f:
content = tar_f.read() content = tar_f.read()
if is_binary(content): if is_binary(content):
diff['dst_binary'] = 1 diff['dst_binary'] = 1
else: else:
@ -546,9 +545,9 @@ def is_file_idempotent(client, container, managed_path, container_path, follow_l
add_diff_dst_from_regular_member(diff, max_file_size_for_diff, in_path, tar, member) add_diff_dst_from_regular_member(diff, max_file_size_for_diff, in_path, tar, member)
return container_path, mode, False return container_path, mode, False
tar_f = tar.extractfile(member) # in Python 2, this *cannot* be used in `with`... with tar.extractfile(member) as tar_f:
with open(managed_path, 'rb') as local_f: with open(managed_path, 'rb') as local_f:
is_equal = are_fileobjs_equal_with_diff_of_first(tar_f, local_f, member.size, diff, max_file_size_for_diff, in_path) is_equal = are_fileobjs_equal_with_diff_of_first(tar_f, local_f, member.size, diff, max_file_size_for_diff, in_path)
return container_path, mode, is_equal return container_path, mode, is_equal
def process_symlink(in_path, member): def process_symlink(in_path, member):
@ -707,8 +706,8 @@ def is_content_idempotent(client, container, content, container_path, follow_lin
add_diff_dst_from_regular_member(diff, max_file_size_for_diff, in_path, tar, member) add_diff_dst_from_regular_member(diff, max_file_size_for_diff, in_path, tar, member)
return container_path, mode, False return container_path, mode, False
tar_f = tar.extractfile(member) # in Python 2, this *cannot* be used in `with`... with tar.extractfile(member) as tar_f:
is_equal = are_fileobjs_equal_with_diff_of_first(tar_f, io.BytesIO(content), member.size, diff, max_file_size_for_diff, in_path) is_equal = are_fileobjs_equal_with_diff_of_first(tar_f, io.BytesIO(content), member.size, diff, max_file_size_for_diff, in_path)
return container_path, mode, is_equal return container_path, mode, is_equal
def process_symlink(in_path, member): def process_symlink(in_path, member):
@ -783,15 +782,15 @@ def copy_content_into_container(client, container, content, container_path, foll
def parse_modern(mode): def parse_modern(mode):
if isinstance(mode, string_types): if isinstance(mode, str):
return int(to_native(mode), 8) return int(to_native(mode), 8)
if isinstance(mode, integer_types): if isinstance(mode, int):
return mode return mode
raise TypeError('must be an octal string or an integer, got {mode!r}'.format(mode=mode)) raise TypeError('must be an octal string or an integer, got {mode!r}'.format(mode=mode))
def parse_octal_string_only(mode): def parse_octal_string_only(mode):
if isinstance(mode, string_types): if isinstance(mode, str):
return int(to_native(mode), 8) return int(to_native(mode), 8)
raise TypeError('must be an octal string, got {mode!r}'.format(mode=mode)) raise TypeError('must be an octal string, got {mode!r}'.format(mode=mode))

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""
@ -164,19 +163,17 @@ exec_id:
version_added: 2.1.0 version_added: 2.1.0
""" """
import selectors
import shlex import shlex
import traceback import traceback
from ansible.module_utils.common.text.converters import to_text, to_bytes, to_native from ansible.module_utils.common.text.converters import to_text, to_bytes, to_native
from ansible_collections.community.docker.plugins.module_utils._six import string_types
from ansible_collections.community.docker.plugins.module_utils.common_api import ( from ansible_collections.community.docker.plugins.module_utils.common_api import (
AnsibleDockerClient, AnsibleDockerClient,
RequestException, RequestException,
) )
from ansible_collections.community.docker.plugins.module_utils.selectors import selectors
from ansible_collections.community.docker.plugins.module_utils.socket_handler import ( from ansible_collections.community.docker.plugins.module_utils.socket_handler import (
DockerSocketHandlerModule, DockerSocketHandlerModule,
) )
@ -228,7 +225,7 @@ def main():
if env is not None: if env is not None:
for name, value in list(env.items()): for name, value in list(env.items()):
if not isinstance(value, string_types): if not isinstance(value, str):
client.module.fail_json( client.module.fail_json(
msg="Non-string value found for env option. Ambiguous env options must be " msg="Non-string value found for env option. Ambiguous env options must be "
"wrapped in quotes to avoid them being interpreted. Key: %s" % (name, )) "wrapped in quotes to avoid them being interpreted. Key: %s" % (name, ))

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""
@ -177,7 +176,6 @@ import traceback
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.common.text.converters import to_native, to_text from ansible.module_utils.common.text.converters import to_native, to_text
from ansible_collections.community.docker.plugins.module_utils._six import string_types
from ansible_collections.community.docker.plugins.module_utils._api.context.api import ( from ansible_collections.community.docker.plugins.module_utils._api.context.api import (
ContextAPI, ContextAPI,
@ -214,7 +212,7 @@ def context_to_json(context, current):
module_config = {} module_config = {}
if 'docker' in context.endpoints: if 'docker' in context.endpoints:
endpoint = context.endpoints['docker'] endpoint = context.endpoints['docker']
if isinstance(endpoint.get('Host'), string_types): if isinstance(endpoint.get('Host'), str):
host_str = to_text(endpoint['Host']) host_str = to_text(endpoint['Host'])
# Adjust protocol name so that it works with the Docker CLI tool as well # Adjust protocol name so that it works with the Docker CLI tool as well

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""

View File

@ -5,8 +5,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""

View File

@ -7,8 +7,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""

View File

@ -4,9 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""
module: docker_node module: docker_node

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""

View File

@ -6,8 +6,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""

View File

@ -5,8 +5,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""
@ -161,7 +160,6 @@ import os
import tempfile import tempfile
import traceback import traceback
from ansible_collections.community.docker.plugins.module_utils._six import string_types
from time import sleep from time import sleep
from ansible.module_utils.common.text.converters import to_native from ansible.module_utils.common.text.converters import to_native
@ -280,7 +278,7 @@ def main():
with os.fdopen(compose_file_fd, 'w') as stack_file: with os.fdopen(compose_file_fd, 'w') as stack_file:
compose_files.append(compose_file) compose_files.append(compose_file)
stack_file.write(yaml_dump(compose_def)) stack_file.write(yaml_dump(compose_def))
elif isinstance(compose_def, string_types): elif isinstance(compose_def, str):
compose_files.append(compose_def) compose_files.append(compose_def)
else: else:
client.fail("compose element '%s' must be a string or a dictionary" % compose_def) client.fail("compose element '%s' must be a string or a dictionary" % compose_def)

View File

@ -5,9 +5,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""
module: docker_stack_info module: docker_stack_info

View File

@ -5,9 +5,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function) from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""
module: docker_stack_task_info module: docker_stack_task_info

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""
module: docker_swarm module: docker_swarm

View File

@ -4,9 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""
module: docker_swarm_info module: docker_swarm_info

View File

@ -4,8 +4,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function from __future__ import annotations
__metaclass__ = type
DOCUMENTATION = r""" DOCUMENTATION = r"""
module: docker_swarm_service module: docker_swarm_service
@ -870,7 +869,6 @@ from ansible_collections.community.docker.plugins.module_utils.util import (
) )
from ansible.module_utils.basic import human_to_bytes from ansible.module_utils.basic import human_to_bytes
from ansible_collections.community.docker.plugins.module_utils._six import string_types
from ansible.module_utils.common.text.converters import to_text, to_native from ansible.module_utils.common.text.converters import to_text, to_native
try: try:
@ -904,11 +902,11 @@ def get_docker_environment(env, env_files):
parsed_env_file = parse_env_file(env_file) parsed_env_file = parse_env_file(env_file)
for name, value in parsed_env_file.items(): for name, value in parsed_env_file.items():
env_dict[name] = str(value) env_dict[name] = str(value)
if env is not None and isinstance(env, string_types): if env is not None and isinstance(env, str):
env = env.split(',') env = env.split(',')
if env is not None and isinstance(env, dict): if env is not None and isinstance(env, dict):
for name, value in env.items(): for name, value in env.items():
if not isinstance(value, string_types): if not isinstance(value, str):
raise ValueError( raise ValueError(
'Non-string value found for env option. ' 'Non-string value found for env option. '
'Ambiguous env options must be wrapped in quotes to avoid YAML parsing. Key: %s' % name 'Ambiguous env options must be wrapped in quotes to avoid YAML parsing. Key: %s' % name
@ -943,7 +941,7 @@ def get_docker_networks(networks, network_ids):
return None return None
parsed_networks = [] parsed_networks = []
for network in networks: for network in networks:
if isinstance(network, string_types): if isinstance(network, str):
parsed_network = {'name': network} parsed_network = {'name': network}
elif isinstance(network, dict): elif isinstance(network, dict):
if 'name' not in network: if 'name' not in network:
@ -957,7 +955,7 @@ def get_docker_networks(networks, network_ids):
if not isinstance(aliases, list): if not isinstance(aliases, list):
raise TypeError('"aliases" network option is only allowed as a list') raise TypeError('"aliases" network option is only allowed as a list')
if not all( if not all(
isinstance(alias, string_types) for alias in aliases isinstance(alias, str) for alias in aliases
): ):
raise TypeError('Only strings are allowed as network aliases.') raise TypeError('Only strings are allowed as network aliases.')
parsed_network['aliases'] = aliases parsed_network['aliases'] = aliases
@ -991,7 +989,7 @@ def get_nanoseconds_from_raw_option(name, value):
return None return None
elif isinstance(value, int): elif isinstance(value, int):
return value return value
elif isinstance(value, string_types): elif isinstance(value, str):
try: try:
return int(value) return int(value)
except ValueError: except ValueError:
@ -1070,7 +1068,7 @@ def has_list_changed(new_list, old_list, sort_lists=True, sort_key=None):
for new_item, old_item in zip_data: for new_item, old_item in zip_data:
is_same_type = type(new_item) == type(old_item) # noqa: E721, pylint: disable=unidiomatic-typecheck is_same_type = type(new_item) == type(old_item) # noqa: E721, pylint: disable=unidiomatic-typecheck
if not is_same_type: if not is_same_type:
if isinstance(new_item, string_types) and isinstance(old_item, string_types): if isinstance(new_item, str) and isinstance(old_item, str):
# Even though the types are different between these items, # Even though the types are different between these items,
# they are both strings. Try matching on the same string type. # they are both strings. Try matching on the same string type.
try: try:
@ -1474,13 +1472,13 @@ class DockerService(DockerBaseClass):
s.networks = get_docker_networks(ap['networks'], network_ids) s.networks = get_docker_networks(ap['networks'], network_ids)
s.command = ap['command'] s.command = ap['command']
if isinstance(s.command, string_types): if isinstance(s.command, str):
s.command = shlex.split(s.command) s.command = shlex.split(s.command)
elif isinstance(s.command, list): elif isinstance(s.command, list):
invalid_items = [ invalid_items = [
(index, item) (index, item)
for index, item in enumerate(s.command) for index, item in enumerate(s.command)
if not isinstance(item, string_types) if not isinstance(item, str)
] ]
if invalid_items: if invalid_items:
errors = ', '.join( errors = ', '.join(

Some files were not shown because too many files have changed in this diff Show More