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 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
@ -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.
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/).

View File

@ -8,16 +8,6 @@
"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"
[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 = "git"
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:
[[sessions.ansible_test_integration.groups]]
@ -254,12 +205,14 @@ runtime_container_options = [
]
[[sessions.ee_check.execution_environments]]
name = "2.15-rocky-9"
description = "ansible-core 2.15 @ Rocky Linux 9"
name = "2.17-rocky-9"
description = "ansible-core 2.17 @ Rocky Linux 9"
test_playbooks = ["tests/ee/all.yml"]
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.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_container_options = [
# 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
name: docker
version: 4.8.1
version: 5.0.0-a1
readme: README.md
authors:
- Ansible Docker Working Group
@ -15,7 +15,6 @@ description: Modules and plugins for working with Docker
license:
- GPL-3.0-or-later
- Apache-2.0
- MIT
# license_file: COPYING
tags:
- 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)
# SPDX-License-Identifier: GPL-3.0-or-later
requires_ansible: '>=2.15.0'
requires_ansible: '>=2.17.0'
action_groups:
docker:
- 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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
DOCUMENTATION = r"""
author:
@ -115,9 +114,10 @@ options:
import fcntl
import os
import os.path
import selectors
import subprocess
import re
from shlex import quote as shlex_quote
from shlex import quote
from ansible.errors import AnsibleError, AnsibleFileNotFound, AnsibleConnectionFailure
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.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
display = Display()
@ -433,7 +432,7 @@ class Connection(ConnectionBase):
raise AnsibleFileNotFound(
"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
# running containers, so we use docker exec to implement this
# 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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
DOCUMENTATION = r"""
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
DOCUMENTATION = r"""
name: nsenter
@ -42,6 +41,7 @@ notes:
import os
import pty
import selectors
import subprocess
import fcntl
@ -52,8 +52,6 @@ from ansible.plugins.connection import ConnectionBase
from ansible.utils.display import Display
from ansible.utils.path import unfrackpath
from ansible_collections.community.docker.plugins.module_utils.selectors import selectors
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
class ModuleDocFragment(object):
@ -303,7 +302,6 @@ requirements:
- pywin32 (when using named pipes on Windows 32)
- paramiko (when using SSH with O(use_ssh_client=false))
- pyOpenSSL (when using TLS)
- backports.ssl_match_hostname (when using TLS on Python 2)
'''
# 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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
DOCUMENTATION = r"""
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
DOCUMENTATION = r"""
name: docker_swarm
@ -14,7 +12,6 @@ author:
- Stefan Heitmüller (@morph027) <stefan.heitmueller@gmx.com>
short_description: Ansible dynamic inventory plugin for Docker swarm nodes
requirements:
- python >= 2.7
- L(Docker SDK for Python,https://docker-py.readthedocs.io/en/stable/) >= 1.10.0
extends_documentation_fragment:
- 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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import traceback
from ansible_collections.community.docker.plugins.module_utils._six import PY2
REQUESTS_IMPORT_ERROR = None
URLLIB3_IMPORT_ERROR = None
BACKPORTS_SSL_MATCH_HOSTNAME_IMPORT_ERROR = None
try:
@ -41,11 +37,11 @@ except ImportError:
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
except ImportError:
try:
import urllib3
import urllib3 # pylint: disable=unused-import
from urllib3 import connection as urllib3_connection # pylint: disable=unused-import
except ImportError:
URLLIB3_IMPORT_ERROR = traceback.format_exc()
@ -76,16 +72,6 @@ except ImportError:
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():
if REQUESTS_IMPORT_ERROR is not None:
from .errors import MissingRequirementException
@ -99,9 +85,3 @@ def fail_on_missing_imports():
raise MissingRequirementException(
'You have to install urllib3',
'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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import json
import logging
import struct
from functools import partial
from ansible_collections.community.docker.plugins.module_utils._six import PY3, binary_type, iteritems, string_types, raise_from, quote
from urllib.parse import quote
from .. import auth
from .._import_helper import fail_on_missing_imports
@ -183,11 +181,11 @@ class APIClient(
self.base_url = base_url
# 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()
else:
self._version = version
if not isinstance(self._version, string_types):
if not isinstance(self._version, str):
raise DockerException(
'Version parameter must be a string or None. Found {0}'.format(
type(version).__name__
@ -247,7 +245,7 @@ class APIClient(
def _url(self, pathfmt, *args, **kwargs):
for arg in args:
if not isinstance(arg, string_types):
if not isinstance(arg, str):
raise ValueError(
'Expected a string but found {0} ({1}) '
'instead'.format(arg, type(arg))
@ -268,7 +266,7 @@ class APIClient(
try:
response.raise_for_status()
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):
if json and binary:
@ -286,7 +284,7 @@ class APIClient(
# so we do this disgusting thing here.
data2 = {}
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:
data2[k] = v
elif data is not None:
@ -310,12 +308,10 @@ class APIClient(
sock = response.raw._fp.fp.raw.sock
elif self.base_url.startswith('http+docker://ssh'):
sock = response.raw._fp.fp.channel
elif PY3:
else:
sock = response.raw._fp.fp.raw
if self.base_url.startswith("https://"):
sock = sock._sock
else:
sock = response.raw._fp.fp._sock
try:
# Keep a reference to the response to stop it being garbage
# collected. If the response is garbage collected, it will
@ -333,8 +329,7 @@ class APIClient(
if response.raw._fp.chunked:
if decode:
for chunk in json_stream.json_stream(self._stream_helper(response, False)):
yield chunk
yield from json_stream.json_stream(self._stream_helper(response, False))
else:
reader = response.raw
while not reader.closed:
@ -396,8 +391,7 @@ class APIClient(
socket = self._get_raw_response_socket(response)
self._disable_socket_timeout(socket)
for out in response.iter_content(chunk_size, decode):
yield out
yield from response.iter_content(chunk_size, decode)
def _read_from_socket(self, response, stream, tty=True, demux=False):
"""Consume all data from the socket, close the response and return the
@ -468,7 +462,7 @@ class APIClient(
self._result(res, binary=True)
self._raise_for_status(res)
sep = binary_type()
sep = b''
if stream:
return self._multiplexed_response_stream_helper(res)
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import base64
import json
import logging
from ansible_collections.community.docker.plugins.module_utils._six import iteritems, string_types
from . import errors
from .credentials.store import Store
from .credentials.errors import StoreError, CredentialsNotFound
@ -111,7 +108,7 @@ class AuthConfig(dict):
"""
conf = {}
for registry, entry in iteritems(entries):
for registry, entry in entries.items():
if not isinstance(entry, dict):
log.debug('Config entry for key %s is not auth config', registry)
# 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))
return self.auths[registry]
for key, conf in iteritems(self.auths):
for key, conf in self.auths.items():
if resolve_index_name(key) == registry:
log.debug("Found %s", repr(key))
return conf
@ -326,7 +323,7 @@ def convert_to_hostname(url):
def decode_auth(auth):
if isinstance(auth, string_types):
if isinstance(auth, str):
auth = auth.encode('ascii')
s = base64.b64decode(auth)
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import json
import os
from ansible_collections.community.docker.plugins.module_utils._six import raise_from
from .. import errors
from .config import (
@ -148,9 +145,9 @@ class ContextAPI(object):
raise ValueError('"default" is a reserved context name')
names.append(name)
except Exception as e:
raise_from(errors.ContextException(
raise errors.ContextException(
"Failed to load metafile {filepath}: {e}".format(filepath=filepath, e=e),
), e)
) from e
contexts = [cls.get_default_context()]
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import hashlib
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import json
import os
from shutil import copyfile, rmtree
from ansible_collections.community.docker.plugins.module_utils._six import raise_from
from ..errors import ContextException
from ..tls import TLSConfig
@ -120,9 +117,9 @@ class Context(object):
metadata = json.load(f)
except (OSError, KeyError, ValueError) as e:
# unknown format
raise_from(Exception(
raise Exception(
"Detected corrupted meta file for context {name} : {e}".format(name=name, e=e)
), e)
) from e
# for docker endpoints, set defaults for
# 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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
PROGRAM_PREFIX = 'docker-credential-'
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import errno
import json
import subprocess
from ansible_collections.community.docker.plugins.module_utils._six import PY3, binary_type
from . import constants
from . import errors
from .utils import create_environment_dict
@ -42,7 +39,7 @@ class Store(object):
""" Retrieve credentials for `server`. If no credentials are found,
a `StoreError` will be raised.
"""
if not isinstance(server, binary_type):
if not isinstance(server, bytes):
server = server.encode('utf-8')
data = self._execute('get', server)
result = json.loads(data.decode('utf-8'))
@ -73,7 +70,7 @@ class Store(object):
""" Erase credentials for `server`. Raises a `StoreError` if an error
occurs.
"""
if not isinstance(server, binary_type):
if not isinstance(server, bytes):
server = server.encode('utf-8')
self._execute('erase', server)
@ -87,20 +84,9 @@ class Store(object):
output = None
env = create_environment_dict(self.environment)
try:
if PY3:
output = subprocess.check_output(
[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
)
output = subprocess.check_output(
[self.exe, subcmd], input=data_input, env=env,
)
except subprocess.CalledProcessError as e:
raise errors.process_store_error(e, self.program)
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import os
import sys
from ansible_collections.community.docker.plugins.module_utils._six import PY2
if PY2:
from distutils.spawn import find_executable as which
else:
from shutil import which
from shutil import which
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
every extension declared in PATHEXT instead of just `.exe`
"""
if not PY2:
# shutil.which() already uses PATHEXT on Windows, so on
# Python 3 we can simply use shutil.which() in all cases.
# (https://github.com/docker/docker-py/commit/42789818bed5d86b487a030e2e60b02bf0cfa284)
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
# shutil.which() already uses PATHEXT on Windows, so on
# Python 3 we can simply use shutil.which() in all cases.
# (https://github.com/docker/docker-py/commit/42789818bed5d86b487a030e2e60b02bf0cfa284)
return which(executable, path=path)
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
from ._import_helper import HTTPError as _HTTPError
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):
@ -43,7 +41,7 @@ def create_api_error_from_http_exception(e):
cls = ImageNotFound
else:
cls = NotFound
raise_from(cls(e, response=response, explanation=explanation), e)
raise cls(e, response=response, explanation=explanation) from e
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import os
import ssl
import sys
from . import errors
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 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:
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
from ansible_collections.community.docker.plugins.module_utils._six import Empty
from queue import Empty
from .. import constants
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import functools
import io
import time
import traceback
from ansible_collections.community.docker.plugins.module_utils._six import PY2
PYWIN32_IMPORT_ERROR = None
try:
import win32file
@ -152,9 +149,6 @@ class NpipeSocket(object):
@check_closed
def recv_into(self, buf, nbytes=0):
if PY2:
return self._recv_into_py2(buf, nbytes)
readbuf = buf
if not isinstance(buf, memoryview):
readbuf = memoryview(buf)
@ -176,12 +170,6 @@ class NpipeSocket(object):
finally:
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
def send(self, string, flags=0):
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import logging
import os
@ -16,8 +15,8 @@ import signal
import socket
import subprocess
import traceback
from ansible_collections.community.docker.plugins.module_utils._six import PY3, Empty, urlparse
from queue import Empty
from urllib.parse import urlparse
from .basehttpadapter import BaseHTTPAdapter
from .. import constants
@ -100,8 +99,7 @@ class SSHSocket(socket.socket):
def makefile(self, mode):
if not self.proc:
self.connect()
if PY3:
self.proc.stdout.channel = self
self.proc.stdout.channel = self
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
""" Resolves OpenSSL issues in some servers:
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import socket
from ansible_collections.community.docker.plugins.module_utils._six import PY2
from .basehttpadapter import BaseHTTPAdapter
from .. import constants
@ -46,12 +43,9 @@ class UnixHTTPConnection(urllib3_connection.HTTPConnection, object):
self.disable_buffering = True
def response_class(self, sock, *args, **kwargs):
if PY2:
# FIXME: We may need to disable buffering on Py3 as well,
# but there's no clear way to do it at the moment. See:
# https://github.com/docker/docker-py/issues/1799
kwargs['buffering'] = not self.disable_buffering
# FIXME: We may need to disable buffering on Py3,
# but there's no clear way to do it at the moment. See:
# https://github.com/docker/docker-py/issues/1799
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import io
import os
@ -17,8 +16,6 @@ import re
import tarfile
import tempfile
from ansible_collections.community.docker.plugins.module_utils._six import PY3
from . import fnmatch
from ..constants import IS_WINDOWS_PLATFORM, WINDOWS_LONGPATH_PREFIX
@ -131,13 +128,7 @@ def mkbuildcontext(dockerfile):
f = tempfile.NamedTemporaryFile()
t = tarfile.open(mode='w', fileobj=f)
if isinstance(dockerfile, io.StringIO):
dfinfo = tarfile.TarInfo('Dockerfile')
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)
raise TypeError('Please use io.BytesIO to create in-memory Dockerfiles')
elif isinstance(dockerfile, io.BytesIO):
dfinfo = tarfile.TarInfo('Dockerfile')
dfinfo.size = len(dockerfile.getvalue())
@ -225,8 +216,7 @@ class PatternMatcher(object):
break
if skip:
continue
for sub in rec_walk(cur):
yield sub
yield from rec_walk(cur)
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import json
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
"""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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import json
import json.decoder
from ansible_collections.community.docker.plugins.module_utils._six import text_type
from ..errors import StreamParseError
@ -29,7 +26,7 @@ def stream_as_text(stream):
instead of byte streams.
"""
for data in stream:
if not isinstance(data, text_type):
if not isinstance(data, str):
data = data.decode('utf-8', 'replace')
yield data
@ -56,7 +53,7 @@ def json_stream(stream):
def line_splitter(buffer, separator=u'\n'):
index = buffer.find(text_type(separator))
index = buffer.find(str(separator))
if index == -1:
return None
return buffer[:index + 1], buffer[index + 1:]
@ -70,7 +67,7 @@ def split_buffer(stream, splitter=None, decoder=lambda a: a):
of the input.
"""
splitter = splitter or line_splitter
buffered = text_type('')
buffered = ''
for data in stream_as_text(stream):
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import errno
import os
@ -16,8 +15,6 @@ import select
import socket as pysocket
import struct
from ansible_collections.community.docker.plugins.module_utils._six import PY3, binary_type
from ..transport.npipesocket import NpipeSocket
@ -41,7 +38,7 @@ def read(socket, n=4096):
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"):
# Limited to 1024
select.select([socket], [], [])
@ -53,7 +50,7 @@ def read(socket, n=4096):
try:
if hasattr(socket, 'recv'):
return socket.recv(n)
if PY3 and isinstance(socket, getattr(pysocket, 'SocketIO')):
if isinstance(socket, getattr(pysocket, 'SocketIO')):
return socket.read(n)
return os.read(socket.fileno(), n)
except EnvironmentError as e:
@ -75,7 +72,7 @@ def read_exactly(socket, n):
Reads exactly n bytes from socket
Raises SocketError if there is not enough data
"""
data = binary_type()
data = b''
while len(data) < n:
next_data = read(socket, n - len(data))
if not next_data:
@ -163,7 +160,7 @@ def consume_socket_output(frames, demux=False):
if demux is False:
# If the streams are multiplexed, the generator returns strings, that
# we just need to concatenate.
return binary_type().join(frames)
return b''.join(frames)
# If the streams are demultiplexed, the generator yields tuples
# (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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import base64
import collections
@ -19,8 +18,6 @@ import shlex
import string
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 ..constants import DEFAULT_HTTP_HOST
from ..constants import DEFAULT_UNIX_SOCKET
@ -28,10 +25,7 @@ from ..constants import DEFAULT_NPIPE
from ..constants import BYTE_UNITS
from ..tls import TLSConfig
if PY2:
from urlparse import urlparse, urlunparse
else:
from urllib.parse import urlparse, urlunparse
from urllib.parse import urlparse, urlunparse
URLComponents = collections.namedtuple(
@ -55,9 +49,7 @@ def create_ipam_config(*args, **kwargs):
def decode_json_header(header):
data = base64.b64decode(header)
if PY3:
data = data.decode('utf-8')
data = base64.b64decode(header).decode('utf-8')
return json.loads(data)
@ -97,7 +89,7 @@ def _convert_port_binding(binding):
if len(binding) == 2:
result['HostPort'] = binding[1]
result['HostIp'] = binding[0]
elif isinstance(binding[0], string_types):
elif isinstance(binding[0], str):
result['HostIp'] = binding[0]
else:
result['HostPort'] = binding[0]
@ -121,7 +113,7 @@ def _convert_port_binding(binding):
def convert_port_bindings(port_bindings):
result = {}
for k, v in iteritems(port_bindings):
for k, v in port_bindings.items():
key = str(k)
if '/' not in key:
key += '/tcp'
@ -138,7 +130,7 @@ def convert_volume_binds(binds):
result = []
for k, v in binds.items():
if isinstance(k, binary_type):
if isinstance(k, bytes):
k = k.decode('utf-8')
if isinstance(v, dict):
@ -149,7 +141,7 @@ def convert_volume_binds(binds):
)
bind = v['bind']
if isinstance(bind, binary_type):
if isinstance(bind, bytes):
bind = bind.decode('utf-8')
if 'ro' in v:
@ -175,15 +167,11 @@ def convert_volume_binds(binds):
else:
mode = v['propagation']
result.append(
text_type('{0}:{1}:{2}').format(k, bind, mode)
)
result.append('{0}:{1}:{2}'.format(k, bind, mode))
else:
if isinstance(v, binary_type):
if isinstance(v, bytes):
v = v.decode('utf-8')
result.append(
text_type('{0}:{1}:rw').format(k, v)
)
result.append('{0}:{1}:rw'.format(k, v))
return result
@ -199,7 +187,7 @@ def convert_tmpfs_mounts(tmpfs):
result = {}
for mount in tmpfs:
if isinstance(mount, string_types):
if isinstance(mount, str):
if ":" in mount:
name, options = mount.split(":", 1)
else:
@ -224,7 +212,7 @@ def convert_service_networks(networks):
result = []
for n in networks:
if isinstance(n, string_types):
if isinstance(n, str):
n = {'Target': n}
result.append(n)
return result
@ -333,7 +321,7 @@ def parse_devices(devices):
if isinstance(device, dict):
device_list.append(device)
continue
if not isinstance(device, string_types):
if not isinstance(device, str):
raise errors.DockerException(
'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):
result = {}
for k, v in iteritems(filters):
for k, v in filters.items():
if isinstance(v, bool):
v = 'true' if v else 'false'
if not isinstance(v, list):
v = [v, ]
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
]
return json.dumps(result)
def parse_bytes(s):
if isinstance(s, integer_types + (float,)):
if isinstance(s, (int, float)):
return s
if len(s) == 0:
return 0
@ -458,7 +446,7 @@ def parse_bytes(s):
def normalize_links(links):
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)]
@ -493,8 +481,6 @@ def parse_env_file(env_file):
def split_command(command):
if PY2 and not isinstance(command, binary_type):
command = command.encode('utf-8')
return shlex.split(command)
@ -502,22 +488,22 @@ def format_environment(environment):
def format_env(key, value):
if value is None:
return key
if isinstance(value, binary_type):
if isinstance(value, bytes):
value = value.decode('utf-8')
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):
# Use format dictated by Swarm API if container is part of a task
if task:
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 [
'{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.
"""
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
# 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)
# SPDX-License-Identifier: Apache-2.0
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import base64
import random
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():
@ -17,10 +15,7 @@ def generate_insecure_key():
while True:
# Generate a one-byte key. Right now the functions below do not use more
# than one byte, so this is sufficient.
if PY2:
key = chr(random.randint(0, 255))
else:
key = bytes([random.randint(0, 255)])
key = bytes([random.randint(0, 255)])
# Return anything that is not zero
if key != b'\x00':
return key
@ -31,12 +26,8 @@ def scramble(value, key):
if len(key) < 1:
raise ValueError('Key must be at least one byte')
value = to_bytes(value)
if PY2:
k = ord(key[0])
value = b''.join([chr(k ^ ord(b)) for b in value])
else:
k = key[0]
value = bytes([k ^ b for b in value])
k = key[0]
value = bytes([k ^ b for b in value])
return '=S=' + to_native(base64.b64encode(value))
@ -47,10 +38,6 @@ def unscramble(value, key):
if not value.startswith(u'=S='):
raise ValueError('Value does not start with indicator')
value = base64.b64decode(value[3:])
if PY2:
k = ord(key[0])
value = b''.join([chr(k ^ ord(b)) for b in value])
else:
k = key[0]
value = bytes([k ^ b for b in value])
k = key[0]
value = bytes([k ^ b for b in 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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import abc
@ -12,9 +11,9 @@ import platform
import re
import sys
import traceback
from collections.abc import Mapping, Sequence
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_collections.community.docker.plugins.module_utils.version import LooseVersion
@ -209,10 +208,8 @@ class AnsibleDockerClientBase(Client):
"state." % (platform.node(), sys.executable))
if not HAS_DOCKER_PY:
msg = missing_required_lib("Docker SDK for Python: docker>=5.0.0 (Python >= 3.6) or "
"docker<5.0.0 (Python 2.7)")
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"
msg = missing_required_lib("Docker SDK for Python: docker>=5.0.0")
msg = msg + ", for example via `pip install docker`. The error was: %s"
self.fail(msg % HAS_DOCKER_ERROR, exception=HAS_DOCKER_TRACEBACK)
if self.docker_py_version < LooseVersion(min_docker_version):
@ -695,5 +692,5 @@ class AnsibleDockerClient(AnsibleDockerClientBase):
if isinstance(result, Sequence):
for warning in result:
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))

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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import abc
import os
import re
from collections.abc import Mapping, Sequence
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_collections.community.docker.plugins.module_utils.version import LooseVersion
@ -579,5 +578,5 @@ class AnsibleDockerClient(AnsibleDockerClientBase):
if isinstance(result, Sequence):
for warning in result:
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))

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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import abc
@ -13,7 +12,6 @@ import shlex
from ansible.module_utils.basic import AnsibleModule, env_fallback
from ansible.module_utils.common.process import get_bin_path
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
@ -86,7 +84,7 @@ class AnsibleDockerClientBase(object):
self._info = None
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.docker_api_version_str = to_native(self._version['Server']['ApiVersion'])
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))
@abc.abstractmethod
# 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...
def call_cli(self, *args, check_rc=False, data=None, cwd=None, environ_update=None):
pass
# 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,
)
# 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])
def call_cli(self, *args, check_rc=False, data=None, cwd=None, environ_update=None):
environment = self._environment.copy()
if 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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import json
@ -14,10 +13,10 @@ import shutil
import tempfile
import traceback
from collections import namedtuple
from shlex import quote
from ansible.module_utils.basic import missing_required_lib
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.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:
resource_type = ResourceType.IMAGE_LAYER
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)
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']]
@ -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))
result['failed'] = True
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['stderr'] = to_native(stderr)
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import base64
import datetime
@ -16,7 +15,6 @@ import stat
import tarfile
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
@ -126,12 +124,7 @@ def _regular_content_tar_generator(content, out_file, user_id, group_id, mode, u
tarinfo.uid = user_id
tarinfo.gid = group_id
tarinfo.size = len(content)
try:
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.mtime = int(datetime.datetime.now().timestamp())
tarinfo.type = tarfile.REGTYPE
tarinfo.linkname = ''
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):
os.unlink(b_out_path)
in_f = tar.extractfile(member) # in Python 2, this *cannot* be used in `with`...
with open(b_out_path, 'wb') as out_f:
shutil.copyfileobj(in_f, out_f)
with tar.extractfile(member) as in_f:
with open(b_out_path, 'wb') as out_f:
shutil.copyfileobj(in_f, out_f)
return in_path
def process_symlink(in_path, member):
@ -385,16 +378,10 @@ def _execute_command(client, container, command, log=None, check_rc=False):
try:
exec_data = client.post_json_to_json('/containers/{0}/exec', container, data=data)
except NotFound as e:
raise_from(
DockerFileCopyError('Could not find container "{container}"'.format(container=container)),
e,
)
raise DockerFileCopyError('Could not find container "{container}"'.format(container=container)) from e
except APIError as e:
if e.response is not None and e.response.status_code == 409:
raise_from(
DockerFileCopyError('Cannot execute command in paused container "{container}"'.format(container=container)),
e,
)
raise DockerFileCopyError('Cannot execute command in paused container "{container}"'.format(container=container)) from e
raise
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import json
import os
@ -31,18 +30,7 @@ class ImageArchiveManifestSummary(object):
class ImageArchiveInvalidException(Exception):
def __init__(self, message, cause):
'''
: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
pass
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):
return None
tf = tarfile.open(archive_path, 'r')
try:
with tarfile.open(archive_path, 'r') as tf:
try:
ef = tf.extractfile('manifest.json')
try:
text = ef.read().decode('utf-8')
manifest = json.loads(text)
with tf.extractfile('manifest.json') as ef:
manifest = json.load(ef)
except Exception as exc:
raise ImageArchiveInvalidException(
"Failed to decode and deserialize manifest.json: %s" % to_native(exc),
exc
)
finally:
# In Python 2.6, this does not have __exit__
ef.close()
"Failed to decode and deserialize manifest.json: %s" % to_native(exc)
) from exc
if len(manifest) == 0:
raise ImageArchiveInvalidException(
"Expected to have at least one entry in manifest.json but found none",
None
"Expected to have at least one entry in manifest.json but found none"
)
result = []
@ -112,9 +93,8 @@ def load_archived_image_manifest(archive_path):
config_file = meta['Config']
except KeyError as exc:
raise ImageArchiveInvalidException(
"Failed to get Config entry from {0}th manifest in manifest.json: {1}".format(index + 1, to_native(exc)),
exc
)
"Failed to get Config entry from {0}th manifest in manifest.json: {1}".format(index + 1, to_native(exc))
) from exc
# Extracts hash without 'sha256:' prefix
try:
@ -122,9 +102,8 @@ def load_archived_image_manifest(archive_path):
image_id = os.path.splitext(config_file)[0]
except Exception as exc:
raise ImageArchiveInvalidException(
"Failed to extract image id from config file name %s: %s" % (config_file, to_native(exc)),
exc
)
"Failed to extract image id from config file name %s: %s" % (config_file, to_native(exc))
) from exc
for prefix in (
'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']
except KeyError as exc:
raise ImageArchiveInvalidException(
"Failed to get RepoTags entry from {0}th manifest in manifest.json: {1}".format(index + 1, to_native(exc)),
exc
)
"Failed to get RepoTags entry from {0}th manifest in manifest.json: {1}".format(index + 1, to_native(exc))
) from exc
result.append(ImageArchiveManifestSummary(
image_id=image_id,
@ -150,18 +128,13 @@ def load_archived_image_manifest(archive_path):
raise
except Exception as exc:
raise ImageArchiveInvalidException(
"Failed to extract manifest.json from tar file %s: %s" % (archive_path, to_native(exc)),
exc
)
finally:
# In Python 2.6, TarFile does not have __exit__
tf.close()
"Failed to extract manifest.json from tar file %s: %s" % (archive_path, to_native(exc))
) from exc
except ImageArchiveInvalidException:
raise
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):
@ -189,6 +162,5 @@ def archived_image_manifest(archive_path):
if len(results) == 1:
return results[0]
raise ImageArchiveInvalidException(
"Expected to have one entry in manifest.json but found %s" % len(results),
None
"Expected to have one entry in manifest.json but found %s" % len(results)
)

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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
import abc
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.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 (
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')
if 'env' in values:
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 '
'wrapped in quotes to avoid them being interpreted. Key: %s' % (name, ))
final_env[name] = to_text(value, errors='surrogate_or_strict')
@ -695,7 +693,7 @@ def _preprocess_log(module, values):
if 'log_options' in values:
options = {}
for k, v in values['log_options'].items():
if not isinstance(v, string_types):
if not isinstance(v, str):
module.warn(
"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." % (
@ -780,7 +778,7 @@ def _preprocess_ports(module, values):
# Any published port should also be exposed
for publish_port in values['published_ports']:
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 = int(port)
else:
@ -789,7 +787,7 @@ def _preprocess_ports(module, values):
for exposed_port in exposed:
if exposed_port[1] != protocol:
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('-')
if int(start_port) <= port <= int(end_port):
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
import json
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
import re
from time import sleep

View File

@ -6,16 +6,7 @@
"""Provide selectors import."""
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
# Once we drop support for ansible-core 2.16, we can remove the try/except.
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
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import os
@ -11,8 +10,6 @@ import os.path
import socket as pysocket
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.socket_helper import (
@ -85,7 +82,7 @@ class DockerSocketHandlerBase(object):
return
else:
raise
elif not PY2 and isinstance(self._sock, getattr(pysocket, 'SocketIO')):
elif isinstance(self._sock, getattr(pysocket, 'SocketIO')):
data = self._sock.read()
else:
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import fcntl
@ -11,8 +10,6 @@ import os
import os.path
import socket as pysocket
from ansible_collections.community.docker.plugins.module_utils._six import PY2
def make_file_unblocking(file):
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"
log('Shutting down for writing not possible; trying shutdown instead: {0}'.format(e))
sock.shutdown()
elif not PY2 and isinstance(sock, getattr(pysocket, 'SocketIO')):
elif isinstance(sock, getattr(pysocket, 'SocketIO')):
sock._sock.shutdown(pysocket.SHUT_WR)
else:
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import json
import re
from datetime import timedelta
from urllib.parse import urlparse
from ansible.module_utils.basic import env_fallback
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
@ -289,7 +288,7 @@ def sanitize_labels(labels, labels_field, client=None, module=None):
if labels is None:
return
for k, v in list(labels.items()):
if not isinstance(k, string_types):
if not isinstance(k, str):
fail(
"The key {key!r} of {field} is not a string!".format(
field=labels_field, key=k))

View File

@ -6,8 +6,7 @@
"""Provide version object to compare version numbers."""
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
DOCUMENTATION = r"""
@ -441,7 +440,6 @@ import traceback
from ansible.module_utils.common.validation import check_type_int
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 (
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, ))
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))
try:
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
DOCUMENTATION = r"""
@ -169,7 +168,6 @@ import shlex
import traceback
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 (
AnsibleModuleDockerClient,
@ -210,7 +208,7 @@ class ExecManager(BaseComposeManager):
if self.env is not None:
for name, value in list(self.env.items()):
if not isinstance(value, string_types):
if not isinstance(value, str):
self.fail(
"Non-string value found for env option. Ambiguous env options must be "
"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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
DOCUMENTATION = r"""
@ -242,7 +241,6 @@ import shlex
import traceback
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 (
AnsibleModuleDockerClient,
@ -296,7 +294,7 @@ class ExecManager(BaseComposeManager):
if self.env is not None:
for name, value in list(self.env.items()):
if not isinstance(value, string_types):
if not isinstance(value, str):
self.fail(
"Non-string value found for env option. Ambiguous env options must be "
"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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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.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
@ -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
return
tar_f = tar.extractfile(member) # in Python 2, this *cannot* be used in `with`...
content = tar_f.read()
with tar.extractfile(member) as tar_f:
content = tar_f.read()
if is_binary(content):
diff['dst_binary'] = 1
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)
return container_path, mode, False
tar_f = tar.extractfile(member) # in Python 2, this *cannot* be used in `with`...
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)
with tar.extractfile(member) as tar_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)
return container_path, mode, is_equal
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)
return container_path, mode, False
tar_f = tar.extractfile(member) # in Python 2, this *cannot* be used in `with`...
is_equal = are_fileobjs_equal_with_diff_of_first(tar_f, io.BytesIO(content), member.size, diff, max_file_size_for_diff, in_path)
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)
return container_path, mode, is_equal
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):
if isinstance(mode, string_types):
if isinstance(mode, str):
return int(to_native(mode), 8)
if isinstance(mode, integer_types):
if isinstance(mode, int):
return mode
raise TypeError('must be an octal string or an integer, got {mode!r}'.format(mode=mode))
def parse_octal_string_only(mode):
if isinstance(mode, string_types):
if isinstance(mode, str):
return int(to_native(mode), 8)
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
DOCUMENTATION = r"""
@ -164,19 +163,17 @@ exec_id:
version_added: 2.1.0
"""
import selectors
import shlex
import traceback
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 (
AnsibleDockerClient,
RequestException,
)
from ansible_collections.community.docker.plugins.module_utils.selectors import selectors
from ansible_collections.community.docker.plugins.module_utils.socket_handler import (
DockerSocketHandlerModule,
)
@ -228,7 +225,7 @@ def main():
if env is not None:
for name, value in list(env.items()):
if not isinstance(value, string_types):
if not isinstance(value, str):
client.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, ))

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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
DOCUMENTATION = r"""
@ -177,7 +176,6 @@ import traceback
from ansible.module_utils.basic import AnsibleModule
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 (
ContextAPI,
@ -214,7 +212,7 @@ def context_to_json(context, current):
module_config = {}
if 'docker' in context.endpoints:
endpoint = context.endpoints['docker']
if isinstance(endpoint.get('Host'), string_types):
if isinstance(endpoint.get('Host'), str):
host_str = to_text(endpoint['Host'])
# 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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
DOCUMENTATION = r"""
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
DOCUMENTATION = r"""
@ -161,7 +160,6 @@ import os
import tempfile
import traceback
from ansible_collections.community.docker.plugins.module_utils._six import string_types
from time import sleep
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:
compose_files.append(compose_file)
stack_file.write(yaml_dump(compose_def))
elif isinstance(compose_def, string_types):
elif isinstance(compose_def, str):
compose_files.append(compose_def)
else:
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
DOCUMENTATION = r"""
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
DOCUMENTATION = r"""
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
DOCUMENTATION = r"""
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
DOCUMENTATION = r"""
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)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from __future__ import annotations
DOCUMENTATION = r"""
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_collections.community.docker.plugins.module_utils._six import string_types
from ansible.module_utils.common.text.converters import to_text, to_native
try:
@ -904,11 +902,11 @@ def get_docker_environment(env, env_files):
parsed_env_file = parse_env_file(env_file)
for name, value in parsed_env_file.items():
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(',')
if env is not None and isinstance(env, dict):
for name, value in env.items():
if not isinstance(value, string_types):
if not isinstance(value, str):
raise ValueError(
'Non-string value found for env option. '
'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
parsed_networks = []
for network in networks:
if isinstance(network, string_types):
if isinstance(network, str):
parsed_network = {'name': network}
elif isinstance(network, dict):
if 'name' not in network:
@ -957,7 +955,7 @@ def get_docker_networks(networks, network_ids):
if not isinstance(aliases, list):
raise TypeError('"aliases" network option is only allowed as a list')
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.')
parsed_network['aliases'] = aliases
@ -991,7 +989,7 @@ def get_nanoseconds_from_raw_option(name, value):
return None
elif isinstance(value, int):
return value
elif isinstance(value, string_types):
elif isinstance(value, str):
try:
return int(value)
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:
is_same_type = type(new_item) == type(old_item) # noqa: E721, pylint: disable=unidiomatic-typecheck
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,
# they are both strings. Try matching on the same string type.
try:
@ -1474,13 +1472,13 @@ class DockerService(DockerBaseClass):
s.networks = get_docker_networks(ap['networks'], network_ids)
s.command = ap['command']
if isinstance(s.command, string_types):
if isinstance(s.command, str):
s.command = shlex.split(s.command)
elif isinstance(s.command, list):
invalid_items = [
(index, item)
for index, item in enumerate(s.command)
if not isinstance(item, string_types)
if not isinstance(item, str)
]
if invalid_items:
errors = ', '.join(

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