mirror of
https://github.com/ansible-collections/community.docker.git
synced 2026-07-29 03:46:55 +00:00
Cleanup with ruff check (#1182)
* Implement improvements suggested by ruff check. * Add ruff check to CI.
This commit is contained in:
@@ -698,9 +698,7 @@ class APIClient(_Session):
|
||||
if auth.INDEX_URL not in auth_data and auth.INDEX_NAME in auth_data:
|
||||
auth_data[auth.INDEX_URL] = auth_data.get(auth.INDEX_NAME, {})
|
||||
|
||||
log.debug(
|
||||
"Sending auth config (%s)", ", ".join(repr(k) for k in auth_data.keys())
|
||||
)
|
||||
log.debug("Sending auth config (%s)", ", ".join(repr(k) for k in auth_data))
|
||||
|
||||
if auth_data:
|
||||
headers["X-Registry-Config"] = auth.encode_header(auth_data)
|
||||
|
||||
@@ -292,7 +292,7 @@ class AuthConfig(dict):
|
||||
log.debug("No entry found")
|
||||
return None
|
||||
except StoreError as e:
|
||||
raise errors.DockerException(f"Credentials store error: {e}")
|
||||
raise errors.DockerException(f"Credentials store error: {e}") from e
|
||||
|
||||
def _get_store_instance(self, name: str) -> Store:
|
||||
if name not in self._stores:
|
||||
@@ -310,7 +310,7 @@ class AuthConfig(dict):
|
||||
if self.creds_store:
|
||||
# Retrieve all credentials from the default store
|
||||
store = self._get_store_instance(self.creds_store)
|
||||
for k in store.list().keys():
|
||||
for k in store.list():
|
||||
auth_data[k] = self._resolve_authconfig_credstore(k, self.creds_store)
|
||||
auth_data[convert_to_hostname(k)] = auth_data[k]
|
||||
|
||||
|
||||
@@ -102,8 +102,7 @@ def get_tls_dir(name: str | None = None, endpoint: str = "") -> str:
|
||||
|
||||
def get_context_host(path: str | None = None, tls: bool = False) -> str:
|
||||
host = parse_host(path, IS_WINDOWS_PLATFORM, tls)
|
||||
if host == DEFAULT_UNIX_SOCKET:
|
||||
if host == DEFAULT_UNIX_SOCKET and host.startswith("http+"):
|
||||
# remove http+ from default docker socket url
|
||||
if host.startswith("http+"):
|
||||
host = host[5:]
|
||||
host = host[5:]
|
||||
return host
|
||||
|
||||
@@ -90,13 +90,13 @@ class Store:
|
||||
env=env,
|
||||
)
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise errors.process_store_error(e, self.program)
|
||||
raise errors.process_store_error(e, self.program) from e
|
||||
except OSError as e:
|
||||
if e.errno == errno.ENOENT:
|
||||
raise errors.StoreError(
|
||||
f"{self.program} not installed or not available in PATH"
|
||||
)
|
||||
) from e
|
||||
raise errors.StoreError(
|
||||
f'Unexpected OS error "{e.strerror}", errno={e.errno}'
|
||||
)
|
||||
) from e
|
||||
return output
|
||||
|
||||
@@ -98,7 +98,7 @@ def create_archive(
|
||||
extra_files = extra_files or []
|
||||
if not fileobj:
|
||||
# pylint: disable-next=consider-using-with
|
||||
fileobj = tempfile.NamedTemporaryFile()
|
||||
fileobj = tempfile.NamedTemporaryFile() # noqa: SIM115
|
||||
|
||||
with tarfile.open(mode="w:gz" if gzip else "w", fileobj=fileobj) as tarf:
|
||||
if files is None:
|
||||
@@ -146,7 +146,8 @@ def create_archive(
|
||||
|
||||
|
||||
def mkbuildcontext(dockerfile: io.BytesIO | t.IO[bytes]) -> t.IO[bytes]:
|
||||
f = tempfile.NamedTemporaryFile() # pylint: disable=consider-using-with
|
||||
# pylint: disable-next=consider-using-with
|
||||
f = tempfile.NamedTemporaryFile() # noqa: SIM115
|
||||
try:
|
||||
with tarfile.open(mode="w", fileobj=f) as tarf:
|
||||
if isinstance(dockerfile, io.StringIO): # type: ignore
|
||||
@@ -195,11 +196,14 @@ class PatternMatcher:
|
||||
for pattern in self.patterns:
|
||||
negative = pattern.exclusion
|
||||
match = pattern.match(filepath)
|
||||
if not match and parent_path != "":
|
||||
if len(pattern.dirs) <= len(parent_path_dirs):
|
||||
match = pattern.match(
|
||||
os.path.sep.join(parent_path_dirs[: len(pattern.dirs)])
|
||||
)
|
||||
if (
|
||||
not match
|
||||
and parent_path != ""
|
||||
and len(pattern.dirs) <= len(parent_path_dirs)
|
||||
):
|
||||
match = pattern.match(
|
||||
os.path.sep.join(parent_path_dirs[: len(pattern.dirs)])
|
||||
)
|
||||
|
||||
if match:
|
||||
matched = not negative
|
||||
|
||||
@@ -22,7 +22,7 @@ from ..transport.npipesocket import NpipeSocket
|
||||
|
||||
|
||||
if t.TYPE_CHECKING:
|
||||
from collections.abc import Iterable, Sequence
|
||||
from collections.abc import Sequence
|
||||
|
||||
from ..._socket_helper import SocketLike
|
||||
|
||||
@@ -59,8 +59,8 @@ def read(socket: SocketLike, n: int = 4096) -> bytes | None:
|
||||
try:
|
||||
if hasattr(socket, "recv"):
|
||||
return socket.recv(n)
|
||||
if isinstance(socket, getattr(pysocket, "SocketIO")):
|
||||
return socket.read(n)
|
||||
if isinstance(socket, pysocket.SocketIO): # type: ignore
|
||||
return socket.read(n) # type: ignore[unreachable]
|
||||
return os.read(socket.fileno(), n)
|
||||
except EnvironmentError as e:
|
||||
if e.errno not in recoverable_errors:
|
||||
|
||||
@@ -36,7 +36,6 @@ from ..tls import TLSConfig
|
||||
|
||||
|
||||
if t.TYPE_CHECKING:
|
||||
import ssl
|
||||
from collections.abc import Mapping, Sequence
|
||||
|
||||
|
||||
@@ -298,7 +297,7 @@ def parse_host(addr: str | None, is_win32: bool = False, tls: bool = False) -> s
|
||||
if proto == "unix" and parsed_url.hostname is not None:
|
||||
# For legacy reasons, we consider unix://path
|
||||
# to be valid and equivalent to unix:///path
|
||||
path = "/".join((parsed_url.hostname, path))
|
||||
path = f"{parsed_url.hostname}/{path}"
|
||||
|
||||
netloc = parsed_url.netloc
|
||||
if proto in ("tcp", "ssh"):
|
||||
@@ -429,9 +428,8 @@ def parse_bytes(s: int | float | str) -> int | float:
|
||||
if len(s) == 0:
|
||||
return 0
|
||||
|
||||
if s[-2:-1].isalpha() and s[-1].isalpha():
|
||||
if s[-1] == "b" or s[-1] == "B":
|
||||
s = s[:-1]
|
||||
if s[-2:-1].isalpha() and s[-1].isalpha() and (s[-1] == "b" or s[-1] == "B"):
|
||||
s = s[:-1]
|
||||
units = BYTE_UNITS
|
||||
suffix = s[-1].lower()
|
||||
|
||||
|
||||
@@ -718,9 +718,8 @@ class AnsibleDockerClient(AnsibleDockerClientBase):
|
||||
) -> None:
|
||||
self.option_minimal_versions: dict[str, dict[str, t.Any]] = {}
|
||||
for option in self.module.argument_spec:
|
||||
if ignore_params is not None:
|
||||
if option in ignore_params:
|
||||
continue
|
||||
if ignore_params is not None and option in ignore_params:
|
||||
continue
|
||||
self.option_minimal_versions[option] = {}
|
||||
self.option_minimal_versions.update(option_minimal_versions)
|
||||
|
||||
|
||||
@@ -654,9 +654,8 @@ class AnsibleDockerClient(AnsibleDockerClientBase):
|
||||
) -> None:
|
||||
self.option_minimal_versions: dict[str, dict[str, t.Any]] = {}
|
||||
for option in self.module.argument_spec:
|
||||
if ignore_params is not None:
|
||||
if option in ignore_params:
|
||||
continue
|
||||
if ignore_params is not None and option in ignore_params:
|
||||
continue
|
||||
self.option_minimal_versions[option] = {}
|
||||
self.option_minimal_versions.update(option_minimal_versions)
|
||||
|
||||
|
||||
@@ -690,9 +690,7 @@ def emit_warnings(
|
||||
|
||||
|
||||
def is_failed(events: Sequence[Event], rc: int) -> bool:
|
||||
if rc:
|
||||
return True
|
||||
return False
|
||||
return bool(rc)
|
||||
|
||||
|
||||
def update_failed(
|
||||
|
||||
@@ -479,9 +479,8 @@ def fetch_file(
|
||||
|
||||
reader = tar.extractfile(member)
|
||||
if reader:
|
||||
with reader as in_f:
|
||||
with open(b_out_path, "wb") as out_f:
|
||||
shutil.copyfileobj(in_f, out_f)
|
||||
with reader as in_f, open(b_out_path, "wb") as out_f:
|
||||
shutil.copyfileobj(in_f, out_f)
|
||||
return in_path
|
||||
|
||||
def process_symlink(in_path: str, member: tarfile.TarInfo) -> str:
|
||||
|
||||
@@ -890,14 +890,15 @@ def _preprocess_mounts(
|
||||
check_collision(container, "volumes")
|
||||
new_vols.append(f"{host}:{container}:{mode}")
|
||||
continue
|
||||
if len(parts) == 2:
|
||||
if not _is_volume_permissions(parts[1]) and re.match(
|
||||
r"[.~]", parts[0]
|
||||
):
|
||||
host = os.path.abspath(os.path.expanduser(parts[0]))
|
||||
check_collision(parts[1], "volumes")
|
||||
new_vols.append(f"{host}:{parts[1]}:rw")
|
||||
continue
|
||||
if (
|
||||
len(parts) == 2
|
||||
and not _is_volume_permissions(parts[1])
|
||||
and re.match(r"[.~]", parts[0])
|
||||
):
|
||||
host = os.path.abspath(os.path.expanduser(parts[0]))
|
||||
check_collision(parts[1], "volumes")
|
||||
new_vols.append(f"{host}:{parts[1]}:rw")
|
||||
continue
|
||||
check_collision(parts[min(1, len(parts) - 1)], "volumes")
|
||||
new_vols.append(vol)
|
||||
values["volumes"] = new_vols
|
||||
|
||||
@@ -219,12 +219,11 @@ class DockerAPIEngineDriver(EngineDriver[AnsibleDockerClient]):
|
||||
return False
|
||||
|
||||
def is_container_running(self, container: dict[str, t.Any]) -> bool:
|
||||
if container.get("State"):
|
||||
if container["State"].get("Running") and not container["State"].get(
|
||||
"Ghost", False
|
||||
):
|
||||
return True
|
||||
return False
|
||||
return bool(
|
||||
container.get("State")
|
||||
and container["State"].get("Running")
|
||||
and not container["State"].get("Ghost", False)
|
||||
)
|
||||
|
||||
def is_container_paused(self, container: dict[str, t.Any]) -> bool:
|
||||
if container.get("State"):
|
||||
@@ -1706,9 +1705,8 @@ def _get_expected_values_mounts(
|
||||
parts = vol.split(":")
|
||||
if len(parts) == 3:
|
||||
continue
|
||||
if len(parts) == 2:
|
||||
if not _is_volume_permissions(parts[1]):
|
||||
continue
|
||||
if len(parts) == 2 and not _is_volume_permissions(parts[1]):
|
||||
continue
|
||||
expected_vols[vol] = {}
|
||||
if expected_vols:
|
||||
expected_values["volumes"] = expected_vols
|
||||
@@ -1805,9 +1803,8 @@ def _set_values_mounts(
|
||||
parts = volume.split(":")
|
||||
if len(parts) == 3:
|
||||
continue
|
||||
if len(parts) == 2:
|
||||
if not _is_volume_permissions(parts[1]):
|
||||
continue
|
||||
if len(parts) == 2 and not _is_volume_permissions(parts[1]):
|
||||
continue
|
||||
volumes[volume] = {}
|
||||
data["Volumes"] = volumes
|
||||
if "volume_binds" in values:
|
||||
|
||||
@@ -217,11 +217,13 @@ class ContainerManager(DockerBaseClass, t.Generic[Client]):
|
||||
"The wildcard can only be used with comparison modes 'strict' and 'ignore'!"
|
||||
)
|
||||
for option in self.all_options.values():
|
||||
if option.name == "networks":
|
||||
# `networks` is special: only update if
|
||||
# some value is actually specified
|
||||
if self.module.params["networks"] is None:
|
||||
continue
|
||||
# `networks` is special: only update if
|
||||
# some value is actually specified
|
||||
if (
|
||||
option.name == "networks"
|
||||
and self.module.params["networks"] is None
|
||||
):
|
||||
continue
|
||||
option.comparison = value
|
||||
# Now process all other comparisons.
|
||||
comp_aliases_used: dict[str, str] = {}
|
||||
@@ -679,13 +681,17 @@ class ContainerManager(DockerBaseClass, t.Generic[Client]):
|
||||
def _image_is_different(
|
||||
self, image: dict[str, t.Any] | None, container: Container
|
||||
) -> bool:
|
||||
if image and image.get("Id"):
|
||||
if container and container.image:
|
||||
if image.get("Id") != container.image:
|
||||
self.diff_tracker.add(
|
||||
"image", parameter=image.get("Id"), active=container.image
|
||||
)
|
||||
return True
|
||||
if (
|
||||
image
|
||||
and image.get("Id")
|
||||
and container
|
||||
and container.image
|
||||
and image.get("Id") != container.image
|
||||
):
|
||||
self.diff_tracker.add(
|
||||
"image", parameter=image.get("Id"), active=container.image
|
||||
)
|
||||
return True
|
||||
return False
|
||||
|
||||
def _compose_create_parameters(self, image: str) -> dict[str, t.Any]:
|
||||
@@ -927,14 +933,13 @@ class ContainerManager(DockerBaseClass, t.Generic[Client]):
|
||||
"ipv6_address"
|
||||
] != network_info_ipam.get("IPv6Address"):
|
||||
diff = True
|
||||
if network.get("aliases"):
|
||||
if not compare_generic(
|
||||
network["aliases"],
|
||||
network_info.get("Aliases"),
|
||||
"allow_more_present",
|
||||
"set",
|
||||
):
|
||||
diff = True
|
||||
if network.get("aliases") and not compare_generic(
|
||||
network["aliases"],
|
||||
network_info.get("Aliases"),
|
||||
"allow_more_present",
|
||||
"set",
|
||||
):
|
||||
diff = True
|
||||
if network.get("links"):
|
||||
expected_links = []
|
||||
for link, alias in network["links"]:
|
||||
|
||||
@@ -73,7 +73,7 @@ class DockerSocketHandlerBase:
|
||||
|
||||
def __exit__(
|
||||
self,
|
||||
type_: t.Type[BaseException] | None,
|
||||
type_: type[BaseException] | None,
|
||||
value: BaseException | None,
|
||||
tb: TracebackType | None,
|
||||
) -> None:
|
||||
@@ -199,10 +199,9 @@ class DockerSocketHandlerBase:
|
||||
if event & selectors.EVENT_WRITE != 0:
|
||||
self._write()
|
||||
result = len(events)
|
||||
if self._paramiko_read_workaround and len(self._write_buffer) > 0:
|
||||
if self._sock.send_ready(): # type: ignore
|
||||
self._write()
|
||||
result += 1
|
||||
if self._paramiko_read_workaround and len(self._write_buffer) > 0 and self._sock.send_ready(): # type: ignore
|
||||
self._write()
|
||||
result += 1
|
||||
return result > 0
|
||||
|
||||
def is_eof(self) -> bool:
|
||||
|
||||
@@ -64,8 +64,8 @@ def shutdown_writing(
|
||||
# probably: "TypeError: shutdown() takes 1 positional argument but 2 were given"
|
||||
log(f"Shutting down for writing not possible; trying shutdown instead: {e}")
|
||||
sock.shutdown() # type: ignore
|
||||
elif isinstance(sock, getattr(pysocket, "SocketIO")):
|
||||
sock._sock.shutdown(pysocket.SHUT_WR)
|
||||
elif isinstance(sock, pysocket.SocketIO): # type: ignore
|
||||
sock._sock.shutdown(pysocket.SHUT_WR) # type: ignore[unreachable]
|
||||
else:
|
||||
log("No idea how to signal end of writing")
|
||||
|
||||
|
||||
@@ -115,9 +115,7 @@ class AnsibleDockerSwarmClient(AnsibleDockerClient):
|
||||
:return: True if node is Swarm Worker, False otherwise
|
||||
"""
|
||||
|
||||
if self.check_if_swarm_node() and not self.check_if_swarm_manager():
|
||||
return True
|
||||
return False
|
||||
return bool(self.check_if_swarm_node() and not self.check_if_swarm_manager())
|
||||
|
||||
def check_if_swarm_node_is_down(
|
||||
self, node_id: str | None = None, repeat_check: int = 1
|
||||
@@ -181,9 +179,8 @@ class AnsibleDockerSwarmClient(AnsibleDockerClient):
|
||||
self.fail(
|
||||
"Cannot inspect node: To inspect node execute module on Swarm Manager"
|
||||
)
|
||||
if exc.status_code == 404:
|
||||
if skip_missing:
|
||||
return None
|
||||
if exc.status_code == 404 and skip_missing:
|
||||
return None
|
||||
self.fail(f"Error while reading from Swarm manager: {exc}")
|
||||
except Exception as exc: # pylint: disable=broad-exception-caught
|
||||
self.fail(f"Error inspecting swarm node: {exc}")
|
||||
@@ -191,19 +188,18 @@ class AnsibleDockerSwarmClient(AnsibleDockerClient):
|
||||
json_str = json.dumps(node_info, ensure_ascii=False)
|
||||
node_info = json.loads(json_str)
|
||||
|
||||
if "ManagerStatus" in node_info:
|
||||
if node_info["ManagerStatus"].get("Leader"):
|
||||
# This is workaround of bug in Docker when in some cases the Leader IP is 0.0.0.0
|
||||
# Check moby/moby#35437 for details
|
||||
count_colons = node_info["ManagerStatus"]["Addr"].count(":")
|
||||
if count_colons == 1:
|
||||
swarm_leader_ip = (
|
||||
node_info["ManagerStatus"]["Addr"].split(":", 1)[0]
|
||||
or node_info["Status"]["Addr"]
|
||||
)
|
||||
else:
|
||||
swarm_leader_ip = node_info["Status"]["Addr"]
|
||||
node_info["Status"]["Addr"] = swarm_leader_ip
|
||||
if "ManagerStatus" in node_info and node_info["ManagerStatus"].get("Leader"):
|
||||
# This is workaround of bug in Docker when in some cases the Leader IP is 0.0.0.0
|
||||
# Check moby/moby#35437 for details
|
||||
count_colons = node_info["ManagerStatus"]["Addr"].count(":")
|
||||
if count_colons == 1:
|
||||
swarm_leader_ip = (
|
||||
node_info["ManagerStatus"]["Addr"].split(":", 1)[0]
|
||||
or node_info["Status"]["Addr"]
|
||||
)
|
||||
else:
|
||||
swarm_leader_ip = node_info["Status"]["Addr"]
|
||||
node_info["Status"]["Addr"] = swarm_leader_ip
|
||||
return node_info
|
||||
|
||||
def get_all_nodes_inspect(self) -> list[dict[str, t.Any]]:
|
||||
|
||||
@@ -27,7 +27,7 @@ if t.TYPE_CHECKING:
|
||||
from ._common_api import AnsibleDockerClientBase as CAPIADCB
|
||||
from ._common_cli import AnsibleDockerClientBase as CCLIADCB
|
||||
|
||||
Client = t.Union[CADCB, CAPIADCB, CCLIADCB]
|
||||
Client = t.Union[CADCB, CAPIADCB, CCLIADCB] # noqa: UP007
|
||||
|
||||
|
||||
DEFAULT_DOCKER_HOST = "unix:///var/run/docker.sock"
|
||||
@@ -94,9 +94,7 @@ BYTE_SUFFIXES = ["B", "KB", "MB", "GB", "TB", "PB"]
|
||||
|
||||
def is_image_name_id(name: str) -> bool:
|
||||
"""Check whether the given image name is in fact an image ID (hash)."""
|
||||
if re.match("^sha256:[0-9a-fA-F]{64}$", name):
|
||||
return True
|
||||
return False
|
||||
return bool(re.match("^sha256:[0-9a-fA-F]{64}$", name))
|
||||
|
||||
|
||||
def is_valid_tag(tag: str, allow_empty: bool = False) -> bool:
|
||||
|
||||
Reference in New Issue
Block a user