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 <noreply@anthropic.com>create-pull-request/i18n
| @@ -142,6 +142,11 @@ matrix_bot_meowlnir_bots_pruning_on_empty_roster_enabled: false | |||||
| # Only waited on when the service was not already running. | # Only waited on when the service was not already running. | ||||
| matrix_bot_meowlnir_bots_start_wait_time_seconds: 15 | 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. | # The name and topic given to management rooms that the playbook creates. | ||||
| # Only used by bots with `management_room_auto_create` enabled. | # Only used by bots with `management_room_auto_create` enabled. | ||||
| matrix_bot_meowlnir_management_room_name: Meowlnir management room | matrix_bot_meowlnir_management_room_name: Meowlnir management room | ||||
| @@ -14,6 +14,7 @@ set -eu | |||||
| CONFIG_FILE='{{ matrix_bot_meowlnir_config_path }}/config.yaml' | CONFIG_FILE='{{ matrix_bot_meowlnir_config_path }}/config.yaml' | ||||
| CONTAINER_NAME='matrix-bot-meowlnir' | CONTAINER_NAME='matrix-bot-meowlnir' | ||||
| API_BASE='http://localhost:{{ matrix_bot_meowlnir_config_meowlnir_port }}' | API_BASE='http://localhost:{{ matrix_bot_meowlnir_config_meowlnir_port }}' | ||||
| REQUEST_TIMEOUT='{{ matrix_bot_meowlnir_api_request_timeout_seconds }}' | |||||
| if [ $# -lt 2 ]; then | if [ $# -lt 2 ]; then | ||||
| echo "Usage: $(basename "$0") <METHOD> <PATH> [JSON_BODY]" >&2 | echo "Usage: $(basename "$0") <METHOD> <PATH> [JSON_BODY]" >&2 | ||||
| @@ -40,7 +41,7 @@ fi | |||||
| if [ -n "$body" ]; then | if [ -n "$body" ]; then | ||||
| exec {{ devture_systemd_docker_base_host_command_docker }} exec "$CONTAINER_NAME" \ | 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 "Authorization: Bearer $secret" \ | ||||
| -H 'Content-Type: application/json' \ | -H 'Content-Type: application/json' \ | ||||
| -d "$body" \ | -d "$body" \ | ||||
| @@ -49,7 +50,7 @@ if [ -n "$body" ]; then | |||||
| fi | fi | ||||
| exec {{ devture_systemd_docker_base_host_command_docker }} exec "$CONTAINER_NAME" \ | 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 "Authorization: Bearer $secret" \ | ||||
| -w '\n%{http_code}' \ | -w '\n%{http_code}' \ | ||||
| "$API_BASE$api_path" | "$API_BASE$api_path" | ||||
| @@ -19,6 +19,7 @@ HOMESERVER_DOMAIN='{{ matrix_bot_meowlnir_config_homeserver_domain }}' | |||||
| ROOM_NAME='{{ matrix_bot_meowlnir_management_room_name }}' | ROOM_NAME='{{ matrix_bot_meowlnir_management_room_name }}' | ||||
| ROOM_TOPIC='{{ matrix_bot_meowlnir_management_room_topic | trim }}' | ROOM_TOPIC='{{ matrix_bot_meowlnir_management_room_topic | trim }}' | ||||
| ENCRYPTED='{{ 'true' if matrix_bot_meowlnir_config_encryption_enable else 'false' }}' | ENCRYPTED='{{ 'true' if matrix_bot_meowlnir_config_encryption_enable else 'false' }}' | ||||
| REQUEST_TIMEOUT='{{ matrix_bot_meowlnir_api_request_timeout_seconds }}' | |||||
| if [ $# -lt 2 ]; then | if [ $# -lt 2 ]; then | ||||
| echo "Usage: $(basename "$0") <bot_localpart> <initial_manager_mxid>..." >&2 | echo "Usage: $(basename "$0") <bot_localpart> <initial_manager_mxid>..." >&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. | # 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. | # Prints the body, with the HTTP status code on the final line. | ||||
| response="$({{ devture_systemd_docker_base_host_command_docker }} exec "$CONTAINER_NAME" \ | 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 "Authorization: Bearer $as_token" \ | ||||
| -H 'Content-Type: application/json' \ | -H 'Content-Type: application/json' \ | ||||
| -d "$create_body" \ | -d "$create_body" \ | ||||