playbooks/roles/vhosts/acp_server_opencode/tasks/validate.yml
Haitao Pan 4364786465
fix(acp_server_opencode): service PATH + bin var + surface adapter crash in validate (#21)
ACP readiness probe returned 000 for the full retry window on
xworkmate-bridge-ubuntu-26 (nothing listening = adapter crash-loop), but the
play aborted at the probe so the real cause never reached the CI log.

- systemd unit: add Environment=PATH ({{ acp_opencode_path }}, parity with the
  launchd plist) so the lazily-spawned opencode/node CLI resolves; replace the
  hardcoded --opencode-bin /usr/bin/opencode with {{ acp_opencode_binary_path }}
  ({{ npm_global_bin }}/opencode), matching the gemini/codex roles and macOS.
- validate.yml: wrap the readiness probe in block/rescue that dumps systemctl
  status + journalctl on failure, so the adapter crash reason is visible.
- fix latent undefined var in the summary (acp_opencode_adapter_http ->
  acp_opencode_adapter_probe), which would have errored once the endpoint came up.

Co-authored-by: Haitao Pan <manbuzhe2009@qq.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 15:25:32 +08:00

96 lines
4.1 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
- name: Validate Caddy configuration
ansible.builtin.command: caddy validate --config "{{ acp_opencode_caddyfile_path }}"
changed_when: false
when: acp_opencode_manage_caddy | bool
- name: Check OpenCode ACP listener
ansible.builtin.shell: |
if command -v ss >/dev/null 2>&1; then
ss -ltnp
else
lsof -nP -iTCP -sTCP:LISTEN 2>/dev/null || true
fi
args:
executable: /bin/bash
register: acp_opencode_ss
changed_when: false
failed_when: false
# 用 curl 重试循环替代 uri服务刚 (重)启时 adapter 会先 accept TCP 但短时间内不
# 应答(读挂起),而 uri 默认 30s 超时 + retries/until 在连接超时上不可靠循环(实测
# 仅试一次即失败)。每次 5s 上限、真重试给冷启动足够时间adapter 就绪后 ~4ms 回 200
# 包在 block/rescue探针失败时把 systemctl status + journalctl 打到 CI 日志,
# 否则 play 在此中止,看不到 adapter 进程真正的崩溃原因(如 last code 000
- name: Validate OpenCode local ACP endpoint
block:
- name: Validate OpenCode local ACP endpoint (readiness retry)
ansible.builtin.shell: |
set -eu
url="http://{{ acp_opencode_listen_host }}:{{ acp_opencode_listen_port }}/acp/rpc"
body='{"jsonrpc":"2.0","id":1,"method":"acp.capabilities","params":{}}'
code=""
for i in $(seq 1 30); do
code="$(curl -s -m 5 -o /dev/null -w '%{http_code}' -X POST "$url" \
-H 'Content-Type: application/json' -d "$body" 2>/dev/null || true)"
if [ "$code" = "200" ]; then
echo "OpenCode ACP endpoint ready after ${i} attempt(s)"
exit 0
fi
sleep 2
done
echo "OpenCode ACP endpoint ${url} not ready after retries (last code: ${code:-none})" >&2
exit 1
args:
executable: /bin/bash
changed_when: false
register: acp_opencode_adapter_probe
rescue:
- name: Capture OpenCode ACP service status on failure
ansible.builtin.command: systemctl status "{{ acp_opencode_service_name }}" --no-pager --full
register: acp_opencode_status_fail
changed_when: false
failed_when: false
when: ansible_os_family != 'Darwin'
- name: Capture recent OpenCode ACP service logs on failure
ansible.builtin.command: journalctl -u "{{ acp_opencode_service_name }}" -n 80 --no-pager
register: acp_opencode_journal_fail
changed_when: false
failed_when: false
when: ansible_os_family != 'Darwin'
- name: Show OpenCode ACP failure diagnostics
ansible.builtin.debug:
msg:
- "Probe stderr: {{ acp_opencode_adapter_probe.stderr | default('N/A') }}"
- "Listeners: {{ acp_opencode_ss.stdout | default('N/A') }}"
- "Service status: {{ acp_opencode_status_fail.stdout | default('N/A') }}"
- "Recent logs: {{ acp_opencode_journal_fail.stdout | default('N/A') }}"
- name: Fail after emitting OpenCode ACP diagnostics
ansible.builtin.fail:
msg: >-
OpenCode ACP endpoint
{{ acp_opencode_listen_host }}:{{ acp_opencode_listen_port }} did not
become ready. See the diagnostics above (service status + journal) for
the adapter crash cause.
- name: Show OpenCode ACP status
ansible.builtin.command: systemctl status "{{ acp_opencode_service_name }}" --no-pager
register: acp_opencode_status
changed_when: false
failed_when: false
when: ansible_os_family != 'Darwin'
- name: Show OpenCode ACP validation summary
ansible.builtin.debug:
msg:
- "OpenCode public base URL: {{ acp_opencode_public_base_url }}"
- "Preferred WebSocket endpoint: {{ acp_opencode_public_base_url }}/acp"
- "Compatibility HTTP RPC endpoint: {{ acp_opencode_public_base_url }}/acp/rpc"
- "OpenCode ACP adapter listener: {{ acp_opencode_listen_host }}:{{ acp_opencode_listen_port }}"
- "Readiness probe: {{ acp_opencode_adapter_probe.stdout | default('N/A') }}"
- "Service: {{ acp_opencode_status.stdout | default('N/A') }}"
- "Socket: {{ acp_opencode_ss.stdout | default('N/A') }}"