Python code modernization, 4/n (#1162)

* Address attribute-defined-outside-init.

* Address broad-exception-raised.

* Address broad-exception-caught.

* Address consider-iterating-dictionary.

* Address consider-using-dict-comprehension.

* Address consider-using-f-string.

* Address consider-using-in.

* Address consider-using-max-builtin.

* Address some consider-using-with.

* Address invalid-name.

* Address keyword-arg-before-vararg.

* Address line-too-long.

* Address no-else-continue.

* Address no-else-raise.

* Address no-else-return.

* Remove broken dead code.

* Make consider-using-f-string changes compatible with older Python versions.

* Python 3.11 and earlier apparently do not like multi-line f-strings.
This commit is contained in:
Felix Fontein 2025-10-11 23:06:50 +02:00 committed by GitHub
parent 33c8a49191
commit cad22de628
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
59 changed files with 556 additions and 630 deletions

View File

@ -381,23 +381,9 @@ disable=raw-checker-failed,
# To clean up: # To clean up:
abstract-method, abstract-method,
arguments-differ, arguments-differ,
attribute-defined-outside-init,
broad-exception-caught,
broad-exception-raised,
consider-iterating-dictionary,
consider-using-dict-comprehension,
consider-using-f-string,
consider-using-in,
consider-using-max-builtin,
consider-using-with, consider-using-with,
fixme, fixme,
import-error, # TODO figure out why pylint cannot find the module import-error, # TODO figure out why pylint cannot find the module
invalid-name,
keyword-arg-before-vararg,
line-too-long,
no-else-continue,
no-else-raise,
no-else-return,
no-member, no-member,
no-name-in-module, # TODO figure out why pylint cannot find the module no-name-in-module, # TODO figure out why pylint cannot find the module
not-an-iterable, # TODO: needs better typing info not-an-iterable, # TODO: needs better typing info

View File

@ -155,6 +155,8 @@ class Connection(ConnectionBase):
self._docker_args = [] self._docker_args = []
self._container_user_cache = {} self._container_user_cache = {}
self._version = None self._version = None
self.remote_user = None
self.timeout = None
# Windows uses Powershell modules # Windows uses Powershell modules
if getattr(self._shell, "_IS_WINDOWS", False): if getattr(self._shell, "_IS_WINDOWS", False):
@ -180,9 +182,9 @@ class Connection(ConnectionBase):
old_version_subcommand = ["version"] old_version_subcommand = ["version"]
old_docker_cmd = [self.docker_cmd] + cmd_args + old_version_subcommand old_docker_cmd = [self.docker_cmd] + cmd_args + old_version_subcommand
p = subprocess.Popen( with subprocess.Popen(
old_docker_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE old_docker_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE
) ) as p:
cmd_output, err = p.communicate() cmd_output, err = p.communicate()
return old_docker_cmd, to_native(cmd_output), err, p.returncode return old_docker_cmd, to_native(cmd_output), err, p.returncode
@ -194,9 +196,9 @@ class Connection(ConnectionBase):
new_version_subcommand = ["version", "--format", "'{{.Server.Version}}'"] new_version_subcommand = ["version", "--format", "'{{.Server.Version}}'"]
new_docker_cmd = [self.docker_cmd] + cmd_args + new_version_subcommand new_docker_cmd = [self.docker_cmd] + cmd_args + new_version_subcommand
p = subprocess.Popen( with subprocess.Popen(
new_docker_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE new_docker_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE
) ) as p:
cmd_output, err = p.communicate() cmd_output, err = p.communicate()
return new_docker_cmd, to_native(cmd_output), err, p.returncode return new_docker_cmd, to_native(cmd_output), err, p.returncode
@ -221,12 +223,11 @@ class Connection(ConnectionBase):
container = self.get_option("remote_addr") container = self.get_option("remote_addr")
if container in self._container_user_cache: if container in self._container_user_cache:
return self._container_user_cache[container] return self._container_user_cache[container]
p = subprocess.Popen( with subprocess.Popen(
[self.docker_cmd, "inspect", "--format", "{{.Config.User}}", container], [self.docker_cmd, "inspect", "--format", "{{.Config.User}}", container],
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, stderr=subprocess.PIPE,
) ) as p:
out, err = p.communicate() out, err = p.communicate()
out = to_text(out, errors="surrogate_or_strict") out = to_text(out, errors="surrogate_or_strict")
@ -348,7 +349,6 @@ class Connection(ConnectionBase):
) >= LooseVersion("1.7"): ) >= LooseVersion("1.7"):
# Support for specifying the exec user was added in docker 1.7 # Support for specifying the exec user was added in docker 1.7
return self.remote_user return self.remote_user
else:
self.remote_user = None self.remote_user = None
actual_user = self._get_docker_remote_user() actual_user = self._get_docker_remote_user()
if actual_user != self.get_option("remote_user"): if actual_user != self.get_option("remote_user"):
@ -356,12 +356,11 @@ class Connection(ConnectionBase):
f'docker {self.docker_version} does not support remote_user, using container default: {actual_user or "?"}' f'docker {self.docker_version} does not support remote_user, using container default: {actual_user or "?"}'
) )
return actual_user return actual_user
elif self._display.verbosity > 2: if self._display.verbosity > 2:
# Since we are not setting the actual_user, look it up so we have it for logging later # Since we are not setting the actual_user, look it up so we have it for logging later
# Only do this if display verbosity is high enough that we'll need the value # Only do this if display verbosity is high enough that we'll need the value
# This saves overhead from calling into docker when we do not need to. # This saves overhead from calling into docker when we do not need to.
return self._get_docker_remote_user() return self._get_docker_remote_user()
else:
return None return None
def _connect(self, port=None): def _connect(self, port=None):
@ -390,12 +389,12 @@ class Connection(ConnectionBase):
local_cmd = [to_bytes(i, errors="surrogate_or_strict") for i in local_cmd] local_cmd = [to_bytes(i, errors="surrogate_or_strict") for i in local_cmd]
p = subprocess.Popen( with subprocess.Popen(
local_cmd, local_cmd,
stdin=subprocess.PIPE, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, stderr=subprocess.PIPE,
) ) as p:
display.debug("done running command with Popen()") display.debug("done running command with Popen()")
if self.become and self.become.expect_prompt() and sudoable: if self.become and self.become.expect_prompt() and sudoable:
@ -486,7 +485,6 @@ class Connection(ConnectionBase):
import ntpath import ntpath
return ntpath.normpath(remote_path) return ntpath.normpath(remote_path)
else:
if not remote_path.startswith(os.path.sep): if not remote_path.startswith(os.path.sep):
remote_path = os.path.join(os.path.sep, remote_path) remote_path = os.path.join(os.path.sep, remote_path)
return os.path.normpath(remote_path) return os.path.normpath(remote_path)
@ -557,9 +555,9 @@ class Connection(ConnectionBase):
] ]
args = [to_bytes(i, errors="surrogate_or_strict") for i in args] args = [to_bytes(i, errors="surrogate_or_strict") for i in args]
p = subprocess.Popen( with subprocess.Popen(
args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE
) ) as p:
p.communicate() p.communicate()
if getattr(self._shell, "_IS_WINDOWS", False): if getattr(self._shell, "_IS_WINDOWS", False):
@ -573,14 +571,18 @@ class Connection(ConnectionBase):
# Older docker does not have native support for fetching files command `cp` # Older docker does not have native support for fetching files command `cp`
# If `cp` fails, try to use `dd` instead # If `cp` fails, try to use `dd` instead
args = self._build_exec_cmd( args = self._build_exec_cmd(
[self._play_context.executable, "-c", f"dd if={in_path} bs={BUFSIZE}"] [
self._play_context.executable,
"-c",
f"dd if={in_path} bs={BUFSIZE}",
]
) )
args = [to_bytes(i, errors="surrogate_or_strict") for i in args] args = [to_bytes(i, errors="surrogate_or_strict") for i in args]
with open( with open(
to_bytes(actual_out_path, errors="surrogate_or_strict"), "wb" to_bytes(actual_out_path, errors="surrogate_or_strict"), "wb"
) as out_file: ) as out_file:
try: try:
p = subprocess.Popen( pp = subprocess.Popen(
args, args,
stdin=subprocess.PIPE, stdin=subprocess.PIPE,
stdout=out_file, stdout=out_file,
@ -590,9 +592,9 @@ class Connection(ConnectionBase):
raise AnsibleError( raise AnsibleError(
"docker connection requires dd command in the container to put files" "docker connection requires dd command in the container to put files"
) )
stdout, stderr = p.communicate() stdout, stderr = pp.communicate()
if p.returncode != 0: if pp.returncode != 0:
raise AnsibleError( raise AnsibleError(
f"failed to fetch file {in_path} to {out_path}:\n{stdout}\n{stderr}" f"failed to fetch file {in_path} to {out_path}:\n{stdout}\n{stderr}"
) )

View File

@ -159,7 +159,6 @@ class Connection(ConnectionBase):
raise AnsibleConnectionFailure( raise AnsibleConnectionFailure(
f'Could not find container "{remote_addr}" or resource in it ({e})' f'Could not find container "{remote_addr}" or resource in it ({e})'
) )
else:
raise AnsibleConnectionFailure( raise AnsibleConnectionFailure(
f'Could not find container "{remote_addr}" ({e})' f'Could not find container "{remote_addr}" ({e})'
) )
@ -370,7 +369,6 @@ class Connection(ConnectionBase):
import ntpath import ntpath
return ntpath.normpath(remote_path) return ntpath.normpath(remote_path)
else:
if not remote_path.startswith(os.path.sep): if not remote_path.startswith(os.path.sep):
remote_path = os.path.join(os.path.sep, remote_path) remote_path = os.path.join(os.path.sep, remote_path)
return os.path.normpath(remote_path) return os.path.normpath(remote_path)

View File

@ -66,6 +66,7 @@ class Connection(ConnectionBase):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.cwd = None self.cwd = None
self._nsenter_pid = None
def _connect(self): def _connect(self):
self._nsenter_pid = self.get_option("nsenter_pid") self._nsenter_pid = self.get_option("nsenter_pid")
@ -133,7 +134,7 @@ class Connection(ConnectionBase):
except (IOError, OSError) as e: except (IOError, OSError) as e:
display.debug(f"Unable to open pty: {e}") display.debug(f"Unable to open pty: {e}")
p = subprocess.Popen( with subprocess.Popen(
cmd, cmd,
shell=isinstance(cmd, (str, bytes)), shell=isinstance(cmd, (str, bytes)),
executable=executable if isinstance(cmd, (str, bytes)) else None, executable=executable if isinstance(cmd, (str, bytes)) else None,
@ -141,8 +142,7 @@ class Connection(ConnectionBase):
stdin=stdin, stdin=stdin,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, stderr=subprocess.PIPE,
) ) as p:
# if we created a master, we can close the other half of the pty now, otherwise master is stdin # if we created a master, we can close the other half of the pty now, otherwise master is stdin
if master is not None: if master is not None:
os.close(stdin) os.close(stdin)

View File

@ -125,16 +125,16 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
NAME = "community.docker.docker_machine" NAME = "community.docker.docker_machine"
DOCKER_MACHINE_PATH = None docker_machine_path = None
def _run_command(self, args): def _run_command(self, args):
if not self.DOCKER_MACHINE_PATH: if not self.docker_machine_path:
try: try:
self.DOCKER_MACHINE_PATH = get_bin_path("docker-machine") self.docker_machine_path = get_bin_path("docker-machine")
except ValueError as e: except ValueError as e:
raise AnsibleError(to_native(e)) raise AnsibleError(to_native(e))
command = [self.DOCKER_MACHINE_PATH] command = [self.docker_machine_path]
command.extend(args) command.extend(args)
display.debug(f"Executing command {command}") display.debug(f"Executing command {command}")
try: try:
@ -217,11 +217,11 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
if daemon_env == "require": if daemon_env == "require":
display.warning(f"{warning_prefix}: host will be skipped") display.warning(f"{warning_prefix}: host will be skipped")
return True return True
else: # 'optional', 'optional-silently'
if daemon_env == "optional": if daemon_env == "optional":
display.warning( display.warning(
f"{warning_prefix}: host will lack dm_DOCKER_xxx variables" f"{warning_prefix}: host will lack dm_DOCKER_xxx variables"
) )
# daemon_env is 'optional-silently'
return False return False
def _populate(self): def _populate(self):

View File

@ -199,7 +199,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
) )
update_tls_hostname(raw_params) update_tls_hostname(raw_params)
connect_params = get_connect_params(raw_params, fail_function=self._fail) connect_params = get_connect_params(raw_params, fail_function=self._fail)
self.client = docker.DockerClient(**connect_params) client = docker.DockerClient(**connect_params)
self.inventory.add_group("all") self.inventory.add_group("all")
self.inventory.add_group("manager") self.inventory.add_group("manager")
self.inventory.add_group("worker") self.inventory.add_group("worker")
@ -217,9 +217,9 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
host_uri_port = "2375" host_uri_port = "2375"
try: try:
self.nodes = self.client.nodes.list() nodes = client.nodes.list()
for node in self.nodes: for node in nodes:
node_attrs = self.client.nodes.get(node.id).attrs node_attrs = client.nodes.get(node.id).attrs
unsafe_node_attrs = make_unsafe(node_attrs) unsafe_node_attrs = make_unsafe(node_attrs)
if not filter_host( if not filter_host(
self, unsafe_node_attrs["ID"], unsafe_node_attrs, filters self, unsafe_node_attrs["ID"], unsafe_node_attrs, filters

View File

@ -70,14 +70,16 @@ except ImportError:
self.connection = self self.connection = self
self.connectionpool = self self.connectionpool = self
self.RecentlyUsedContainer = object() self.RecentlyUsedContainer = object() # pylint: disable=invalid-name
self.PoolManager = object() self.PoolManager = object() # pylint: disable=invalid-name
self.match_hostname = object() self.match_hostname = object()
self.HTTPConnectionPool = _HTTPConnectionPool self.HTTPConnectionPool = ( # pylint: disable=invalid-name
_HTTPConnectionPool
)
class FakeURLLIB3Connection: class FakeURLLIB3Connection:
def __init__(self): def __init__(self):
self.HTTPConnection = _HTTPConnection self.HTTPConnection = _HTTPConnection # pylint: disable=invalid-name
urllib3 = FakeURLLIB3() urllib3 = FakeURLLIB3()
urllib3_connection = FakeURLLIB3Connection() urllib3_connection = FakeURLLIB3Connection()

View File

@ -47,7 +47,7 @@ from ..transport.sshconn import PARAMIKO_IMPORT_ERROR, SSHHTTPAdapter
from ..transport.ssladapter import SSLHTTPAdapter from ..transport.ssladapter import SSLHTTPAdapter
from ..transport.unixconn import UnixHTTPAdapter from ..transport.unixconn import UnixHTTPAdapter
from ..utils import config, json_stream, utils from ..utils import config, json_stream, utils
from ..utils.decorators import check_resource, update_headers from ..utils.decorators import update_headers
from ..utils.proxy import ProxyConfig from ..utils.proxy import ProxyConfig
from ..utils.socket import consume_socket_output, demux_adaptor, frames_iter from ..utils.socket import consume_socket_output, demux_adaptor, frames_iter
from .daemon import DaemonApiMixin from .daemon import DaemonApiMixin
@ -278,7 +278,6 @@ class APIClient(_Session, DaemonApiMixin):
if kwargs.get("versioned_api", True): if kwargs.get("versioned_api", True):
return f"{self.base_url}/v{self._version}{pathfmt.format(*args)}" return f"{self.base_url}/v{self._version}{pathfmt.format(*args)}"
else:
return f"{self.base_url}{pathfmt.format(*args)}" return f"{self.base_url}{pathfmt.format(*args)}"
def _raise_for_status(self, response): def _raise_for_status(self, response):
@ -427,7 +426,6 @@ class APIClient(_Session, DaemonApiMixin):
if stream: if stream:
return gen return gen
else:
try: try:
# Wait for all the frames, concatenate them, and return the result # Wait for all the frames, concatenate them, and return the result
return consume_socket_output(gen, demux=demux) return consume_socket_output(gen, demux=demux)
@ -462,14 +460,6 @@ class APIClient(_Session, DaemonApiMixin):
s.settimeout(None) s.settimeout(None)
@check_resource("container")
def _check_is_tty(self, container):
cont = self.inspect_container(container)
return cont["Config"]["Tty"]
def _get_result(self, container, stream, res):
return self._get_result_tty(stream, res, self._check_is_tty(container))
def _get_result_tty(self, stream, res, is_tty): def _get_result_tty(self, stream, res, is_tty):
# We should also use raw streaming (without keep-alive) # We should also use raw streaming (without keep-alive)
# if we are dealing with a tty-enabled container. # if we are dealing with a tty-enabled container.
@ -484,7 +474,6 @@ class APIClient(_Session, DaemonApiMixin):
sep = b"" sep = b""
if stream: if stream:
return self._multiplexed_response_stream_helper(res) return self._multiplexed_response_stream_helper(res)
else:
return sep.join(list(self._multiplexed_buffer_helper(res))) return sep.join(list(self._multiplexed_buffer_helper(res)))
def _unmount(self, *args): def _unmount(self, *args):
@ -497,7 +486,6 @@ class APIClient(_Session, DaemonApiMixin):
except _InvalidSchema as e: except _InvalidSchema as e:
if self._custom_adapter: if self._custom_adapter:
return self._custom_adapter return self._custom_adapter
else:
raise e raise e
@property @property

View File

@ -368,7 +368,7 @@ def _load_legacy_config(config_file):
} }
} }
} }
except Exception as e: except Exception as e: # pylint: disable=broad-exception-caught
log.debug(e) log.debug(e)
pass pass

