mirror of
https://github.com/ansible-collections/community.docker.git
synced 2025-12-15 11:32:05 +00:00
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:
parent
b9cf9015c4
commit
1f2817fa20
@ -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.
|
|
||||||
@ -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/).
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
5
changelogs/fragments/5.0.0.yml
Normal file
5
changelogs/fragments/5.0.0.yml
Normal 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).
|
||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
@ -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()
|
||||||
|
|
||||||
|
|||||||
@ -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):
|
||||||
|
|||||||
@ -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):
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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)
|
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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'
|
||||||
|
|||||||
@ -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):
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
@ -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):
|
||||||
|
|||||||
@ -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):
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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/
|
||||||
|
|||||||
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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)
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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.
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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())
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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
|
|
||||||
@ -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))
|
||||||
|
|||||||
@ -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))
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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']
|
||||||
|
|
||||||
|
|||||||
@ -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
|
|
||||||
)
|
)
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
|
||||||
|
|||||||
@ -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())
|
||||||
|
|||||||
@ -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')
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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))
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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, )
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
@ -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, )
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
@ -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))
|
||||||
|
|
||||||
|
|||||||
@ -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, ))
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
Loading…
Reference in New Issue
Block a user