fix(swarm): bound the in-container probes and retry only safe fider POSTs

Review follow-up on the in-container probes of gitea, shopware and fider.

- fider: the tenant POST over /dev/tcp waited on `head` without a bound,
  so a peer that accepts and stays silent blocked the task for good. It
  now runs under `timeout` (TIMEOUT_FACTOR-scaled 30 s, the old uri
  socket timeout) and reads the status line with the `read` builtin, so
  the bound kills the whole probe. Only outcomes Fider never committed
  are retried: a refused connect and a 5xx (Fider rolls the request
  transaction back on a handler error). A timeout or a closed socket
  after the request was sent fails the task instead of resending the
  POST; the next run's tenant count decides again.
- fider: both bootstrap tasks get `no_log` behind MASK_CREDENTIALS_IN_LOGS,
  as the body carries the administrator's name and email.
- shopware: each wget probe runs under `timeout`, as busybox wget waits
  900 s per read by default.
- shopware, gitea: the first readiness wait derives its retries from
  lookup('timeout', 300) again, the budget of the wait_for it replaced,
  so TIMEOUT_FACTOR scales it.

Refs #1089

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 5.5 committed 2026-10-29 01:41:55 +01:00
1 parent 276004c152
commit c2577560f8
3 files changed
+13 -8

No files matched your search

+9 -5
View File
@@ -41,6 +41,7 @@
body_format: json
body: "{{ FIDER_TENANT_BOOTSTRAP_BODY }}"
status_code: [200, 201]
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
when:
- DEPLOYMENT_MODE == 'compose'
- (fider_tenant_count.rows[0][0] | int) == 0
@@ -48,18 +49,21 @@
- name: "🥾 Fider | Bootstrap initial tenant via API (swarm in-container)"
ansible.builtin.shell:
cmd: >- # nocheck: container-exec-resolver runtime-resolved CID, delegated to the hosting node
container exec -i {{ FIDER_LOCAL_CID | quote }} bash -c
container exec -i {{ FIDER_LOCAL_CID | quote }}
timeout {{ lookup('timeout', 30) | int }} bash -c
'set -e; body=$(cat); length=$(printf %s "$body" | wc -c);
exec 3<>"/dev/tcp/127.0.0.1/$1";
exec 3<>"/dev/tcp/127.0.0.1/$1" || exit 75;
printf "POST /_api/tenants HTTP/1.0\r\nContent-Type: application/json\r\nContent-Length: %d\r\n\r\n%s" "$length" "$body" >&3;
head -n1 <&3 | cut -d" " -f2' _ {{ FIDER_INTERNAL_PORT | quote }}
read -r _ status _ <&3; printf %s "$status";
case $status in 5*) exit 75;; esac' _ {{ FIDER_INTERNAL_PORT | quote }}
stdin: "{{ FIDER_TENANT_BOOTSTRAP_BODY | to_json }}"
register: fider_tenant_bootstrap
changed_when: true
failed_when: (fider_tenant_bootstrap.stdout | trim) not in ['200', '201']
failed_when: fider_tenant_bootstrap.rc != 0 or (fider_tenant_bootstrap.stdout | trim) not in ['200', '201']
retries: 30
delay: 2
until: fider_tenant_bootstrap.rc == 0
until: fider_tenant_bootstrap.rc != 75
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
delegate_to: "{{ FIDER_HOST_NODE }}"
when:
- DEPLOYMENT_MODE == 'swarm'
+1 -1
View File
@@ -13,7 +13,7 @@
delegate_to: "{{ GITEA_HOST_NODE }}"
register: gitea_http_ready
changed_when: false
retries: 60
retries: "{{ ((lookup('timeout', 300) | int) / 5) | round(0, 'ceil') | int }}"
delay: 5
until: gitea_http_ready.rc == 0
@@ -49,11 +49,12 @@
- name: ⏳ Wait for Shopware HTTP endpoint
ansible.builtin.shell: >- # nocheck: container-exec-resolver runtime-resolved CID, delegated to the hosting node
container exec {{ SHOPWARE_WEB_LOCAL_CID | quote }}
sh -c 'wget -q --spider "$1/robots.txt" || wget -q --spider "$1/"' _ {{ SHOPWARE_API_BASE | quote }}
sh -c 'timeout "$2" wget -q --spider "$1/robots.txt" || timeout "$2" wget -q --spider "$1/"'
_ {{ SHOPWARE_API_BASE | quote }} {{ lookup('timeout', 10) | int }}
delegate_to: "{{ SHOPWARE_WEB_HOST_NODE }}"
register: shopware_http_ready
changed_when: false
retries: 60
retries: "{{ ((lookup('timeout', 300) | int) / 5) | round(0, 'ceil') | int }}"
delay: 5
until: shopware_http_ready.rc == 0