View File

@ -36,7 +36,7 @@ def get_current_context_name_with_source():
json.load(f).get("currentContext", "default"), json.load(f).get("currentContext", "default"),
f"configuration file {docker_cfg_path}", f"configuration file {docker_cfg_path}",
) )
except Exception: except Exception: # pylint: disable=broad-exception-caught
pass pass
return "default", "fallback value" return "default", "fallback value"
@ -54,7 +54,7 @@ def write_context_name_to_docker_config(name=None):
try: try:
with open(docker_cfg_path, "rt", encoding="utf-8") as f: with open(docker_cfg_path, "rt", encoding="utf-8") as f:
config = json.load(f) config = json.load(f)
except Exception as e: except Exception as e: # pylint: disable=broad-exception-caught
return e return e
current_context = config.get("currentContext", None) current_context = config.get("currentContext", None)
if current_context and not name: if current_context and not name:
@ -68,7 +68,7 @@ def write_context_name_to_docker_config(name=None):
try: try:
with open(docker_cfg_path, "wt", encoding="utf-8") as f: with open(docker_cfg_path, "wt", encoding="utf-8") as f:
json.dump(config, f, indent=4) json.dump(config, f, indent=4)
except Exception as e: except Exception as e: # pylint: disable=broad-exception-caught
return e return e

View File

@ -42,7 +42,7 @@ class Context:
description=None, description=None,
): ):
if not name: if not name:
raise Exception("Name not provided") raise ValueError("Name not provided")
self.name = name self.name = name
self.context_type = None self.context_type = None
self.orchestrator = orchestrator self.orchestrator = orchestrator
@ -136,7 +136,7 @@ class Context:
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 Exception( raise RuntimeError(
f"Detected corrupted meta file for context {name} : {e}" f"Detected corrupted meta file for context {name} : {e}"
) from e ) from e
@ -157,7 +157,7 @@ class Context:
def _load_certs(self): def _load_certs(self):
certs = {} certs = {}
tls_dir = get_tls_dir(self.name) tls_dir = get_tls_dir(self.name)
for endpoint in self.endpoints.keys(): for endpoint in self.endpoints:
if not os.path.isdir(os.path.join(tls_dir, endpoint)): if not os.path.isdir(os.path.join(tls_dir, endpoint)):
continue continue
ca_cert = None ca_cert = None
@ -238,11 +238,11 @@ class Context:
return self.context_type is None return self.context_type is None
@property @property
def Name(self): def Name(self): # pylint: disable=invalid-name
return self.name return self.name
@property @property
def Host(self): def Host(self): # pylint: disable=invalid-name
if not self.orchestrator or self.orchestrator == "swarm": if not self.orchestrator or self.orchestrator == "swarm":
endpoint = self.endpoints.get("docker", None) endpoint = self.endpoints.get("docker", None)
if endpoint: if endpoint:
@ -252,27 +252,27 @@ class Context:
return self.endpoints[self.orchestrator].get("Host", None) return self.endpoints[self.orchestrator].get("Host", None)
@property @property
def Orchestrator(self): def Orchestrator(self): # pylint: disable=invalid-name
return self.orchestrator return self.orchestrator
@property @property
def Metadata(self): def Metadata(self): # pylint: disable=invalid-name
meta = {} meta = {}
if self.orchestrator: if self.orchestrator:
meta = {"StackOrchestrator": self.orchestrator} meta = {"StackOrchestrator": self.orchestrator}
return {"Name": self.name, "Metadata": meta, "Endpoints": self.endpoints} return {"Name": self.name, "Metadata": meta, "Endpoints": self.endpoints}
@property @property
def TLSConfig(self): def TLSConfig(self): # pylint: disable=invalid-name
key = self.orchestrator key = self.orchestrator
if not key or key == "swarm": if not key or key == "swarm":
key = "docker" key = "docker"
if key in self.tls_cfg.keys(): if key in self.tls_cfg:
return self.tls_cfg[key] return self.tls_cfg[key]
return None return None
@property @property
def TLSMaterial(self): def TLSMaterial(self): # pylint: disable=invalid-name
certs = {} certs = {}
for endpoint, tls in self.tls_cfg.items(): for endpoint, tls in self.tls_cfg.items():
cert, key = tls.cert cert, key = tls.cert
@ -280,5 +280,5 @@ class Context:
return {"TLSMaterial": certs} return {"TLSMaterial": certs}
@property @property
def Storage(self): def Storage(self): # pylint: disable=invalid-name
return {"Storage": {"MetadataPath": self.meta_path, "TLSPath": self.tls_path}} return {"Storage": {"MetadataPath": self.meta_path, "TLSPath": self.tls_path}}

View File

@ -91,7 +91,6 @@ class Store:
raise errors.StoreError( raise errors.StoreError(
f"{self.program} not installed or not available in PATH" f"{self.program} not installed or not available in PATH"
) )
else:
raise errors.StoreError( raise errors.StoreError(
f'Unexpected OS error "{e.strerror}", errno={e.errno}' f'Unexpected OS error "{e.strerror}", errno={e.errno}'
) )

View File

@ -28,9 +28,9 @@ except ImportError:
PYWIN32_IMPORT_ERROR = traceback.format_exc() PYWIN32_IMPORT_ERROR = traceback.format_exc()
cERROR_PIPE_BUSY = 0xE7 ERROR_PIPE_BUSY = 0xE7
cSECURITY_SQOS_PRESENT = 0x100000 SECURITY_SQOS_PRESENT = 0x100000
cSECURITY_ANONYMOUS = 0 SECURITY_ANONYMOUS = 0
MAXIMUM_RETRY_COUNT = 10 MAXIMUM_RETRY_COUNT = 10
@ -55,7 +55,9 @@ class NpipeSocket:
def __init__(self, handle=None): def __init__(self, handle=None):
self._timeout = win32pipe.NMPWAIT_USE_DEFAULT_WAIT self._timeout = win32pipe.NMPWAIT_USE_DEFAULT_WAIT
self._handle = handle self._handle = handle
self._address = None
self._closed = False self._closed = False
self.flags = None
def accept(self): def accept(self):
raise NotImplementedError() raise NotImplementedError()
@ -77,8 +79,8 @@ class NpipeSocket:
None, None,
win32file.OPEN_EXISTING, win32file.OPEN_EXISTING,
( (
cSECURITY_ANONYMOUS SECURITY_ANONYMOUS
| cSECURITY_SQOS_PRESENT | SECURITY_SQOS_PRESENT
| win32file.FILE_FLAG_OVERLAPPED | win32file.FILE_FLAG_OVERLAPPED
), ),
0, 0,
@ -86,7 +88,7 @@ class NpipeSocket:
except win32pipe.error as e: except win32pipe.error as e:
# See Remarks: # See Remarks:
# https://msdn.microsoft.com/en-us/library/aa365800.aspx # https://msdn.microsoft.com/en-us/library/aa365800.aspx
if e.winerror == cERROR_PIPE_BUSY: if e.winerror == ERROR_PIPE_BUSY:
# Another program or thread has grabbed our pipe instance # Another program or thread has grabbed our pipe instance
# before we got to it. Wait for availability and attempt to # before we got to it. Wait for availability and attempt to
# connect again. # connect again.

View File

