Files
computer-playbook/roles/web-app-dashboard/tasks/02_manager_ops.yml
kevinveenbirkenbachandClaude Opus 5.5 30d03287de fix(web-app-dashboard): wait only for branding assets the deployment serves
Without web-svc-asset in the inventory, services.asset.url falls back to
the public https://file.infinito.nexus/assets. The branding-asset wait
then matched the public logo and favicon and polled the project's public
website before the first compose start. Since that host stopped
answering on 2026-10-21, every deploy that disables the asset service
failed after 60 retries, among them the workspace compose track on main
(run 39684179395: ubuntu and centos, "Status code was -1 ... Errno 101
Network is unreachable" for file.infinito.nexus/assets/img/logo.png).

The slurp, the URL collection and the wait now run in one block guarded
by the dashboard's own services.asset.enabled, so the deploy waits only
for assets the shared file service of this deployment serves.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 07:18:51 +02:00

140 lines
4.9 KiB
YAML

---
- name: "🔎 Check if host-specific config.yaml exists in {{ DASHBOARD_CONFIG_INV_PATH }}"
stat:
path: "{{ DASHBOARD_CONFIG_INV_PATH }}"
delegate_to: localhost
become: false
register: config_file
- name: 📄 Load menu categories
include_vars:
file: "menu_categories.yml"
- name: 🧩 Load docker cards
set_fact:
portfolio_cards: "{{ lookup('docker_cards', 'roles') }}"
- name: 🔍 Probe Simple Icons reachability per card slug (on the stack host)
uri_retry:
url: "{{ DASHBOARD_SIMPLEICONS_SYNC_URL_BASE }}{{ item }}.svg"
method: HEAD
status_code: [200, 404]
validate_certs: false
register: dashboard_simpleicons_probe
loop: "{{ portfolio_cards | simpleicon_slugs }}"
loop_control:
label: "{{ item }}"
delegate_to: "{{ STACK_HOST }}"
run_once: true
when: DASHBOARD_SIMPLEICONS_ENABLED | bool
changed_when: false
- name: "📄 Load Dashboard Brand logos"
set_fact:
portfolio_cards: >-
{{ portfolio_cards | add_simpleicon_source(
dashboard_simpleicons_probe.results
| selectattr('status', 'equalto', 200)
| map(attribute='item')
| list,
DASHBOARD_SIMPLEICONS_URL_BASE) }}
when: DASHBOARD_SIMPLEICONS_ENABLED | bool
changed_when: false
- name: 👥 Group docker cards
set_fact:
portfolio_menu_data: "{{ lookup('docker_cards_grouped', portfolio_cards, portfolio_menu_categories) }}"
- name: "📄 Render Dashboard config.yaml (local + swarm peers)"
ansible.builtin.include_tasks:
file: "{{ lookup('path_absolute', 'roles/sys-svc-compose/tasks/utils/render_replicated_templates.yml') }}"
vars:
role_templates:
- src: "{{ DASHBOARD_CONFIG_INV_PATH if config_file.stat.exists else DASHBOARD_CONFIG_YML_SRC_FILE }}"
dest: "{{ DASHBOARD_CONFIG_YML_DEST }}"
- name: ⏳ Wait for branding assets this deployment serves
when: DASHBOARD_ASSET_ENABLED | bool
block:
- name: 🧩 Load rendered dashboard config before first compose start
slurp:
src: "{{ DASHBOARD_CONFIG_YML_DEST }}"
register: dashboard_rendered_config_raw
- name: 📊 Collect branding asset URLs served by the shared file service
set_fact:
dashboard_branding_asset_urls: >-
{{
[
(
dashboard_platform_logo_source
if dashboard_platform_logo_source.startswith(dashboard_asset_url_base)
else ''
),
(
dashboard_platform_favicon_source
if dashboard_platform_favicon_source.startswith(dashboard_asset_url_base)
else ''
),
(
dashboard_company_logo_source
if dashboard_company_logo_source.startswith(dashboard_asset_url_base)
else ''
)
]
| select('string')
| reject('equalto', '')
| unique
| list
}}
vars:
dashboard_rendered_config: "{{ dashboard_rendered_config_raw.content | b64decode | from_yaml }}"
dashboard_asset_url_base: "{{ lookup('config', 'web-svc-asset', 'services.asset.url') }}"
dashboard_platform_logo_source: "{{ ((dashboard_rendered_config.get('platform') or {}).get('logo') or {}).get('source', '') }}"
dashboard_platform_favicon_source: "{{ ((dashboard_rendered_config.get('platform') or {}).get('favicon') or {}).get('source', '') }}"
dashboard_company_logo_source: "{{ ((dashboard_rendered_config.get('company') or {}).get('logo') or {}).get('source', '') }}"
changed_when: false
- name: ⏳ Wait for dashboard branding assets before first compose start
uri_retry:
url: "{{ item }}"
status_code: 200
validate_certs: false
register: dashboard_branding_asset_http
retries: 60
delay: 5
until: dashboard_branding_asset_http.status == 200
loop: "{{ dashboard_branding_asset_urls }}"
loop_control:
label: "{{ item }}"
delegate_to: "{{ STACK_HOST }}"
run_once: true
- name: "🚿 Flush compose handlers"
meta: flush_handlers
- name: "✅ Ensure Simple Icons is reachable and refresh dashboard cards"
when: DASHBOARD_SIMPLEICONS_ENABLED | bool
block:
- name: ✅ Ensure shared Simple Icons service is loaded before refresh
include_tasks: utils/load/app.yml
vars:
load_app_id: web-svc-simpleicons
- name: 🚿 Flush handlers after loading shared Simple Icons service
meta: flush_handlers
- name: 🔄 Refresh dashboard cards after Simple Icons becomes reachable
include_tasks: "03_simpleicons_refresh.yml"
- name: ⏳ Wait for Dashboard HTTP endpoint (so all logos can download during init)
uri_retry:
url: "http://{{ DOCKER_REACH_HOST }}:{{ http_port }}/"
status_code: 200
register: dashboard_http
retries: 60
delay: 5
until: dashboard_http.status == 200
delegate_to: "{{ STACK_HOST }}"
run_once: true