--- - name: "🔍 Resolve {{ application_id }} hosting node + container id" ansible.builtin.include_tasks: "{{ lookup('path_absolute', 'roles/sys-svc-compose/tasks/utils/swarm/resolve_host_cid.yml') }}" vars: resolve_service_key: fider resolve_output_prefix: FIDER resolve_compose_cid: "{{ FIDER_CONTAINER }}" - name: "⏳ Wait for {{ application_id }} HTTP endpoint (compose host-port)" wait_for: host: "{{ DOCKER_REACH_HOST }}" port: "{{ lookup('config', application_id, 'services.fider.ports.local.http') }}" delay: 5 timeout: "{{ lookup('timeout', 300) | int }}" when: DEPLOYMENT_MODE == 'compose' - name: "⏳ Wait for {{ application_id }} HTTP endpoint (swarm in-container)" ansible.builtin.shell: > # nocheck: container-exec-resolver runtime-resolved CID, delegated to the hosting node container exec {{ FIDER_LOCAL_CID | quote }} ./fider ping register: fider_http_ready changed_when: false retries: 60 delay: 5 until: fider_http_ready.rc == 0 delegate_to: "{{ FIDER_HOST_NODE }}" when: DEPLOYMENT_MODE == 'swarm' - name: "🔎 Fider | Check if tenant is already initialized" database_query: config: "{{ lookup('database', application_id) }}" query_file: "{{ role_path }}/files/sql/count-tenants.sql" expect_rows: true mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" register: fider_tenant_count changed_when: false - name: "🥾 Fider | Bootstrap initial tenant via API (compose host-port)" uri_retry: url: "http://{{ DOCKER_REACH_HOST }}:{{ lookup('config', application_id, 'services.fider.ports.local.http') }}/_api/tenants" method: POST 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 - 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 }} 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" || 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; 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.rc != 0 or (fider_tenant_bootstrap.stdout | trim) not in ['200', '201'] retries: 30 delay: 2 until: fider_tenant_bootstrap.rc != 75 no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" delegate_to: "{{ FIDER_HOST_NODE }}" when: - DEPLOYMENT_MODE == 'swarm' - (fider_tenant_count.rows[0][0] | int) == 0 - name: "📁 Fider | Create admin user (bypass email verification)" database_query: config: "{{ lookup('database', application_id) }}" query_file: "{{ role_path }}/files/sql/create-admin-user.sql" named_args: full_name: "{{ lookup('users', 'administrator').firstname }} {{ lookup('users', 'administrator').lastname }}" email: "{{ lookup('users', 'administrator').email }}" mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" changed_when: true - name: "🟢 Fider | Activate tenant (set status=1 to bypass email confirmation)" database_query: config: "{{ lookup('database', application_id) }}" query_file: "{{ role_path }}/files/sql/activate-tenants.sql" mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" changed_when: true