@ -72,7 +72,7 @@ class SSHSocket(socket.socket):
env.pop("LD_LIBRARY_PATH", None) env.pop("LD_LIBRARY_PATH", None)
env.pop("SSL_CERT_FILE", None) env.pop("SSL_CERT_FILE", None)
self.proc = subprocess.Popen( self.proc = subprocess.Popen( # pylint: disable=consider-using-with
args, args,
env=env, env=env,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
@ -82,7 +82,7 @@ class SSHSocket(socket.socket):
def _write(self, data): def _write(self, data):
if not self.proc or self.proc.stdin.closed: if not self.proc or self.proc.stdin.closed:
raise Exception( raise RuntimeError(
"SSH subprocess not initiated. connect() must be called first." "SSH subprocess not initiated. connect() must be called first."
) )
written = self.proc.stdin.write(data) written = self.proc.stdin.write(data)
@ -97,7 +97,7 @@ class SSHSocket(socket.socket):
def recv(self, n): def recv(self, n):
if not self.proc: if not self.proc:
raise Exception( raise RuntimeError(
"SSH subprocess not initiated. connect() must be called first." "SSH subprocess not initiated. connect() must be called first."
) )
return self.proc.stdout.read(n) return self.proc.stdout.read(n)

View File

@ -125,19 +125,22 @@ def create_archive(root, files=None, fileobj=None, gzip=False, extra_files=None)
def mkbuildcontext(dockerfile): def mkbuildcontext(dockerfile):
f = tempfile.NamedTemporaryFile() f = tempfile.NamedTemporaryFile() # pylint: disable=consider-using-with
t = tarfile.open(mode="w", fileobj=f) try:
with tarfile.open(mode="w", fileobj=f) as t:
if isinstance(dockerfile, io.StringIO): if isinstance(dockerfile, io.StringIO):
raise TypeError("Please use io.BytesIO to create in-memory Dockerfiles") raise TypeError("Please use io.BytesIO to create in-memory Dockerfiles")
elif isinstance(dockerfile, io.BytesIO): if isinstance(dockerfile, io.BytesIO):
dfinfo = tarfile.TarInfo("Dockerfile") dfinfo = tarfile.TarInfo("Dockerfile")
dfinfo.size = len(dockerfile.getvalue()) dfinfo.size = len(dockerfile.getvalue())
dockerfile.seek(0) dockerfile.seek(0)
else: else:
dfinfo = t.gettarinfo(fileobj=dockerfile, arcname="Dockerfile") dfinfo = t.gettarinfo(fileobj=dockerfile, arcname="Dockerfile")
t.addfile(dfinfo, dockerfile) t.addfile(dfinfo, dockerfile)
t.close()
f.seek(0) f.seek(0)
except Exception: # noqa: E722
f.close()
raise
return f return f

View File

@ -68,7 +68,6 @@ def home_dir():
""" """
if IS_WINDOWS_PLATFORM: if IS_WINDOWS_PLATFORM:
return os.environ.get("USERPROFILE", "") return os.environ.get("USERPROFILE", "")
else:
return os.path.expanduser("~") return os.path.expanduser("~")

View File

@ -17,23 +17,6 @@ from .. import errors
from . import utils from . import utils
def check_resource(resource_name):
def decorator(f):
@functools.wraps(f)
def wrapped(self, resource_id=None, *args, **kwargs):
if resource_id is None and kwargs.get(resource_name):
resource_id = kwargs.pop(resource_name)
if isinstance(resource_id, dict):
resource_id = resource_id.get("Id", resource_id.get("ID"))
if not resource_id:
raise errors.NullResource("Resource ID was not provided")
return f(self, resource_id, *args, **kwargs)
return wrapped
return decorator
def minimum_version(version): def minimum_version(version):
def decorator(f): def decorator(f):
@functools.wraps(f) @functools.wraps(f)

View File

@ -90,7 +90,6 @@ def split_port(port):
if external is not None and len(internal) != len(external): if external is not None and len(internal) != len(external):
raise ValueError("Port ranges don't match in length") raise ValueError("Port ranges don't match in length")
return internal, external return internal, external
else:
if not external: if not external:
external = [None] * len(internal) external = [None] * len(internal)
elif len(internal) != len(external): elif len(internal) != len(external):

View File

@ -111,7 +111,6 @@ def frames_iter(socket, tty):
""" """
if tty: if tty:
return ((STDOUT, frame) for frame in frames_iter_tty(socket)) return ((STDOUT, frame) for frame in frames_iter_tty(socket))
else:
return frames_iter_no_tty(socket) return frames_iter_no_tty(socket)
@ -194,7 +193,6 @@ def demux_adaptor(stream_id, data):
""" """
if stream_id == STDOUT: if stream_id == STDOUT:
return (data, None) return (data, None)
elif stream_id == STDERR: if stream_id == STDERR:
return (None, data) return (None, data)
else:
raise ValueError(f"{stream_id} is not a valid stream") raise ValueError(f"{stream_id} is not a valid stream")

View File

@ -75,9 +75,8 @@ def compare_version(v1, v2):
s2 = StrictVersion(v2) s2 = StrictVersion(v2)
if s1 == s2: if s1 == s2:
return 0 return 0
elif s1 > s2: if s1 > s2:
return -1 return -1
else:
return 1 return 1
@ -250,7 +249,7 @@ def parse_host(addr, is_win32=False, tls=False):
# These protos are valid aliases for our library but not for the # These protos are valid aliases for our library but not for the
# official spec # official spec
if proto == "http" or proto == "https": if proto in ("http", "https"):
tls = proto == "https" tls = proto == "https"
proto = "tcp" proto = "tcp"
elif proto == "http+unix": elif proto == "http+unix":
@ -273,7 +272,6 @@ def parse_host(addr, is_win32=False, tls=False):
raise errors.DockerException( raise errors.DockerException(
f"Invalid bind address format: no path allowed for this protocol: {addr}" f"Invalid bind address format: no path allowed for this protocol: {addr}"
) )
else:
path = parsed_url.path path = parsed_url.path
if proto == "unix" and parsed_url.hostname is not None: if proto == "unix" and parsed_url.hostname is not None:
# For legacy reasons, we consider unix://path # For legacy reasons, we consider unix://path
@ -419,7 +417,7 @@ def parse_bytes(s):
else: else:
digits_part = s[:-1] digits_part = s[:-1]
if suffix in units.keys() or suffix.isdigit(): if suffix in units or suffix.isdigit():
try: try:
digits = float(digits_part) digits = float(digits_part)
except ValueError: except ValueError:

View File

@ -98,7 +98,7 @@ MIN_DOCKER_VERSION = "1.8.0"
if not HAS_DOCKER_PY: if not HAS_DOCKER_PY:
docker_version = None docker_version = None # pylint: disable=invalid-name
# No Docker SDK for Python. Create a place holder client to allow # No Docker SDK for Python. Create a place holder client to allow
# instantiation of AnsibleModule and proper error handing # instantiation of AnsibleModule and proper error handing
@ -194,7 +194,7 @@ class AnsibleDockerClientBase(Client):
def __init__(self, min_docker_version=None, min_docker_api_version=None): def __init__(self, min_docker_version=None, min_docker_api_version=None):
if min_docker_version is None: if min_docker_version is None:
min_docker_version = MIN_DOCKER_VERSION min_docker_version = MIN_DOCKER_VERSION
NEEDS_DOCKER_PY2 = LooseVersion(min_docker_version) >= LooseVersion("2.0.0") needs_docker_py2 = LooseVersion(min_docker_version) >= LooseVersion("2.0.0")
self.docker_py_version = LooseVersion(docker_version) self.docker_py_version = LooseVersion(docker_version)
@ -218,7 +218,7 @@ class AnsibleDockerClientBase(Client):
f"Error: Docker SDK for Python version is {docker_version} ({platform.node()}'s Python {sys.executable})." f"Error: Docker SDK for Python version is {docker_version} ({platform.node()}'s Python {sys.executable})."
f" Minimum version required is {min_docker_version}." f" Minimum version required is {min_docker_version}."
) )
if not NEEDS_DOCKER_PY2: if not needs_docker_py2:
# The minimal required version is < 2.0 (and the current version as well). # The minimal required version is < 2.0 (and the current version as well).
# Advertise docker (instead of docker-py). # Advertise docker (instead of docker-py).
msg += DOCKERPYUPGRADE_RECOMMEND_DOCKER msg += DOCKERPYUPGRADE_RECOMMEND_DOCKER
@ -237,7 +237,7 @@ class AnsibleDockerClientBase(Client):
self.docker_api_version_str = self.api_version self.docker_api_version_str = self.api_version
except APIError as exc: except APIError as exc:
self.fail(f"Docker API error: {exc}") self.fail(f"Docker API error: {exc}")
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error connecting: {exc}") self.fail(f"Error connecting: {exc}")
self.docker_api_version = LooseVersion(self.docker_api_version_str) self.docker_api_version = LooseVersion(self.docker_api_version_str)
@ -409,7 +409,7 @@ class AnsibleDockerClientBase(Client):
return result return result
except NotFound: except NotFound:
return None return None
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error inspecting container: {exc}") self.fail(f"Error inspecting container: {exc}")
def get_container(self, name=None): def get_container(self, name=None):
@ -441,7 +441,7 @@ class AnsibleDockerClientBase(Client):
break break
except SSLError as exc: except SSLError as exc:
self._handle_ssl_error(exc) self._handle_ssl_error(exc)
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error retrieving container list: {exc}") self.fail(f"Error retrieving container list: {exc}")
if result is None: if result is None:
@ -470,7 +470,7 @@ class AnsibleDockerClientBase(Client):
break break
except SSLError as exc: except SSLError as exc:
self._handle_ssl_error(exc) self._handle_ssl_error(exc)
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error retrieving network list: {exc}") self.fail(f"Error retrieving network list: {exc}")
if result is not None: if result is not None:
@ -483,7 +483,7 @@ class AnsibleDockerClientBase(Client):
self.log("Completed network inspection") self.log("Completed network inspection")
except NotFound: except NotFound:
return None return None
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error inspecting network: {exc}") self.fail(f"Error inspecting network: {exc}")
return result return result
@ -533,7 +533,7 @@ class AnsibleDockerClientBase(Client):
except NotFound: except NotFound:
self.log(f"Image {name}:{tag} not found.") self.log(f"Image {name}:{tag} not found.")
return None return None
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error inspecting image {name}:{tag} - {exc}") self.fail(f"Error inspecting image {name}:{tag} - {exc}")
return inspection return inspection
@ -555,7 +555,7 @@ class AnsibleDockerClientBase(Client):
self.fail(f"Error inspecting image ID {image_id} - {exc}") self.fail(f"Error inspecting image ID {image_id} - {exc}")
self.log(f"Image {image_id} not found.") self.log(f"Image {image_id} not found.")
return None return None
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error inspecting image ID {image_id} - {exc}") self.fail(f"Error inspecting image ID {image_id} - {exc}")
return inspection return inspection
@ -567,7 +567,7 @@ class AnsibleDockerClientBase(Client):
""" """
try: try:
response = self.images(name=name) response = self.images(name=name)
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error searching for image {name} - {exc}") self.fail(f"Error searching for image {name} - {exc}")
images = response images = response
if tag: if tag:
@ -606,7 +606,7 @@ class AnsibleDockerClientBase(Client):
) )
else: else:
self.fail(f"Error pulling {name} - {line.get('error')}") self.fail(f"Error pulling {name} - {line.get('error')}")
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error pulling image {name}:{tag} - {exc}") self.fail(f"Error pulling image {name}:{tag} - {exc}")
new_tag = self.find_image(name, tag) new_tag = self.find_image(name, tag)

View File

@ -128,7 +128,7 @@ class AnsibleDockerClientBase(Client):
) )
except APIError as exc: except APIError as exc:
self.fail(f"Docker API error: {exc}") self.fail(f"Docker API error: {exc}")
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error connecting: {exc}") self.fail(f"Error connecting: {exc}")
self.docker_api_version = LooseVersion(self.docker_api_version_str) self.docker_api_version = LooseVersion(self.docker_api_version_str)
@ -308,7 +308,7 @@ class AnsibleDockerClientBase(Client):
return result return result
except NotFound: except NotFound:
return None return None
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error inspecting container: {exc}") self.fail(f"Error inspecting container: {exc}")
def get_container(self, name=None): def get_container(self, name=None):
@ -347,7 +347,7 @@ class AnsibleDockerClientBase(Client):
break break
except SSLError as exc: except SSLError as exc:
self._handle_ssl_error(exc) self._handle_ssl_error(exc)
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error retrieving container list: {exc}") self.fail(f"Error retrieving container list: {exc}")
if result is None: if result is None:
@ -377,7 +377,7 @@ class AnsibleDockerClientBase(Client):
break break
except SSLError as exc: except SSLError as exc:
self._handle_ssl_error(exc) self._handle_ssl_error(exc)
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error retrieving network list: {exc}") self.fail(f"Error retrieving network list: {exc}")
if result is not None: if result is not None:
@ -390,7 +390,7 @@ class AnsibleDockerClientBase(Client):
self.log("Completed network inspection") self.log("Completed network inspection")
except NotFound: except NotFound:
return None return None
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error inspecting network: {exc}") self.fail(f"Error inspecting network: {exc}")
return result return result
@ -412,7 +412,7 @@ class AnsibleDockerClientBase(Client):
else: else:
params["filters"] = convert_filters({"reference": name}) params["filters"] = convert_filters({"reference": name})
images = self.get_json("/images/json", params=params) images = self.get_json("/images/json", params=params)
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error searching for image {name} - {exc}") self.fail(f"Error searching for image {name} - {exc}")
if tag: if tag:
lookup = f"{name}:{tag}" lookup = f"{name}:{tag}"
@ -472,7 +472,7 @@ class AnsibleDockerClientBase(Client):
except NotFound: except NotFound:
self.log(f"Image {name}:{tag} not found.") self.log(f"Image {name}:{tag} not found.")
return None return None
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error inspecting image {name}:{tag} - {exc}") self.fail(f"Error inspecting image {name}:{tag} - {exc}")
self.log(f"Image {name}:{tag} not found.") self.log(f"Image {name}:{tag} not found.")
@ -493,7 +493,7 @@ class AnsibleDockerClientBase(Client):
self.fail(f"Error inspecting image ID {image_id} - {exc}") self.fail(f"Error inspecting image ID {image_id} - {exc}")
self.log(f"Image {image_id} not found.") self.log(f"Image {image_id} not found.")
return None return None
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error inspecting image ID {image_id} - {exc}") self.fail(f"Error inspecting image ID {image_id} - {exc}")
def pull_image(self, name, tag="latest", image_platform=None): def pull_image(self, name, tag="latest", image_platform=None):
@ -535,7 +535,7 @@ class AnsibleDockerClientBase(Client):
) )
else: else:
self.fail(f"Error pulling {name} - {line.get('error')}") self.fail(f"Error pulling {name} - {line.get('error')}")
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error pulling image {name}:{tag} - {exc}") self.fail(f"Error pulling image {name}:{tag} - {exc}")
new_tag = self.find_image(name, tag) new_tag = self.find_image(name, tag)

