From 74e50df93122d12fd68aa254d61009340119103a Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Mon, 17 Aug 2026 08:57:56 +0300 Subject: [PATCH] Add request timeouts to matrix-bot-meowlnir helper scripts Without a timeout, a request against an API which accepts connections but never answers (e.g. Meowlnir stuck retrying against a homeserver that rejects its appservice token) hangs the playbook forever instead of failing with a usable error. Co-Authored-By: Claude Fable 5 --- roles/custom/matrix-bot-meowlnir/defaults/main.yml | 5 +++++ .../custom/matrix-bot-meowlnir/templates/bin/meowlnir-api.j2 | 5 +++-- .../templates/bin/meowlnir-create-management-room.j2 | 3 ++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/roles/custom/matrix-bot-meowlnir/defaults/main.yml b/roles/custom/matrix-bot-meowlnir/defaults/main.yml index 2f84938c4..e0c4149f3 100644 --- a/roles/custom/matrix-bot-meowlnir/defaults/main.yml +++ b/roles/custom/matrix-bot-meowlnir/defaults/main.yml @@ -142,6 +142,11 @@ matrix_bot_meowlnir_bots_pruning_on_empty_roster_enabled: false # Only waited on when the service was not already running. matrix_bot_meowlnir_bots_start_wait_time_seconds: 15 +# How long a single request made through the helper scripts in `bin/` may take, in seconds. +# Applies to requests against both Meowlnir's management API and the homeserver's Client-Server API. +# Bounded so that an API which accepts connections but never answers turns into a clear error instead of hanging the playbook (or a human caller) forever. +matrix_bot_meowlnir_api_request_timeout_seconds: 60 + # The name and topic given to management rooms that the playbook creates. # Only used by bots with `management_room_auto_create` enabled. matrix_bot_meowlnir_management_room_name: Meowlnir management room diff --git a/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-api.j2 b/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-api.j2 index 3e17abae6..b2af72684 100755 --- a/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-api.j2 +++ b/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-api.j2 @@ -14,6 +14,7 @@ set -eu CONFIG_FILE='{{ matrix_bot_meowlnir_config_path }}/config.yaml' CONTAINER_NAME='matrix-bot-meowlnir' API_BASE='http://localhost:{{ matrix_bot_meowlnir_config_meowlnir_port }}' +REQUEST_TIMEOUT='{{ matrix_bot_meowlnir_api_request_timeout_seconds }}' if [ $# -lt 2 ]; then echo "Usage: $(basename "$0") [JSON_BODY]" >&2 @@ -40,7 +41,7 @@ fi if [ -n "$body" ]; then exec {{ devture_systemd_docker_base_host_command_docker }} exec "$CONTAINER_NAME" \ - curl -sS -X "$method" \ + curl -sS --max-time "$REQUEST_TIMEOUT" -X "$method" \ -H "Authorization: Bearer $secret" \ -H 'Content-Type: application/json' \ -d "$body" \ @@ -49,7 +50,7 @@ if [ -n "$body" ]; then fi exec {{ devture_systemd_docker_base_host_command_docker }} exec "$CONTAINER_NAME" \ - curl -sS -X "$method" \ + curl -sS --max-time "$REQUEST_TIMEOUT" -X "$method" \ -H "Authorization: Bearer $secret" \ -w '\n%{http_code}' \ "$API_BASE$api_path" diff --git a/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-create-management-room.j2 b/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-create-management-room.j2 index ee51be8c7..361be2437 100755 --- a/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-create-management-room.j2 +++ b/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-create-management-room.j2 @@ -19,6 +19,7 @@ HOMESERVER_DOMAIN='{{ matrix_bot_meowlnir_config_homeserver_domain }}' ROOM_NAME='{{ matrix_bot_meowlnir_management_room_name }}' ROOM_TOPIC='{{ matrix_bot_meowlnir_management_room_topic | trim }}' ENCRYPTED='{{ 'true' if matrix_bot_meowlnir_config_encryption_enable else 'false' }}' +REQUEST_TIMEOUT='{{ matrix_bot_meowlnir_api_request_timeout_seconds }}' if [ $# -lt 2 ]; then echo "Usage: $(basename "$0") ..." >&2 @@ -65,7 +66,7 @@ user_id_param="$(urlencode "$bot_mxid")" # Runs curl inside the container, because the homeserver is only reachable over the container network. # Prints the body, with the HTTP status code on the final line. response="$({{ devture_systemd_docker_base_host_command_docker }} exec "$CONTAINER_NAME" \ - curl -sS -X POST \ + curl -sS --max-time "$REQUEST_TIMEOUT" -X POST \ -H "Authorization: Bearer $as_token" \ -H 'Content-Type: application/json' \ -d "$create_body" \