mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-10 12:47:04 +00:00
A curl against an accepted-but-silent peer hangs forever: task retries
never fire because the first attempt never returns, and the CI job dies
at the 6h runner cut (proven by the mailu admin-API hang that took the
suitecrm/peertube swarm legs down). The new `curl` filter renders the
hardened base command ("{{ 30 | curl }}" -> curl -s --connect-timeout 5
--max-time 30); scaling composes with lookup('timeout').
test_curl_via_filter enforces it: bare curl invocations in role tasks,
templates and shipped scripts fail the lint with a pointer to the
filter. Plain .sh files, which cannot render Jinja, pass by pinning
--max-time inline; Docker healthchecks are exempt (their timeout field
caps them); `# nocheck: curl-timeout` opts out (catalogued in
suppression.md).
Convert all 34 existing invocations: mailu (replacing the short-lived
MAILU_CURL var), elasticsearch, checkmk, yourls (300s for the
schema-creating installer POST), the telegram alert script, and the
plain scripts of jellyfin, svc-runner, apt_repo, moodle (600s tarball)
and the mattermost provisioner. Mailu's user/token tasks additionally
carry task-level timeouts so a wedged container exec cannot stall the
play.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
44 lines
1.5 KiB
Python
44 lines
1.5 KiB
Python
"""Render the timeout-hardened curl base command (SPOT).
|
|
|
|
{{ 30 | curl }} -> curl -s --connect-timeout 5 --max-time 30
|
|
{{ 300 | curl }} -> curl -s --connect-timeout 5 --max-time 300
|
|
{{ lookup('timeout', 30) | curl }} -> TIMEOUT_FACTOR-scaled variant
|
|
|
|
Args:
|
|
max_time: Seconds for the whole transfer; without it curl hangs forever
|
|
on an accepted-but-silent peer and task retries never fire.
|
|
connect_timeout: Seconds curl waits for the TCP/TLS connect (default 5).
|
|
|
|
Callers append their own flags (``-S``, ``-f``, ``-o``, ...) after the filter.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from ansible.errors import AnsibleFilterError
|
|
|
|
|
|
def curl(max_time: Any, connect_timeout: Any = 5) -> str:
|
|
try:
|
|
max_time_val = int(max_time)
|
|
connect_timeout_val = int(connect_timeout)
|
|
except (TypeError, ValueError) as exc:
|
|
raise AnsibleFilterError(
|
|
f"curl filter: max_time {max_time!r} / connect_timeout "
|
|
f"{connect_timeout!r} must be integers (seconds)"
|
|
) from exc
|
|
if max_time_val <= 0 or connect_timeout_val <= 0:
|
|
raise AnsibleFilterError(
|
|
f"curl filter: max_time {max_time_val} and connect_timeout "
|
|
f"{connect_timeout_val} must be > 0"
|
|
)
|
|
return f"curl -s --connect-timeout {connect_timeout_val} --max-time {max_time_val}"
|
|
|
|
|
|
class FilterModule:
|
|
def filters(self):
|
|
return {
|
|
"curl": curl,
|
|
}
|