View File

@ -159,7 +159,7 @@ class AnsibleDockerClientBase:
self.warn(to_native(stderr)) self.warn(to_native(stderr))
try: try:
data = json.loads(stdout) data = json.loads(stdout)
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail( self.fail(
f"Error while parsing JSON output of {self._compose_cmd_str(args)}: {exc}\nJSON output: {to_native(stdout)}" f"Error while parsing JSON output of {self._compose_cmd_str(args)}: {exc}\nJSON output: {to_native(stdout)}"
) )
@ -177,7 +177,7 @@ class AnsibleDockerClientBase:
line = line.strip() line = line.strip()
if line.startswith(b"{"): if line.startswith(b"{"):
result.append(json.loads(line)) result.append(json.loads(line))
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail( self.fail(
f"Error while parsing JSON output of {self._compose_cmd_str(args)}: {exc}\nJSON output: {to_native(stdout)}" f"Error while parsing JSON output of {self._compose_cmd_str(args)}: {exc}\nJSON output: {to_native(stdout)}"
) )

View File

@ -176,9 +176,13 @@ _RE_PULL_EVENT = re.compile(
r"\s*" r"\s*"
r"(?P<service>\S+)" r"(?P<service>\S+)"
r"\s+" r"\s+"
r"(?P<status>%s)" f"(?P<status>{'|'.join(re.escape(status) for status in DOCKER_STATUS_PULL)})"
r"\s*" r"\s*"
r"$" % "|".join(re.escape(status) for status in DOCKER_STATUS_PULL) r"$"
)
_DOCKER_PULL_PROGRESS_WD = sorted(
DOCKER_PULL_PROGRESS_DONE | DOCKER_PULL_PROGRESS_WORKING
) )
_RE_PULL_PROGRESS = re.compile( _RE_PULL_PROGRESS = re.compile(
@ -186,14 +190,10 @@ _RE_PULL_PROGRESS = re.compile(
r"\s*" r"\s*"
r"(?P<layer>\S+)" r"(?P<layer>\S+)"
r"\s+" r"\s+"
r"(?P<status>%s)" f"(?P<status>{'|'.join(re.escape(status) for status in _DOCKER_PULL_PROGRESS_WD)})"
r"\s*" r"\s*"
r"(?:|\s\[[^]]+\]\s+\S+\s*|\s+[0-9.kKmMgGbB]+/[0-9.kKmMgGbB]+\s*)" r"(?:|\s\[[^]]+\]\s+\S+\s*|\s+[0-9.kKmMgGbB]+/[0-9.kKmMgGbB]+\s*)"
r"$" r"$"
% "|".join(
re.escape(status)
for status in sorted(DOCKER_PULL_PROGRESS_DONE | DOCKER_PULL_PROGRESS_WORKING)
)
) )
_RE_ERROR_EVENT = re.compile( _RE_ERROR_EVENT = re.compile(
@ -201,10 +201,10 @@ _RE_ERROR_EVENT = re.compile(
r"\s*" r"\s*"
r"(?P<resource_id>\S+)" r"(?P<resource_id>\S+)"
r"\s+" r"\s+"
r"(?P<status>%s)" f"(?P<status>{'|'.join(re.escape(status) for status in DOCKER_STATUS_ERROR)})"
r"\s*" r"\s*"
r"(?P<msg>\S.*\S)?" r"(?P<msg>\S.*\S)?"
r"$" % "|".join(re.escape(status) for status in DOCKER_STATUS_ERROR) r"$"
) )
_RE_WARNING_EVENT = re.compile( _RE_WARNING_EVENT = re.compile(
@ -212,10 +212,10 @@ _RE_WARNING_EVENT = re.compile(
r"\s*" r"\s*"
r"(?P<resource_id>\S+)" r"(?P<resource_id>\S+)"
r"\s+" r"\s+"
r"(?P<status>%s)" f"(?P<status>{'|'.join(re.escape(status) for status in DOCKER_STATUS_WARNING)})"
r"\s*" r"\s*"
r"(?P<msg>\S.*\S)?" r"(?P<msg>\S.*\S)?"
r"$" % "|".join(re.escape(status) for status in DOCKER_STATUS_WARNING) r"$"
) )
_RE_CONTINUE_EVENT = re.compile(r"^\s*(?P<resource_id>\S+)\s+-\s*(?P<msg>\S(?:|.*\S))$") _RE_CONTINUE_EVENT = re.compile(r"^\s*(?P<resource_id>\S+)\s+-\s*(?P<msg>\S(?:|.*\S))$")
@ -405,7 +405,7 @@ def parse_json_events(stderr, warn_function=None):
continue continue
try: try:
line_data = json.loads(line) line_data = json.loads(line)
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
if warn_function: if warn_function:
warn_function( warn_function(
f"Cannot parse event from line: {line!r}: {exc}. Please report this at " f"Cannot parse event from line: {line!r}: {exc}. Please report this at "
@ -544,7 +544,7 @@ def parse_events(stderr, dry_run=False, warn_function=None, nonzero_rc=False):
line, warn_missing_dry_run_prefix, warn_function line, warn_missing_dry_run_prefix, warn_function
) )
continue continue
elif parsed: if parsed:
continue continue
match = _RE_BUILD_PROGRESS_EVENT.match(line) match = _RE_BUILD_PROGRESS_EVENT.match(line)
if match: if match:
@ -748,7 +748,7 @@ class BaseComposeManager(DockerBaseClass):
encoding="utf-8", encoding="utf-8",
Dumper=_SafeDumper, Dumper=_SafeDumper,
) )
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error writing to {compose_file} - {exc}") self.fail(f"Error writing to {compose_file} - {exc}")
else: else:
self.project_src = os.path.abspath(parameters["project_src"]) self.project_src = os.path.abspath(parameters["project_src"])
@ -804,7 +804,7 @@ class BaseComposeManager(DockerBaseClass):
if version == "dev": if version == "dev":
return None return None
return version.lstrip("v") return version.lstrip("v")
except Exception: except Exception: # pylint: disable=broad-exception-caught
return None return None
def get_compose_version_from_api(self): def get_compose_version_from_api(self):
@ -946,6 +946,6 @@ class BaseComposeManager(DockerBaseClass):
for directory in self.cleanup_dirs: for directory in self.cleanup_dirs:
try: try:
shutil.rmtree(directory, True) shutil.rmtree(directory, True)
except Exception: except Exception: # pylint: disable=broad-exception-caught
# should not happen, but simply ignore to be on the safe side # should not happen, but simply ignore to be on the safe side
pass pass

View File

@ -133,10 +133,9 @@ def parse_line(line, logrus_mode=False):
key.append(cur) key.append(cur)
parser.next() parser.next()
return _Mode.KEY return _Mode.KEY
elif cur == "=": if cur == "=":
parser.next() parser.next()
return _Mode.EQUAL return _Mode.EQUAL
else:
if logrus_mode: if logrus_mode:
raise InvalidLogFmt('Key must always be followed by "=" in logrus mode') raise InvalidLogFmt('Key must always be followed by "=" in logrus mode')
handle_kv(has_no_value=True) handle_kv(has_no_value=True)
@ -148,10 +147,9 @@ def parse_line(line, logrus_mode=False):
value.append(cur) value.append(cur)
parser.next() parser.next()
return _Mode.IDENT_VALUE return _Mode.IDENT_VALUE
elif cur == '"': if cur == '"':
parser.next() parser.next()
return _Mode.QUOTED_VALUE return _Mode.QUOTED_VALUE
else:
handle_kv() handle_kv()
parser.next() parser.next()
return _Mode.GARBAGE return _Mode.GARBAGE
@ -161,7 +159,6 @@ def parse_line(line, logrus_mode=False):
value.append(cur) value.append(cur)
parser.next() parser.next()
return _Mode.IDENT_VALUE return _Mode.IDENT_VALUE
else:
handle_kv() handle_kv()
parser.next() parser.next()
return _Mode.GARBAGE return _Mode.GARBAGE
@ -182,13 +179,12 @@ def parse_line(line, logrus_mode=False):
value.append(parser.parse_unicode_sequence()) value.append(parser.parse_unicode_sequence())
parser.next() parser.next()
return _Mode.QUOTED_VALUE return _Mode.QUOTED_VALUE
elif cur == '"': if cur == '"':
handle_kv() handle_kv()
parser.next() parser.next()
return _Mode.GARBAGE return _Mode.GARBAGE
elif cur < " ": if cur < " ":
raise InvalidLogFmt("Control characters in quoted string are not allowed") raise InvalidLogFmt("Control characters in quoted string are not allowed")
else:
value.append(cur) value.append(cur)
parser.next() parser.next()
return _Mode.QUOTED_VALUE return _Mode.QUOTED_VALUE
@ -204,7 +200,7 @@ def parse_line(line, logrus_mode=False):
mode = parsers[mode](parser.cur()) mode = parsers[mode](parser.cur())
if mode == _Mode.KEY and logrus_mode: if mode == _Mode.KEY and logrus_mode:
raise InvalidLogFmt('Key must always be followed by "=" in logrus mode') raise InvalidLogFmt('Key must always be followed by "=" in logrus mode')
if mode == _Mode.KEY or mode == _Mode.EQUAL: if mode in (_Mode.KEY, _Mode.EQUAL):
handle_kv(has_no_value=True) handle_kv(has_no_value=True)
elif mode == _Mode.IDENT_VALUE: elif mode == _Mode.IDENT_VALUE:
handle_kv() handle_kv()

View File

@ -58,7 +58,7 @@ def _get_ansible_type(value_type):
if value_type == "set": if value_type == "set":
return "list" return "list"
if value_type not in ("list", "dict", "bool", "int", "float", "str"): if value_type not in ("list", "dict", "bool", "int", "float", "str"):
raise Exception(f'Invalid type "{value_type}"') raise ValueError(f'Invalid type "{value_type}"')
return value_type return value_type
@ -87,13 +87,13 @@ class Option:
needs_elements = self.value_type in ("list", "set") needs_elements = self.value_type in ("list", "set")
needs_ansible_elements = self.ansible_type in ("list",) needs_ansible_elements = self.ansible_type in ("list",)
if elements is not None and not needs_elements: if elements is not None and not needs_elements:
raise Exception("elements only allowed for lists/sets") raise ValueError("elements only allowed for lists/sets")
if elements is None and needs_elements: if elements is None and needs_elements:
raise Exception("elements required for lists/sets") raise ValueError("elements required for lists/sets")
if ansible_elements is not None and not needs_ansible_elements: if ansible_elements is not None and not needs_ansible_elements:
raise Exception("Ansible elements only allowed for Ansible lists") raise ValueError("Ansible elements only allowed for Ansible lists")
if (elements is None and ansible_elements is None) and needs_ansible_elements: if (elements is None and ansible_elements is None) and needs_ansible_elements:
raise Exception("Ansible elements required for Ansible lists") raise ValueError("Ansible elements required for Ansible lists")
self.elements = elements if needs_elements else None self.elements = elements if needs_elements else None
self.ansible_elements = ( self.ansible_elements = (
(ansible_elements or _get_ansible_type(elements)) (ansible_elements or _get_ansible_type(elements))
@ -104,7 +104,7 @@ class Option:
self.ansible_type == "list" and self.ansible_elements == "dict" self.ansible_type == "list" and self.ansible_elements == "dict"
) or (self.ansible_type == "dict") ) or (self.ansible_type == "dict")
if ansible_suboptions is not None and not needs_suboptions: if ansible_suboptions is not None and not needs_suboptions:
raise Exception( raise ValueError(
"suboptions only allowed for Ansible lists with dicts, or Ansible dicts" "suboptions only allowed for Ansible lists with dicts, or Ansible dicts"
) )
if ( if (
@ -113,7 +113,7 @@ class Option:
and not needs_no_suboptions and not needs_no_suboptions
and not not_an_ansible_option and not not_an_ansible_option
): ):
raise Exception( raise ValueError(
"suboptions required for Ansible lists with dicts, or Ansible dicts" "suboptions required for Ansible lists with dicts, or Ansible dicts"
) )
self.ansible_suboptions = ansible_suboptions if needs_suboptions else None self.ansible_suboptions = ansible_suboptions if needs_suboptions else None
@ -431,15 +431,14 @@ def _parse_port_range(range_or_port, module):
if "-" in range_or_port: if "-" in range_or_port:
try: try:
start, end = [int(port) for port in range_or_port.split("-")] start, end = [int(port) for port in range_or_port.split("-")]
except Exception: except ValueError:
module.fail_json(msg=f'Invalid port range: "{range_or_port}"') module.fail_json(msg=f'Invalid port range: "{range_or_port}"')
if end < start: if end < start:
module.fail_json(msg=f'Invalid port range: "{range_or_port}"') module.fail_json(msg=f'Invalid port range: "{range_or_port}"')
return list(range(start, end + 1)) return list(range(start, end + 1))
else:
try: try:
return [int(range_or_port)] return [int(range_or_port)]
except Exception: except ValueError:
module.fail_json(msg=f'Invalid port: "{range_or_port}"') module.fail_json(msg=f'Invalid port: "{range_or_port}"')
@ -707,7 +706,7 @@ def _preprocess_mounts(module, values):
if mount_dict["tmpfs_mode"] is not None: if mount_dict["tmpfs_mode"] is not None:
try: try:
mount_dict["tmpfs_mode"] = int(mount_dict["tmpfs_mode"], 8) mount_dict["tmpfs_mode"] = int(mount_dict["tmpfs_mode"], 8)
except Exception: except ValueError:
module.fail_json( module.fail_json(
msg=f'tmp_fs mode of mount "{target}" is not an octal string!' msg=f'tmp_fs mode of mount "{target}" is not an octal string!'
) )
@ -747,7 +746,7 @@ def _preprocess_mounts(module, values):
check_collision(container, "volumes") check_collision(container, "volumes")
new_vols.append(f"{host}:{container}:{mode}") new_vols.append(f"{host}:{container}:{mode}")
continue continue
elif len(parts) == 2: if len(parts) == 2:
if not _is_volume_permissions(parts[1]) and re.match( if not _is_volume_permissions(parts[1]) and re.match(
r"[.~]", parts[0] r"[.~]", parts[0]
): ):

View File

@ -124,7 +124,7 @@ def _get_ansible_type(our_type):
if our_type == "set": if our_type == "set":
return "list" return "list"
if our_type not in ("list", "dict", "bool", "int", "float", "str"): if our_type not in ("list", "dict", "bool", "int", "float", "str"):
raise Exception(f'Invalid type "{our_type}"') raise ValueError(f'Invalid type "{our_type}"')
return our_type return our_type
@ -266,7 +266,7 @@ class DockerAPIEngineDriver(EngineDriver):
# Ensure driver_opts values are strings # Ensure driver_opts values are strings
for key, val in value.items(): for key, val in value.items():
if not isinstance(val, str): if not isinstance(val, str):
raise Exception( raise ValueError(
f"driver_opts values must be strings, got {type(val).__name__} for key '{key}'" f"driver_opts values must be strings, got {type(val).__name__} for key '{key}'"
) )
params[dest_para] = value params[dest_para] = value
@ -278,7 +278,7 @@ class DockerAPIEngineDriver(EngineDriver):
params[dest_para] = value params[dest_para] = value
if parameters: if parameters:
ups = ", ".join([f'"{p}"' for p in sorted(parameters)]) ups = ", ".join([f'"{p}"' for p in sorted(parameters)])
raise Exception( raise ValueError(
f"Unknown parameter(s) for connect_container_to_network for Docker API driver: {ups}" f"Unknown parameter(s) for connect_container_to_network for Docker API driver: {ups}"
) )
ipam_config = {} ipam_config = {}
@ -347,7 +347,6 @@ class DockerAPIEngineDriver(EngineDriver):
) )
output = client._get_result_tty(False, res, config["Config"]["Tty"]) output = client._get_result_tty(False, res, config["Config"]["Tty"])
return output, True return output, True
else:
return f"Result logged using `{logging_driver}` driver", False return f"Result logged using `{logging_driver}` driver", False
def update_container(self, client, container_id, update_parameters): def update_container(self, client, container_id, update_parameters):
@ -399,13 +398,13 @@ class DockerAPIEngineDriver(EngineDriver):
# New docker daemon versions do not allow containers to be removed # New docker daemon versions do not allow containers to be removed
# if they are paused. Make sure we do not end up in an infinite loop. # if they are paused. Make sure we do not end up in an infinite loop.
if count == 3: if count == 3:
raise Exception(f"{exc} [tried to unpause three times]") raise RuntimeError(f"{exc} [tried to unpause three times]")
count += 1 count += 1
# Unpause # Unpause
try: try:
self.unpause_container(client, container_id) self.unpause_container(client, container_id)
except Exception as exc2: except Exception as exc2:
raise Exception(f"{exc2} [while unpausing]") raise RuntimeError(f"{exc2} [while unpausing]")
# Now try again # Now try again
continue continue
raise raise
@ -430,13 +429,13 @@ class DockerAPIEngineDriver(EngineDriver):
# New docker daemon versions do not allow containers to be removed # New docker daemon versions do not allow containers to be removed
# if they are paused. Make sure we do not end up in an infinite loop. # if they are paused. Make sure we do not end up in an infinite loop.
if count == 3: if count == 3:
raise Exception(f"{exc} [tried to unpause three times]") raise RuntimeError(f"{exc} [tried to unpause three times]")
count += 1 count += 1
# Unpause # Unpause
try: try:
self.unpause_container(client, container_id) self.unpause_container(client, container_id)
except Exception as exc2: except Exception as exc2:
raise Exception(f"{exc2} [while unpausing]") raise RuntimeError(f"{exc2} [while unpausing]")
# Now try again # Now try again
continue continue
if ( if (
@ -1060,7 +1059,7 @@ def _get_network_id(module, client, network_name):
network_id = network["Id"] network_id = network["Id"]
break break
return network_id return network_id
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
client.fail(f"Error getting network id for {network_name} - {exc}") client.fail(f"Error getting network id for {network_name} - {exc}")

View File

@ -134,6 +134,7 @@ class ContainerManager(DockerBaseClass):
"The value of default_host_ip must be an empty string, an IPv4 address, " "The value of default_host_ip must be an empty string, an IPv4 address, "
f'or an IPv6 address. Got "{self.param_default_host_ip}" instead.' f'or an IPv6 address. Got "{self.param_default_host_ip}" instead.'
) )
self.parameters = None
def _collect_all_options(self, active_options): def _collect_all_options(self, active_options):
all_options = {} all_options = {}
@ -480,7 +481,7 @@ class ContainerManager(DockerBaseClass):
self.engine_driver.unpause_container( self.engine_driver.unpause_container(
self.client, container.id self.client, container.id
) )
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail( self.fail(
f"Error {'pausing' if self.param_paused else 'unpausing'} container {container.id}: {exc}" f"Error {'pausing' if self.param_paused else 'unpausing'} container {container.id}: {exc}"
) )
@ -567,13 +568,13 @@ class ContainerManager(DockerBaseClass):
if not image or self.param_pull == "always": if not image or self.param_pull == "always":
if not self.check_mode: if not self.check_mode:
self.log("Pull the image.") self.log("Pull the image.")
image, alreadyToLatest = self.engine_driver.pull_image( image, already_to_latest = self.engine_driver.pull_image(
self.client, self.client,
repository, repository,
tag, tag,
image_platform=self.module.params["platform"], image_platform=self.module.params["platform"],
) )
if alreadyToLatest: if already_to_latest:
self.results["changed"] = False self.results["changed"] = False
self.results["actions"].append( self.results["actions"].append(
dict(pulled_image=f"{repository}:{tag}", changed=False) dict(pulled_image=f"{repository}:{tag}", changed=False)
@ -950,7 +951,7 @@ class ContainerManager(DockerBaseClass):
self.engine_driver.disconnect_container_from_network( self.engine_driver.disconnect_container_from_network(
self.client, container.id, diff["parameter"]["id"] self.client, container.id, diff["parameter"]["id"]
) )
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail( self.fail(
f"Error disconnecting container from network {diff['parameter']['name']} - {exc}" f"Error disconnecting container from network {diff['parameter']['name']} - {exc}"
) )
@ -975,7 +976,7 @@ class ContainerManager(DockerBaseClass):
self.engine_driver.connect_container_to_network( self.engine_driver.connect_container_to_network(
self.client, container.id, diff["parameter"]["id"], params self.client, container.id, diff["parameter"]["id"], params
) )
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail( self.fail(
f"Error connecting container to network {diff['parameter']['name']} - {exc}" f"Error connecting container to network {diff['parameter']['name']} - {exc}"
) )
@ -989,7 +990,7 @@ class ContainerManager(DockerBaseClass):
self.engine_driver.disconnect_container_from_network( self.engine_driver.disconnect_container_from_network(
self.client, container.id, network["name"] self.client, container.id, network["name"]
) )
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail( self.fail(
f"Error disconnecting container from network {network['name']} - {exc}" f"Error disconnecting container from network {network['name']} - {exc}"
) )
@ -1027,7 +1028,7 @@ class ContainerManager(DockerBaseClass):
container_id = self.engine_driver.create_container( container_id = self.engine_driver.create_container(
self.client, self.param_name, create_parameters, networks=networks self.client, self.param_name, create_parameters, networks=networks
) )
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error creating container: {exc}") self.fail(f"Error creating container: {exc}")
return self._get_container(container_id) return self._get_container(container_id)
return new_container return new_container
@ -1039,7 +1040,7 @@ class ContainerManager(DockerBaseClass):
if not self.check_mode: if not self.check_mode:
try: try:
self.engine_driver.start_container(self.client, container_id) self.engine_driver.start_container(self.client, container_id)
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error starting container {container_id}: {exc}") self.fail(f"Error starting container {container_id}: {exc}")
if self.module.params["detach"] is False: if self.module.params["detach"] is False:
@ -1096,7 +1097,7 @@ class ContainerManager(DockerBaseClass):
link=link, link=link,
force=force, force=force,
) )
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.client.fail(f"Error removing container {container_id}: {exc}") self.client.fail(f"Error removing container {container_id}: {exc}")
def container_update(self, container_id, update_parameters): def container_update(self, container_id, update_parameters):
@ -1112,7 +1113,7 @@ class ContainerManager(DockerBaseClass):
self.engine_driver.update_container( self.engine_driver.update_container(
self.client, container_id, update_parameters self.client, container_id, update_parameters
) )
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error updating container {container_id}: {exc}") self.fail(f"Error updating container {container_id}: {exc}")
return self._get_container(container_id) return self._get_container(container_id)
@ -1126,7 +1127,7 @@ class ContainerManager(DockerBaseClass):
self.engine_driver.kill_container( self.engine_driver.kill_container(
self.client, container_id, kill_signal=self.param_kill_signal self.client, container_id, kill_signal=self.param_kill_signal
) )
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error killing container {container_id}: {exc}") self.fail(f"Error killing container {container_id}: {exc}")
def container_restart(self, container_id): def container_restart(self, container_id):
@ -1139,7 +1140,7 @@ class ContainerManager(DockerBaseClass):
self.engine_driver.restart_container( self.engine_driver.restart_container(
self.client, container_id, self.module.params["stop_timeout"] or 10 self.client, container_id, self.module.params["stop_timeout"] or 10
) )
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error restarting container {container_id}: {exc}") self.fail(f"Error restarting container {container_id}: {exc}")
return self._get_container(container_id) return self._get_container(container_id)
@ -1156,7 +1157,7 @@ class ContainerManager(DockerBaseClass):
self.engine_driver.stop_container( self.engine_driver.stop_container(
self.client, container_id, self.module.params["stop_timeout"] self.client, container_id, self.module.params["stop_timeout"]
) )
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error stopping container {container_id}: {exc}") self.fail(f"Error stopping container {container_id}: {exc}")

View File

@ -78,14 +78,13 @@ class DockerSocketHandlerBase:
if hasattr(self._sock, "recv"): if hasattr(self._sock, "recv"):
try: try:
data = self._sock.recv(262144) data = self._sock.recv(262144)
except Exception as e: except Exception as e: # pylint: disable=broad-exception-caught
# After calling self._sock.shutdown(), OpenSSL's/urllib3's # After calling self._sock.shutdown(), OpenSSL's/urllib3's
# WrappedSocket seems to eventually raise ZeroReturnError in # WrappedSocket seems to eventually raise ZeroReturnError in
# case of EOF # case of EOF
if "OpenSSL.SSL.ZeroReturnError" in str(type(e)): if "OpenSSL.SSL.ZeroReturnError" in str(type(e)):
self._eof = True self._eof = True
return return
else:
raise raise
elif isinstance(self._sock, getattr(pysocket, "SocketIO")): elif isinstance(self._sock, getattr(pysocket, "SocketIO")):
data = self._sock.read() data = self._sock.read()

View File

@ -67,7 +67,6 @@ def write_to_socket(sock, data):
# WrappedSocket (urllib3/contrib/pyopenssl) does not have `send`, but # WrappedSocket (urllib3/contrib/pyopenssl) does not have `send`, but
# only `sendall`, which uses `_send_until_done` under the hood. # only `sendall`, which uses `_send_until_done` under the hood.
return sock._send_until_done(data) return sock._send_until_done(data)
elif hasattr(sock, "send"): if hasattr(sock, "send"):
return sock.send(data) return sock.send(data)
else:
return os.write(sock.fileno(), data) return os.write(sock.fileno(), data)

View File

@ -74,22 +74,18 @@ class AnsibleDockerSwarmClient(AnsibleDockerClient):
swarm_info = json.loads(json_str) swarm_info = json.loads(json_str)
if swarm_info["Swarm"]["NodeID"]: if swarm_info["Swarm"]["NodeID"]:
return True return True
if swarm_info["Swarm"]["LocalNodeState"] in ( return swarm_info["Swarm"]["LocalNodeState"] in (
"active", "active",
"pending", "pending",
"locked", "locked",
): )
return True
return False return False
else:
try: try:
node_info = self.get_node_inspect(node_id=node_id) node_info = self.get_node_inspect(node_id=node_id)
except APIError: except APIError:
return return
if node_info["ID"] is not None: return node_info["ID"] is not None
return True
return False
def check_if_swarm_manager(self): def check_if_swarm_manager(self):
""" """
@ -138,8 +134,7 @@ class AnsibleDockerSwarmClient(AnsibleDockerClient):
True if node is part of swarm but its state is down, False otherwise True if node is part of swarm but its state is down, False otherwise
""" """
if repeat_check < 1: repeat_check = max(1, repeat_check)
repeat_check = 1
if node_id is None: if node_id is None:
node_id = self.get_swarm_node_id() node_id = self.get_swarm_node_id()
@ -179,7 +174,7 @@ class AnsibleDockerSwarmClient(AnsibleDockerClient):
if skip_missing: if skip_missing:
return None return None
self.fail(f"Error while reading from Swarm manager: {exc}") self.fail(f"Error while reading from Swarm manager: {exc}")
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error inspecting swarm node: {exc}") self.fail(f"Error inspecting swarm node: {exc}")
json_str = json.dumps(node_info, ensure_ascii=False) json_str = json.dumps(node_info, ensure_ascii=False)
@ -215,7 +210,7 @@ class AnsibleDockerSwarmClient(AnsibleDockerClient):
"Cannot inspect node: To inspect node execute module on Swarm Manager" "Cannot inspect node: To inspect node execute module on Swarm Manager"
) )
self.fail(f"Error while reading from Swarm manager: {exc}") self.fail(f"Error while reading from Swarm manager: {exc}")
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error inspecting swarm node: {exc}") self.fail(f"Error inspecting swarm node: {exc}")
json_str = json.dumps(node_info, ensure_ascii=False) json_str = json.dumps(node_info, ensure_ascii=False)
@ -295,7 +290,7 @@ class AnsibleDockerSwarmClient(AnsibleDockerClient):
"Cannot inspect service: To inspect service execute module on Swarm Manager" "Cannot inspect service: To inspect service execute module on Swarm Manager"
) )
self.fail(f"Error inspecting swarm service: {exc}") self.fail(f"Error inspecting swarm service: {exc}")
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error inspecting swarm service: {exc}") self.fail(f"Error inspecting swarm service: {exc}")
json_str = json.dumps(service_info, ensure_ascii=False) json_str = json.dumps(service_info, ensure_ascii=False)

View File

@ -56,13 +56,11 @@ DOCKER_COMMON_ARGS = dict(
debug=dict(type="bool", default=False), debug=dict(type="bool", default=False),
) )
DOCKER_COMMON_ARGS_VARS = dict( DOCKER_COMMON_ARGS_VARS = {
[ option_name: f"ansible_docker_{option_name}"
[option_name, f"ansible_docker_{option_name}"]
for option_name in DOCKER_COMMON_ARGS for option_name in DOCKER_COMMON_ARGS
if option_name != "debug" if option_name != "debug"
] }
)
DOCKER_MUTUALLY_EXCLUSIVE = [] DOCKER_MUTUALLY_EXCLUSIVE = []
@ -100,9 +98,8 @@ def sanitize_result(data):
""" """
if isinstance(data, dict): if isinstance(data, dict):
return dict((k, sanitize_result(v)) for k, v in data.items()) return dict((k, sanitize_result(v)) for k, v in data.items())
elif isinstance(data, (list, tuple)): if isinstance(data, (list, tuple)):
return [sanitize_result(v) for v in data] return [sanitize_result(v) for v in data]
else:
return data return data
@ -196,10 +193,9 @@ def compare_generic(a, b, method, datatype):
# Do proper comparison (both objects not None) # Do proper comparison (both objects not None)
if datatype == "value": if datatype == "value":
return a == b return a == b
elif datatype == "list": if datatype == "list":
if method == "strict": if method == "strict":
return a == b return a == b
else:
i = 0 i = 0
for v in a: for v in a:
while i < len(b) and b[i] != v: while i < len(b) and b[i] != v:
@ -208,19 +204,17 @@ def compare_generic(a, b, method, datatype):
return False return False
i += 1 i += 1
return True return True
elif datatype == "dict": if datatype == "dict":
if method == "strict": if method == "strict":
return a == b return a == b
else:
return compare_dict_allow_more_present(a, b) return compare_dict_allow_more_present(a, b)
elif datatype == "set": if datatype == "set":
set_a = set(a) set_a = set(a)
set_b = set(b) set_b = set(b)
if method == "strict": if method == "strict":
return set_a == set_b return set_a == set_b
else:
return set_b >= set_a return set_b >= set_a
elif datatype == "set(dict)": if datatype == "set(dict)":
for av in a: for av in a:
found = False found = False
for bv in b: for bv in b:
@ -337,9 +331,8 @@ def clean_dict_booleans_for_docker_api(data, allow_sequences=False):
def sanitize(value): def sanitize(value):
if value is True: if value is True:
return "true" return "true"
elif value is False: if value is False:
return "false" return "false"
else:
return str(value) return str(value)
result = dict() result = dict()

View File

@ -243,7 +243,7 @@ class ConfigManager(DockerBaseClass):
try: try:
with open(data_src, "rb") as f: with open(data_src, "rb") as f:
self.data = f.read() self.data = f.read()
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.client.fail(f"Error while reading {data_src}: {exc}") self.client.fail(f"Error while reading {data_src}: {exc}")
self.labels = parameters.get("labels") self.labels = parameters.get("labels")
self.force = parameters.get("force") self.force = parameters.get("force")

View File

@ -343,31 +343,31 @@ def retrieve_diff(
diff["before_header"] = container_path diff["before_header"] = container_path
diff["before"] = "(directory)" diff["before"] = "(directory)"
return return
elif regular_stat["mode"] & (1 << (32 - 4)) != 0: if regular_stat["mode"] & (1 << (32 - 4)) != 0:
diff["before_header"] = container_path diff["before_header"] = container_path
diff["before"] = "(temporary file)" diff["before"] = "(temporary file)"
return return
elif regular_stat["mode"] & (1 << (32 - 5)) != 0: if regular_stat["mode"] & (1 << (32 - 5)) != 0:
diff["before_header"] = container_path diff["before_header"] = container_path
diff["before"] = link_target diff["before"] = link_target
return return
elif regular_stat["mode"] & (1 << (32 - 6)) != 0: if regular_stat["mode"] & (1 << (32 - 6)) != 0:
diff["before_header"] = container_path diff["before_header"] = container_path
diff["before"] = "(device)" diff["before"] = "(device)"
return return
elif regular_stat["mode"] & (1 << (32 - 7)) != 0: if regular_stat["mode"] & (1 << (32 - 7)) != 0:
diff["before_header"] = container_path diff["before_header"] = container_path
diff["before"] = "(named pipe)" diff["before"] = "(named pipe)"
return return
elif regular_stat["mode"] & (1 << (32 - 8)) != 0: if regular_stat["mode"] & (1 << (32 - 8)) != 0:
diff["before_header"] = container_path diff["before_header"] = container_path
diff["before"] = "(socket)" diff["before"] = "(socket)"
return return
elif regular_stat["mode"] & (1 << (32 - 11)) != 0: if regular_stat["mode"] & (1 << (32 - 11)) != 0:
diff["before_header"] = container_path diff["before_header"] = container_path
diff["before"] = "(character device)" diff["before"] = "(character device)"
return return
elif regular_stat["mode"] & (1 << (32 - 13)) != 0: if regular_stat["mode"] & (1 << (32 - 13)) != 0:
diff["before_header"] = container_path diff["before_header"] = container_path
diff["before"] = "(unknown filesystem object)" diff["before"] = "(unknown filesystem object)"
return return
@ -1084,9 +1084,7 @@ def main():
if client.module.params["content_is_b64"]: if client.module.params["content_is_b64"]:
try: try:
content = base64.b64decode(content) content = base64.b64decode(content)
except ( except Exception as e: # pylint: disable=broad-exception-caught
Exception
) as e: # depending on Python version and error, multiple different exceptions can be raised
client.fail(f"Cannot Base64 decode the content option: {e}") client.fail(f"Cannot Base64 decode the content option: {e}")
else: else:
content = to_bytes(content) content = to_bytes(content)

View File

@ -271,7 +271,6 @@ class DockerHostManager(DockerBaseClass):
try: try:
if self.verbose_output: if self.verbose_output:
return self.client.df() return self.client.df()
else:
return dict(LayersSize=self.client.df()["LayersSize"]) return dict(LayersSize=self.client.df()["LayersSize"])
except APIError as exc: except APIError as exc:
self.client.fail(f"Error inspecting docker host: {exc}") self.client.fail(f"Error inspecting docker host: {exc}")

View File

@ -618,7 +618,7 @@ class ImageManager(DockerBaseClass):
except NotFound: except NotFound:
# If the image vanished while we were trying to remove it, do not fail # If the image vanished while we were trying to remove it, do not fail
pass pass
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error removing image {name} - {exc}") self.fail(f"Error removing image {name} - {exc}")
self.results["changed"] = True self.results["changed"] = True
@ -656,12 +656,11 @@ class ImageManager(DockerBaseClass):
if archived is None: if archived is None:
return build_msg("since none present") return build_msg("since none present")
elif ( if (
current_image_id == api_image_id(archived.image_id) current_image_id == api_image_id(archived.image_id)
and [current_image_name] == archived.repo_tags and [current_image_name] == archived.repo_tags
): ):
return None return None
else:
name = ", ".join(archived.repo_tags) name = ", ".join(archived.repo_tags)
return build_msg( return build_msg(
@ -714,14 +713,14 @@ class ImageManager(DockerBaseClass):
DEFAULT_DATA_CHUNK_SIZE, DEFAULT_DATA_CHUNK_SIZE,
False, False,
) )
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error getting image {image_name} - {exc}") self.fail(f"Error getting image {image_name} - {exc}")
try: try:
with open(self.archive_path, "wb") as fd: with open(self.archive_path, "wb") as fd:
for chunk in saved_image: for chunk in saved_image:
fd.write(chunk) fd.write(chunk)
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error writing image archive {self.archive_path} - {exc}") self.fail(f"Error writing image archive {self.archive_path} - {exc}")
self.results["image"] = image self.results["image"] = image
@ -779,12 +778,12 @@ class ImageManager(DockerBaseClass):
for line in self.client._stream_helper(response, decode=True): for line in self.client._stream_helper(response, decode=True):
self.log(line, pretty_print=True) self.log(line, pretty_print=True)
if line.get("errorDetail"): if line.get("errorDetail"):
raise Exception(line["errorDetail"]["message"]) raise RuntimeError(line["errorDetail"]["message"])
status = line.get("status") status = line.get("status")
if status == "Pushing": if status == "Pushing":
changed = True changed = True
self.results["changed"] = changed self.results["changed"] = changed
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
if "unauthorized" in str(exc): if "unauthorized" in str(exc):
if "authentication required" in str(exc): if "authentication required" in str(exc):
self.fail( self.fail(
@ -842,8 +841,8 @@ class ImageManager(DockerBaseClass):
) )
self.client._raise_for_status(res) self.client._raise_for_status(res)
if res.status_code != 201: if res.status_code != 201:
raise Exception("Tag operation failed.") raise RuntimeError("Tag operation failed.")
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error: failed to tag image - {exc}") self.fail(f"Error: failed to tag image - {exc}")
self.results["image"] = self.client.find_image(name=repo, tag=repo_tag) self.results["image"] = self.client.find_image(name=repo, tag=repo_tag)
if image and image["Id"] == self.results["image"]["Id"]: if image and image["Id"] == self.results["image"]["Id"]:
@ -969,9 +968,9 @@ class ImageManager(DockerBaseClass):
if line.get("error"): if line.get("error"):
if line.get("errorDetail"): if line.get("errorDetail"):
errorDetail = line.get("errorDetail") error_detail = line.get("errorDetail")
self.fail( self.fail(
f"Error building {self.name} - code: {errorDetail.get('code')}, message: {errorDetail.get('message')}, logs: {build_output}" f"Error building {self.name} - code: {error_detail.get('code')}, message: {error_detail.get('message')}, logs: {build_output}"
) )
else: else:
self.fail( self.fail(
@ -1019,7 +1018,7 @@ class ImageManager(DockerBaseClass):
f"Error loading image {self.name} - {exc}", f"Error loading image {self.name} - {exc}",
stdout="\n".join(load_output), stdout="\n".join(load_output),
) )
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.client.fail( self.client.fail(
f"Error loading image {self.name} - {exc}", f"Error loading image {self.name} - {exc}",
stdout="\n".join(load_output), stdout="\n".join(load_output),
@ -1076,7 +1075,6 @@ class ImageManager(DockerBaseClass):
if is_image_name_id(self.name): if is_image_name_id(self.name):
return self.client.find_image_by_id(self.name, accept_missing_image=True) return self.client.find_image_by_id(self.name, accept_missing_image=True)
else:
return self.client.find_image(self.name, self.tag) return self.client.find_image(self.name, self.tag)

View File

@ -189,7 +189,7 @@ class ImageExportManager(DockerBaseClass):
with open(self.path, "wb") as fd: with open(self.path, "wb") as fd:
for chunk in chunks: for chunk in chunks:
fd.write(chunk) fd.write(chunk)
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error writing image archive {self.path} - {exc}") self.fail(f"Error writing image archive {self.path} - {exc}")
def export_images(self): def export_images(self):
@ -205,7 +205,7 @@ class ImageExportManager(DockerBaseClass):
DEFAULT_DATA_CHUNK_SIZE, DEFAULT_DATA_CHUNK_SIZE,
False, False,
) )
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error getting image {image_names[0]} - {exc}") self.fail(f"Error getting image {image_names[0]} - {exc}")
else: else:
self.log(f"Getting archive of images {image_names_str}") self.log(f"Getting archive of images {image_names_str}")
@ -219,7 +219,7 @@ class ImageExportManager(DockerBaseClass):
DEFAULT_DATA_CHUNK_SIZE, DEFAULT_DATA_CHUNK_SIZE,
False, False,
) )
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error getting images {image_names_str} - {exc}") self.fail(f"Error getting images {image_names_str} - {exc}")
self.write_chunks(chunks) self.write_chunks(chunks)

View File

@ -212,7 +212,7 @@ class ImageManager(DockerBaseClass):
inspection = self.client.get_json("/images/{0}/json", image["Id"]) inspection = self.client.get_json("/images/{0}/json", image["Id"])
except NotFound: except NotFound:
inspection = None inspection = None
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error inspecting image {image['Id']} - {exc}") self.fail(f"Error inspecting image {image['Id']} - {exc}")
results.append(inspection) results.append(inspection)
return results return results

View File

@ -141,7 +141,7 @@ class ImageManager(DockerBaseClass):
f"Error loading archive {self.path} - {exc}", f"Error loading archive {self.path} - {exc}",
stdout="\n".join(load_output), stdout="\n".join(load_output),
) )
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.client.fail( self.client.fail(
f"Error loading archive {self.path} - {exc}", f"Error loading archive {self.path} - {exc}",
stdout="\n".join(load_output), stdout="\n".join(load_output),

View File

@ -155,11 +155,11 @@ class ImagePusher(DockerBaseClass):
for line in self.client._stream_helper(response, decode=True): for line in self.client._stream_helper(response, decode=True):
self.log(line, pretty_print=True) self.log(line, pretty_print=True)
if line.get("errorDetail"): if line.get("errorDetail"):
raise Exception(line["errorDetail"]["message"]) raise RuntimeError(line["errorDetail"]["message"])
status = line.get("status") status = line.get("status")
if status == "Pushing": if status == "Pushing":
results["changed"] = True results["changed"] = True
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
if "unauthorized" in str(exc): if "unauthorized" in str(exc):
if "authentication required" in str(exc): if "authentication required" in str(exc):
self.client.fail( self.client.fail(

View File

@ -194,7 +194,7 @@ class ImageRemover(DockerBaseClass):
except NotFound: except NotFound:
# If the image vanished while we were trying to remove it, do not fail # If the image vanished while we were trying to remove it, do not fail
res = [] res = []
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error removing image {name} - {exc}") self.fail(f"Error removing image {name} - {exc}")
for entry in res: for entry in res:

View File

@ -214,8 +214,8 @@ class ImageTagger(DockerBaseClass):
) )
self.client._raise_for_status(res) self.client._raise_for_status(res)
if res.status_code != 201: if res.status_code != 201:
raise Exception("Tag operation failed.") raise RuntimeError("Tag operation failed.")
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error: failed to tag image as {name}:{tag} - {exc}") self.fail(f"Error: failed to tag image as {name}:{tag} - {exc}")
return True, msg, tagged_image return True, msg, tagged_image

View File

@ -309,7 +309,7 @@ class LoginManager(DockerBaseClass):
self.log(f"Log into {self.registry_url} with username {self.username}") self.log(f"Log into {self.registry_url} with username {self.username}")
try: try:
response = self._login(self.reauthorize) response = self._login(self.reauthorize)
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail( self.fail(
f"Logging into {self.registry_url} for user {self.username} failed - {exc}" f"Logging into {self.registry_url} for user {self.username} failed - {exc}"
) )
@ -322,7 +322,7 @@ class LoginManager(DockerBaseClass):
if not self.reauthorize and response["password"] != self.password: if not self.reauthorize and response["password"] != self.password:
try: try:
response = self._login(True) response = self._login(True)
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.fail( self.fail(
f"Logging into {self.registry_url} for user {self.username} failed - {exc}" f"Logging into {self.registry_url} for user {self.username} failed - {exc}"
) )

View File

@ -359,7 +359,7 @@ def validate_cidr(cidr):
""" """
if CIDR_IPV4.match(cidr): if CIDR_IPV4.match(cidr):
return "ipv4" return "ipv4"
elif CIDR_IPV6.match(cidr): if CIDR_IPV6.match(cidr):
return "ipv6" return "ipv6"
raise ValueError(f'"{cidr}" is not a valid CIDR') raise ValueError(f'"{cidr}" is not a valid CIDR')

View File

@ -235,7 +235,7 @@ class SecretManager(DockerBaseClass):
try: try:
with open(data_src, "rb") as f: with open(data_src, "rb") as f:
self.data = f.read() self.data = f.read()
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
self.client.fail(f"Error while reading {data_src}: {exc}") self.client.fail(f"Error while reading {data_src}: {exc}")
self.labels = parameters.get("labels") self.labels = parameters.get("labels")
self.force = parameters.get("force") self.force = parameters.get("force")

View File

@ -196,7 +196,6 @@ def docker_service_inspect(client, service_name):
rc, out, err = client.call_cli("service", "inspect", service_name) rc, out, err = client.call_cli("service", "inspect", service_name)
if rc != 0: if rc != 0:
return None return None
else:
ret = json.loads(out)[0]["Spec"] ret = json.loads(out)[0]["Spec"]
return ret return ret

View File

@ -323,6 +323,7 @@ class TaskParameters(DockerBaseClass):
self.join_token = None self.join_token = None
self.data_path_addr = None self.data_path_addr = None
self.data_path_port = None self.data_path_port = None
self.spec = None
# Spec # Spec
self.snapshot_interval = None self.snapshot_interval = None

View File

@ -932,7 +932,6 @@ def get_docker_environment(env, env_files):
if not env_list: if not env_list:
if env is not None or env_files is not None: if env is not None or env_files is not None:
return [] return []
else:
return None return None
return sorted(env_list) return sorted(env_list)
@ -992,14 +991,13 @@ def get_docker_networks(networks, network_ids):
def get_nanoseconds_from_raw_option(name, value): def get_nanoseconds_from_raw_option(name, value):
if value is None: if value is None:
return None return None
elif isinstance(value, int): if isinstance(value, int):
return value return value
elif isinstance(value, str): if isinstance(value, str):
try: try:
return int(value) return int(value)
except ValueError: except ValueError:
return convert_duration_to_nanosecond(value) return convert_duration_to_nanosecond(value)
else:
raise ValueError( raise ValueError(
f"Invalid type for {name} {value} ({type(value)}). Only string or int allowed." f"Invalid type for {name} {value} ({type(value)}). Only string or int allowed."
) )
@ -1046,8 +1044,7 @@ def has_list_changed(new_list, old_list, sort_lists=True, sort_key=None):
if unsorted_list and isinstance(unsorted_list[0], dict): if unsorted_list and isinstance(unsorted_list[0], dict):
if not sort_key: if not sort_key:
raise Exception("A sort key was not specified when sorting list") raise ValueError("A sort key was not specified when sorting list")
else:
return sorted(unsorted_list, key=lambda k: k[sort_key]) return sorted(unsorted_list, key=lambda k: k[sort_key])
# Either the list is empty or does not contain dictionaries # Either the list is empty or does not contain dictionaries
@ -1081,7 +1078,6 @@ def has_list_changed(new_list, old_list, sort_lists=True, sort_key=None):
old_item_casted = new_item_type(old_item) old_item_casted = new_item_type(old_item)
if new_item != old_item_casted: if new_item != old_item_casted:
return True return True
else:
continue continue
except UnicodeEncodeError: except UnicodeEncodeError:
# Fallback to assuming the strings are different # Fallback to assuming the strings are different
@ -1374,7 +1370,7 @@ class DockerService(DockerBaseClass):
try: try:
memory = human_to_bytes(memory) memory = human_to_bytes(memory)
except ValueError as exc: except ValueError as exc:
raise Exception(f"Failed to convert limit_memory to bytes: {exc}") raise ValueError(f"Failed to convert limit_memory to bytes: {exc}")
return { return {
"limit_cpu": cpus, "limit_cpu": cpus,
"limit_memory": memory, "limit_memory": memory,
@ -1396,7 +1392,7 @@ class DockerService(DockerBaseClass):
try: try:
memory = human_to_bytes(memory) memory = human_to_bytes(memory)
except ValueError as exc: except ValueError as exc:
raise Exception(f"Failed to convert reserve_memory to bytes: {exc}") raise ValueError(f"Failed to convert reserve_memory to bytes: {exc}")
return { return {
"reserve_cpu": cpus, "reserve_cpu": cpus,
"reserve_memory": memory, "reserve_memory": memory,
@ -1470,7 +1466,7 @@ class DockerService(DockerBaseClass):
for index, item in invalid_items for index, item in invalid_items
] ]
) )
raise Exception( raise ValueError(
"All items in a command list need to be strings. " "All items in a command list need to be strings. "
f"Check quoting. Invalid items: {errors}." f"Check quoting. Invalid items: {errors}."
) )
@ -2339,7 +2335,7 @@ class DockerServiceManager:
ds.mode = to_text("replicated-job", encoding="utf-8") ds.mode = to_text("replicated-job", encoding="utf-8")
ds.replicas = mode["ReplicatedJob"]["TotalCompletions"] ds.replicas = mode["ReplicatedJob"]["TotalCompletions"]
else: else:
raise Exception(f"Unknown service mode: {mode}") raise ValueError(f"Unknown service mode: {mode}")
raw_data_mounts = task_template_data["ContainerSpec"].get("Mounts") raw_data_mounts = task_template_data["ContainerSpec"].get("Mounts")
if raw_data_mounts: if raw_data_mounts:
@ -2510,7 +2506,7 @@ class DockerServiceManager:
try: try:
current_service = self.get_service(module.params["name"]) current_service = self.get_service(module.params["name"])
except Exception as e: except Exception as e: # pylint: disable=broad-exception-caught
self.client.fail( self.client.fail(
f"Error looking for service named {module.params['name']}: {e}" f"Error looking for service named {module.params['name']}: {e}"
) )
@ -2527,7 +2523,7 @@ class DockerServiceManager:
network_ids, network_ids,
self.client, self.client,
) )
except Exception as e: except Exception as e: # pylint: disable=broad-exception-caught
return self.client.fail(f"Error parsing module parameters: {e}") return self.client.fail(f"Error parsing module parameters: {e}")
changed = False changed = False

View File

@ -87,7 +87,7 @@ def get_existing_volume(client, volume_name):
return client.get_json("/volumes/{0}", volume_name) return client.get_json("/volumes/{0}", volume_name)
except NotFound: except NotFound:
return None return None
except Exception as exc: except Exception as exc: # pylint: disable=broad-exception-caught
client.fail(f"Error inspecting volume: {exc}") client.fail(f"Error inspecting volume: {exc}")

View File

@ -40,6 +40,4 @@ class AnsibleDockerClient(AnsibleDockerClientBase):
) )
def _get_params(self): def _get_params(self):
return dict( return {option: self.plugin.get_option(option) for option in DOCKER_COMMON_ARGS}
[(option, self.plugin.get_option(option)) for option in DOCKER_COMMON_ARGS]
)

View File

@ -37,6 +37,4 @@ class AnsibleDockerClient(AnsibleDockerClientBase):
) )
def _get_params(self): def _get_params(self):
return dict( return {option: self.plugin.get_option(option) for option in DOCKER_COMMON_ARGS}
[(option, self.plugin.get_option(option)) for option in DOCKER_COMMON_ARGS]
)

View File

@ -27,15 +27,15 @@ def make_unsafe(value):
if isinstance(value, Mapping): if isinstance(value, Mapping):
return dict((make_unsafe(key), make_unsafe(val)) for key, val in value.items()) return dict((make_unsafe(key), make_unsafe(val)) for key, val in value.items())
elif isinstance(value, Set): if isinstance(value, Set):
return set(make_unsafe(elt) for elt in value) return set(make_unsafe(elt) for elt in value)
elif is_sequence(value): if is_sequence(value):
return type(value)(make_unsafe(elt) for elt in value) return type(value)(make_unsafe(elt) for elt in value)
elif isinstance(value, bytes): if isinstance(value, bytes):
if _RE_TEMPLATE_CHARS_BYTES.search(value): if _RE_TEMPLATE_CHARS_BYTES.search(value):
value = _make_unsafe(value) value = _make_unsafe(value)
return value return value
elif isinstance(value, str): if isinstance(value, str):
if _RE_TEMPLATE_CHARS.search(value): if _RE_TEMPLATE_CHARS.search(value):
value = _make_unsafe(value) value = _make_unsafe(value)
return value return value

View File

@ -72,7 +72,9 @@ def response(
return res return res
def fake_resolve_authconfig(authconfig, registry=None, *args, **kwargs): def fake_resolve_authconfig(
authconfig, registry=None, *args, **kwargs
): # pylint: disable=keyword-arg-before-vararg
return None return None
@ -87,7 +89,7 @@ def fake_resp(method, url, *args, **kwargs):
elif (url, method) in fake_api.fake_responses: elif (url, method) in fake_api.fake_responses:
key = (url, method) key = (url, method)
if not key: if not key:
raise Exception(f"{method} {url}") raise NotImplementedError(f"{method} {url}")
status_code, content = fake_api.fake_responses[key]() status_code, content = fake_api.fake_responses[key]()
return response(status_code=status_code, content=content) return response(status_code=status_code, content=content)
@ -115,8 +117,8 @@ def fake_read_from_socket(self, response, stream, tty=False, demux=False):
return b"" return b""
url_base = f"{fake_api.prefix}/" url_base = f"{fake_api.prefix}/" # pylint: disable=invalid-name
url_prefix = f"{url_base}v{DEFAULT_DOCKER_API_VERSION}/" url_prefix = f"{url_base}v{DEFAULT_DOCKER_API_VERSION}/" # pylint: disable=invalid-name
class BaseAPIClientTest(unittest.TestCase): class BaseAPIClientTest(unittest.TestCase):
@ -482,7 +484,7 @@ class TCPSocketStreamTest(unittest.TestCase):
stderr_data = cls.stderr_data stderr_data = cls.stderr_data
class Handler(BaseHTTPRequestHandler): class Handler(BaseHTTPRequestHandler):
def do_POST(self): def do_POST(self): # pylint: disable=invalid-name
resp_data = self.get_resp_data() resp_data = self.get_resp_data()
self.send_response(101) self.send_response(101)
self.send_header("Content-Type", "application/vnd.docker.raw-stream") self.send_header("Content-Type", "application/vnd.docker.raw-stream")
@ -498,15 +500,14 @@ class TCPSocketStreamTest(unittest.TestCase):
path = self.path.split("/")[-1] path = self.path.split("/")[-1]
if path == "tty": if path == "tty":
return stdout_data + stderr_data return stdout_data + stderr_data
elif path == "no-tty": if path == "no-tty":
data = b"" data = b""
data += self.frame_header(1, stdout_data) data += self.frame_header(1, stdout_data)
data += stdout_data data += stdout_data
data += self.frame_header(2, stderr_data) data += self.frame_header(2, stderr_data)
data += stderr_data data += stderr_data
return data return data
else: raise NotImplementedError(f"Unknown path {path}")
raise Exception(f"Unknown path {path}")
@staticmethod @staticmethod
def frame_header(stream, data): def frame_header(stream, data):
@ -604,6 +605,7 @@ class DisableSocketTest(unittest.TestCase):
class DummySocket: class DummySocket:
def __init__(self, timeout=60): def __init__(self, timeout=60):
self.timeout = timeout self.timeout = timeout
self._sock = None
def settimeout(self, timeout): def settimeout(self, timeout):
self.timeout = timeout self.timeout = timeout

View File

@ -537,9 +537,9 @@ def post_fake_secret():
# Maps real api url to fake response callback # Maps real api url to fake response callback
prefix = "http+docker://localhost" prefix = "http+docker://localhost" # pylint: disable=invalid-name
if constants.IS_WINDOWS_PLATFORM: if constants.IS_WINDOWS_PLATFORM:
prefix = "http+docker://localnpipe" prefix = "http+docker://localnpipe" # pylint: disable=invalid-name
fake_responses = { fake_responses = {
f"{prefix}/version": get_fake_version, f"{prefix}/version": get_fake_version,

View File

@ -417,7 +417,7 @@ class TarTest(unittest.TestCase):
self.addCleanup(shutil.rmtree, base) self.addCleanup(shutil.rmtree, base)
with tar(base, exclude=exclude) as archive: with tar(base, exclude=exclude) as archive:
tar_data = tarfile.open(fileobj=archive) with tarfile.open(fileobj=archive) as tar_data:
assert sorted(tar_data.getnames()) == sorted(expected_names) assert sorted(tar_data.getnames()) == sorted(expected_names)
def test_tar_with_empty_directory(self): def test_tar_with_empty_directory(self):
@ -426,7 +426,7 @@ class TarTest(unittest.TestCase):
for d in ["foo", "bar"]: for d in ["foo", "bar"]:
os.makedirs(os.path.join(base, d)) os.makedirs(os.path.join(base, d))
with tar(base) as archive: with tar(base) as archive:
tar_data = tarfile.open(fileobj=archive) with tarfile.open(fileobj=archive) as tar_data:
assert sorted(tar_data.getnames()) == ["bar", "foo"] assert sorted(tar_data.getnames()) == ["bar", "foo"]
@pytest.mark.skipif( @pytest.mark.skipif(
@ -454,7 +454,7 @@ class TarTest(unittest.TestCase):
os.makedirs(os.path.join(base, "bar")) os.makedirs(os.path.join(base, "bar"))
os.symlink("../foo", os.path.join(base, "bar/foo")) os.symlink("../foo", os.path.join(base, "bar/foo"))
with tar(base) as archive: with tar(base) as archive:
tar_data = tarfile.open(fileobj=archive) with tarfile.open(fileobj=archive) as tar_data:
assert sorted(tar_data.getnames()) == ["bar", "bar/foo", "foo"] assert sorted(tar_data.getnames()) == ["bar", "bar/foo", "foo"]
@pytest.mark.skipif(IS_WINDOWS_PLATFORM, reason="No symlinks on Windows") @pytest.mark.skipif(IS_WINDOWS_PLATFORM, reason="No symlinks on Windows")
@ -465,7 +465,7 @@ class TarTest(unittest.TestCase):
os.makedirs(os.path.join(base, d)) os.makedirs(os.path.join(base, d))
os.symlink("../foo", os.path.join(base, "bar/foo")) os.symlink("../foo", os.path.join(base, "bar/foo"))
with tar(base) as archive: with tar(base) as archive:
tar_data = tarfile.open(fileobj=archive) with tarfile.open(fileobj=archive) as tar_data:
assert sorted(tar_data.getnames()) == ["bar", "bar/foo", "foo"] assert sorted(tar_data.getnames()) == ["bar", "bar/foo", "foo"]
@pytest.mark.skipif(IS_WINDOWS_PLATFORM, reason="No symlinks on Windows") @pytest.mark.skipif(IS_WINDOWS_PLATFORM, reason="No symlinks on Windows")
@ -477,7 +477,7 @@ class TarTest(unittest.TestCase):
os.symlink("../baz", os.path.join(base, "bar/foo")) os.symlink("../baz", os.path.join(base, "bar/foo"))
with tar(base) as archive: with tar(base) as archive:
tar_data = tarfile.open(fileobj=archive) with tarfile.open(fileobj=archive) as tar_data:
assert sorted(tar_data.getnames()) == ["bar", "bar/foo", "foo"] assert sorted(tar_data.getnames()) == ["bar", "bar/foo", "foo"]
@pytest.mark.skipif(IS_WINDOWS_PLATFORM, reason="No UNIX sockets on Win32") @pytest.mark.skipif(IS_WINDOWS_PLATFORM, reason="No UNIX sockets on Win32")
@ -490,7 +490,7 @@ class TarTest(unittest.TestCase):
self.addCleanup(sock.close) self.addCleanup(sock.close)
sock.bind(os.path.join(base, "test.sock")) sock.bind(os.path.join(base, "test.sock"))
with tar(base) as archive: with tar(base) as archive:
tar_data = tarfile.open(fileobj=archive) with tarfile.open(fileobj=archive) as tar_data:
assert sorted(tar_data.getnames()) == ["bar", "foo"] assert sorted(tar_data.getnames()) == ["bar", "foo"]
def tar_test_negative_mtime_bug(self): def tar_test_negative_mtime_bug(self):
@ -501,7 +501,7 @@ class TarTest(unittest.TestCase):
f.write("Invisible Full Moon") f.write("Invisible Full Moon")
os.utime(filename, (12345, -3600.0)) os.utime(filename, (12345, -3600.0))
with tar(base) as archive: with tar(base) as archive:
tar_data = tarfile.open(fileobj=archive) with tarfile.open(fileobj=archive) as tar_data:
assert tar_data.getnames() == ["th.txt"] assert tar_data.getnames() == ["th.txt"]
assert tar_data.getmember("th.txt").mtime == -3600 assert tar_data.getmember("th.txt").mtime == -3600
@ -513,7 +513,7 @@ class TarTest(unittest.TestCase):
self.addCleanup(shutil.rmtree, base) self.addCleanup(shutil.rmtree, base)
os.symlink(os.path.join(base, "b"), os.path.join(base, "a/c/b")) os.symlink(os.path.join(base, "b"), os.path.join(base, "a/c/b"))
with tar(base) as archive: with tar(base) as archive:
tar_data = tarfile.open(fileobj=archive) with tarfile.open(fileobj=archive) as tar_data:
names = tar_data.getnames() names = tar_data.getnames()
for member in dirs + files: for member in dirs + files:
assert member in names assert member in names

View File

@ -12,6 +12,7 @@ import json
import os import os
import shutil import shutil
import tempfile import tempfile
import typing as t
import unittest import unittest
from pytest import fixture, mark from pytest import fixture, mark
@ -26,6 +27,7 @@ except ImportError:
class FindConfigFileTest(unittest.TestCase): class FindConfigFileTest(unittest.TestCase):
mkdir: t.Callable[[str], os.PathLike[str]]
@fixture(autouse=True) @fixture(autouse=True)
def tmpdir(self, tmpdir): def tmpdir(self, tmpdir):

View File

@ -205,9 +205,8 @@ class ParseEnvFileTest(unittest.TestCase):
of 'file_content' and returns the filename. of 'file_content' and returns the filename.
Don't forget to unlink the file with os.unlink() after. Don't forget to unlink the file with os.unlink() after.
""" """
local_tempfile = tempfile.NamedTemporaryFile(delete=False) with tempfile.NamedTemporaryFile(delete=False) as local_tempfile:
local_tempfile.write(file_content.encode("UTF-8")) local_tempfile.write(file_content.encode("UTF-8"))
local_tempfile.close()
return local_tempfile.name return local_tempfile.name
def test_parse_env_file_proper(self): def test_parse_env_file_proper(self):

View File

@ -2,6 +2,8 @@
# 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
# pylint: disable=line-too-long
from __future__ import annotations from __future__ import annotations
from ansible_collections.community.docker.plugins.module_utils._compose_v2 import ( from ansible_collections.community.docker.plugins.module_utils._compose_v2 import (

View File

@ -50,8 +50,7 @@ def write_irrelevant_tar(file_name):
:type file_name: str :type file_name: str
""" """
tf = tarfile.open(file_name, "w") with tarfile.open(file_name, "w") as tf:
try:
with TemporaryFile() as f: with TemporaryFile() as f:
f.write("Hello, world.".encode("utf-8")) f.write("Hello, world.".encode("utf-8"))
@ -60,6 +59,3 @@ def write_irrelevant_tar(file_name):
f.seek(0) f.seek(0)
tf.addfile(ti, f) tf.addfile(ti, f)
finally:
tf.close()