diff --git a/.github/workflows/ci-orchestrator.yml b/.github/workflows/ci-orchestrator.yml index e1dccacc44..0863e024c3 100644 --- a/.github/workflows/ci-orchestrator.yml +++ b/.github/workflows/ci-orchestrator.yml @@ -50,21 +50,21 @@ jobs: env: WAIT_REQUIRED: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository && !inputs.trusted_pr }} steps: - - name: Mark fork prerequisites as ready outside fork PRs or for trusted PRs + - name: ๐Ÿท๏ธ Mark fork prerequisites as ready outside fork PRs or for trusted PRs if: ${{ env.WAIT_REQUIRED != 'true' }} shell: bash run: | set -euo pipefail echo "Fork prerequisites are implicitly ready (non-fork PR or trusted-pr label)." - - name: Checkout trusted workflow repo (helpers) + - name: โฌ‡๏ธ Checkout trusted workflow repo (helpers) if: ${{ env.WAIT_REQUIRED == 'true' }} uses: actions/checkout@v7 with: ref: ${{ github.event.pull_request.base.sha }} persist-credentials: false - - name: Login to GHCR for CI image checks + - name: ๐Ÿ”‘ Login to GHCR for CI image checks if: ${{ env.WAIT_REQUIRED == 'true' }} uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: @@ -72,7 +72,7 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Wait for privileged fork CI images + - name: โณ Wait for privileged fork CI images if: ${{ env.WAIT_REQUIRED == 'true' }} shell: bash env: @@ -94,7 +94,7 @@ jobs: if: ${{ always() }} runs-on: ubuntu-latest steps: - - name: Assert privileged prerequisites are ready + - name: โœ… Assert privileged prerequisites are ready shell: bash run: | set -euo pipefail @@ -253,10 +253,10 @@ jobs: if: ${{ always() }} runs-on: ubuntu-latest steps: - - name: Fail if any upstream job failed or was cancelled + - name: ๐Ÿ›‘ Fail if any upstream job failed or was cancelled if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }} run: | echo "Pipeline failed: at least one upstream job failed or was cancelled." >&2 exit 1 - - name: Done + - name: โœ… Done run: echo "All checks passed." diff --git a/.github/workflows/cleanup-stale.yml b/.github/workflows/cleanup-stale.yml index 7de697df62..7f8c84878f 100644 --- a/.github/workflows/cleanup-stale.yml +++ b/.github/workflows/cleanup-stale.yml @@ -72,7 +72,7 @@ jobs: runs-on: ubuntu-latest steps: - - name: ๐Ÿ“ฅ Checkout + - name: โฌ‡๏ธ Checkout uses: actions/checkout@v7 - name: ๐Ÿ“ฆ Install project environment diff --git a/.github/workflows/delete-branch.yml b/.github/workflows/delete-branch.yml index e264641eb5..82a3f097b4 100644 --- a/.github/workflows/delete-branch.yml +++ b/.github/workflows/delete-branch.yml @@ -23,10 +23,10 @@ jobs: if: ${{ github.event.ref_type == 'branch' }} runs-on: ubuntu-latest steps: - - name: Checkout + - name: โฌ‡๏ธ Checkout uses: actions/checkout@v7 - - name: Cancel active workflow runs for deleted branch + - name: ๐Ÿšซ Cancel active workflow runs for deleted branch shell: bash env: BRANCH: ${{ github.event.ref }} diff --git a/.github/workflows/dependabot-close.yml b/.github/workflows/dependabot-close.yml index aad8b37a13..b0c5190d60 100644 --- a/.github/workflows/dependabot-close.yml +++ b/.github/workflows/dependabot-close.yml @@ -21,7 +21,7 @@ jobs: if: github.event.pull_request.user.login == 'dependabot[bot]' && vars.CI_ENABLE_AUTO_UPDATES != 'true' runs-on: ubuntu-latest steps: - - name: Close PR + - name: ๐Ÿ“ช Close PR env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} PR_URL: ${{ github.event.pull_request.html_url }} diff --git a/.github/workflows/entry-pull-request-cancel.yml b/.github/workflows/entry-pull-request-cancel.yml index df3808486b..e956558f27 100644 --- a/.github/workflows/entry-pull-request-cancel.yml +++ b/.github/workflows/entry-pull-request-cancel.yml @@ -14,10 +14,10 @@ jobs: cancel-pr-runs: runs-on: ubuntu-latest steps: - - name: Checkout + - name: โฌ‡๏ธ Checkout uses: actions/checkout@v7 - - name: Cancel active workflow runs for closed PR + - name: ๐Ÿšซ Cancel active workflow runs for closed PR shell: bash env: PR_NUMBER: ${{ github.event.pull_request.number }} diff --git a/.github/workflows/entry-pull-request-change.yml b/.github/workflows/entry-pull-request-change.yml index b0a267eaf3..74dcfdb5ab 100644 --- a/.github/workflows/entry-pull-request-change.yml +++ b/.github/workflows/entry-pull-request-change.yml @@ -39,10 +39,10 @@ jobs: scope: ${{ steps.resolve.outputs.scope }} run_ci_orchestrator: ${{ steps.resolve.outputs.run_ci_orchestrator }} steps: - - name: Checkout + - name: โฌ‡๏ธ Checkout uses: actions/checkout@v7 - - name: Resolve PR scope + - name: ๐Ÿ” Resolve PR scope id: resolve env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -56,10 +56,10 @@ jobs: if: ${{ github.event_name == 'pull_request' || github.event.pull_request.head.repo.full_name != github.repository }} runs-on: ubuntu-latest steps: - - name: Checkout + - name: โฌ‡๏ธ Checkout uses: actions/checkout@v7 - - name: Validate branch prefix for detected scope + - name: โœ… Validate branch prefix for detected scope env: PR_HEAD_REF: ${{ github.event.pull_request.head.ref }} PR_SCOPE: ${{ needs.detect-pr-scope.outputs.scope }} @@ -73,7 +73,7 @@ jobs: if: ${{ needs.detect-pr-scope.outputs.run_ci_orchestrator == 'false' }} runs-on: ubuntu-latest steps: - - name: Confirm lightweight PR scope + - name: โœ… Confirm lightweight PR scope shell: bash run: | set -euo pipefail @@ -88,23 +88,23 @@ jobs: whitelist: ${{ steps.resolve.outputs.whitelist }} roles_only: ${{ steps.resolve.outputs.roles_only }} steps: - - name: Checkout + - name: โฌ‡๏ธ Checkout uses: actions/checkout@v7 with: fetch-depth: 0 - - name: Set up Python + - name: ๐Ÿ”ง Set up Python uses: actions/setup-python@v6 with: python-version: "3.12" cache: pip cache-dependency-path: pyproject.toml - - name: Install project (host venv) + - name: ๐Ÿ“ฆ Install project (host venv) shell: bash run: make install - - name: Resolve affected roles + - name: ๐Ÿ” Resolve affected roles id: resolve shell: bash run: | @@ -143,10 +143,10 @@ jobs: image_tag: ${{ steps.out.outputs.image_tag }} trusted: ${{ contains(github.event.pull_request.labels.*.name, 'trusted-pr') }} steps: - - name: Checkout + - name: โฌ‡๏ธ Checkout uses: actions/checkout@v7 - - name: Resolve merge ref and image tag + - name: ๐Ÿ” Resolve merge ref and image tag id: out env: PR_NUMBER: ${{ github.event.pull_request.number }} diff --git a/.github/workflows/entry-push-latest.yml b/.github/workflows/entry-push-latest.yml index ab93c1601d..7b618a9a09 100644 --- a/.github/workflows/entry-push-latest.yml +++ b/.github/workflows/entry-push-latest.yml @@ -26,12 +26,12 @@ jobs: name: ๐Ÿ”„ Sync main runs-on: ubuntu-latest steps: - - name: Checkout repository + - name: โฌ‡๏ธ Checkout repository uses: actions/checkout@v7 with: fetch-depth: 0 - - name: Sync main from source repository + - name: ๐Ÿ”„ Sync main from source repository shell: bash env: CI_SYNC_MAIN_SOURCE_REPOSITORY_DEFAULT: infinito-nexus/core @@ -51,19 +51,19 @@ jobs: skip_reason: ${{ steps.decide.outputs.skip_reason }} commit_in_main: ${{ steps.decide.outputs.commit_in_main }} steps: - - name: Checkout repository + - name: โฌ‡๏ธ Checkout repository uses: actions/checkout@v7 with: fetch-depth: 0 - - name: Fetch main + - name: โฌ‡๏ธ Fetch main if: github.event.created == true shell: bash run: | set -euo pipefail git fetch origin main:refs/remotes/origin/main --force - - name: Decide whether CI should run for this push + - name: ๐Ÿค” Decide whether CI should run for this push id: decide env: GITHUB_EVENT_CREATED: ${{ github.event.created }} @@ -78,7 +78,7 @@ jobs: if: needs.run-policy.outputs.should_run != 'true' runs-on: ubuntu-latest steps: - - name: Explain skip + - name: โญ๏ธ Explain skip shell: bash run: | set -euo pipefail @@ -95,7 +95,7 @@ jobs: is_version: ${{ steps.pick.outputs.is_version }} version_tag: ${{ steps.pick.outputs.version_tag }} steps: - - name: Checkout (with tags) + - name: โฌ‡๏ธ Checkout (with tags) uses: actions/checkout@v7 with: fetch-depth: 0 @@ -129,19 +129,19 @@ jobs: outputs: allowed: ${{ steps.guard.outputs.allowed }} steps: - - name: Checkout (with full history) + - name: โฌ‡๏ธ Checkout (with full history) uses: actions/checkout@v7 with: fetch-depth: 0 fetch-tags: true - - name: Fetch main + - name: โฌ‡๏ธ Fetch main shell: bash run: | set -euo pipefail git fetch origin main:refs/remotes/origin/main --force - - name: "Guard: tag commit must be contained in origin/main" + - name: "๐Ÿ›ก๏ธ Guard: tag commit must be contained in origin/main" id: guard shell: bash env: diff --git a/.github/workflows/images-build-ci.yml b/.github/workflows/images-build-ci.yml index 55d55083b9..9e1047f208 100644 --- a/.github/workflows/images-build-ci.yml +++ b/.github/workflows/images-build-ci.yml @@ -49,7 +49,7 @@ jobs: - name: ๐Ÿ“ฆ Install jq run: ./scripts/install/apt.sh jq - - name: Compute matrix JSON + - name: ๐Ÿงฎ Compute matrix JSON id: out run: scripts/github/runner/images_build_outputs.sh "${{ inputs.distros }}" "${{ inputs.image_tag }}" @@ -64,13 +64,13 @@ jobs: distro: ${{ fromJson(needs.prepare.outputs.matrix) }} steps: - - name: Checkout trusted workflow repo (helpers) + - name: โฌ‡๏ธ Checkout trusted workflow repo (helpers) uses: actions/checkout@v7 with: ref: ${{ github.sha }} persist-credentials: false - - name: Checkout source to build + - name: โฌ‡๏ธ Checkout source to build uses: actions/checkout@v7 with: repository: ${{ inputs.source_repository || github.repository }} @@ -78,21 +78,21 @@ jobs: path: _src persist-credentials: false - - name: Disk pressure (start) + - name: ๐Ÿ’ฝ Disk pressure (start) shell: bash run: bash scripts/github/runner/disk_pressure_report.sh START - - name: Set up Docker Buildx + - name: ๐Ÿ”ง Set up Docker Buildx uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - - name: Login to GHCR + - name: ๐Ÿ”‘ Login to GHCR uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Disk pressure (pre-build) + - name: ๐Ÿ’ฝ Disk pressure (pre-build) shell: bash run: bash scripts/github/runner/disk_pressure_report.sh PRE-BUILD @@ -103,7 +103,7 @@ jobs: set -euo pipefail echo "owner=$(scripts/meta/resolve/repository/owner.sh)" >> "$GITHUB_OUTPUT" - - name: Build & push (retry 7x, 20s) + - name: ๐Ÿ”จ Build & push (retry 7x, 20s) if: ${{ !(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) }} shell: bash env: @@ -117,12 +117,12 @@ jobs: RETRY_DELAY_SECONDS: "20" run: ./scripts/image/push.sh - - name: Disk pressure (post-build) + - name: ๐Ÿ’ฝ Disk pressure (post-build) if: always() shell: bash run: bash scripts/github/runner/disk_pressure_report.sh POST-BUILD - - name: Cleanup (always) + - name: ๐Ÿงน Cleanup (always) if: always() shell: bash run: bash scripts/github/runner/cleanup_docker.sh diff --git a/.github/workflows/images-cleanup-ci.yml b/.github/workflows/images-cleanup-ci.yml index 397ebadb07..2ec0f78952 100644 --- a/.github/workflows/images-cleanup-ci.yml +++ b/.github/workflows/images-cleanup-ci.yml @@ -29,7 +29,7 @@ jobs: steps: - uses: actions/checkout@v7 - - name: Resolve image metadata + - name: ๐Ÿ” Resolve image metadata id: vars shell: bash run: | @@ -45,7 +45,7 @@ jobs: shell: bash run: ./scripts/install/apt.sh jq - - name: Cleanup old ci-* versions + - name: ๐Ÿงน Cleanup old ci-* versions shell: bash env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/images-mirror-all.yml b/.github/workflows/images-mirror-all.yml index 9b047e00b4..7df5cead8e 100644 --- a/.github/workflows/images-mirror-all.yml +++ b/.github/workflows/images-mirror-all.yml @@ -70,47 +70,47 @@ jobs: IMAGES_PER_HOUR: ${{ github.event.inputs.images_per_hour || inputs.images_per_hour || '50' }} steps: - - name: Checkout + - name: โฌ‡๏ธ Checkout uses: actions/checkout@v7 - - name: Resolve GHCR namespace and repository + - name: ๐Ÿ” Resolve GHCR namespace and repository id: vars shell: bash env: GHCR_NAMESPACE_INPUT: ${{ inputs.ghcr_namespace || '' }} run: bash scripts/meta/resolve/ghcr/namespace_and_repository.sh - - name: Setup Python + - name: ๐Ÿ”ง Setup Python uses: actions/setup-python@v6 with: python-version: "3.12" cache: pip cache-dependency-path: pyproject.toml - - name: Install Python deps + - name: ๐Ÿ“ฆ Install Python deps run: | python -m pip install --upgrade pip python -m pip install PyYAML - - name: Install skopeo + - name: ๐Ÿ“ฆ Install skopeo run: ./scripts/install/apt.sh skopeo # Optional: Docker Hub login to avoid rate limits while mirroring - - name: Login to Docker Hub (optional) + - name: ๐Ÿ”‘ Login to Docker Hub (optional) if: ${{ env.DOCKERHUB_USERNAME != '' && env.DOCKERHUB_TOKEN != '' }} uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: username: ${{ env.DOCKERHUB_USERNAME }} password: ${{ env.DOCKERHUB_TOKEN }} - - name: Login to GHCR + - name: ๐Ÿ”‘ Login to GHCR uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Mirror images to GHCR (best-effort) + - name: ๐Ÿชž Mirror images to GHCR (best-effort) shell: bash env: GHCR_NAMESPACE: ${{ steps.vars.outputs.ghcr_namespace }} diff --git a/.github/workflows/images-mirror-cleanup.yml b/.github/workflows/images-mirror-cleanup.yml index aa4e6f4b64..36fb865649 100644 --- a/.github/workflows/images-mirror-cleanup.yml +++ b/.github/workflows/images-mirror-cleanup.yml @@ -43,10 +43,10 @@ jobs: runs-on: ubuntu-latest steps: - - name: Checkout + - name: โฌ‡๏ธ Checkout uses: actions/checkout@v7 - - name: Resolve GHCR namespace and repository + - name: ๐Ÿ” Resolve GHCR namespace and repository id: vars shell: bash run: | @@ -59,14 +59,14 @@ jobs: echo "ghcr_namespace=${ghcr_namespace,,}" >> "$GITHUB_OUTPUT" echo "ghcr_repository=${ghcr_repository}" >> "$GITHUB_OUTPUT" - - name: Setup Python + - name: ๐Ÿ”ง Setup Python uses: actions/setup-python@v6 with: python-version: "3.12" cache: pip cache-dependency-path: pyproject.toml - - name: Run mirror cleanup + - name: โ–ถ๏ธ Run mirror cleanup shell: bash env: GITHUB_TOKEN: ${{ inputs.token != '' && inputs.token || secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/images-mirror-missing.yml b/.github/workflows/images-mirror-missing.yml index e7080b63ce..162a0b0b63 100644 --- a/.github/workflows/images-mirror-missing.yml +++ b/.github/workflows/images-mirror-missing.yml @@ -84,17 +84,17 @@ jobs: IMAGES_PER_HOUR: ${{ inputs.images_per_hour || '' }} steps: - - name: Checkout + - name: โฌ‡๏ธ Checkout uses: actions/checkout@v7 - - name: Resolve GHCR namespace and repository + - name: ๐Ÿ” Resolve GHCR namespace and repository id: vars shell: bash env: GHCR_NAMESPACE_INPUT: ${{ inputs.ghcr_namespace || '' }} run: bash scripts/meta/resolve/ghcr/namespace_and_repository.sh - - name: Checkout source repo for scan (optional) + - name: โฌ‡๏ธ Checkout source repo for scan (optional) if: ${{ inputs.source_repository != '' && inputs.source_ref != '' }} uses: actions/checkout@v7 with: @@ -104,37 +104,37 @@ jobs: fetch-depth: 1 persist-credentials: false - - name: Setup Python + - name: ๐Ÿ”ง Setup Python uses: actions/setup-python@v6 with: python-version: "3.12" cache: pip cache-dependency-path: pyproject.toml - - name: Install Python deps + - name: ๐Ÿ“ฆ Install Python deps run: | python -m pip install --upgrade pip python -m pip install PyYAML - - name: Install skopeo + - name: ๐Ÿ“ฆ Install skopeo run: ./scripts/install/apt.sh skopeo # Optional: Docker Hub login to avoid rate limits while mirroring - - name: Login to Docker Hub (optional) + - name: ๐Ÿ”‘ Login to Docker Hub (optional) if: ${{ env.DOCKERHUB_USERNAME != '' && env.DOCKERHUB_TOKEN != '' && !(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) }} uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: username: ${{ env.DOCKERHUB_USERNAME }} password: ${{ env.DOCKERHUB_TOKEN }} - - name: Login to GHCR + - name: ๐Ÿ”‘ Login to GHCR uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Wait for mirrored images (fork PR) + - name: โณ Wait for mirrored images (fork PR) if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository }} env: GHCR_NAMESPACE: ${{ steps.vars.outputs.ghcr_namespace }} @@ -145,7 +145,7 @@ jobs: IMAGE_WAIT_SLEEP_SECONDS: ${{ inputs.image_wait_sleep_seconds }} run: ./scripts/meta/wait/mirrors.sh - - name: Mirror images to GHCR (only missing, best-effort) + - name: ๐Ÿชž Mirror images to GHCR (only missing, best-effort) if: ${{ !(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) }} shell: bash env: diff --git a/.github/workflows/lint-ansible.yml b/.github/workflows/lint-ansible.yml index d8b41df42a..98a50da6dc 100644 --- a/.github/workflows/lint-ansible.yml +++ b/.github/workflows/lint-ansible.yml @@ -16,33 +16,33 @@ jobs: INFINITO_LINT_RUNNER: host steps: - - name: Checkout repository + - name: โฌ‡๏ธ Checkout repository uses: actions/checkout@v7 - - name: Set up Python + - name: ๐Ÿ”ง Set up Python uses: actions/setup-python@v6 with: python-version: "3.12" cache: pip cache-dependency-path: pyproject.toml - - name: Install ansible-core + ansible-lint + - name: ๐Ÿ“ฆ Install ansible-core + ansible-lint run: | python -m pip install --upgrade pip pip install ansible-core ansible-lint pyyaml - - name: Cache Ansible collections + - name: ๐Ÿ“ฆ Cache Ansible collections uses: actions/cache@v6 with: path: ~/.ansible/collections key: ansible-collections-${{ runner.os }}-${{ hashFiles('requirements/requirements.galaxy.yml', 'requirements/requirements.git.yml') }} - - name: Install required Ansible collections + - name: ๐Ÿ“ฆ Install required Ansible collections run: | ansible-galaxy collection install \ -r requirements/requirements.galaxy.yml - - name: Generate role include files + - name: โš™๏ธ Generate role include files # `tasks/groups/*-roles.yml` are generated artefacts (gitignored # via tasks/groups/.gitignore) referenced by `tasks/stages/*.yml`. # Without them ansible-lint reports a fatal load-failure on @@ -55,5 +55,5 @@ jobs: # script directly without going through `make`. run: PYTHON=python3 PYTHONPATH=. bash scripts/setup.sh - - name: Run lint-ansible via make + - name: โ–ถ๏ธ Run lint-ansible via make run: make lint-ansible diff --git a/.github/workflows/lint-docker.yml b/.github/workflows/lint-docker.yml index b2032b0525..9d1ef27558 100644 --- a/.github/workflows/lint-docker.yml +++ b/.github/workflows/lint-docker.yml @@ -14,9 +14,9 @@ jobs: contents: read security-events: write steps: - - name: Checkout code + - name: โฌ‡๏ธ Checkout code uses: actions/checkout@v7 - - name: Run hadolint (produce SARIF) + - name: โ–ถ๏ธ Run hadolint (produce SARIF) id: hadolint continue-on-error: true uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5 @@ -26,7 +26,7 @@ jobs: output-file: hadolint-results.sarif failure-threshold: warning - - name: Upload analysis results to GitHub + - name: โฌ†๏ธ Upload analysis results to GitHub if: always() uses: github/codeql-action/upload-sarif@v4 with: @@ -34,6 +34,6 @@ jobs: wait-for-processing: true category: hadolint - - name: Fail if SARIF contains warnings/errors + - name: ๐Ÿ›‘ Fail if SARIF contains warnings/errors if: always() run: python3 utils/docker/hadolint.py hadolint-results.sarif diff --git a/.github/workflows/lint-javascript.yml b/.github/workflows/lint-javascript.yml index 777c2e59a1..a270759f6f 100644 --- a/.github/workflows/lint-javascript.yml +++ b/.github/workflows/lint-javascript.yml @@ -15,17 +15,17 @@ jobs: INFINITO_LINT_RUNNER: host steps: - - name: Checkout repository + - name: โฌ‡๏ธ Checkout repository uses: actions/checkout@v7 - - name: Set up Node.js + - name: ๐Ÿ”ง Set up Node.js uses: actions/setup-node@v6 with: node-version: "20" cache: "npm" - - name: Install ESLint dependencies + - name: ๐Ÿ“ฆ Install ESLint dependencies run: npm ci --no-fund --no-audit - - name: Run lint-javascript via make + - name: โ–ถ๏ธ Run lint-javascript via make run: make lint-javascript diff --git a/.github/workflows/lint-makefile.yml b/.github/workflows/lint-makefile.yml index 73d5ada801..1a06cfa493 100644 --- a/.github/workflows/lint-makefile.yml +++ b/.github/workflows/lint-makefile.yml @@ -15,20 +15,20 @@ jobs: INFINITO_LINT_RUNNER: host steps: - - name: Checkout repository + - name: โฌ‡๏ธ Checkout repository uses: actions/checkout@v7 - - name: Set up Python + - name: ๐Ÿ”ง Set up Python uses: actions/setup-python@v6 with: python-version: "3.12" cache: pip cache-dependency-path: pyproject.toml - - name: Install mbake + - name: ๐Ÿ“ฆ Install mbake run: | python -m pip install --upgrade pip pip install mbake - - name: Run mbake format --check via make + - name: โ–ถ๏ธ Run mbake format --check via make run: make lint-makefile diff --git a/.github/workflows/lint-markdown.yml b/.github/workflows/lint-markdown.yml index 47e0ec70aa..70681415c9 100644 --- a/.github/workflows/lint-markdown.yml +++ b/.github/workflows/lint-markdown.yml @@ -13,17 +13,17 @@ jobs: timeout-minutes: 10 steps: - - name: Checkout repository + - name: โฌ‡๏ธ Checkout repository uses: actions/checkout@v7 - - name: Set up Node.js + - name: ๐Ÿ”ง Set up Node.js uses: actions/setup-node@v6 with: node-version: "20" cache: "npm" - - name: Install markdownlint-cli2 + - name: ๐Ÿ“ฆ Install markdownlint-cli2 run: npm install -g markdownlint-cli2 - - name: Run markdownlint-cli2 + - name: โ–ถ๏ธ Run markdownlint-cli2 run: bash scripts/lint/markdown.sh diff --git a/.github/workflows/lint-packages.yml b/.github/workflows/lint-packages.yml index 287ec8e330..309b6f215b 100644 --- a/.github/workflows/lint-packages.yml +++ b/.github/workflows/lint-packages.yml @@ -13,13 +13,13 @@ jobs: timeout-minutes: 5 steps: - - name: Checkout repository + - name: โฌ‡๏ธ Checkout repository uses: actions/checkout@v7 - - name: Install packaging validators + - name: ๐Ÿ“ฆ Install packaging validators run: | sudo apt-get update sudo apt-get install -y --no-install-recommends dpkg-dev rpm - - name: Validate distro packaging metadata + - name: โœ… Validate distro packaging metadata run: bash scripts/lint/packages.sh diff --git a/.github/workflows/lint-playwright.yml b/.github/workflows/lint-playwright.yml index 17f25f1716..8bf000a256 100644 --- a/.github/workflows/lint-playwright.yml +++ b/.github/workflows/lint-playwright.yml @@ -15,17 +15,17 @@ jobs: INFINITO_LINT_RUNNER: host steps: - - name: Checkout repository + - name: โฌ‡๏ธ Checkout repository uses: actions/checkout@v7 - - name: Set up Node.js + - name: ๐Ÿ”ง Set up Node.js uses: actions/setup-node@v6 with: node-version: "20" cache: "npm" - - name: Install npm dependencies (eslint + @playwright/test) + - name: ๐Ÿ“ฆ Install npm dependencies (eslint + @playwright/test) run: npm ci --no-fund --no-audit - - name: Run lint-playwright via make + - name: โ–ถ๏ธ Run lint-playwright via make run: make lint-playwright diff --git a/.github/workflows/lint-python.yml b/.github/workflows/lint-python.yml index da9b5cca5a..5b2331baf5 100644 --- a/.github/workflows/lint-python.yml +++ b/.github/workflows/lint-python.yml @@ -13,25 +13,25 @@ jobs: timeout-minutes: 10 steps: - - name: Checkout repository + - name: โฌ‡๏ธ Checkout repository uses: actions/checkout@v7 - - name: Set up Python + - name: ๐Ÿ”ง Set up Python uses: actions/setup-python@v6 with: python-version: "3.12" cache: pip cache-dependency-path: pyproject.toml - - name: Install ruff + - name: ๐Ÿ“ฆ Install ruff run: | python -m pip install --upgrade pip pip install ruff - - name: Ruff (lint) + - name: ๐Ÿงน Ruff (lint) run: | ruff check . - - name: Ruff (format check) + - name: ๐Ÿงน Ruff (format check) run: | ruff format --check . diff --git a/.github/workflows/lint-shell.yml b/.github/workflows/lint-shell.yml index 63da641f7c..b5d1dd8b64 100644 --- a/.github/workflows/lint-shell.yml +++ b/.github/workflows/lint-shell.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - - name: Run ShellCheck (container) + - name: โ–ถ๏ธ Run ShellCheck (container) run: | mapfile -d '' shell_files < <(find . -type f -name '*.sh' -print0) if [ "${#shell_files[@]}" -eq 0 ]; then diff --git a/.github/workflows/release-highest.yml b/.github/workflows/release-highest.yml index c22176329b..3829373b5f 100644 --- a/.github/workflows/release-highest.yml +++ b/.github/workflows/release-highest.yml @@ -23,13 +23,13 @@ jobs: runs-on: ubuntu-latest steps: - - name: Checkout repository (with tags) + - name: โฌ‡๏ธ Checkout repository (with tags) uses: actions/checkout@v7 with: fetch-depth: 0 fetch-tags: true - - name: Resolve image metadata + - name: ๐Ÿ” Resolve image metadata id: vars shell: bash run: | @@ -43,14 +43,14 @@ jobs: echo "distros=${INFINITO_DISTROS}" } >> "$GITHUB_OUTPUT" - - name: Login to GHCR (for manifest checks) + - name: ๐Ÿ”‘ Login to GHCR (for manifest checks) uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Determine highest version tag with missing release image + - name: ๐Ÿค” Determine highest version tag with missing release image id: pick shell: bash env: @@ -62,7 +62,7 @@ jobs: tag="$(scripts/meta/resolve/missing/highest_release_tag.sh)" echo "tag=${tag}" >> "$GITHUB_OUTPUT" - - name: Ensure GitHub CLI is available + - name: โœ… Ensure GitHub CLI is available shell: bash run: | set -euo pipefail @@ -71,7 +71,7 @@ jobs: fi ./scripts/install/apt.sh gh - - name: Trigger release workflow for missing tag + - name: โšก Trigger release workflow for missing tag if: ${{ steps.pick.outputs.tag != '' }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release-version.yml b/.github/workflows/release-version.yml index 1fac74ee03..f14cdef5b8 100644 --- a/.github/workflows/release-version.yml +++ b/.github/workflows/release-version.yml @@ -42,19 +42,19 @@ jobs: version_tag: ${{ steps.vars.outputs.version_tag }} publish_latest: ${{ steps.highest.outputs.publish_latest }} steps: - - name: Checkout trusted workflow repo (helpers) + - name: โฌ‡๏ธ Checkout trusted workflow repo (helpers) uses: actions/checkout@v7 with: ref: ${{ github.sha }} path: _helpers persist-credentials: false - - name: Resolve release inputs + - name: ๐Ÿ” Resolve release inputs id: vars shell: bash run: bash _helpers/scripts/github/resolve/release_inputs.sh "${{ inputs.tag || github.event.inputs.tag }}" - - name: Checkout repository at version tag + - name: โฌ‡๏ธ Checkout repository at version tag uses: actions/checkout@v7 with: ref: ${{ steps.vars.outputs.version_tag }} @@ -62,7 +62,7 @@ jobs: fetch-depth: 0 fetch-tags: true - - name: Compute CI tag (ci- of version tag) + - name: ๐Ÿงฎ Compute CI tag (ci- of version tag) id: citag shell: bash run: | @@ -70,7 +70,7 @@ jobs: sha="$(git -C _src rev-parse HEAD)" echo "ci_tag=ci-${sha}" >> "$GITHUB_OUTPUT" - - name: Decide whether this version should update latest + - name: ๐Ÿค” Decide whether this version should update latest id: highest shell: bash env: @@ -78,14 +78,14 @@ jobs: VERSION_TAG: ${{ steps.vars.outputs.version_tag }} run: _helpers/scripts/meta/resolve/publish_latest.sh - - name: Login to GHCR (manifest checks) + - name: ๐Ÿ”‘ Login to GHCR (manifest checks) uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Check whether CI images already exist + - name: ๐Ÿ”Ž Check whether CI images already exist id: check shell: bash env: @@ -132,22 +132,22 @@ jobs: PUBLISH_LATEST: ${{ needs.check-ci-images.outputs.publish_latest }} steps: - - name: Checkout trusted workflow repo (helpers) + - name: โฌ‡๏ธ Checkout trusted workflow repo (helpers) uses: actions/checkout@v7 with: ref: ${{ github.sha }} persist-credentials: false - - name: Set up Docker Buildx + - name: ๐Ÿ”ง Set up Docker Buildx uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - - name: Login to GHCR + - name: ๐Ÿ”‘ Login to GHCR uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Retag CI images to release tags (and latest for the highest version) + - name: ๐Ÿท๏ธ Retag CI images to release tags (and latest for the highest version) shell: bash run: scripts/image/release.sh diff --git a/.github/workflows/security-codeql.yml b/.github/workflows/security-codeql.yml index 94d58b3771..45ee43be5d 100644 --- a/.github/workflows/security-codeql.yml +++ b/.github/workflows/security-codeql.yml @@ -77,7 +77,7 @@ jobs: # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages steps: - - name: Checkout repository + - name: โฌ‡๏ธ Checkout repository uses: actions/checkout@v7 # Add any setup steps before running the `github/codeql-action/init` action. @@ -87,7 +87,7 @@ jobs: # uses: actions/setup-example@v1 # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL + - name: ๐ŸŽฌ Initialize CodeQL uses: github/codeql-action/init@v4 with: languages: ${{ matrix.language }} @@ -105,7 +105,7 @@ jobs: # to build your code. # โ„น๏ธ Command-line programs to run using the OS shell. # ๐Ÿ“š See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - name: Run manual build steps + - name: โ–ถ๏ธ Run manual build steps if: matrix.build-mode == 'manual' shell: bash run: | @@ -116,7 +116,7 @@ jobs: echo ' make release' exit 1 - - name: Perform CodeQL Analysis + - name: โ–ถ๏ธ Perform CodeQL Analysis uses: github/codeql-action/analyze@v4 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/test-code-external.yml b/.github/workflows/test-code-external.yml index 87d0ec9bc4..44e584d8da 100644 --- a/.github/workflows/test-code-external.yml +++ b/.github/workflows/test-code-external.yml @@ -16,23 +16,23 @@ jobs: INFINITO_TEST_RUNNER: host steps: - - name: Checkout repository + - name: โฌ‡๏ธ Checkout repository uses: actions/checkout@v7 - - name: Set up Python + - name: ๐Ÿ”ง Set up Python uses: actions/setup-python@v6 with: python-version: "3.12" cache: pip cache-dependency-path: pyproject.toml - - name: Run external tests via make + - name: โ–ถ๏ธ Run external tests via make shell: bash run: | set -euo pipefail make test-external 2>&1 | tee /tmp/external-output.txt - - name: Build step summary from annotations + - name: ๐Ÿ”จ Build step summary from annotations if: always() working-directory: ${{ github.workspace }} run: | diff --git a/.github/workflows/test-code-integration.yml b/.github/workflows/test-code-integration.yml index f41bb1f81a..1fe415bb5c 100644 --- a/.github/workflows/test-code-integration.yml +++ b/.github/workflows/test-code-integration.yml @@ -15,23 +15,23 @@ jobs: INFINITO_TEST_RUNNER: host steps: - - name: Checkout repository + - name: โฌ‡๏ธ Checkout repository uses: actions/checkout@v7 - - name: Set up Python + - name: ๐Ÿ”ง Set up Python uses: actions/setup-python@v6 with: python-version: "3.12" cache: pip cache-dependency-path: pyproject.toml - - name: Run integration tests via make + - name: โ–ถ๏ธ Run integration tests via make shell: bash run: | set -euo pipefail make test-integration 2>&1 | tee /tmp/integration-output.txt - - name: Build step summary from annotations + - name: ๐Ÿ”จ Build step summary from annotations if: always() working-directory: ${{ github.workspace }} run: | diff --git a/.github/workflows/test-code-lint.yml b/.github/workflows/test-code-lint.yml index dbca7abd54..802052f966 100644 --- a/.github/workflows/test-code-lint.yml +++ b/.github/workflows/test-code-lint.yml @@ -15,23 +15,23 @@ jobs: INFINITO_TEST_RUNNER: host steps: - - name: Checkout repository + - name: โฌ‡๏ธ Checkout repository uses: actions/checkout@v7 - - name: Set up Python + - name: ๐Ÿ”ง Set up Python uses: actions/setup-python@v6 with: python-version: "3.12" cache: pip cache-dependency-path: pyproject.toml - - name: Run lint tests via make + - name: โ–ถ๏ธ Run lint tests via make shell: bash run: | set -euo pipefail make test-lint 2>&1 | tee /tmp/lint-output.txt - - name: Build step summary from annotations + - name: ๐Ÿ”จ Build step summary from annotations if: always() working-directory: ${{ github.workspace }} run: | diff --git a/.github/workflows/test-code-unit.yml b/.github/workflows/test-code-unit.yml index 43be0cd086..6646787cb0 100644 --- a/.github/workflows/test-code-unit.yml +++ b/.github/workflows/test-code-unit.yml @@ -15,23 +15,23 @@ jobs: INFINITO_TEST_RUNNER: host steps: - - name: Checkout repository + - name: โฌ‡๏ธ Checkout repository uses: actions/checkout@v7 - - name: Set up Python + - name: ๐Ÿ”ง Set up Python uses: actions/setup-python@v6 with: python-version: "3.12" cache: pip cache-dependency-path: pyproject.toml - - name: Run unit tests via make + - name: โ–ถ๏ธ Run unit tests via make shell: bash run: | set -euo pipefail make test-unit 2>&1 | tee /tmp/unit-output.txt - - name: Build step summary from annotations + - name: ๐Ÿ”จ Build step summary from annotations if: always() working-directory: ${{ github.workspace }} run: | diff --git a/.github/workflows/test-deploy-compose.yml b/.github/workflows/test-deploy-compose.yml index e32c9af6bf..1cb8b4349d 100644 --- a/.github/workflows/test-deploy-compose.yml +++ b/.github/workflows/test-deploy-compose.yml @@ -49,29 +49,29 @@ jobs: shell: bash run: ./scripts/install/apt.sh jq - - name: Install deps (jq + envsubst) + - name: ๐Ÿ“ฆ Install deps (jq + envsubst) shell: bash run: ./scripts/install/apt.sh jq gettext-base - - name: Set up Python + - name: ๐Ÿ”ง Set up Python uses: actions/setup-python@v6 with: python-version: "3.12" cache: pip cache-dependency-path: pyproject.toml - - name: Install project (host venv) + - name: ๐Ÿ“ฆ Install project (host venv) shell: bash run: make install - - name: Resolve effective whitelist (diff vs origin/main) + - name: ๐Ÿ” Resolve effective whitelist (diff vs origin/main) id: resolve_wl shell: bash env: INPUT_WHITELIST: ${{ inputs.whitelist }} run: ./scripts/github/resolve/effective_whitelist.sh - - name: Discover apps + - name: ๐Ÿ” Discover apps id: discover shell: bash env: @@ -79,7 +79,7 @@ jobs: run: ./scripts/github/resolve/output_apps.sh compose: - name: ๐Ÿณ Compose ${{ matrix.apps }}${{ matrix.variant && format(' [{0}]', matrix.variant) || '' }} + name: ๐Ÿณ ${{ matrix.apps }}${{ matrix.variant && format(' {0}',matrix.variant) || '' }} if: needs.discover.outputs.apps != '' && needs.discover.outputs.apps != '[]' runs-on: ubuntu-latest timeout-minutes: 360 @@ -136,7 +136,7 @@ jobs: python3 -m cli.meta.ci.roles.runtime "/tmp/role-runtimes-${{ matrix.apps }}.csv" \ --format markdown >> "$GITHUB_STEP_SUMMARY" - - name: Upload role runtimes CSV + - name: โฌ†๏ธ Upload role runtimes CSV if: always() uses: actions/upload-artifact@v7 with: @@ -149,7 +149,7 @@ jobs: shell: bash run: ./scripts/github/runner/dump_state.sh "post-deploy failure (${{ matrix.apps }})" - - name: Playwright step summary + - name: ๐Ÿ“‹ Playwright step summary if: always() shell: bash run: | @@ -159,7 +159,7 @@ jobs: "${{ matrix.apps }}" \ >> "$GITHUB_STEP_SUMMARY" - - name: Upload Playwright artifacts + - name: โฌ†๏ธ Upload Playwright artifacts if: always() uses: actions/upload-artifact@v7 with: @@ -167,14 +167,14 @@ jobs: path: /tmp/playwright-artifacts/ if-no-files-found: ignore - - name: Zip generated inventory for debugging + - name: ๐Ÿ—œ๏ธ Zip generated inventory for debugging if: always() shell: bash env: APP_ID: ${{ matrix.apps }} run: bash scripts/github/inventory/zip_compose_for_upload.sh - - name: Upload inventory artifact + - name: โฌ†๏ธ Upload inventory artifact if: ${{ always() && !env.ACT }} uses: actions/upload-artifact@v7 with: diff --git a/.github/workflows/test-deploy-swarm.yml b/.github/workflows/test-deploy-swarm.yml index cc41db94b1..7c0cb270cf 100644 --- a/.github/workflows/test-deploy-swarm.yml +++ b/.github/workflows/test-deploy-swarm.yml @@ -51,18 +51,18 @@ jobs: shell: bash run: ./scripts/install/apt.sh jq - - name: Install deps (jq + envsubst) + - name: ๐Ÿ“ฆ Install deps (jq + envsubst) shell: bash run: ./scripts/install/apt.sh jq gettext-base - - name: Set up Python + - name: ๐Ÿ”ง Set up Python uses: actions/setup-python@v6 with: python-version: "3.12" cache: pip cache-dependency-path: pyproject.toml - - name: Install project (host venv) + - name: ๐Ÿ“ฆ Install project (host venv) shell: bash run: | make install-force @@ -70,14 +70,14 @@ jobs: source scripts/meta/env/load.sh echo "${VENV}/bin" >> "${GITHUB_PATH}" - - name: Resolve effective whitelist (diff vs origin/main) + - name: ๐Ÿ” Resolve effective whitelist (diff vs origin/main) id: resolve_wl shell: bash env: INPUT_WHITELIST: ${{ inputs.whitelist }} run: ./scripts/github/resolve/effective_whitelist.sh - - name: Discover apps + - name: ๐Ÿ” Discover apps id: discover shell: bash env: @@ -85,7 +85,7 @@ jobs: run: ./scripts/github/resolve/output_apps.sh swarm: - name: "๐Ÿ Swarm ${{ matrix.apps }}${{ matrix.variant && format(' [{0}]', matrix.variant) || '' }}" + name: "๐Ÿ ${{ matrix.apps }}${{ matrix.variant && format(' {0}',matrix.variant) || '' }}" if: needs.discover.outputs.apps != '' && needs.discover.outputs.apps != '[]' runs-on: ubuntu-latest timeout-minutes: 360 @@ -114,7 +114,7 @@ jobs: docker-images: true swap-storage: true - - name: "Checkout" + - name: "โฌ‡๏ธ Checkout" if: ${{ !env.ACT }} uses: actions/checkout@v7 @@ -123,11 +123,11 @@ jobs: shell: bash run: ./scripts/github/runner/enlarge_swap.sh - - name: "Resolve SWARM_NAME (mandatory; default to the matrix app)" + - name: "๐Ÿ” Resolve SWARM_NAME (mandatory; default to the matrix app)" shell: bash run: echo "SWARM_NAME=${SWARM_NAME:-${{ matrix.apps }}}" >> "$GITHUB_ENV" - - name: "Load swarm topology SPOT into job env" + - name: "๐Ÿ“ฅ Load swarm topology SPOT into job env" shell: bash # Source (not literal-dump) so the mandatory SWARM_NAME prefix expands. run: | @@ -142,14 +142,14 @@ jobs: echo "INFINITO_SWARM_TEST_LABEL=$INFINITO_SWARM_TEST_LABEL" } >> "$GITHUB_ENV" - - name: Set up Python + - name: ๐Ÿ”ง Set up Python uses: actions/setup-python@v6 with: python-version: "3.12" cache: pip cache-dependency-path: pyproject.toml - - name: Install project (host venv) + - name: ๐Ÿ“ฆ Install project (host venv) shell: bash run: | make install-force @@ -157,7 +157,7 @@ jobs: source scripts/meta/env/load.sh echo "${VENV}/bin" >> "${GITHUB_PATH}" - - name: "Create dedicated network for simulated cluster (MTU 1400)" + - name: "๐Ÿ“ Create dedicated network for simulated cluster (MTU 1400)" # MTU 1400: TLS ServerHello fragmentation drops on host PMTU < 1500. run: | docker network create \ @@ -166,22 +166,22 @@ jobs: --opt com.docker.network.driver.mtu=1400 \ "${SWARM_LAB_NETWORK}" - - name: "Start NFSv4 server (empty systemd-Ubuntu)" + - name: "โ–ถ๏ธ Start NFSv4 server (empty systemd-Ubuntu)" run: ${{ env.SCRIPTS }}/01_start_nfs.sh - - name: "Start 3 simulated swarm nodes (systemd Ubuntu)" + - name: "โ–ถ๏ธ Start 3 simulated swarm nodes (systemd Ubuntu)" run: ${{ env.SCRIPTS }}/02_start_swarm_nodes.sh - - name: "Capture node + NFS-server IPs" + - name: "๐Ÿ–ฅ๏ธ Capture node + NFS-server IPs" run: ${{ env.SCRIPTS }}/03_capture_ips.sh - - name: "Bootstrap Python on every node (minimum Ansible can connect)" + - name: "๐Ÿฅพ Bootstrap Python on every node (minimum Ansible can connect)" run: ${{ env.SCRIPTS }}/04_bootstrap_nodes.sh - - name: "Project setup (.dockerignore + dotenv + scripts/setup.sh)" + - name: "๐Ÿ”ง Project setup (.dockerignore + dotenv + scripts/setup.sh)" run: make setup - - name: "Matrix-deploy ${{ matrix.apps }} across variant rounds (provision + deploy + in-deploy e2e + converge/verify per round)" + - name: "๐Ÿš€ Matrix-deploy ${{ matrix.apps }}: provision/deploy/e2e/verify per round" env: variant: ${{ matrix.variant }} run: | @@ -195,27 +195,27 @@ jobs: sudo -E env "PATH=$PATH" "HOME=$HOME" "SWARM_NAME=${SWARM_NAME:-}" "variant=${variant:-}" python3 -m cli.administration.deploy.swarm.matrix fi - - name: "Seed content (pre-drain marker on NFS volume)" + - name: "๐ŸŒฑ Seed content (pre-drain marker on NFS volume)" run: ${{ env.SCRIPTS }}/09_seed_content.sh - - name: "Drain the worker running ${{ matrix.apps }} + force reschedule" + - name: "๐Ÿ’ช Drain the worker running ${{ matrix.apps }} + force reschedule" run: ${{ env.SCRIPTS }}/10_drain_worker.sh - - name: "Assert state survived the reschedule" + - name: "โœ… Assert state survived the reschedule" run: ${{ env.SCRIPTS }}/11_assert_state.sh - - name: "Collect diagnostics on failure" + - name: "๐Ÿ“Š Collect diagnostics on failure" if: failure() run: ${{ env.SCRIPTS }}/12_collect_diagnostics.sh - - name: "Zip generated inventory for debugging" + - name: "๐Ÿ—œ๏ธ Zip generated inventory for debugging" if: always() shell: bash env: APP_ID: ${{ matrix.apps }} run: bash scripts/github/inventory/zip_swarm_for_upload.sh - - name: "Upload inventory artifact" + - name: "โฌ†๏ธ Upload inventory artifact" if: ${{ always() && !env.ACT }} uses: actions/upload-artifact@v7 with: @@ -223,14 +223,14 @@ jobs: path: /tmp/inventory-swarm-${{ matrix.apps }}.zip if-no-files-found: ignore - - name: "Collect Playwright reports from the manager" + - name: "๐Ÿ“Š Collect Playwright reports from the manager" if: always() shell: bash env: APP_ID: ${{ matrix.apps }} run: ${{ env.SCRIPTS }}/collect_playwright_reports.sh - - name: "Upload Playwright artifacts" + - name: "โฌ†๏ธ Upload Playwright artifacts" if: ${{ always() && !env.ACT }} uses: actions/upload-artifact@v7 with: @@ -238,6 +238,6 @@ jobs: path: /tmp/playwright-artifacts/ if-no-files-found: ignore - - name: "Cleanup" + - name: "๐Ÿงน Cleanup" if: always() run: ${{ env.SCRIPTS }}/13_cleanup.sh diff --git a/.github/workflows/test-dns.yml b/.github/workflows/test-dns.yml index 7c1905e585..3c09c4c33d 100644 --- a/.github/workflows/test-dns.yml +++ b/.github/workflows/test-dns.yml @@ -32,10 +32,10 @@ jobs: owner: ${{ steps.vars.outputs.owner }} repo_name: ${{ steps.vars.outputs.repo_name }} steps: - - name: Checkout + - name: โฌ‡๏ธ Checkout uses: actions/checkout@v7 - - name: Resolve image coordinates + - name: ๐Ÿ” Resolve image coordinates id: vars shell: bash run: | @@ -51,7 +51,7 @@ jobs: shell: bash run: ./scripts/install/apt.sh jq - - name: Compute matrix JSON + - name: ๐Ÿงฎ Compute matrix JSON id: out shell: bash run: | @@ -79,14 +79,14 @@ jobs: distro: ${{ fromJson(needs.prepare.outputs.matrix) }} steps: - - name: Checkout + - name: โฌ‡๏ธ Checkout uses: actions/checkout@v7 - - name: Install dnsutils (dig) + - name: ๐Ÿ“ฆ Install dnsutils (dig) shell: bash run: ./scripts/install/apt.sh dnsutils - - name: Start stack (coredns + infinito) for distro + - name: โ–ถ๏ธ Start stack (coredns + infinito) for distro shell: bash env: INFINITO_DISTRO: ${{ matrix.distro }} @@ -94,7 +94,7 @@ jobs: set -euo pipefail make compose-up - - name: DNS test suite + - name: ๐ŸŒ DNS test suite shell: bash env: INFINITO_DISTRO: ${{ matrix.distro }} @@ -102,14 +102,14 @@ jobs: set -euo pipefail scripts/tests/dns.sh - - name: Dump CoreDNS logs on failure + - name: ๐Ÿ’พ Dump CoreDNS logs on failure if: failure() shell: bash run: | docker ps -a || true docker logs infinito-coredns --tail=200 || true - - name: Dump infinito logs on failure + - name: ๐Ÿ’พ Dump infinito logs on failure if: failure() shell: bash env: diff --git a/.github/workflows/test-environment.yml b/.github/workflows/test-environment.yml index f7d6195f42..9277f6a8ec 100644 --- a/.github/workflows/test-environment.yml +++ b/.github/workflows/test-environment.yml @@ -51,10 +51,10 @@ jobs: docker-images: true swap-storage: false - - name: Checkout repository + - name: โฌ‡๏ธ Checkout repository uses: actions/checkout@v7 - - name: Run dev environment routine + - name: โ–ถ๏ธ Run dev environment routine shell: bash run: | set -euo pipefail diff --git a/.github/workflows/test-install-make.yml b/.github/workflows/test-install-make.yml index de3b348163..0e674f68e2 100644 --- a/.github/workflows/test-install-make.yml +++ b/.github/workflows/test-install-make.yml @@ -1,4 +1,4 @@ -name: "๐Ÿ“ฅ Test: Install Make" +name: "๐Ÿ“ฆ Test: Install Make" on: workflow_call: @@ -22,10 +22,10 @@ jobs: distro: [arch, debian, ubuntu, fedora, centos] steps: - - name: Checkout repository + - name: โฌ‡๏ธ Checkout repository uses: actions/checkout@v7 - - name: Resolve paths from default.env + - name: ๐Ÿ” Resolve paths from default.env run: | for key in INFINITO_SRC_DIR INFINITO_VENV_DIR; do value="$(awk -F= -v k="^${key}=" '$0 ~ k {print $2; exit}' default.env)" @@ -33,7 +33,7 @@ jobs: echo "${key}=${value}" >> "$GITHUB_ENV" done - - name: Install & test in pkgmgr virgin container + - name: ๐Ÿ“ฆ Install & test in pkgmgr virgin container run: | docker run --rm \ -e NIX_CONFIG="${NIX_CONFIG}" \ diff --git a/.github/workflows/test-install-pkgmgr.yml b/.github/workflows/test-install-pkgmgr.yml index eaaaef204f..3d62074f4a 100644 --- a/.github/workflows/test-install-pkgmgr.yml +++ b/.github/workflows/test-install-pkgmgr.yml @@ -1,4 +1,4 @@ -name: "๐Ÿ“ฅ Test: Install Package Manager" +name: "๐Ÿ“ฆ Test: Install Package Manager" on: workflow_call: @@ -22,16 +22,16 @@ jobs: distro: [arch, debian, ubuntu, fedora, centos] steps: - - name: Checkout repository + - name: โฌ‡๏ธ Checkout repository uses: actions/checkout@v7 - - name: Resolve INFINITO_VENV_DIR from default.env + - name: ๐Ÿ” Resolve INFINITO_VENV_DIR from default.env run: | venv_dir="$(awk -F= '/^INFINITO_VENV_DIR=/{print $2; exit}' default.env)" test -n "${venv_dir}" || { echo "INFINITO_VENV_DIR not found in default.env" >&2; exit 1; } echo "INFINITO_VENV_DIR=${venv_dir}" >> "$GITHUB_ENV" - - name: Install & test in pkgmgr virgin container + - name: ๐Ÿ“ฆ Install & test in pkgmgr virgin container run: | docker run --rm \ -w "/root/" \ diff --git a/.github/workflows/update.yml b/.github/workflows/update.yml index 20f5ff2a67..24e8276af4 100644 --- a/.github/workflows/update.yml +++ b/.github/workflows/update.yml @@ -18,27 +18,27 @@ jobs: if: vars.CI_ENABLE_AUTO_UPDATES == 'true' runs-on: ubuntu-latest steps: - - name: Checkout + - name: โฌ‡๏ธ Checkout uses: actions/checkout@v7 - - name: Set up Python + - name: ๐Ÿ”ง Set up Python uses: actions/setup-python@v6 with: python-version: "3.12" cache: pip cache-dependency-path: pyproject.toml - - name: Install update dependencies + - name: ๐Ÿ“ฆ Install update dependencies run: bash scripts/github/update/install_python.sh - - name: Update Docker image versions + - name: ๐Ÿ”„ Update Docker image versions run: bash scripts/github/update/image_versions.sh - - name: Check for changes + - name: ๐Ÿ”Ž Check for changes id: diff run: bash scripts/github/resolve/check_git_changes.sh roles - - name: Generate app token + - name: โš™๏ธ Generate app token if: steps.diff.outputs.changed == 'true' id: app-token uses: actions/create-github-app-token@v3 @@ -46,7 +46,7 @@ jobs: client-id: ${{ secrets.BOT_APP_CLIENT_ID }} private-key: ${{ secrets.BOT_APP_PRIVATE_KEY }} - - name: Open PR if Docker image versions changed + - name: ๐Ÿ“‚ Open PR if Docker image versions changed if: steps.diff.outputs.changed == 'true' env: GH_TOKEN: ${{ steps.app-token.outputs.token }} @@ -63,27 +63,27 @@ jobs: if: vars.CI_ENABLE_AUTO_UPDATES == 'true' runs-on: ubuntu-latest steps: - - name: Checkout + - name: โฌ‡๏ธ Checkout uses: actions/checkout@v7 - - name: Set up Python + - name: ๐Ÿ”ง Set up Python uses: actions/setup-python@v6 with: python-version: "3.12" cache: pip cache-dependency-path: pyproject.toml - - name: Install update dependencies + - name: ๐Ÿ“ฆ Install update dependencies run: bash scripts/github/update/install_python.sh - - name: Update repository refs + - name: ๐Ÿ”„ Update repository refs run: bash scripts/github/update/repository_refs.sh - - name: Check for changes + - name: ๐Ÿ”Ž Check for changes id: diff run: bash scripts/github/resolve/check_git_changes.sh roles - - name: Generate app token + - name: โš™๏ธ Generate app token if: steps.diff.outputs.changed == 'true' id: app-token uses: actions/create-github-app-token@v3 @@ -91,7 +91,7 @@ jobs: client-id: ${{ secrets.BOT_APP_CLIENT_ID }} private-key: ${{ secrets.BOT_APP_PRIVATE_KEY }} - - name: Open PR if repository refs changed + - name: ๐Ÿ“‚ Open PR if repository refs changed if: steps.diff.outputs.changed == 'true' env: GH_TOKEN: ${{ steps.app-token.outputs.token }} @@ -108,23 +108,23 @@ jobs: if: vars.CI_ENABLE_AUTO_UPDATES == 'true' runs-on: ubuntu-latest steps: - - name: Checkout + - name: โฌ‡๏ธ Checkout uses: actions/checkout@v7 - - name: Set up Node.js + - name: ๐Ÿ”ง Set up Node.js uses: actions/setup-node@v6 with: node-version: lts/* cache: "npm" - - name: Update skills + - name: ๐Ÿ”„ Update skills run: bash scripts/install/skills/update.sh - - name: Check for changes + - name: ๐Ÿ”Ž Check for changes id: diff run: bash scripts/github/resolve/check_git_changes.sh skills-lock.json - - name: Generate app token + - name: โš™๏ธ Generate app token if: steps.diff.outputs.changed == 'true' id: app-token uses: actions/create-github-app-token@v3 @@ -132,7 +132,7 @@ jobs: client-id: ${{ secrets.BOT_APP_CLIENT_ID }} private-key: ${{ secrets.BOT_APP_PRIVATE_KEY }} - - name: Open PR if skills-lock.json changed + - name: ๐Ÿ“‚ Open PR if skills-lock.json changed if: steps.diff.outputs.changed == 'true' env: GH_TOKEN: ${{ steps.app-token.outputs.token }} diff --git a/cli/build/include/__main__.py b/cli/build/include/__main__.py index a0e3b02c93..b7963060ef 100644 --- a/cli/build/include/__main__.py +++ b/cli/build/include/__main__.py @@ -185,13 +185,13 @@ def gen_condi_role_incl(roles_dir, prefixes=None): app_id = role['application_id'] entries.append( - f"- name: setup {app_id}\n" + f"- name: ๐Ÿ”ง setup {app_id}\n" f" when: ('{app_id}' | application_allowed(group_names, lookup('deployment').whitelist))\n" f" include_role:\n" f" name: {role_name}\n" ) entries.append( - f"- name: flush handlers after {app_id}\n" + f"- name: ๐Ÿšฟ flush handlers after {app_id}\n" f" meta: flush_handlers\n" ) diff --git a/roles/desk-bluray-player/tasks/main.yml b/roles/desk-bluray-player/tasks/main.yml index 4a6796b9f3..ee4dd8fca1 100644 --- a/roles/desk-bluray-player/tasks/main.yml +++ b/roles/desk-bluray-player/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: install vlc and blu ray software +- name: ๐Ÿ“ฆ install vlc and blu ray software package: name: - vlc diff --git a/roles/desk-chromium/tasks/main.yml b/roles/desk-chromium/tasks/main.yml index 42fc27843a..f04339f00b 100644 --- a/roles/desk-chromium/tasks/main.yml +++ b/roles/desk-chromium/tasks/main.yml @@ -1,26 +1,26 @@ --- -- name: Update package cache (Debian/Ubuntu) +- name: ๐Ÿ”„ Update package cache (Debian/Ubuntu) apt: update_cache: true when: ansible_facts['os_family'] == "Debian" -- name: Install Chromium browser +- name: ๐Ÿ“ฆ Install Chromium browser package: name: "{{ chromium_package }}" state: present -- name: Install KeePassXC +- name: ๐Ÿ“ฆ Install KeePassXC package: name: keepassxc state: present -- name: Ensure Chromium policies directory exists +- name: โœ… Ensure Chromium policies directory exists file: path: /etc/chromium/policies/managed state: directory mode: "0755" -- name: Copy the extensions policy file for Chromium +- name: ๐Ÿ“‹ Copy the extensions policy file for Chromium template: # nocheck: stack-host-template (per-host workstation chromium policy) src: extensions_policy.json.j2 dest: /etc/chromium/policies/managed/extensions_policy.json diff --git a/roles/desk-copyq/tasks/main.yml b/roles/desk-copyq/tasks/main.yml index 65f62c5ecf..db017bc1d7 100644 --- a/roles/desk-copyq/tasks/main.yml +++ b/roles/desk-copyq/tasks/main.yml @@ -1,17 +1,17 @@ --- -- name: Install CopyQ clipboard manager +- name: ๐Ÿ“ฆ Install CopyQ clipboard manager package: name: copyq state: present -- name: Ensure autostart directory exists +- name: โœ… Ensure autostart directory exists file: path: "{{ ansible_facts['env']['HOME'] }}/.config/autostart" state: directory mode: "0755" become: false -- name: Add CopyQ to user autostart +- name: โž• Add CopyQ to user autostart copy: dest: "{{ ansible_facts['env']['HOME'] }}/.config/autostart/copyq.desktop" content: | @@ -26,6 +26,6 @@ mode: "0644" become: false -- name: Include CopyQ server systemdโ€‘user service setup +- name: ๐Ÿ“‚ Include CopyQ server systemdโ€‘user service setup import_tasks: server.yml when: copyq_server_enabled | bool diff --git a/roles/desk-copyq/tasks/server.yml b/roles/desk-copyq/tasks/server.yml index d0e95fc77e..be148d96af 100644 --- a/roles/desk-copyq/tasks/server.yml +++ b/roles/desk-copyq/tasks/server.yml @@ -1,12 +1,12 @@ --- -- name: Ensure systemd user unit directory exists +- name: โœ… Ensure systemd user unit directory exists file: path: "{{ ansible_facts['env']['HOME'] }}/.config/systemd/user" state: directory mode: "0755" become: false -- name: Install CopyQ user service unit +- name: ๐Ÿ“ฆ Install CopyQ user service unit copy: dest: "{{ ansible_facts['env']['HOME'] }}/.config/systemd/user/copyq.service" content: | @@ -22,13 +22,13 @@ mode: "0644" become: false -- name: Reload systemd user daemon +- name: ๐Ÿ”„ Reload systemd user daemon systemd: scope: user daemon_reload: true become: false -- name: Enable and start CopyQ user service +- name: ๐ŸŸข Enable and start CopyQ user service systemd: name: copyq.service scope: user diff --git a/roles/desk-docker/tasks/main.yml b/roles/desk-docker/tasks/main.yml index e6226e83c3..545ab8e4ab 100644 --- a/roles/desk-docker/tasks/main.yml +++ b/roles/desk-docker/tasks/main.yml @@ -1,12 +1,12 @@ --- -- name: install docker +- name: ๐Ÿ“ฆ install docker package: name: - docker - docker-compose state: present -- name: "Adding user {{ lookup('users', WORKSTATION_USER).username }} to relevant docker usergroup" +- name: "๐Ÿ”ง Add user {{ lookup('users', WORKSTATION_USER).username }} to docker group" user: name: "{{ lookup('users', WORKSTATION_USER).username }}" groups: docker diff --git a/roles/desk-dotlinker/tasks/01_install.yml b/roles/desk-dotlinker/tasks/01_install.yml index 512ce71346..bf3eaaa0a0 100644 --- a/roles/desk-dotlinker/tasks/01_install.yml +++ b/roles/desk-dotlinker/tasks/01_install.yml @@ -1,5 +1,5 @@ --- -- name: Install dotlinker via pkgmgr +- name: ๐Ÿ“ฆ Install dotlinker via pkgmgr include_role: name: pkgmgr-install vars: diff --git a/roles/desk-dotlinker/tasks/02_apply.yml b/roles/desk-dotlinker/tasks/02_apply.yml index c067119816..90a9babb2f 100644 --- a/roles/desk-dotlinker/tasks/02_apply.yml +++ b/roles/desk-dotlinker/tasks/02_apply.yml @@ -1,12 +1,12 @@ --- -- name: Ensure dotlinker user is defined +- name: โœ… Ensure dotlinker user is defined ansible.builtin.assert: that: - dotlinker_user is defined - dotlinker_user | length > 0 fail_msg: "dotlinker_user must be provided by the calling role." -- name: Ensure dotlinker config directory exists +- name: โœ… Ensure dotlinker config directory exists ansible.builtin.file: path: "{{ dotlinker_config_path | dirname }}" state: directory @@ -14,7 +14,7 @@ group: "{{ dotlinker_user }}" mode: "0755" -- name: Register mappings in dotlinker +- name: ๐Ÿ“ Register mappings in dotlinker ansible.builtin.command: argv: >- {{ @@ -31,7 +31,7 @@ label: "{{ item.name }}" when: dotlinker_mappings | length > 0 -- name: Apply dotlinker mappings (pull) +- name: ๐Ÿ“Œ Apply dotlinker mappings (pull) ansible.builtin.command: > {{ dotlinker_cli_name | quote }} -c {{ (dotlinker_config_path ) | quote }} diff --git a/roles/desk-firefox/tasks/main.yml b/roles/desk-firefox/tasks/main.yml index c36d18db99..cfbb8de4fe 100644 --- a/roles/desk-firefox/tasks/main.yml +++ b/roles/desk-firefox/tasks/main.yml @@ -1,16 +1,16 @@ --- -- name: Install Firefox +- name: ๐Ÿ“ฆ Install Firefox package: name: "{{ firefox_package }}" state: present -- name: Ensure Firefox distribution policies directory exists +- name: โœ… Ensure Firefox distribution policies directory exists file: path: "{{ firefox_policy_dir }}" state: directory mode: "0755" -- name: Deploy Firefox Enterprise Policies file +- name: ๐Ÿš€ Deploy Firefox Enterprise Policies file template: # nocheck: stack-host-template (per-host workstation firefox policy) src: policies.json.j2 dest: "{{ firefox_policy_file }}" diff --git a/roles/desk-git/tasks/main.yml b/roles/desk-git/tasks/main.yml index a41c27c7ee..e968a62a86 100644 --- a/roles/desk-git/tasks/main.yml +++ b/roles/desk-git/tasks/main.yml @@ -1,11 +1,11 @@ --- -- name: install git +- name: ๐Ÿ“ฆ install git package: name: git state: present become: true -- name: Install gitcon CLI system-wide via pip +- name: ๐Ÿ“ฆ Install gitcon CLI system-wide via pip include_role: name: sys-pip-install vars: @@ -14,7 +14,7 @@ - when: run_once_desk_git is not defined block: - - name: setup git (as workstation user) + - name: ๐Ÿ”ง setup git (as workstation user) ansible.builtin.command: argv: - "{{ lookup('command_path', 'gitcon') }}" diff --git a/roles/desk-gnome-caffeine/tasks/01_core.yml b/roles/desk-gnome-caffeine/tasks/01_core.yml index 68dc56a289..6bce271569 100644 --- a/roles/desk-gnome-caffeine/tasks/01_core.yml +++ b/roles/desk-gnome-caffeine/tasks/01_core.yml @@ -1,17 +1,17 @@ --- -- name: Install caffeine +- name: ๐Ÿ“ฆ Install caffeine include_role: name: sys-aur-install vars: yay_install_packages: - caffeine-ng -- name: Create autostart directory if it doesn't exist +- name: ๐Ÿ“ Create autostart directory if it doesn't exist file: path: "{{auto_start_directory}}" state: directory -- name: Copy caffeine.desktop file to autostart directory +- name: ๐Ÿ“‹ Copy caffeine.desktop file to autostart directory template: # nocheck: stack-host-template (per-host workstation autostart file) src: caffeine.desktop.j2 dest: "{{auto_start_directory}}caffeine.desktop" diff --git a/roles/desk-gnome-extensions/tasks/01_core.yml b/roles/desk-gnome-extensions/tasks/01_core.yml index 3c7b423196..d6e7c78c29 100644 --- a/roles/desk-gnome-extensions/tasks/01_core.yml +++ b/roles/desk-gnome-extensions/tasks/01_core.yml @@ -1,15 +1,15 @@ --- -- name: GNOME Activate Extensions +- name: ๐ŸŸข GNOME Activate Extensions ansible.builtin.shell: gsettings set org.gnome.shell disable-user-extensions false become: false -- name: "pkgmgr install" +- name: "๐Ÿ“ฆ pkgmgr install" include_role: name: pkgmgr-install vars: package_name: cli-gnome-extension-manager -- name: Execute CLI GNOME Extension manager script +- name: โ–ถ๏ธ Execute CLI GNOME Extension manager script ansible.builtin.shell: cli-gnome-extension-manager "{{ item[0] }}" "{{ item[1] }}" "{{ item[2] }}" loop: "{{ lookup('config', application_id, 'services.gnome-extensions.plugins') }}" become: false diff --git a/roles/desk-gnome-terminal/tasks/01_core.yml b/roles/desk-gnome-terminal/tasks/01_core.yml index 44ccf2876d..dcb24939bd 100644 --- a/roles/desk-gnome-terminal/tasks/01_core.yml +++ b/roles/desk-gnome-terminal/tasks/01_core.yml @@ -1,12 +1,12 @@ --- -- name: Install Gnome Terminal +- name: ๐Ÿ“ฆ Install Gnome Terminal # @see https://en.wikipedia.org/wiki/GNOME_Terminal package: name: - gnome-terminal state: present -- name: "Set zsh as default shell for {{ lookup('users', WORKSTATION_USER).username }}" +- name: "๐Ÿ”ง Set zsh as default shell for {{ lookup('users', WORKSTATION_USER).username }}" user: name: "{{ lookup('users', WORKSTATION_USER).username }}" shell: /usr/bin/zsh diff --git a/roles/desk-gnome/tasks/01_core.yml b/roles/desk-gnome/tasks/01_core.yml index 0c865bc72f..23d6371d38 100644 --- a/roles/desk-gnome/tasks/01_core.yml +++ b/roles/desk-gnome/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Install GNOME GSettings schemas + GNOME Shell (cross-distro) +- name: ๐Ÿ“ฆ Install GNOME GSettings schemas + GNOME Shell (cross-distro) become: true vars: gnome_schema_packages: @@ -32,7 +32,7 @@ }} state: present -- name: Include dependencies +- name: ๐Ÿ“‚ Include dependencies include_role: name: "{{ dependency_role }}" loop: diff --git a/roles/desk-gnome/tasks/02_extensions.yml b/roles/desk-gnome/tasks/02_extensions.yml index 76bd2a2b62..8800e2b22f 100644 --- a/roles/desk-gnome/tasks/02_extensions.yml +++ b/roles/desk-gnome/tasks/02_extensions.yml @@ -1,15 +1,15 @@ --- -- name: GNOME Activate Extensions +- name: ๐ŸŸข GNOME Activate Extensions ansible.builtin.shell: gsettings set org.gnome.shell disable-user-extensions false become: false -- name: "pkgmgr install" +- name: "๐Ÿ“ฆ pkgmgr install" include_role: name: pkgmgr-install vars: package_name: cli-gnome-extension-manager -- name: Execute CLI GNOME Extension manager script +- name: โ–ถ๏ธ Execute CLI GNOME Extension manager script ansible.builtin.shell: >- cli-gnome-extension-manager "{{ 'enable' if item.value.enabled | bool else 'disable' }}" diff --git a/roles/desk-gnucash/tasks/main.yml b/roles/desk-gnucash/tasks/main.yml index f1e12d5026..daeefce5d9 100644 --- a/roles/desk-gnucash/tasks/main.yml +++ b/roles/desk-gnucash/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: Install GnuCash +- name: ๐Ÿ“ฆ Install GnuCash package: name: - gnucash diff --git a/roles/desk-jrnl/tasks/main.yml b/roles/desk-jrnl/tasks/main.yml index c14bf8c4b2..5233698679 100644 --- a/roles/desk-jrnl/tasks/main.yml +++ b/roles/desk-jrnl/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: install jrnl +- name: ๐Ÿ“ฆ install jrnl package: name: - jrnl diff --git a/roles/desk-keepassxc/tasks/main.yml b/roles/desk-keepassxc/tasks/main.yml index 7743b62948..07d3c0c16c 100644 --- a/roles/desk-keepassxc/tasks/main.yml +++ b/roles/desk-keepassxc/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: install security tools +- name: ๐Ÿ“ฆ install security tools package: name: - keepassxc diff --git a/roles/desk-libreoffice/tasks/main.yml b/roles/desk-libreoffice/tasks/main.yml index c589723c8d..0dfba10be5 100644 --- a/roles/desk-libreoffice/tasks/main.yml +++ b/roles/desk-libreoffice/tasks/main.yml @@ -1,12 +1,12 @@ --- -- name: install libreoffice +- name: ๐Ÿ“ฆ install libreoffice package: name: - ttf-liberation - "libreoffice-{{ lookup('applications', 'desk-libreoffice').flavor }}" state: present -- name: install libreoffice language packages +- name: ๐Ÿ“ฆ install libreoffice language packages package: name: "libreoffice-{{ lookup('applications', 'desk-libreoffice').flavor }}-{{ item }}" state: present diff --git a/roles/desk-micro/tasks/main.yml b/roles/desk-micro/tasks/main.yml index 5644f7067b..a9129ae6a7 100644 --- a/roles/desk-micro/tasks/main.yml +++ b/roles/desk-micro/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: install micro +- name: ๐Ÿ“ฆ install micro package: name: - micro diff --git a/roles/desk-neovim/tasks/main.yml b/roles/desk-neovim/tasks/main.yml index 7deaadb92d..006546c68e 100644 --- a/roles/desk-neovim/tasks/main.yml +++ b/roles/desk-neovim/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: install neovim +- name: ๐Ÿ“ฆ install neovim package: name: - neovim diff --git a/roles/desk-nextcloud/tasks/main.yml b/roles/desk-nextcloud/tasks/main.yml index a1545000b5..406f104286 100644 --- a/roles/desk-nextcloud/tasks/main.yml +++ b/roles/desk-nextcloud/tasks/main.yml @@ -1,14 +1,14 @@ --- -- name: Install nextcloud-client +- name: ๐Ÿ“ฆ Install nextcloud-client package: name: nextcloud-client state: present -- name: Initialize dotlinker mapping list +- name: ๐ŸŽฌ Initialize dotlinker mapping list ansible.builtin.set_fact: nextcloud_dotlinker_mappings: [] -- name: Build dotlinker mappings for Nextcloud folders +- name: ๐Ÿ”จ Build dotlinker mappings for Nextcloud folders ansible.builtin.set_fact: nextcloud_dotlinker_mappings: >- {{ @@ -23,7 +23,7 @@ }} loop: "{{ nextcloud_dotlinker_folders }}" -- name: Add dump mapping (Dump -> InstantUpload) +- name: โž• Add dump mapping (Dump -> InstantUpload) ansible.builtin.set_fact: nextcloud_dotlinker_mappings: >- {{ @@ -37,7 +37,7 @@ ] }} -- name: Apply Nextcloud folder mappings via dotlinker +- name: ๐Ÿ“Œ Apply Nextcloud folder mappings via dotlinker ansible.builtin.include_role: name: desk-dotlinker vars: diff --git a/roles/desk-obs/tasks/main.yml b/roles/desk-obs/tasks/main.yml index b199160673..a8deeb5d80 100644 --- a/roles/desk-obs/tasks/main.yml +++ b/roles/desk-obs/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: install streaming +- name: ๐Ÿ“ฆ install streaming package: name: - obs-studio diff --git a/roles/desk-qbittorrent/tasks/main.yml b/roles/desk-qbittorrent/tasks/main.yml index 5ed5e63091..79d81ecef3 100644 --- a/roles/desk-qbittorrent/tasks/main.yml +++ b/roles/desk-qbittorrent/tasks/main.yml @@ -1,6 +1,6 @@ --- - block: - - name: install torrent software + - name: ๐Ÿ“ฆ install torrent software include_role: name: sys-aur-install vars: diff --git a/roles/desk-retroarch/tasks/main.yml b/roles/desk-retroarch/tasks/main.yml index af3bf4a5b4..edb9c51c9a 100644 --- a/roles/desk-retroarch/tasks/main.yml +++ b/roles/desk-retroarch/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: Install RetroArch and assets +- name: ๐Ÿ“ฆ Install RetroArch and assets package: name: "{{ retroarch_packages }}" state: present diff --git a/roles/desk-spotify/tasks/main.yml b/roles/desk-spotify/tasks/main.yml index 4455f39b03..e950775964 100644 --- a/roles/desk-spotify/tasks/main.yml +++ b/roles/desk-spotify/tasks/main.yml @@ -1,6 +1,6 @@ --- - block: - - name: install spotify + - name: ๐Ÿ“ฆ install spotify include_role: name: sys-aur-install vars: diff --git a/roles/desk-ssh/tasks/01_core.yml b/roles/desk-ssh/tasks/01_core.yml index 27f6a6c52a..8996de8785 100644 --- a/roles/desk-ssh/tasks/01_core.yml +++ b/roles/desk-ssh/tasks/01_core.yml @@ -1,10 +1,10 @@ --- -- name: Include dependency 'dev-shell' +- name: ๐Ÿ“‚ Include dependency 'dev-shell' include_role: name: dev-shell when: run_once_dev_shell is not defined -- name: pull ssh repository from {{desk_ssh_repository}} +- name: โฌ‡๏ธ pull ssh repository from {{desk_ssh_repository}} git: repo: "{{desk_ssh_repository}}" dest: "$HOME/.ssh" @@ -14,26 +14,26 @@ ignore_errors: true become: false -- name: Warn if repo is not reachable +- name: โš ๏ธ Warn if repo is not reachable debug: msg: "Warning: Repository is not reachable." when: git_result.failed and MODE_DEBUG | bool -- name: Ensure systemd user directory exists +- name: โœ… Ensure systemd user directory exists file: path: "$HOME/.config/systemd/user" state: directory mode: "0700" become: false -- name: Deploy ssh-agent systemd unit file +- name: ๐Ÿš€ Deploy ssh-agent systemd unit file template: # nocheck: stack-host-template (per-host/user workstation systemd unit) src: ssh-agent.service.j2 dest: "$HOME/.config/systemd/user/ssh-agent.service" mode: "0644" become: false -- name: Enable and start ssh-agent service +- name: ๐ŸŸข Enable and start ssh-agent service systemd: name: ssh-agent.service scope: user @@ -42,7 +42,7 @@ daemon_reload: true become: false -- name: Ensure ~/.profile exists with common environment +- name: โœ… Ensure ~/.profile exists with common environment lineinfile: path: "$HOME/.profile" line: 'export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket"' diff --git a/roles/desk-torbrowser/tasks/main.yml b/roles/desk-torbrowser/tasks/main.yml index d530a55cfc..d130cec346 100644 --- a/roles/desk-torbrowser/tasks/main.yml +++ b/roles/desk-torbrowser/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: Install torbrowser +- name: ๐Ÿ“ฆ Install torbrowser package: name: - tor diff --git a/roles/desk-virtualbox/tasks/01_core.yml b/roles/desk-virtualbox/tasks/01_core.yml index 83d33c781c..05a088dde5 100644 --- a/roles/desk-virtualbox/tasks/01_core.yml +++ b/roles/desk-virtualbox/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Install VirtualBox and kernel modules +- name: ๐Ÿ“ฆ Install VirtualBox and kernel modules become: true community.general.pacman: name: >- @@ -8,19 +8,19 @@ state: present update_cache: true -- name: Load vbox kernel modules +- name: ๐Ÿ“ฅ Load vbox kernel modules become: true command: vboxreload register: vboxreload_output failed_when: vboxreload_output.rc != 0 and '"vboxdrv"' not in vboxreload_output.stderr -- name: Build and install Oracle VirtualBox extension pack +- name: ๐Ÿ”จ Build and install Oracle VirtualBox extension pack become: true command: pamac build --no-confirm virtualbox-ext-oracle args: creates: /usr/lib/virtualbox/ExtensionPacks/Oracle_VM_VirtualBox_Extension_Pack -- name: Add current user to vboxusers group +- name: โž• Add current user to vboxusers group become: true user: name: "{{ lookup('env','USER') }}" diff --git a/roles/desk-virtualbox/tasks/main.yml b/roles/desk-virtualbox/tasks/main.yml index 8e2dff9a83..9b31472827 100644 --- a/roles/desk-virtualbox/tasks/main.yml +++ b/roles/desk-virtualbox/tasks/main.yml @@ -4,7 +4,7 @@ - run_once_desk_virtualbox is not defined - ansible_facts['os_family'] == "Archlinux" -- name: WARNING - VirtualBox role is Arch-only, skipping on this host +- name: ๐ŸŽญ WARNING - VirtualBox role is Arch-only, skipping on this host debug: msg: >- WARNING: Skipping VirtualBox setup because this role is Arch/Manjaro-only. diff --git a/roles/desk-zoom/tasks/main.yml b/roles/desk-zoom/tasks/main.yml index d8ec3addf0..7879748b9d 100644 --- a/roles/desk-zoom/tasks/main.yml +++ b/roles/desk-zoom/tasks/main.yml @@ -1,6 +1,6 @@ --- - block: - - name: install video conference software + - name: ๐Ÿ“ฆ install video conference software include_role: name: sys-aur-install vars: diff --git a/roles/dev-arduino/tasks/main.yml b/roles/dev-arduino/tasks/main.yml index 26020dd595..c1ee30032f 100644 --- a/roles/dev-arduino/tasks/main.yml +++ b/roles/dev-arduino/tasks/main.yml @@ -1,12 +1,12 @@ --- -- name: install arduino developer tools +- name: ๐Ÿ“ฆ install arduino developer tools package: name: - arduino - arduino-docs state: present -- name: "Adding user {{ lookup('users', WORKSTATION_USER).username }} to relevant arduino usergroups" +- name: "๐Ÿ”ง Add user {{ lookup('users', WORKSTATION_USER).username }} to arduino groups" ansible.builtin.user: name: "{{ lookup('users', WORKSTATION_USER).username }}" groups: diff --git a/roles/dev-base-devel/tasks/main.yml b/roles/dev-base-devel/tasks/main.yml index 6190f2a7f1..41b53bff47 100644 --- a/roles/dev-base-devel/tasks/main.yml +++ b/roles/dev-base-devel/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: Install base development toolchain (cross-distro) +- name: ๐Ÿ“ฆ Install base development toolchain (cross-distro) become: true vars: dev_base_devel_packages: diff --git a/roles/dev-core/tasks/main.yml b/roles/dev-core/tasks/main.yml index f4107c2586..2d73e1ce56 100644 --- a/roles/dev-core/tasks/main.yml +++ b/roles/dev-core/tasks/main.yml @@ -1,11 +1,11 @@ --- - block: - - name: Include dependency 'pkgmgr' + - name: ๐Ÿ“‚ Include dependency 'pkgmgr' include_role: name: pkgmgr when: run_once_pkgmgr is not defined - - name: install base developer tools + - name: ๐Ÿ“ฆ install base developer tools package: name: - code diff --git a/roles/dev-fakeroot/tasks/01_core.yml b/roles/dev-fakeroot/tasks/01_core.yml index 3fdeab3705..5e11276abf 100644 --- a/roles/dev-fakeroot/tasks/01_core.yml +++ b/roles/dev-fakeroot/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Resolve fakeroot package names for current distribution +- name: ๐Ÿ” Resolve fakeroot package names for current distribution ansible.builtin.set_fact: dev_fakeroot_packages: >- {{ @@ -8,7 +8,7 @@ else [] }} -- name: Fail for unsupported distribution in dev-fakeroot role +- name: ๐Ÿ›‘ Fail for unsupported distribution in dev-fakeroot role ansible.builtin.assert: that: - (dev_fakeroot_packages | length) > 0 @@ -16,13 +16,13 @@ Unsupported distribution for dev-fakeroot role: {{ ansible_facts['distribution'] }} ({{ ansible_facts['os_family'] }}). -- name: Enable EPEL on CentOS Stream (required for fakeroot package) +- name: ๐ŸŸข Enable EPEL on CentOS Stream (required for fakeroot package) ansible.builtin.package: name: epel-release state: present when: ansible_facts['distribution'] in ['CentOS', 'CentOS Stream'] -- name: Install fakeroot package(s) +- name: ๐Ÿ“ฆ Install fakeroot package(s) ansible.builtin.package: name: "{{ dev_fakeroot_packages }}" state: present diff --git a/roles/dev-gcc/tasks/main.yml b/roles/dev-gcc/tasks/main.yml index 25e5592746..801d5532cc 100644 --- a/roles/dev-gcc/tasks/main.yml +++ b/roles/dev-gcc/tasks/main.yml @@ -1,6 +1,6 @@ --- - block: - - name: Install GCC compiler and runtime (cross-distro) + - name: ๐Ÿ“ฆ Install GCC compiler and runtime (cross-distro) ansible.builtin.package: name: >- {{ diff --git a/roles/dev-git/tasks/main.yml b/roles/dev-git/tasks/main.yml index 36ef6ede42..9fc06ce505 100644 --- a/roles/dev-git/tasks/main.yml +++ b/roles/dev-git/tasks/main.yml @@ -1,6 +1,6 @@ --- - block: - - name: install git + - name: ๐Ÿ“ฆ install git package: name: git state: present diff --git a/roles/dev-java/tasks/main.yml b/roles/dev-java/tasks/main.yml index a046c5f648..ddb2483abc 100644 --- a/roles/dev-java/tasks/main.yml +++ b/roles/dev-java/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: install java +- name: ๐Ÿ“ฆ install java package: name: - jdk11-openjdk diff --git a/roles/dev-locales/tasks/main.yml b/roles/dev-locales/tasks/main.yml index 0cd03e3626..d9a4eb03cd 100644 --- a/roles/dev-locales/tasks/main.yml +++ b/roles/dev-locales/tasks/main.yml @@ -1,14 +1,14 @@ --- -- name: Setup locale.gen +- name: ๐Ÿ”ง Setup locale.gen template: # nocheck: stack-host-template (per-host /etc/locale.gen) src: locale.gen.j2 dest: /etc/locale.gen -- name: Setup locale.conf +- name: ๐Ÿ”ง Setup locale.conf template: # nocheck: stack-host-template (per-host /etc/locale.conf, not stack-host-only) src: locale.conf.j2 dest: /etc/locale.conf -- name: Generate locales +- name: โš™๏ธ Generate locales shell: locale-gen become: true diff --git a/roles/dev-make/tasks/main.yml b/roles/dev-make/tasks/main.yml index ab81d290fe..2677832580 100644 --- a/roles/dev-make/tasks/main.yml +++ b/roles/dev-make/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: install make +- name: ๐Ÿ“ฆ install make package: name: make state: present diff --git a/roles/dev-nix/tasks/01_core.yml b/roles/dev-nix/tasks/01_core.yml index 6b594af08d..11018a8987 100644 --- a/roles/dev-nix/tasks/01_core.yml +++ b/roles/dev-nix/tasks/01_core.yml @@ -4,20 +4,20 @@ # - Non-Arch systems: use the official installer with SHA256 verification # 0) Ensure CA trust is present and discover CA bundle path for Nix TLS -- name: Ensure system CA certificates are installed +- name: โœ… Ensure system CA certificates are installed ansible.builtin.package: name: ca-certificates state: present become: true -- name: Probe CA bundle candidate paths +- name: ๐Ÿ” Probe CA bundle candidate paths ansible.builtin.stat: path: "{{ item }}" loop: "{{ DEV_NIX_SSL_CERT_FILE_CANDIDATES }}" register: dev_nix_ssl_cert_file_probe become: true -- name: Set CA bundle path for Nix +- name: ๐Ÿ”ง Set CA bundle path for Nix ansible.builtin.set_fact: dev_nix_ssl_cert_file: >- {{ @@ -31,7 +31,7 @@ }} # 1) Arch-based systems: just install the distro package -- name: Install Nix via package manager on Arch-based systems +- name: ๐Ÿ“ฆ Install Nix via package manager on Arch-based systems package: name: nix state: present @@ -42,19 +42,19 @@ - ansible_facts.architecture == "x86_64" # 2) Non-Arch systems: delegate installer logic to a separate task file -- name: Include non-Arch installer logic +- name: ๐Ÿ“‚ Include non-Arch installer logic ansible.builtin.include_tasks: 02_non_arch_installer.yml when: not ( ansible_facts.os_family == "Archlinux" and ansible_facts.distribution == "Archlinux" and ansible_facts.architecture == "x86_64" ) # 3) Configure Nix experimental features (common for all platforms) -- name: Ensure Nix config directory exists +- name: โœ… Ensure Nix config directory exists ansible.builtin.file: path: /etc/nix state: directory mode: "0755" become: true -- name: Deploy Nix configuration (nix.conf) +- name: ๐Ÿš€ Deploy Nix configuration (nix.conf) ansible.builtin.template: # nocheck: stack-host-template (per-host /etc/nix/nix.conf, not stack-host-only) src: "nix.conf.j2" dest: "/etc/nix/nix.conf" diff --git a/roles/dev-nix/tasks/02_non_arch_installer.yml b/roles/dev-nix/tasks/02_non_arch_installer.yml index 476de024ef..3a0f9c8836 100644 --- a/roles/dev-nix/tasks/02_non_arch_installer.yml +++ b/roles/dev-nix/tasks/02_non_arch_installer.yml @@ -4,7 +4,7 @@ # and run the daemon (multi-user) installer. # 1) Fetch the official SHA256 from releases.nixos.org on the control node -- name: Fetch official Nix installer SHA256 +- name: โฌ‡๏ธ Fetch official Nix installer SHA256 uri_retry: url: "{{ dev_nix_installer_sha256_url }}" return_content: true @@ -13,14 +13,14 @@ run_once: true become: false -- name: Set expected installer checksum from official SHA256 +- name: ๐Ÿ”ง Set expected installer checksum from official SHA256 ansible.builtin.set_fact: dev_nix_installer_sha256: >- {{ dev_nix_official_sha_response.content.split()[0] | trim }} run_once: true # 2) Download installer script on the target and verify via checksum -- name: Download Nix installer script from official releases +- name: โฌ‡๏ธ Download Nix installer script from official releases get_url_retry: url: "{{ dev_nix_installer_url }}" dest: "{{ dev_nix_installer_dest }}" @@ -32,14 +32,14 @@ become: true # 3) Locate nix binary in common paths and install only if missing -- name: Probe common nix binary paths before installation +- name: ๐Ÿ” Probe common nix binary paths before installation ansible.builtin.stat: path: "{{ item }}" loop: "{{ dev_nix_binary_candidates }}" register: dev_nix_binary_probe_before become: true -- name: Set nix binary path detected before installation +- name: ๐Ÿ”ง Set nix binary path detected before installation ansible.builtin.set_fact: dev_nix_binary_path_before: >- {{ @@ -52,18 +52,18 @@ ) | default("", true) }} -- name: Install Nix via official installer when no Nix binary is present +- name: ๐Ÿ“ฆ Install Nix via official installer when no Nix binary is present ansible.builtin.include_tasks: 03_install_official.yml when: dev_nix_binary_path_before | length == 0 -- name: Probe common nix binary paths after installation +- name: ๐Ÿ” Probe common nix binary paths after installation ansible.builtin.stat: path: "{{ item }}" loop: "{{ dev_nix_binary_candidates }}" register: dev_nix_binary_probe_after become: true -- name: Set nix binary path for systemd usage +- name: ๐Ÿ”ง Set nix binary path for systemd usage ansible.builtin.set_fact: dev_nix_binary_path: >- {{ @@ -76,14 +76,14 @@ ) | default("", true) }} -- name: Fail if nix binary is missing after installation +- name: ๐Ÿ›‘ Fail if nix binary is missing after installation ansible.builtin.fail: msg: >- Nix binary could not be found after installation. Checked: {{ dev_nix_binary_candidates | join(', ') }} when: dev_nix_binary_path | length == 0 -- name: Ensure nix is reachable in PATH for systemd services +- name: โœ… Ensure nix is reachable in PATH for systemd services ansible.builtin.file: src: "{{ dev_nix_binary_path }}" dest: /usr/local/bin/nix @@ -92,7 +92,7 @@ when: dev_nix_binary_path != "/usr/local/bin/nix" # 4) Optionally drop shell snippet for Nix -- name: Optionally drop shell snippet for Nix +- name: ๐Ÿ—‘๏ธ Optionally drop shell snippet for Nix ansible.builtin.script: cmd: >- {{ role_path }}/files/write_nix_shell_snippet.sh @@ -106,7 +106,7 @@ when: dev_nix_enable_shell_snippet | bool become: true -- name: Aggressively prune Nix data (GC + optimise) +- name: ๐Ÿงน Aggressively prune Nix data (GC + optimise) # CI/Debug cleanup to prevent huge disk usage from Nix store + old generations become: true ansible.builtin.script: > diff --git a/roles/dev-nix/tasks/02a_nix_install_only.yml b/roles/dev-nix/tasks/02a_nix_install_only.yml index 7b86e1f5de..71410deaad 100644 --- a/roles/dev-nix/tasks/02a_nix_install_only.yml +++ b/roles/dev-nix/tasks/02a_nix_install_only.yml @@ -4,7 +4,7 @@ # a separate include_tasks file keeps the test_block_size MAX_TASKS=3 threshold # from triggering on the parent block while preserving the single `when:` guard. -- name: Purge stale nixbld users blocking the multi-user installer +- name: ๐Ÿงน Purge stale nixbld users blocking the multi-user installer ansible.builtin.script: cmd: "{{ role_path }}/files/purge_stale_nixbld.sh" register: dev_nix_purge_stale_nixbld_result @@ -14,13 +14,13 @@ dev_nix_purge_stale_nixbld_result.rc != 0 or dev_nix_purge_stale_nixbld_result.stdout is search('\\[FAIL\\]') -- name: Read existing nixbld group entry before installer run +- name: ๐Ÿ“– Read existing nixbld group entry before installer run ansible.builtin.getent: database: group key: nixbld fail_key: false -- name: Set build group override for Nix installer when nixbld exists +- name: ๐Ÿ”ง Set build group override for Nix installer when nixbld exists ansible.builtin.set_fact: dev_nix_installer_build_group_id: "{{ ansible_facts.getent_group.nixbld[1] }}" # `getent ... fail_key: false` inserts the key with a `None` value when the @@ -30,13 +30,13 @@ - ansible_facts.getent_group is defined - ansible_facts.getent_group.nixbld is not none -- name: Read existing nixbld1 user entry before installer run +- name: ๐Ÿ“– Read existing nixbld1 user entry before installer run ansible.builtin.getent: database: passwd key: nixbld1 fail_key: false -- name: Set first build uid override for Nix installer when nixbld1 exists +- name: ๐Ÿ”ง Set first build uid override for Nix installer when nixbld1 exists ansible.builtin.set_fact: dev_nix_installer_first_build_uid: "{{ ansible_facts.getent_passwd.nixbld1[1] }}" # Same None-vs-missing trap as for the group entry above. @@ -44,7 +44,7 @@ - ansible_facts.getent_passwd is defined - ansible_facts.getent_passwd.nixbld1 is not none -- name: Run Nix installer in daemon (multi-user) mode if Nix is not installed +- name: โ–ถ๏ธ Run Nix installer in daemon (multi-user) mode if Nix is not installed ansible.builtin.shell: > "{{ dev_nix_installer_dest }}" --daemon environment: >- diff --git a/roles/dev-nix/tasks/03_install_official.yml b/roles/dev-nix/tasks/03_install_official.yml index 21bcec4601..9337fa0509 100644 --- a/roles/dev-nix/tasks/03_install_official.yml +++ b/roles/dev-nix/tasks/03_install_official.yml @@ -1,5 +1,5 @@ --- -- name: Purge stale nixbld users blocking the multi-user installer +- name: ๐Ÿงน Purge stale nixbld users blocking the multi-user installer ansible.builtin.script: cmd: "{{ role_path }}/files/purge_stale_nixbld.sh" register: dev_nix_purge_stale_nixbld_result @@ -10,14 +10,14 @@ dev_nix_purge_stale_nixbld_result.stdout is search('\\[FAIL\\]') become: true -- name: Read existing nixbld group entry before installer run +- name: ๐Ÿ“– Read existing nixbld group entry before installer run ansible.builtin.getent: database: group key: nixbld fail_key: false become: true -- name: Set build group override for Nix installer when nixbld exists +- name: ๐Ÿ”ง Set build group override for Nix installer when nixbld exists ansible.builtin.set_fact: dev_nix_installer_build_group_id: "{{ ansible_facts.getent_group.nixbld[1] }}" # `getent ... fail_key: false` inserts the key with a `None` value when the @@ -27,14 +27,14 @@ - ansible_facts.getent_group is defined - ansible_facts.getent_group.nixbld is not none -- name: Read existing nixbld1 user entry before installer run +- name: ๐Ÿ“– Read existing nixbld1 user entry before installer run ansible.builtin.getent: database: passwd key: nixbld1 fail_key: false become: true -- name: Set first build uid override for Nix installer when nixbld1 exists +- name: ๐Ÿ”ง Set first build uid override for Nix installer when nixbld1 exists ansible.builtin.set_fact: dev_nix_installer_first_build_uid: "{{ ansible_facts.getent_passwd.nixbld1[1] }}" # Same None-vs-missing trap as for the group entry above. @@ -42,7 +42,7 @@ - ansible_facts.getent_passwd is defined - ansible_facts.getent_passwd.nixbld1 is not none -- name: Run Nix installer in daemon (multi-user) mode +- name: โ–ถ๏ธ Run Nix installer in daemon (multi-user) mode ansible.builtin.shell: > "{{ dev_nix_installer_dest }}" --daemon environment: >- diff --git a/roles/dev-nodejs/tasks/main.yml b/roles/dev-nodejs/tasks/main.yml index 3925373738..c642154c8c 100644 --- a/roles/dev-nodejs/tasks/main.yml +++ b/roles/dev-nodejs/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: Ensure Node.js is installed +- name: โœ… Ensure Node.js is installed package: name: nodejs state: present diff --git a/roles/dev-npm/tasks/main.yml b/roles/dev-npm/tasks/main.yml index f485a4ff53..20a5add0b8 100644 --- a/roles/dev-npm/tasks/main.yml +++ b/roles/dev-npm/tasks/main.yml @@ -1,10 +1,10 @@ --- -- name: Ensure npm is installed +- name: โœ… Ensure npm is installed package: name: npm state: present -- name: Run 'npm ci' +- name: โ–ถ๏ธ Run 'npm ci' command: npm ci args: chdir: "{{ npm_project_folder }}" diff --git a/roles/dev-python/tasks/01_core.yml b/roles/dev-python/tasks/01_core.yml index 684c3377c9..18b0b7554c 100644 --- a/roles/dev-python/tasks/01_core.yml +++ b/roles/dev-python/tasks/01_core.yml @@ -1,10 +1,10 @@ --- -- name: Include dependency 'sys-pip' +- name: ๐Ÿ“‚ Include dependency 'sys-pip' include_role: name: sys-pip when: run_once_sys_pip is not defined -- name: Install and prefer Python 3.11+ as default +- name: ๐Ÿ“ฆ Install and prefer Python 3.11+ as default ansible.builtin.script: "{{ role_path }}/files/install.sh" environment: SKIP_DOCKER_APT_SANITIZER: "1" diff --git a/roles/dev-shell/tasks/01_core.yml b/roles/dev-shell/tasks/01_core.yml index 6150fe2d6b..a8f9c673cd 100644 --- a/roles/dev-shell/tasks/01_core.yml +++ b/roles/dev-shell/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Ensure ~/.bash_profile sources ~/.profile +- name: โœ… Ensure ~/.bash_profile sources ~/.profile lineinfile: path: "$HOME/.bash_profile" line: "[ -f ~/.profile ] && . ~/.profile" @@ -9,7 +9,7 @@ mode: "0644" become: false -- name: Ensure ~/.zprofile sources ~/.profile +- name: โœ… Ensure ~/.zprofile sources ~/.profile lineinfile: path: "$HOME/.zprofile" line: "[ -f ~/.profile ] && . ~/.profile" diff --git a/roles/drv-epson-multiprinter/tasks/01_core.yml b/roles/drv-epson-multiprinter/tasks/01_core.yml index 35b51b0386..9b274f6390 100644 --- a/roles/drv-epson-multiprinter/tasks/01_core.yml +++ b/roles/drv-epson-multiprinter/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: install AUR packages for epson +- name: ๐Ÿ“ฆ install AUR packages for epson include_role: name: sys-aur-install vars: diff --git a/roles/drv-intel/tasks/main.yml b/roles/drv-intel/tasks/main.yml index c3d66436e7..333d992767 100644 --- a/roles/drv-intel/tasks/main.yml +++ b/roles/drv-intel/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: Resolve Intel media driver package names for current distribution +- name: ๐Ÿ” Resolve Intel media driver package names for current distribution ansible.builtin.set_fact: drv_intel_packages: >- {{ @@ -8,7 +8,7 @@ else [] }} -- name: Fail for unsupported distribution in drv-intel role +- name: ๐Ÿ›‘ Fail for unsupported distribution in drv-intel role ansible.builtin.assert: that: - (drv_intel_packages | length) > 0 @@ -16,13 +16,13 @@ Unsupported distribution for drv-intel role: {{ ansible_facts['distribution'] }} ({{ ansible_facts['os_family'] }}). -- name: Enable EPEL on CentOS Stream (required for Intel VA-API driver packages) +- name: ๐ŸŸข Enable EPEL on CentOS Stream (required for Intel VA-API driver packages) ansible.builtin.package: name: epel-release state: present when: ansible_facts['distribution'] in ['CentOS', 'CentOS Stream'] -- name: Install Intel media driver package(s) +- name: ๐Ÿ“ฆ Install Intel media driver package(s) ansible.builtin.package: name: "{{ drv_intel_packages }}" state: present diff --git a/roles/drv-lid-switch/tasks/01_core.yml b/roles/drv-lid-switch/tasks/01_core.yml index c86a6d4d9c..a82664c6b3 100644 --- a/roles/drv-lid-switch/tasks/01_core.yml +++ b/roles/drv-lid-switch/tasks/01_core.yml @@ -1,19 +1,19 @@ --- -- name: Install setup-hibernate via pip (system-wide) +- name: ๐Ÿ“ฆ Install setup-hibernate via pip (system-wide) include_role: name: sys-pip-install vars: package_name: setup-hibernate global_install: true -- name: Setup hibernate +- name: ๐Ÿ”ง Setup hibernate ansible.builtin.command: argv: - "{{ lookup('command_path', 'setup-hibernate') }}" - --non-interactive become: true -- name: Configure systemd lid switch behavior to hibernate on lid close (battery), lock on AC and docked +- name: "๐Ÿ”ง Lid switch: hibernate on battery, lock on AC/docked" become: true lineinfile: path: /etc/systemd/logind.conf @@ -22,7 +22,7 @@ backup: true notify: Restart systemd-logind -- name: Configure systemd to lock session when lid is closed on external power +- name: ๐Ÿ”ง Configure systemd to lock session when lid is closed on external power lineinfile: path: /etc/systemd/logind.conf regexp: "^#?HandleLidSwitchExternalPower=" @@ -31,7 +31,7 @@ notify: Restart systemd-logind become: true -- name: Configure systemd to lock session when lid is closed while docked +- name: ๐Ÿ”ง Configure systemd to lock session when lid is closed while docked lineinfile: path: /etc/systemd/logind.conf regexp: "^#?HandleLidSwitchDocked=" diff --git a/roles/drv-non-free/tasks/main.yml b/roles/drv-non-free/tasks/main.yml index a6846ae2b0..ffc9912448 100644 --- a/roles/drv-non-free/tasks/main.yml +++ b/roles/drv-non-free/tasks/main.yml @@ -1,9 +1,9 @@ --- -- name: Gather OS facts (ensure we know distribution) +- name: ๐Ÿ“Š Gather OS facts (ensure we know distribution) ansible.builtin.setup: when: ansible_facts is not defined -- name: Ensure mhwd is installed on Manjaro +- name: โœ… Ensure mhwd is installed on Manjaro package: name: mhwd state: present @@ -13,18 +13,18 @@ - ansible_facts['distribution'] in ['ManjaroLinux', 'Manjaro'] register: mhwd_install -- name: Detect mhwd command +- name: ๐Ÿ” Detect mhwd command ansible.builtin.stat: path: /usr/bin/mhwd register: mhwd_binary -- name: Install nonfree drivers via mhwd (Manjaro only) +- name: ๐Ÿ“ฆ Install nonfree drivers via mhwd (Manjaro only) ansible.builtin.shell: mhwd -a pci nonfree 0300 become: true when: - mhwd_binary.stat.exists -- name: Warn when mhwd is not available +- name: โš ๏ธ Warn when mhwd is not available ansible.builtin.debug: msg: > Skipping proprietary GPU driver installation: `mhwd` not found. diff --git a/roles/gen-hunspell/tasks/main.yml b/roles/gen-hunspell/tasks/main.yml index 5f71415467..6271f56c60 100644 --- a/roles/gen-hunspell/tasks/main.yml +++ b/roles/gen-hunspell/tasks/main.yml @@ -1,10 +1,10 @@ --- -- name: install hunspell +- name: ๐Ÿ“ฆ install hunspell package: name: hunspell state: present -- name: install hunspell language packages +- name: ๐Ÿ“ฆ install hunspell language packages package: name: "hunspell-{{ item }}" state: present diff --git a/roles/pkgmgr-install/tasks/01_core.yml b/roles/pkgmgr-install/tasks/01_core.yml index 6dc7735863..55b982ef93 100644 --- a/roles/pkgmgr-install/tasks/01_core.yml +++ b/roles/pkgmgr-install/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Include dependency 'pkgmgr' +- name: ๐Ÿ“‚ Include dependency 'pkgmgr' include_role: name: pkgmgr when: run_once_pkgmgr is not defined diff --git a/roles/pkgmgr-install/tasks/main.yml b/roles/pkgmgr-install/tasks/main.yml index f7de41b8fa..08ccce1fa8 100644 --- a/roles/pkgmgr-install/tasks/main.yml +++ b/roles/pkgmgr-install/tasks/main.yml @@ -2,7 +2,7 @@ - include_tasks: 01_core.yml when: run_once_pkgmgr_install is not defined -- name: "Install '{{ package_name }}' via pkgmgr (non-interactive)" +- name: "๐Ÿ“ฆ Install '{{ package_name }}' via pkgmgr (non-interactive)" shell: | set -euo pipefail @@ -25,7 +25,7 @@ delay: 20 until: pkgmgr_update.rc == 0 -- name: "Assert | pkgmgr path resolves '{{ package_name }}'" +- name: "โœ… Assert | pkgmgr path resolves '{{ package_name }}'" shell: | set -euo pipefail "{{ ansible_facts['env']['HOME'] }}/.venvs/pkgmgr/bin/pkgmgr" path "{{ package_name }}" >/dev/null diff --git a/roles/pkgmgr/tasks/01_core.yml b/roles/pkgmgr/tasks/01_core.yml index 5789d77ece..dae9c3265c 100644 --- a/roles/pkgmgr/tasks/01_core.yml +++ b/roles/pkgmgr/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Include dependencies +- name: ๐Ÿ“‚ Include dependencies include_role: name: "{{ dependency_role }}" loop: @@ -9,12 +9,12 @@ loop_control: loop_var: dependency_role -- name: "Include SSH" +- name: "๐Ÿ“‚ Include SSH" include_role: name: "sys-svc-ssh" when: not (run_once_sys_svc_ssh | default(false) | bool) -- name: Ensure GitHub host key is in known_hosts +- name: โœ… Ensure GitHub host key is in known_hosts known_hosts: path: "~/.ssh/known_hosts" name: github.com @@ -22,7 +22,7 @@ become: true no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Pull pkgmgr repo (shallow) and pin to stable +- name: โฌ‡๏ธ Pull pkgmgr repo (shallow) and pin to stable include_role: name: sys-util-git-pull vars: @@ -38,7 +38,7 @@ sys_util_git_pull_remote: "origin" sys_util_git_pull_become: true -- name: Run the Package Manager install command to create an alias for Kevins package manager +- name: ๐Ÿ“ฆ Install Kevins package manager and create its shell alias shell: | source ~/.venvs/pkgmgr/bin/activate make setup @@ -47,9 +47,9 @@ executable: /bin/bash become: true -- name: "PKGMGR | Update pkgmgr (non-interactive) with safe debug on failure" +- name: "๐Ÿ”„ PKGMGR | Update pkgmgr (non-interactive) with safe debug on failure" block: - - name: update pkgmgr (non-interactive) + - name: ๐Ÿ”„ update pkgmgr (non-interactive) ansible.builtin.shell: | set -euo pipefail export GIT_TERMINAL_PROMPT=0 @@ -66,7 +66,7 @@ until: pkgmgr_update.rc == 0 rescue: - - name: "PKGMGR | Failure report (sanitized)" + - name: "๐Ÿ“Š PKGMGR | Failure report (sanitized)" ansible.builtin.debug: msg: note: "Sanitized debug (no credentials printed)." @@ -96,7 +96,7 @@ stdout_tail: "{{ (pkgmgr_update.stdout | default('')).splitlines()[-60:] | join('\n') }}" stderr_tail: "{{ (pkgmgr_update.stderr | default('')).splitlines()[-60:] | join('\n') }}" - - name: "PKGMGR | Fail explicitly after sanitized debug" + - name: "๐Ÿ›‘ PKGMGR | Fail explicitly after sanitized debug" ansible.builtin.fail: msg: >- pkgmgr update failed. See sanitized debug output above (no credentials printed). diff --git a/roles/svc-ai-ollama/tasks/01_core.yml b/roles/svc-ai-ollama/tasks/01_core.yml index 458caa04d3..80056d88bf 100644 --- a/roles/svc-ai-ollama/tasks/01_core.yml +++ b/roles/svc-ai-ollama/tasks/01_core.yml @@ -1,12 +1,12 @@ --- - include_tasks: utils/once/flag.yml -- name: "Setup container network for {{ application_id }}" +- name: "๐Ÿ”ง Setup container network for {{ application_id }}" include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/network/routine.yml' ] | path_join }}" vars: compose_handlers_flush: true -- name: Pre-pull Ollama models +- name: โฌ‡๏ธ Pre-pull Ollama models vars: _cmd: "container exec -i {{ OLLAMA_CONTAINER_ADDRESS }} ollama pull {{ model }}" shell: "{{ _cmd }}" diff --git a/roles/svc-bkp-container-2-local/tasks/01_core.yml b/roles/svc-bkp-container-2-local/tasks/01_core.yml index 2acff0d00d..545621b8fc 100644 --- a/roles/svc-bkp-container-2-local/tasks/01_core.yml +++ b/roles/svc-bkp-container-2-local/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: Include dependencies +- name: ๐Ÿ“‚ Include dependencies include_role: name: "{{ item }}" loop: @@ -13,11 +13,11 @@ - include_tasks: 02_install.yml when: backup_docker_to_local_folder is not defined -- name: "reset (if enabled) for {{ role_name}}" +- name: "โ™ป๏ธ reset (if enabled) for {{ role_name}}" include_tasks: 03_reset.yml when: MODE_RESET | bool -- name: Ensure secrets directory exists (root only) +- name: โœ… Ensure secrets directory exists (root only) ansible.builtin.file: path: "{{ DIR_SECRETS }}" state: directory @@ -25,7 +25,7 @@ group: root mode: "0700" -- name: Ensure databases.csv exists (root only) +- name: โœ… Ensure databases.csv exists (root only) ansible.builtin.file: path: "{{ FILE_DATABASE_SECRETS }}" state: touch @@ -33,16 +33,16 @@ group: root mode: "0600" -- name: Check if databases.csv has content +- name: ๐Ÿ”Ž Check if databases.csv has content file_has_content: path: "{{ FILE_DATABASE_SECRETS }}" register: db_csv -- name: Compute backup force-flush flag +- name: ๐Ÿงฎ Compute backup force-flush flag ansible.builtin.set_fact: _backup_force_flush_instant: "{{ MODE_BACKUP | bool and db_csv.exists and db_csv.has_content }}" -- name: "Execute system service setup for '{{ system_service_id }}'" +- name: "โ–ถ๏ธ Execute system service setup for '{{ system_service_id }}'" include_role: name: sys-service vars: diff --git a/roles/svc-bkp-container-2-local/tasks/02_install.yml b/roles/svc-bkp-container-2-local/tasks/02_install.yml index fda70dbf89..f8303f5f68 100644 --- a/roles/svc-bkp-container-2-local/tasks/02_install.yml +++ b/roles/svc-bkp-container-2-local/tasks/02_install.yml @@ -1,12 +1,12 @@ --- -- name: "Install 'backup-docker-to-local' via pip" +- name: "๐Ÿ“ฆ Install 'backup-docker-to-local' via pip" include_role: name: sys-pip-install vars: package_name: "backup-docker-to-local==1.7.1" global_install: true -- name: Assert required baudolo commands are available +- name: โœ… Assert required baudolo commands are available ansible.builtin.assert: that: - (lookup('command_path', cmd_name) | string | length) > 0 diff --git a/roles/svc-bkp-container-2-local/tasks/03_reset.yml b/roles/svc-bkp-container-2-local/tasks/03_reset.yml index f530558cce..6b5a5fc7c0 100644 --- a/roles/svc-bkp-container-2-local/tasks/03_reset.yml +++ b/roles/svc-bkp-container-2-local/tasks/03_reset.yml @@ -1,5 +1,5 @@ --- -- name: "Remove databases CSV (reset)" +- name: "๐Ÿ—‘๏ธ Remove databases CSV (reset)" ansible.builtin.file: path: "{{ FILE_DATABASE_SECRETS }}" state: absent diff --git a/roles/svc-bkp-container-2-local/tasks/04_seed-database-to-backup.yml b/roles/svc-bkp-container-2-local/tasks/04_seed-database-to-backup.yml index 76c1d5015b..ce98f5d2a1 100644 --- a/roles/svc-bkp-container-2-local/tasks/04_seed-database-to-backup.yml +++ b/roles/svc-bkp-container-2-local/tasks/04_seed-database-to-backup.yml @@ -1,7 +1,7 @@ --- - include_tasks: 02_install.yml -- name: "Ensure /etc/baudolo exists" +- name: "โœ… Ensure /etc/baudolo exists" ansible.builtin.file: path: "{{ DIR_SECRETS }}" state: directory @@ -9,7 +9,7 @@ group: root mode: "0755" -- name: "BKP | Debug seed context (sanitized)" +- name: "๐Ÿ› BKP | Debug seed context (sanitized)" ansible.builtin.debug: msg: | database_consumer_id: "{{ database_consumer_id | default('undefined') }}" @@ -22,7 +22,7 @@ when: MODE_DEBUG | bool changed_when: false -- name: "BKP | Assert required database variables are explicitly passed" +- name: "โœ… BKP | Assert required database variables are explicitly passed" ansible.builtin.assert: that: - database_instance is defined @@ -55,7 +55,7 @@ Note: database_name may be an empty string to represent "all databases". changed_when: false -- name: Seed database definition via baudolo-seed (system binary) +- name: ๐ŸŒฑ Seed database definition via baudolo-seed (system binary) ansible.builtin.command: argv: - "{{ lookup('command_path', 'baudolo-seed') | string }}" diff --git a/roles/svc-bkp-container-2-local/tasks/main.yml b/roles/svc-bkp-container-2-local/tasks/main.yml index e52d75cf1e..1c99011d51 100644 --- a/roles/svc-bkp-container-2-local/tasks/main.yml +++ b/roles/svc-bkp-container-2-local/tasks/main.yml @@ -1,10 +1,10 @@ --- -- name: "Manage container backups on STACK_HOST only" +- name: "๐Ÿ”ง Manage container backups on STACK_HOST only" when: IS_STACK_HOST | bool block: - include_tasks: 01_core.yml when: run_once_svc_bkp_container_2_local is not defined - - name: "include 04_seed-database-to-backup.yml" + - name: "๐Ÿ“‚ include 04_seed-database-to-backup.yml" include_tasks: 04_seed-database-to-backup.yml when: BKP_CONTAINER_2_LOCAL_DB_ENABLED | bool diff --git a/roles/svc-bkp-local-2-device/tasks/main.yml b/roles/svc-bkp-local-2-device/tasks/main.yml index e8613bc34f..480fbcbad9 100644 --- a/roles/svc-bkp-local-2-device/tasks/main.yml +++ b/roles/svc-bkp-local-2-device/tasks/main.yml @@ -1,6 +1,6 @@ --- - block: - - name: Include dependencies + - name: ๐Ÿ“‚ Include dependencies include_role: name: "{{ item }}" loop: @@ -10,7 +10,7 @@ - include_tasks: utils/once/flag.yml when: run_once_svc_bkp_local_2_device is not defined -- name: Fail if any backup_to_usb variable is empty +- name: ๐Ÿ›‘ Fail if any backup_to_usb variable is empty assert: that: - BACKUP_TO_USB_MOUNT != "" diff --git a/roles/svc-bkp-remote-2-local/tasks/01_core.yml b/roles/svc-bkp-remote-2-local/tasks/01_core.yml index 8ec42afa63..1e92a9e1ad 100644 --- a/roles/svc-bkp-remote-2-local/tasks/01_core.yml +++ b/roles/svc-bkp-remote-2-local/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: Include dependencies +- name: ๐Ÿ“‚ Include dependencies include_role: name: "{{ item }}" loop: @@ -11,13 +11,13 @@ - sys-ctl-cln-bkps - user-backup -- name: "Create Directory '{{ DOCKER_BACKUP_REMOTE_2_LOCAL_DIR }}'" +- name: "๐Ÿ“ Create Directory '{{ DOCKER_BACKUP_REMOTE_2_LOCAL_DIR }}'" file: path: "{{ DOCKER_BACKUP_REMOTE_2_LOCAL_DIR }}" state: directory mode: "0755" -- name: "Deploy '{{ DOCKER_BACKUP_REMOTE_2_LOCAL_SCRIPT }}'" +- name: "๐Ÿš€ Deploy '{{ DOCKER_BACKUP_REMOTE_2_LOCAL_SCRIPT }}'" copy: src: "{{ DOCKER_BACKUP_REMOTE_2_LOCAL_FILE }}" dest: "{{ DOCKER_BACKUP_REMOTE_2_LOCAL_SCRIPT }}" diff --git a/roles/svc-db-elasticsearch/tasks/01_core.yml b/roles/svc-db-elasticsearch/tasks/01_core.yml index f5192c8f37..6515c8c0aa 100644 --- a/roles/svc-db-elasticsearch/tasks/01_core.yml +++ b/roles/svc-db-elasticsearch/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: "Setup container network for {{ application_id }}" +- name: "๐Ÿ”ง Setup container network for {{ application_id }}" include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/network/routine.yml' ] | path_join }}" vars: compose_handlers_flush: true @@ -9,7 +9,7 @@ application_id: "svc-db-elasticsearch" database_consumer_id: "svc-db-elasticsearch" -- name: "ELASTICSEARCH | Wait until container is running (not restarting)" +- name: "โณ ELASTICSEARCH | Wait until container is running (not restarting)" ansible.builtin.shell: > container inspect --format '{{ "{{.State.Status}}" }} {{ "{{.State.Restarting}}" }}' {{ ELASTICSEARCH_CONTAINER_ADDRESS }} register: es_state @@ -20,7 +20,7 @@ (es_state.stdout is not search('true')) changed_when: false -- name: "ELASTICSEARCH | Confirm cluster answers (HTTP API)" +- name: "โœ… ELASTICSEARCH | Confirm cluster answers (HTTP API)" ansible.builtin.shell: > {{ ELASTICSEARCH_EXEC_SHELL }} 'curl -fsS -u "elastic:$ELASTIC_PW" diff --git a/roles/svc-db-elasticsearch/tasks/02_init.yml b/roles/svc-db-elasticsearch/tasks/02_init.yml index e45b6b7337..ecd3c0f7ef 100644 --- a/roles/svc-db-elasticsearch/tasks/02_init.yml +++ b/roles/svc-db-elasticsearch/tasks/02_init.yml @@ -1,11 +1,11 @@ --- -- name: "Assert correct context" +- name: "โœ… Assert correct context" ansible.builtin.assert: that: - application_id == 'svc-db-elasticsearch' - database_consumer_id != 'svc-db-elasticsearch' -- name: "Resolve consumer index namespace + credentials" +- name: "๐Ÿ” Resolve consumer index namespace + credentials" ansible.builtin.set_fact: elasticsearch_consumer_entity: "{{ database_consumer_id | get_entity_name }}" elasticsearch_consumer_username: "{{ lookup('engine', 'elasticsearch', database_consumer_id, 'username') }}" @@ -13,9 +13,9 @@ changed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Wait until elasticsearch security API works +- name: โณ Wait until elasticsearch security API works block: - - name: "ELASTICSEARCH | Wait for security API" + - name: "โณ ELASTICSEARCH | Wait for security API" ansible.builtin.shell: > {{ ELASTICSEARCH_EXEC_SHELL }} 'curl -fsS -u "elastic:$ELASTIC_PW" @@ -28,13 +28,13 @@ no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" rescue: - - name: "ELASTICSEARCH | container logs (last 200 lines)" + - name: "๐Ÿ“ฆ ELASTICSEARCH | container logs (last 200 lines)" ansible.builtin.command: "container logs --tail 200 {{ ELASTICSEARCH_CONTAINER }}" register: dbg_es_logs changed_when: false failed_when: false - - name: "ELASTICSEARCH | Failure report" + - name: "๐Ÿ“Š ELASTICSEARCH | Failure report" ansible.builtin.debug: msg: elasticsearch_container: "{{ ELASTICSEARCH_CONTAINER }}" @@ -42,13 +42,13 @@ elasticsearch_port: "{{ ELASTICSEARCH_PORT }}" last_logs: "{{ dbg_es_logs.stdout | default('') }}" - - name: "ELASTICSEARCH | Fail explicitly after logs" + - name: "๐Ÿ›‘ ELASTICSEARCH | Fail explicitly after logs" ansible.builtin.fail: msg: >- Elasticsearch did not become ready for security API requests. Last 200 container log lines were printed above. -- name: "Create role scoped to '{{ elasticsearch_consumer_entity }}-*' indices" +- name: "๐Ÿ“ Create role scoped to '{{ elasticsearch_consumer_entity }}-*' indices" ansible.builtin.shell: > {{ ELASTICSEARCH_EXEC_SHELL }} 'curl -fsS -u "elastic:$ELASTIC_PW" @@ -70,7 +70,7 @@ changed_when: es_role_result.stdout is search('\"created\"\\s*:\\s*true') no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Build elasticsearch user payload for {{ elasticsearch_consumer_username }}" +- name: "๐Ÿ”จ Build elasticsearch user payload for {{ elasticsearch_consumer_username }}" ansible.builtin.set_fact: es_user_payload: password: "{{ elasticsearch_consumer_password }}" @@ -79,7 +79,7 @@ changed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Create user '{{ elasticsearch_consumer_username }}' bound to its index role" +- name: "๐Ÿ“ Create user '{{ elasticsearch_consumer_username }}' bound to its index role" ansible.builtin.shell: > {{ ELASTICSEARCH_EXEC_SHELL }} 'curl -fsS -u "elastic:$ELASTIC_PW" @@ -93,7 +93,7 @@ changed_when: es_user_result.stdout is search('\"created\"\\s*:\\s*true') no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Ensure consumer index namespace exists: {{ elasticsearch_consumer_entity }}" +- name: "โœ… Ensure consumer index namespace exists: {{ elasticsearch_consumer_entity }}" ansible.builtin.shell: > {{ ELASTICSEARCH_EXEC_SHELL }} 'curl -sS -o /dev/null -w "%{http_code}" -u "elastic:$ELASTIC_PW" diff --git a/roles/svc-db-elasticsearch/tasks/main.yml b/roles/svc-db-elasticsearch/tasks/main.yml index 96c10d29f8..b3de1b6909 100644 --- a/roles/svc-db-elasticsearch/tasks/main.yml +++ b/roles/svc-db-elasticsearch/tasks/main.yml @@ -9,6 +9,6 @@ vars: handler_role_name: "sys-svc-compose" -- name: "Initialize dedicated index namespace" +- name: "๐ŸŽฌ Initialize dedicated index namespace" include_tasks: 02_init.yml when: database_init | bool diff --git a/roles/svc-db-mariadb/tasks/01_core.yml b/roles/svc-db-mariadb/tasks/01_core.yml index 84b7856331..e3fa817260 100644 --- a/roles/svc-db-mariadb/tasks/01_core.yml +++ b/roles/svc-db-mariadb/tasks/01_core.yml @@ -1,12 +1,12 @@ --- - include_tasks: utils/once/flag.yml -- name: "Setup container network for {{ application_id }}" +- name: "๐Ÿ”ง Setup container network for {{ application_id }}" include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/network/routine.yml' ] | path_join }}" vars: compose_handlers_flush: true -- name: Install MySQL Python client library via pip +- name: ๐Ÿ“ฆ Install MySQL Python client library via pip include_role: name: sys-pip-install vars: @@ -15,7 +15,7 @@ global_install: true when: MARIADB_EXPOSE_LOCAL | bool -- name: "Wait until the MariaDB container with hostname '{{ MARIADB_NAME }}' is running" +- name: "โณ Wait until MariaDB container {{ MARIADB_NAME }} is running" community.docker.docker_container_info: name: "{{ MARIADB_NAME }}" register: db_info @@ -28,7 +28,7 @@ when: DEPLOYMENT_MODE == 'compose' - block: - - name: "Root password reset | Check login with desired password (inside container)" + - name: "๐Ÿ”Ž Root password reset | Check login with desired password (inside container)" ansible.builtin.shell: cmd: >- container exec -i {{ MARIADB_CONTAINER_ADDRESS }} @@ -45,14 +45,14 @@ delay: 5 until: mariadb_login_desired.rc == 0 - - name: "Ensure MariaDB root password matches desired value" + - name: "โœ… Ensure MariaDB root password matches desired value" include_tasks: 03_reset_root_password.yml when: - mariadb_login_desired.rc != 0 when: MARIADB_ALLOW_RESET_WITHOUT_PREVIOUS | bool -- name: "Wait until MariaDB accepts root credentials (inside container)" +- name: "โณ Wait until MariaDB accepts root credentials (inside container)" ansible.builtin.shell: cmd: >- container exec -i {{ MARIADB_CONTAINER_ADDRESS }} @@ -68,7 +68,7 @@ delay: 5 until: mariadb_cli.rc == 0 -- name: "Wait until MariaDB accepts root credentials (via mysql_db)" +- name: "โณ Wait until MariaDB accepts root credentials (via mysql_db)" community.mysql.mysql_db: name: "{{ MARIADB_HEALTHCHECK_DB }}" state: present diff --git a/roles/svc-db-mariadb/tasks/02_init.yml b/roles/svc-db-mariadb/tasks/02_init.yml index d152ec3e8c..a65fcfd096 100644 --- a/roles/svc-db-mariadb/tasks/02_init.yml +++ b/roles/svc-db-mariadb/tasks/02_init.yml @@ -1,6 +1,6 @@ --- - block: - - name: "Create database: {{ database_name }} (host via mysql_db)" + - name: "๐Ÿ“ Create database: {{ database_name }} (host via mysql_db)" community.mysql.mysql_db: name: "{{ database_name }}" state: present @@ -12,7 +12,7 @@ collation: "{{ MARIADB_COLLATION }}" config_file: "" - - name: "Create database user: {{ database_username }} (host via mysql_user)" + - name: "๐Ÿ“ Create database user: {{ database_username }} (host via mysql_user)" community.mysql.mysql_user: name: "{{ database_username }}" password: "{{ database_password }}" @@ -27,7 +27,7 @@ when: MARIADB_EXPOSE_LOCAL | bool - block: - - name: "Create database: {{ database_name }} (container via mariadb CLI)" + - name: "๐Ÿ“ Create database: {{ database_name }} (container via mariadb CLI)" ansible.builtin.shell: cmd: >- container exec -i @@ -43,7 +43,7 @@ no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" changed_when: false - - name: "Create database user + grant privileges (container via mariadb CLI)" + - name: "๐Ÿ“ Create database user + grant privileges (container via mariadb CLI)" ansible.builtin.shell: cmd: >- container exec -i diff --git a/roles/svc-db-mariadb/tasks/03_reset_root_password.yml b/roles/svc-db-mariadb/tasks/03_reset_root_password.yml index 6d8e8db26b..f409c8becd 100644 --- a/roles/svc-db-mariadb/tasks/03_reset_root_password.yml +++ b/roles/svc-db-mariadb/tasks/03_reset_root_password.yml @@ -1,5 +1,5 @@ --- -- name: "Root password reset | Refuse reset unless explicitly enabled" +- name: "โ™ป๏ธ Root password reset | Refuse reset unless explicitly enabled" ansible.builtin.assert: that: - MARIADB_ALLOW_RESET_WITHOUT_PREVIOUS | bool @@ -9,13 +9,13 @@ or reset the password manually. changed_when: false -- name: "Root password reset | Stop MariaDB compose container" +- name: "โน๏ธ Root password reset | Stop MariaDB compose container" community.docker.docker_container: name: "{{ MARIADB_NAME }}" state: stopped when: DEPLOYMENT_MODE == 'compose' -- name: "Root password reset | Scale MariaDB swarm service to 0 replicas" +- name: "๐Ÿ“ Root password reset | Scale MariaDB swarm service to 0 replicas" ansible.builtin.command: cmd: >- docker service update --detach=false --replicas 0 @@ -25,7 +25,7 @@ when: DEPLOYMENT_MODE == 'swarm' changed_when: true -- name: "Root password reset | Wait until MariaDB swarm task fully stops" +- name: "โณ Root password reset | Wait until MariaDB swarm task fully stops" ansible.builtin.shell: | set -euo pipefail running=$(docker service ps \ @@ -44,7 +44,7 @@ changed_when: false when: DEPLOYMENT_MODE == 'swarm' -- name: "Root password reset | Start recovery container (skip grants)" +- name: "โ–ถ๏ธ Root password reset | Start recovery container (skip grants)" community.docker.docker_container: name: "{{ MARIADB_RECOVERY_NAME }}" image: "{{ MARIADB_RECOVERY_IMAGE }}" @@ -60,7 +60,7 @@ delegate_to: "{{ STACK_HOST }}" run_once: true -- name: "Root password reset | Wait until recovery server is ready" +- name: "โณ Root password reset | Wait until recovery server is ready" ansible.builtin.command: argv: - container @@ -78,7 +78,7 @@ delay: 2 until: (mariadb_recovery_ready['rc'] | default(1)) == 0 -- name: "Root password reset | Set new root password in recovery mode" +- name: "๐Ÿ”ง Root password reset | Set new root password in recovery mode" ansible.builtin.command: argv: - container @@ -97,7 +97,7 @@ changed_when: true failed_when: mariadb_reset_root.rc != 0 -- name: "Root password reset | Stop and remove recovery container" +- name: "โน๏ธ Root password reset | Stop and remove recovery container" community.docker.docker_container: name: "{{ MARIADB_RECOVERY_NAME }}" state: absent @@ -105,13 +105,13 @@ delegate_to: "{{ STACK_HOST }}" run_once: true -- name: "Root password reset | Start MariaDB compose container again" +- name: "โ–ถ๏ธ Root password reset | Start MariaDB compose container again" community.docker.docker_container: name: "{{ MARIADB_NAME }}" state: started when: DEPLOYMENT_MODE == 'compose' -- name: "Root password reset | Scale MariaDB swarm service back to 1 replica" +- name: "๐Ÿ“ Root password reset | Scale MariaDB swarm service back to 1 replica" ansible.builtin.command: cmd: >- docker service update --detach=false --replicas 1 diff --git a/roles/svc-db-mariadb/tasks/main.yml b/roles/svc-db-mariadb/tasks/main.yml index e842e79196..cbdba7d463 100644 --- a/roles/svc-db-mariadb/tasks/main.yml +++ b/roles/svc-db-mariadb/tasks/main.yml @@ -4,6 +4,6 @@ vars: application_id: svc-db-mariadb -- name: "Initialize dedicated database" +- name: "๐ŸŽฌ Initialize dedicated database" include_tasks: 02_init.yml when: database_init | bool diff --git a/roles/svc-db-memcached/tasks/01_core.yml b/roles/svc-db-memcached/tasks/01_core.yml index bcb45a55a3..e766c2958f 100644 --- a/roles/svc-db-memcached/tasks/01_core.yml +++ b/roles/svc-db-memcached/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: "Setup container network for {{ application_id }}" +- name: "๐Ÿ”ง Setup container network for {{ application_id }}" include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/network/routine.yml' ] | path_join }}" vars: compose_handlers_flush: true @@ -9,7 +9,7 @@ application_id: "svc-db-memcached" database_consumer_id: "svc-db-memcached" -- name: "MEMCACHED | Wait until container is running (not restarting)" +- name: "โณ MEMCACHED | Wait until container is running (not restarting)" ansible.builtin.shell: > container inspect --format '{{ "{{.State.Status}}" }} {{ "{{.State.Restarting}}" }}' {{ MEMCACHED_CONTAINER_ADDRESS }} register: memcached_state @@ -20,7 +20,7 @@ (memcached_state.stdout is not search('true')) changed_when: false -- name: "MEMCACHED | Confirm engine answers (version handshake)" +- name: "โœ… MEMCACHED | Confirm engine answers (version handshake)" ansible.builtin.shell: > {{ MEMCACHED_EXEC_SHELL }} '{{ MEMCACHED_PROBE }}' diff --git a/roles/svc-db-memcached/tasks/02_init.yml b/roles/svc-db-memcached/tasks/02_init.yml index 90dd8ebbcb..73f995b827 100644 --- a/roles/svc-db-memcached/tasks/02_init.yml +++ b/roles/svc-db-memcached/tasks/02_init.yml @@ -1,13 +1,13 @@ --- -- name: "Assert correct context" +- name: "โœ… Assert correct context" ansible.builtin.assert: that: - application_id == 'svc-db-memcached' - database_consumer_id != 'svc-db-memcached' -- name: Wait until Memcached answers +- name: โณ Wait until Memcached answers block: - - name: "MEMCACHED | Confirm engine answers before provisioning (version handshake)" + - name: "โœ… MEMCACHED | Confirm engine answers before provisioning (version handshake)" ansible.builtin.shell: > {{ MEMCACHED_EXEC_SHELL }} '{{ MEMCACHED_PROBE }}' @@ -18,13 +18,13 @@ changed_when: false rescue: - - name: "MEMCACHED | container logs (last 200 lines)" + - name: "๐Ÿ“ฆ MEMCACHED | container logs (last 200 lines)" ansible.builtin.command: "container logs --tail 200 {{ MEMCACHED_CONTAINER }}" register: dbg_memcached_logs changed_when: false failed_when: false - - name: "MEMCACHED | Failure report" + - name: "๐Ÿ“Š MEMCACHED | Failure report" ansible.builtin.debug: msg: memcached_container: "{{ MEMCACHED_CONTAINER }}" @@ -32,13 +32,13 @@ memcached_port: "{{ MEMCACHED_PORT }}" last_logs: "{{ dbg_memcached_logs.stdout | default('') }}" - - name: "MEMCACHED | Fail explicitly after logs" + - name: "๐Ÿ›‘ MEMCACHED | Fail explicitly after logs" ansible.builtin.fail: msg: >- Memcached did not answer the version handshake. Last 200 container log lines were printed above. -- name: "MEMCACHED | No per-consumer provisioning (key-prefix isolation only)" +- name: "๐Ÿšซ MEMCACHED | No per-consumer provisioning (key-prefix isolation only)" ansible.builtin.debug: msg: >- Memcached has no native auth or namespace; consumer '{{ database_consumer_id }}' diff --git a/roles/svc-db-memcached/tasks/main.yml b/roles/svc-db-memcached/tasks/main.yml index 4fd24b4053..c409ef08c7 100644 --- a/roles/svc-db-memcached/tasks/main.yml +++ b/roles/svc-db-memcached/tasks/main.yml @@ -9,6 +9,6 @@ vars: handler_role_name: "sys-svc-compose" -- name: "Verify per-consumer namespace (key-prefix isolation)" +- name: "โœ… Verify per-consumer namespace (key-prefix isolation)" include_tasks: 02_init.yml when: database_init | bool diff --git a/roles/svc-db-openldap/tasks/01_core.yml b/roles/svc-db-openldap/tasks/01_core.yml index 53a2882bc8..e4c0b66b08 100644 --- a/roles/svc-db-openldap/tasks/01_core.yml +++ b/roles/svc-db-openldap/tasks/01_core.yml @@ -1,30 +1,30 @@ --- - include_tasks: utils/once/flag.yml -- name: "Create LDIF directories under {{ OPENLDAP_LDIF_PATH_HOST }} (must exist before swarm stack bind-mount)" +- name: "๐Ÿ“ Create LDIF dirs {{ OPENLDAP_LDIF_PATH_HOST }} before swarm bind-mount" file: path: "{{ OPENLDAP_LDIF_PATH_HOST }}{{ item }}" state: directory mode: "0755" loop: "{{ OPENLDAP_LDIF_TYPES }}" -- name: Initialize docker +- name: ๐ŸŽฌ Initialize docker include_tasks: 02_docker.yml -- name: Create {{ lookup('domain',application_id) }}.conf if LDAP is exposed to internet +- name: ๐Ÿ“„ Render {{ lookup('domain',application_id) }}.conf if LDAP is public stack_host_template: src: "nginx.stream.conf.j2" dest: "{{ lookup('nginx','directories.configuration.streams') }}{{ lookup('domain',application_id) }}.conf" notify: restart openresty when: OPENLDAP_NETWORK_SWITCH_PUBLIC | bool -- name: Remove {{ lookup('domain',application_id) }}.conf if LDAP is not exposed to internet +- name: ๐Ÿงน Remove {{ lookup('domain',application_id) }}.conf if LDAP not public file: path: "{{ lookup('nginx','directories.configuration.streams') }}{{ lookup('domain',application_id) }}.conf" state: absent when: not OPENLDAP_NETWORK_SWITCH_PUBLIC | bool -- name: "Wait for LDAP to be available" +- name: "โณ Wait for LDAP to be available" wait_for: host: "{{ DOCKER_REACH_HOST }}" port: "{{ lookup('config', application_id, 'services.openldap.ports.local.ldap') }}" @@ -33,7 +33,7 @@ state: started when: DEPLOYMENT_MODE == 'compose' -- name: Check if current RootDN/RootPW already work +- name: ๐Ÿ”Ž Check if current RootDN/RootPW already work ansible.builtin.shell: > container exec {{ OPENLDAP_CONTAINER_ADDRESS }} ldapwhoami -x -H ldap://127.0.0.1:389 -D "{{ OPENLDAP_BIND_DN }}" -w "{{ OPENLDAP_BIND_PW }}" @@ -43,7 +43,7 @@ changed_when: false failed_when: false -- name: Ensure LDAP RootPW is set on every deploy +- name: โœ… Ensure LDAP RootPW is set on every deploy include_tasks: 02_credentials.yml when: - OPENLDAP_NETWORK_SWITCH_LOCAL | bool @@ -52,7 +52,7 @@ # NOTE: Credentials reset removed (Bitnami-specific). RootDN/RootPW are bootstrapped via container env. -- name: Set OPENLDAP_MODULE_DN (from filesystem) +- name: ๐Ÿ”ง Set OPENLDAP_MODULE_DN (from filesystem) shell: > container exec {{ OPENLDAP_CONTAINER_ADDRESS }} sh -lc 'grep -m1 "^dn: " /etc/ldap/slapd.d/cn=config/cn=module{0}.ldif | sed "s/^dn: //"' @@ -62,7 +62,7 @@ changed_when: false failed_when: openldap_module_dn_raw.rc != 0 or (openldap_module_dn_raw.stdout | trim) == "" -- name: Normalize OPENLDAP_MODULE_DN (ensure ,cn=config suffix) +- name: ๐Ÿ“ Normalize OPENLDAP_MODULE_DN (ensure ,cn=config suffix) set_fact: OPENLDAP_MODULE_DN: >- {{ @@ -70,7 +70,7 @@ ~ ('' if (openldap_module_dn_raw.stdout | trim) is search(',cn=config$') else ',cn=config') }} -- name: Query available LDAP databases +- name: ๐Ÿ” Query available LDAP databases shell: > container exec {{ OPENLDAP_CONTAINER_ADDRESS }} ldapsearch -Q -Y EXTERNAL -H {{ OPENLDAP_CONFIG_URI }} -LLL -b cn=config "(olcDatabase=*)" dn @@ -79,7 +79,7 @@ run_once: true changed_when: false -- name: Set OPENLDAP_DATA_BACKEND_DN (mdb preferred, hdb fallback) +- name: ๐Ÿ”ง Set OPENLDAP_DATA_BACKEND_DN (mdb preferred, hdb fallback) set_fact: OPENLDAP_DATA_BACKEND_DN: >- {{ @@ -100,7 +100,7 @@ ) ) }} -- name: Normalize OPENLDAP_DATA_BACKEND_DN (ensure ,cn=config suffix) +- name: ๐Ÿ“ Normalize OPENLDAP_DATA_BACKEND_DN (ensure ,cn=config suffix) set_fact: OPENLDAP_DATA_BACKEND_DN: >- {{ @@ -109,7 +109,7 @@ }} when: OPENLDAP_DATA_BACKEND_DN | default('') | length > 0 -- name: "Import LDIF Configuration" +- name: "๐Ÿ“‚ Import LDIF Configuration" include_tasks: _ldifs_creation.yml loop: - configuration @@ -117,17 +117,17 @@ loop_var: folder when: OPENLDAP_PROVISION_CONFIGURATION | bool -- name: flush LDIF handlers +- name: ๐Ÿšฟ flush LDIF handlers meta: flush_handlers -- name: Load python-ldap build prerequisites +- name: ๐Ÿ“ฅ Load python-ldap build prerequisites include_tasks: _python_ldap_prerequisites.yml -- name: Load python-ldap header fallback when Python.h is missing +- name: ๐Ÿ“ฅ Load python-ldap header fallback when Python.h is missing include_tasks: _python_ldap_header_fallback.yml when: not openldap_python_header.stat.exists -- name: Install python-ldap in active Ansible interpreter +- name: ๐Ÿ“ฆ Install python-ldap in active Ansible interpreter include_role: name: sys-pip-install vars: @@ -135,7 +135,7 @@ package_state: present global_install: true -- name: Sanity check python-ldap import (verbose) +- name: โœ… Sanity check python-ldap import (verbose) ansible.builtin.shell: | set -euo pipefail {{ ansible_python_interpreter }} - <<'EOF' @@ -151,7 +151,7 @@ changed_when: false when: MODE_DEBUG | bool -- name: "Include Schemas (if enabled)" +- name: "๐Ÿ“‚ Include Schemas (if enabled)" include_tasks: file: 03_schemas.yml apply: @@ -159,11 +159,11 @@ delegate_to: "{{ STACK_HOST }}" when: OPENLDAP_PROVISION_SCHEMAS | bool -- name: "Import LDAP Entries (if enabled)" +- name: "๐Ÿ“‚ Import LDAP Entries (if enabled)" include_tasks: 04_users.yml when: OPENLDAP_PROVISION_USERS | bool -- name: "Import LDIF Data (if enabled)" +- name: "๐Ÿ“‚ Import LDIF Data (if enabled)" include_tasks: _ldifs_creation.yml loop: - groups @@ -173,6 +173,6 @@ - meta: flush_handlers -- name: "Add Objects to all users" +- name: "โž• Add Objects to all users" include_tasks: 05_update.yml when: OPENLDAP_PROVISION_UPDATE | bool diff --git a/roles/svc-db-openldap/tasks/02_credentials.yml b/roles/svc-db-openldap/tasks/02_credentials.yml index 8edb17bf53..c3a77e85be 100644 --- a/roles/svc-db-openldap/tasks/02_credentials.yml +++ b/roles/svc-db-openldap/tasks/02_credentials.yml @@ -1,5 +1,5 @@ --- -- name: Query data backend DN (cn=config) +- name: ๐Ÿ” Query data backend DN (cn=config) ansible.builtin.shell: > container exec {{ OPENLDAP_CONTAINER_ADDRESS }} ldapsearch -Q -Y EXTERNAL -H {{ OPENLDAP_CONFIG_URI }} -LLL -b cn=config "(olcDatabase=*)" dn @@ -8,7 +8,7 @@ run_once: true changed_when: false -- name: Determine data backend DN (prefer mdb, fallback hdb) +- name: ๐Ÿค” Determine data backend DN (prefer mdb, fallback hdb) ansible.builtin.set_fact: openldap_data_backend_dn: >- {{ @@ -32,12 +32,12 @@ ) }} -- name: Fail if backend DN could not be detected +- name: ๐Ÿ›‘ Fail if backend DN could not be detected ansible.builtin.fail: msg: "Could not detect OpenLDAP data backend DN from cn=config." when: openldap_data_backend_dn | default('') | length == 0 -- name: Generate hash for desired RootPW +- name: โš™๏ธ Generate hash for desired RootPW ansible.builtin.shell: > container exec {{ OPENLDAP_CONTAINER_ADDRESS }} slappasswd -s "{{ OPENLDAP_BIND_PW }}" @@ -46,7 +46,7 @@ run_once: true changed_when: false -- name: Set RootDN and RootPW only if bind check failed +- name: ๐Ÿ”ง Set RootDN and RootPW only if bind check failed ansible.builtin.shell: | container exec -i {{ OPENLDAP_CONTAINER_ADDRESS }} ldapmodify -Q -Y EXTERNAL -H {{ OPENLDAP_CONFIG_URI }} <- {{ @@ -107,7 +107,7 @@ ############################################################################### # 2) Create the LDAP entry if it does not yet exist ############################################################################### -- name: Ensure LDAP users exist +- name: โœ… Ensure LDAP users exist community.general.ldap_entry: dn: "{{ LDAP.USER.ATTRIBUTES.ID }}={{ item.key }},{{ LDAP.DN.OU.USERS }}" server_uri: "{{ OPENLDAP_SERVER_URI }}" @@ -142,7 +142,7 @@ # - Use LDAP Password Modify extended operation # - Server-side hashing is applied (your cn=config sets olcPasswordHash: {SSHA}) ############################################################################### -- name: Set LDAP user password (per-user update policy) +- name: ๐Ÿ”ง Set LDAP user password (per-user update policy) community.general.ldap_passwd: server_uri: "{{ OPENLDAP_SERVER_URI }}" bind_dn: "{{ OPENLDAP_BIND_DN }}" @@ -161,7 +161,7 @@ ############################################################################### # 3) Keep the objectClass list AND the mail attribute up-to-date ############################################################################### -- name: Ensure required objectClass values and mail address are present +- name: โœ… Ensure required objectClass values and mail address are present community.general.ldap_attrs: dn: "{{ LDAP.USER.ATTRIBUTES.ID }}={{ item.key }},{{ LDAP.DN.OU.USERS }}" server_uri: "{{ OPENLDAP_SERVER_URI }}" diff --git a/roles/svc-db-openldap/tasks/05_update.yml b/roles/svc-db-openldap/tasks/05_update.yml index 8f537f3b53..aa933edf02 100644 --- a/roles/svc-db-openldap/tasks/05_update.yml +++ b/roles/svc-db-openldap/tasks/05_update.yml @@ -1,5 +1,5 @@ --- -- name: Gather all users with their current objectClass list +- name: ๐Ÿ“Š Gather all users with their current objectClass list community.general.ldap_search: server_uri: "{{ OPENLDAP_SERVER_URI }}" bind_dn: "{{ OPENLDAP_BIND_DN }}" @@ -13,7 +13,7 @@ - "{{ LDAP.USER.ATTRIBUTES.ID }}" register: ldap_users_with_classes -- name: Add only missing auxiliary classes +- name: โž• Add only missing auxiliary classes community.general.ldap_attrs: server_uri: "{{ OPENLDAP_SERVER_URI }}" bind_dn: "{{ OPENLDAP_BIND_DN }}" diff --git a/roles/svc-db-openldap/tasks/_ldifs_creation.yml b/roles/svc-db-openldap/tasks/_ldifs_creation.yml index 80c12f3acf..9c75bbec18 100644 --- a/roles/svc-db-openldap/tasks/_ldifs_creation.yml +++ b/roles/svc-db-openldap/tasks/_ldifs_creation.yml @@ -1,5 +1,5 @@ --- -- name: "Render LDIF files at {{ OPENLDAP_LDIF_PATH_HOST }}{{ folder }} (local + swarm peers)" +- name: "๐Ÿ“„ Render LDIF files at {{ OPENLDAP_LDIF_PATH_HOST }}{{ folder }} (peers)" ansible.builtin.include_tasks: file: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/render_replicated_templates.yml'] | path_join }}" vars: diff --git a/roles/svc-db-openldap/tasks/_python_ldap_header_fallback.yml b/roles/svc-db-openldap/tasks/_python_ldap_header_fallback.yml index 9e9387d8c2..d6f4b2ba2e 100644 --- a/roles/svc-db-openldap/tasks/_python_ldap_header_fallback.yml +++ b/roles/svc-db-openldap/tasks/_python_ldap_header_fallback.yml @@ -1,5 +1,5 @@ --- -- name: Resolve active Python major.minor for header package candidates +- name: ๐Ÿ” Resolve active Python major.minor for header package candidates ansible.builtin.command: argv: - "{{ ansible_python_interpreter }}" @@ -8,7 +8,7 @@ register: openldap_python_major_minor changed_when: false -- name: Resolve Python header package templates and version tokens +- name: ๐Ÿ” Resolve Python header package templates and version tokens ansible.builtin.set_fact: openldap_python_major_minor_value: "{{ openldap_python_major_minor.stdout | trim }}" openldap_python_major_minor_nodot: "{{ (openldap_python_major_minor.stdout | trim) | replace('.', '') }}" @@ -18,7 +18,7 @@ }} changed_when: false -- name: Build Python header package candidates for current OS family +- name: ๐Ÿ”จ Build Python header package candidates for current OS family ansible.builtin.set_fact: openldap_python_header_package_candidates: >- {{ @@ -30,7 +30,7 @@ }} changed_when: false -- name: Attempt to install Python header package candidates +- name: ๐Ÿ“ฆ Attempt to install Python header package candidates ansible.builtin.package: name: "{{ item }}" state: present @@ -38,12 +38,12 @@ failed_when: false when: openldap_python_header_package_candidates | length > 0 -- name: Re-check whether Python.h exists for active interpreter +- name: ๐Ÿ”Ž Re-check whether Python.h exists for active interpreter ansible.builtin.stat: path: "{{ openldap_python_header_path }}" register: openldap_python_header_after -- name: Assert Python.h exists for active interpreter +- name: โœ… Assert Python.h exists for active interpreter ansible.builtin.assert: that: - openldap_python_header_after.stat.exists diff --git a/roles/svc-db-openldap/tasks/_python_ldap_prerequisites.yml b/roles/svc-db-openldap/tasks/_python_ldap_prerequisites.yml index b04262a809..3a94af38dc 100644 --- a/roles/svc-db-openldap/tasks/_python_ldap_prerequisites.yml +++ b/roles/svc-db-openldap/tasks/_python_ldap_prerequisites.yml @@ -1,5 +1,5 @@ --- -- name: Resolve python-ldap native library packages for current OS family +- name: ๐Ÿ” Resolve python-ldap native library packages for current OS family ansible.builtin.set_fact: openldap_python_ldap_native_lib_packages: >- {{ @@ -7,13 +7,13 @@ }} changed_when: false -- name: Install python-ldap native library build dependencies +- name: ๐Ÿ“ฆ Install python-ldap native library build dependencies ansible.builtin.package: name: "{{ openldap_python_ldap_native_lib_packages }}" state: present when: openldap_python_ldap_native_lib_packages | length > 0 -- name: Resolve Python include directory for active interpreter +- name: ๐Ÿ” Resolve Python include directory for active interpreter ansible.builtin.command: argv: - "{{ ansible_python_interpreter }}" @@ -22,12 +22,12 @@ register: openldap_python_include_dir changed_when: false -- name: Set Python.h path for active interpreter +- name: ๐Ÿ”ง Set Python.h path for active interpreter ansible.builtin.set_fact: openldap_python_header_path: "{{ (openldap_python_include_dir.stdout | trim) ~ '/Python.h' }}" changed_when: false -- name: Check whether Python.h exists for active interpreter +- name: ๐Ÿ”Ž Check whether Python.h exists for active interpreter ansible.builtin.stat: path: "{{ openldap_python_header_path }}" register: openldap_python_header diff --git a/roles/svc-db-openldap/tasks/schemas/moodle.yml b/roles/svc-db-openldap/tasks/schemas/moodle.yml index 01d88c3c7d..bfe5cf53b6 100644 --- a/roles/svc-db-openldap/tasks/schemas/moodle.yml +++ b/roles/svc-db-openldap/tasks/schemas/moodle.yml @@ -3,7 +3,7 @@ # no equivalent in core inetOrgPerson: phonetic given/family name # and IANA timezone name. -- name: Ensure custom LDAP schema snippet via ldapsm (moodle) +- name: โœ… Ensure custom LDAP schema snippet via ldapsm (moodle) vars: schema_name: "moodle" attribute_defs: @@ -32,6 +32,6 @@ changed_when: "'Created schema entry' in ldapsm_moodle_result.stdout" check_mode: false -- name: Show ldapsm output (moodle) +- name: ๐Ÿ‘๏ธ Show ldapsm output (moodle) debug: var: ldapsm_moodle_result.stdout_lines diff --git a/roles/svc-db-openldap/tasks/schemas/nextcloud.yml b/roles/svc-db-openldap/tasks/schemas/nextcloud.yml index f9d1e241cb..afd814f361 100644 --- a/roles/svc-db-openldap/tasks/schemas/nextcloud.yml +++ b/roles/svc-db-openldap/tasks/schemas/nextcloud.yml @@ -1,5 +1,5 @@ --- -- name: Ensure custom LDAP schema snippet via ldapsm +- name: โœ… Ensure custom LDAP schema snippet via ldapsm vars: schema_name: "nextcloud" attribute_defs: @@ -24,6 +24,6 @@ changed_when: "'Created schema entry' in ldapsm_result.stdout" check_mode: false -- name: Show ldapsm output +- name: ๐Ÿ‘๏ธ Show ldapsm output debug: var: ldapsm_result.stdout_lines diff --git a/roles/svc-db-openldap/tasks/schemas/openssh_lpk.yml b/roles/svc-db-openldap/tasks/schemas/openssh_lpk.yml index c8eab536b8..4ad8992d49 100644 --- a/roles/svc-db-openldap/tasks/schemas/openssh_lpk.yml +++ b/roles/svc-db-openldap/tasks/schemas/openssh_lpk.yml @@ -1,5 +1,5 @@ --- -- name: Ensure OpenSSH-LPK schema via ldapsm +- name: โœ… Ensure OpenSSH-LPK schema via ldapsm vars: schema_name: "openssh-lpk" attribute_defs: @@ -30,6 +30,6 @@ changed_when: "'Created schema entry' in opensshlpk_ldapsm.stdout" check_mode: false -- name: Show ldapsm output for openssh-lpk +- name: ๐Ÿ‘๏ธ Show ldapsm output for openssh-lpk debug: var: opensshlpk_ldapsm.stdout_lines diff --git a/roles/svc-db-postgres/tasks/01_core.yml b/roles/svc-db-postgres/tasks/01_core.yml index a99c9de615..76aac05f07 100644 --- a/roles/svc-db-postgres/tasks/01_core.yml +++ b/roles/svc-db-postgres/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: "Setup container network for {{ application_id }}" +- name: "๐Ÿ”ง Setup container network for {{ application_id }}" include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/network/routine.yml' ] | path_join }}" vars: compose_handlers_flush: true @@ -9,14 +9,14 @@ application_id: "svc-db-postgres" database_consumer_id: "svc-db-postgres" -- name: Install 'psycopg2-binary' +- name: ๐Ÿ“ฆ Install 'psycopg2-binary' include_role: name: sys-pip-install vars: package_name: "psycopg2-binary" global_install: true -- name: "POSTGRES | Wait until container is running (not restarting)" +- name: "โณ POSTGRES | Wait until container is running (not restarting)" ansible.builtin.shell: > container inspect --format '{{ "{{.State.Status}}" }} {{ "{{.State.Restarting}}" }}' {{ POSTGRES_CONTAINER_ADDRESS }} register: pg_state @@ -29,7 +29,7 @@ (pg_state.stdout is not search('true')) changed_when: false -- name: "POSTGRES | Confirm SQL works (socket)" +- name: "โœ… POSTGRES | Confirm SQL works (socket)" ansible.builtin.shell: > container exec --user postgres {{ POSTGRES_CONTAINER_ADDRESS }} sh -lc 'psql -U postgres -d postgres -Atc "SELECT 1" >/dev/null' @@ -41,7 +41,7 @@ until: pg_sql_ready.rc == 0 changed_when: false -- name: "POSTGRES | Ensure postgres superuser password matches inventory" +- name: "โœ… POSTGRES | Ensure postgres superuser password matches inventory" ansible.builtin.script: > set_postgres_superuser_password.sh {{ POSTGRES_CONTAINER_ADDRESS | quote }} diff --git a/roles/svc-db-postgres/tasks/02_init.yml b/roles/svc-db-postgres/tasks/02_init.yml index a9510947f8..f4d06c51d3 100644 --- a/roles/svc-db-postgres/tasks/02_init.yml +++ b/roles/svc-db-postgres/tasks/02_init.yml @@ -1,20 +1,20 @@ --- -- name: "Assert correct context" +- name: "โœ… Assert correct context" ansible.builtin.assert: that: - application_id == 'svc-db-postgres' - database_consumer_id != 'svc-db-postgres' -- name: Normalize postgres credential strings for module args +- name: ๐Ÿ“ Normalize postgres credential strings for module args ansible.builtin.set_fact: postgres_login_password_string: "{{ POSTGRES_PASSWORD | string }}" postgres_database_password_string: "{{ database_password | string }}" changed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Wait until postgres TCP auth works +- name: โณ Wait until postgres TCP auth works block: - - name: Wait for Postgres TCP auth + - name: โณ Wait for Postgres TCP auth ansible.builtin.shell: > {{ POSTGRES_EXEC_SHELL }} 'psql -h "{{ POSTGRES_LOCAL_HOST }}" -p "{{ POSTGRES_PORT }}" @@ -26,13 +26,13 @@ changed_when: false rescue: - - name: "POSTGRES | container logs (last 200 lines)" + - name: "๐Ÿ“ฆ POSTGRES | container logs (last 200 lines)" ansible.builtin.command: "container logs --tail 200 {{ POSTGRES_CONTAINER }}" register: dbg_docker_logs changed_when: false failed_when: false - - name: "POSTGRES | Failure report" + - name: "๐Ÿ“Š POSTGRES | Failure report" ansible.builtin.debug: msg: postgres_container: "{{ POSTGRES_CONTAINER }}" @@ -40,14 +40,14 @@ postgres_port: "{{ POSTGRES_PORT }}" last_logs: "{{ dbg_docker_logs.stdout | default('') }}" - - name: "POSTGRES | Fail explicitly after logs" + - name: "๐Ÿ›‘ POSTGRES | Fail explicitly after logs" ansible.builtin.fail: msg: >- Postgres did not become ready for TCP authentication. Last 200 container log lines were printed above. # 1) Create the database -- name: "Create database: {{ database_name }}" +- name: "๐Ÿ“ Create database: {{ database_name }}" community.postgresql.postgresql_db: name: "{{ database_name }}" state: present @@ -61,7 +61,7 @@ delay: "{{ POSTGRES_DELAY }}" # 2) Create the database user (with password) -- name: "Create database user: {{ database_username }}" +- name: "๐Ÿ“ Create database user: {{ database_username }}" community.postgresql.postgresql_user: name: "{{ database_username }}" password: "{{ postgres_database_password_string }}" @@ -77,9 +77,9 @@ delay: "{{ POSTGRES_DELAY }}" # 3) Enable LOGIN for the role (removes NOLOGIN) -- name: "POSTGRES | Ensure LOGIN for role {{ database_username }} (with debug on failure)" +- name: "โœ… Ensure LOGIN for role {{ database_username }} (debug on failure)" block: - - name: "POSTGRES | Enable login for role {{ database_username }}" + - name: "๐ŸŸข POSTGRES | Enable login for role {{ database_username }}" # nocheck: database-query โ€” svc-db-postgres bootstraps its own DB; the `database_query` module's `lookup('database', ...)` indirection isn't usable from inside the role that provides the lookup target. community.postgresql.postgresql_query: db: postgres @@ -98,7 +98,7 @@ rescue: # --- High-signal Ansible context ----------------------------------------- - - name: "POSTGRES | Debug context (vars, without secrets)" + - name: "๐Ÿ› POSTGRES | Debug context (vars, without secrets)" ansible.builtin.debug: msg: application_id: "{{ application_id }}" @@ -112,7 +112,7 @@ POSTGRES_IMAGE: "{{ POSTGRES_IMAGE | default('n/a') }}" changed_when: false - - name: "POSTGRES | container info (DockerRootDir)" + - name: "๐Ÿ“ฆ POSTGRES | container info (DockerRootDir)" ansible.builtin.shell: | set -e {% raw %} @@ -123,39 +123,39 @@ failed_when: false # --- Container existence & status ---------------------------------------- - - name: "POSTGRES | container ps (postgres)" + - name: "๐Ÿ“ฆ POSTGRES | container ps (postgres)" ansible.builtin.command: "container ps -a --no-trunc --filter name=^/{{ POSTGRES_CONTAINER }}$" register: dbg_docker_ps changed_when: false failed_when: false - - name: "POSTGRES | container inspect (escaped go-templates)" + - name: "๐Ÿ“ฆ POSTGRES | container inspect (escaped go-templates)" ansible.builtin.script: "{{ role_path }}/files/inspect_container.sh {{ POSTGRES_CONTAINER }}" register: dbg_docker_inspect changed_when: false failed_when: false - - name: "POSTGRES | container logs (last 250 lines)" + - name: "๐Ÿ“ฆ POSTGRES | container logs (last 250 lines)" ansible.builtin.command: "container logs --tail 250 {{ POSTGRES_CONTAINER }}" register: dbg_docker_logs changed_when: false failed_when: false # --- Port / connectivity checks ------------------------------------------ - - name: "POSTGRES | Check port listening on host (ss)" + - name: "๐Ÿ”Ž POSTGRES | Check port listening on host (ss)" ansible.builtin.shell: "ss -lntp | grep -E '(:{{ POSTGRES_PORT }}\\s)' || true" register: dbg_ss changed_when: false failed_when: false - - name: "POSTGRES | pg_isready inside container" + - name: "๐Ÿ“ฆ POSTGRES | pg_isready inside container" ansible.builtin.shell: "container exec {{ POSTGRES_CONTAINER_ADDRESS }} pg_isready -U postgres || true" register: dbg_pg_isready changed_when: false failed_when: false # Password auth test - - name: "POSTGRES | psql auth test (SELECT 1) using PGPASSWORD" + - name: "๐Ÿ”‘ POSTGRES | psql auth test (SELECT 1) using PGPASSWORD" ansible.builtin.shell: > {{ POSTGRES_EXEC_SHELL }} 'psql -U postgres -d postgres -c "SELECT 1"' @@ -165,7 +165,7 @@ no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" # --- Server-side details (best effort) ----------------------------------- - - name: "POSTGRES | Show hba_file + config_file" + - name: "๐Ÿ‘๏ธ POSTGRES | Show hba_file + config_file" ansible.builtin.shell: > {{ POSTGRES_EXEC_SHELL }} 'psql -U postgres -d postgres -Atc @@ -175,7 +175,7 @@ failed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" - - name: "POSTGRES | Dump pg_hba.conf (best effort)" + - name: "๐Ÿ’พ POSTGRES | Dump pg_hba.conf (best effort)" ansible.builtin.script: "{{ role_path }}/files/dump_pg_hba.sh" environment: POSTGRES_CONTAINER_ADDRESS: "{{ POSTGRES_CONTAINER_ADDRESS }}" @@ -185,7 +185,7 @@ failed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" - - name: "POSTGRES | Active connections / roles snapshot (best effort)" + - name: "๐Ÿ“ธ POSTGRES | Active connections / roles snapshot (best effort)" ansible.builtin.shell: > {{ POSTGRES_EXEC_SHELL }} 'psql -U postgres -d postgres -c @@ -197,7 +197,7 @@ no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" # --- Final consolidated output ------------------------------------------- - - name: "POSTGRES | Failure report (sanitized)" + - name: "๐Ÿ“Š POSTGRES | Failure report (sanitized)" ansible.builtin.debug: msg: original_error: "{{ ansible_failed_result | default({}) }}" @@ -219,14 +219,14 @@ postgres_enable_login: "{{ postgres_enable_login | default({}) }}" changed_when: false - - name: "POSTGRES | Fail explicitly after debug" + - name: "๐Ÿ›‘ POSTGRES | Fail explicitly after debug" ansible.builtin.fail: msg: >- Failed to ALTER ROLE "{{ database_username }}" WITH LOGIN. See debug output above (container logs, inspect, pg_isready, psql auth test, hba/config). # 4) Grant ALL privileges on all tables in the public schema -- name: "Grant ALL privileges on tables in public schema to {{ database_username }}" +- name: "๐Ÿ” Grant ALL privileges on tables in public schema to {{ database_username }}" community.postgresql.postgresql_privs: db: "{{ database_name }}" roles: "{{ database_username }}" @@ -245,7 +245,7 @@ delay: "{{ POSTGRES_DELAY }}" # 5) Grant ALL privileges at the database level -- name: "Grant all privileges on database {{ database_name }} to {{ database_username }}" +- name: "๐Ÿ” Grant all privileges on {{ database_name }} to {{ database_username }}" community.postgresql.postgresql_privs: db: "{{ database_name }}" roles: "{{ database_username }}" @@ -262,7 +262,7 @@ delay: "{{ POSTGRES_DELAY }}" # 6) Grant USAGE/CREATE on schema and set default privileges -- name: "Set comprehensive schema privileges for {{ database_username }}" +- name: "๐Ÿ”ง Set comprehensive schema privileges for {{ database_username }}" # nocheck: database-query โ€” svc-db-postgres bootstraps its own DB; the `database_query` module's `lookup('database', ...)` indirection isn't usable from inside the role that provides the lookup target. community.postgresql.postgresql_query: db: "{{ database_name }}" @@ -276,7 +276,7 @@ retries: "{{ POSTGRES_RETRIES }}" delay: "{{ POSTGRES_DELAY }}" -- name: "Ensure consumer-specific extensions ({{ database_consumer_id }})" +- name: "โœ… Ensure consumer-specific extensions ({{ database_consumer_id }})" community.postgresql.postgresql_ext: db: "{{ database_name }}" ext: "{{ item }}" diff --git a/roles/svc-db-postgres/tasks/main.yml b/roles/svc-db-postgres/tasks/main.yml index c8457b6b5a..acdc86ed7b 100644 --- a/roles/svc-db-postgres/tasks/main.yml +++ b/roles/svc-db-postgres/tasks/main.yml @@ -9,7 +9,7 @@ vars: handler_role_name: "sys-svc-compose" -- name: "Initialize dedicated database" +- name: "๐ŸŽฌ Initialize dedicated database" include_tasks: 02_init.yml when: database_init | bool vars: diff --git a/roles/svc-db-qdrant/tasks/01_core.yml b/roles/svc-db-qdrant/tasks/01_core.yml index baa042b9cf..98d86782f8 100644 --- a/roles/svc-db-qdrant/tasks/01_core.yml +++ b/roles/svc-db-qdrant/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: "Setup container network for {{ application_id }}" +- name: "๐Ÿ”ง Setup container network for {{ application_id }}" include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/network/routine.yml' ] | path_join }}" vars: compose_handlers_flush: true @@ -9,7 +9,7 @@ application_id: "svc-db-qdrant" database_consumer_id: "svc-db-qdrant" -- name: "QDRANT | Wait until container is running (not restarting)" +- name: "โณ QDRANT | Wait until container is running (not restarting)" ansible.builtin.shell: > container inspect --format '{{ "{{.State.Status}}" }} {{ "{{.State.Restarting}}" }}' {{ QDRANT_CONTAINER_ADDRESS }} register: qdrant_state @@ -20,7 +20,7 @@ (qdrant_state.stdout is not search('true')) changed_when: false -- name: "QDRANT | Confirm HTTP API is ready (/readyz)" +- name: "โœ… QDRANT | Confirm HTTP API is ready (/readyz)" ansible.builtin.shell: > {{ QDRANT_EXEC_SHELL }} 'exec 3<>/dev/tcp/127.0.0.1/6333; printf "GET /readyz HTTP/1.0\r\n\r\n" >&3; grep -q "200 OK" <&3' diff --git a/roles/svc-db-qdrant/tasks/02_init.yml b/roles/svc-db-qdrant/tasks/02_init.yml index 67d6b13397..b9f4dadd86 100644 --- a/roles/svc-db-qdrant/tasks/02_init.yml +++ b/roles/svc-db-qdrant/tasks/02_init.yml @@ -1,11 +1,11 @@ --- -- name: "Assert correct context" +- name: "โœ… Assert correct context" ansible.builtin.assert: that: - application_id == 'svc-db-qdrant' - database_consumer_id != 'svc-db-qdrant' -- name: "QDRANT | Wait until HTTP API is ready (/readyz)" +- name: "โณ QDRANT | Wait until HTTP API is ready (/readyz)" ansible.builtin.shell: > {{ QDRANT_EXEC_SHELL }} 'exec 3<>/dev/tcp/127.0.0.1/6333; printf "GET /readyz HTTP/1.0\r\n\r\n" >&3; grep -q "200 OK" <&3' @@ -15,7 +15,7 @@ until: qdrant_init_ready.rc == 0 changed_when: false -- name: "QDRANT | Per-consumer collection namespace is prefix-only (no server-side provisioning)" +- name: "๐Ÿ”ง QDRANT | Per-consumer namespace is prefix-only (no server-side provisioning)" ansible.builtin.debug: msg: >- Qdrant consumer '{{ database_consumer_id }}' uses collection prefix diff --git a/roles/svc-db-qdrant/tasks/main.yml b/roles/svc-db-qdrant/tasks/main.yml index c0e80c5f79..c87b5f690d 100644 --- a/roles/svc-db-qdrant/tasks/main.yml +++ b/roles/svc-db-qdrant/tasks/main.yml @@ -9,6 +9,6 @@ vars: handler_role_name: "sys-svc-compose" -- name: "Initialize dedicated collection namespace" +- name: "๐ŸŽฌ Initialize dedicated collection namespace" include_tasks: 02_init.yml when: database_init | bool diff --git a/roles/svc-db-rabbitmq/tasks/01_core.yml b/roles/svc-db-rabbitmq/tasks/01_core.yml index 55462d360d..5108f5d313 100644 --- a/roles/svc-db-rabbitmq/tasks/01_core.yml +++ b/roles/svc-db-rabbitmq/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: "Setup container network for {{ application_id }}" +- name: "๐Ÿ”ง Setup container network for {{ application_id }}" include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/network/routine.yml' ] | path_join }}" vars: compose_handlers_flush: true @@ -9,7 +9,7 @@ application_id: "svc-db-rabbitmq" database_consumer_id: "svc-db-rabbitmq" -- name: "RABBITMQ | Wait until container is running (not restarting)" +- name: "โณ RABBITMQ | Wait until container is running (not restarting)" ansible.builtin.shell: > container inspect --format '{{ "{{.State.Status}}" }} {{ "{{.State.Restarting}}" }}' {{ RABBITMQ_CONTAINER_ADDRESS }} register: rmq_state @@ -20,7 +20,7 @@ (rmq_state.stdout is not search('true')) changed_when: false -- name: "RABBITMQ | Confirm broker answers (rabbitmq-diagnostics ping)" +- name: "โœ… RABBITMQ | Confirm broker answers (rabbitmq-diagnostics ping)" ansible.builtin.shell: > {{ RABBITMQ_EXEC_SHELL }} 'rabbitmq-diagnostics -q ping' diff --git a/roles/svc-db-rabbitmq/tasks/02_init.yml b/roles/svc-db-rabbitmq/tasks/02_init.yml index 9686f5b773..80744aa0d8 100644 --- a/roles/svc-db-rabbitmq/tasks/02_init.yml +++ b/roles/svc-db-rabbitmq/tasks/02_init.yml @@ -1,11 +1,11 @@ --- -- name: "Assert correct context" +- name: "โœ… Assert correct context" ansible.builtin.assert: that: - application_id == 'svc-db-rabbitmq' - database_consumer_id != 'svc-db-rabbitmq' -- name: "Resolve consumer vhost + credentials" +- name: "๐Ÿ” Resolve consumer vhost + credentials" ansible.builtin.set_fact: rabbitmq_consumer_vhost: "{{ database_consumer_id | get_entity_name }}" rabbitmq_consumer_username: "{{ lookup('engine', 'rabbitmq', database_consumer_id, 'username') }}" @@ -13,9 +13,9 @@ changed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Wait until rabbitmqctl reaches the broker +- name: โณ Wait until rabbitmqctl reaches the broker block: - - name: "RABBITMQ | Wait for management API readiness" + - name: "โณ RABBITMQ | Wait for management API readiness" ansible.builtin.shell: > {{ RABBITMQ_EXEC_SHELL }} 'rabbitmqctl -q await_startup' @@ -26,13 +26,13 @@ changed_when: false rescue: - - name: "RABBITMQ | container logs (last 200 lines)" + - name: "๐Ÿ“ฆ RABBITMQ | container logs (last 200 lines)" ansible.builtin.command: "container logs --tail 200 {{ RABBITMQ_CONTAINER }}" register: dbg_rmq_logs changed_when: false failed_when: false - - name: "RABBITMQ | Failure report" + - name: "๐Ÿ“Š RABBITMQ | Failure report" ansible.builtin.debug: msg: rabbitmq_container: "{{ RABBITMQ_CONTAINER }}" @@ -40,13 +40,13 @@ rabbitmq_port: "{{ RABBITMQ_PORT }}" last_logs: "{{ dbg_rmq_logs.stdout | default('') }}" - - name: "RABBITMQ | Fail explicitly after logs" + - name: "๐Ÿ›‘ RABBITMQ | Fail explicitly after logs" ansible.builtin.fail: msg: >- RabbitMQ did not become ready for rabbitmqctl management requests. Last 200 container log lines were printed above. -- name: "RABBITMQ | List existing vhosts" +- name: "๐Ÿ“‹ RABBITMQ | List existing vhosts" ansible.builtin.shell: > {{ RABBITMQ_EXEC_SHELL }} 'rabbitmqctl -q list_vhosts --formatter json' @@ -56,7 +56,7 @@ delay: "{{ RABBITMQ_DELAY }}" until: rmq_vhosts.rc == 0 -- name: "Create vhost: {{ rabbitmq_consumer_vhost }}" +- name: "๐Ÿ“ Create vhost: {{ rabbitmq_consumer_vhost }}" ansible.builtin.shell: > {{ RABBITMQ_EXEC_SHELL }} 'rabbitmqctl -q add_vhost {{ rabbitmq_consumer_vhost | quote }}' @@ -69,7 +69,7 @@ rabbitmq_consumer_vhost not in (rmq_vhosts.stdout | from_json | map(attribute='name') | list) -- name: "RABBITMQ | List existing users" +- name: "๐Ÿ“‹ RABBITMQ | List existing users" ansible.builtin.shell: > {{ RABBITMQ_EXEC_SHELL }} 'rabbitmqctl -q list_users --formatter json' @@ -79,7 +79,7 @@ delay: "{{ RABBITMQ_DELAY }}" until: rmq_users.rc == 0 -- name: "Create user: {{ rabbitmq_consumer_username }}" +- name: "๐Ÿ“ Create user: {{ rabbitmq_consumer_username }}" ansible.builtin.shell: > container exec -e RMQ_PW={{ rabbitmq_consumer_password | quote }} {{ RABBITMQ_CONTAINER_ADDRESS }} sh -lc 'rabbitmqctl -q add_user {{ rabbitmq_consumer_username | quote }} "$RMQ_PW"' @@ -93,7 +93,7 @@ rabbitmq_consumer_username not in (rmq_users.stdout | from_json | map(attribute='user') | list) -- name: "Ensure user password matches inventory: {{ rabbitmq_consumer_username }}" +- name: "โœ… Ensure user password matches inventory: {{ rabbitmq_consumer_username }}" ansible.builtin.shell: > container exec -e RMQ_PW={{ rabbitmq_consumer_password | quote }} {{ RABBITMQ_CONTAINER_ADDRESS }} sh -lc 'rabbitmqctl -q change_password {{ rabbitmq_consumer_username | quote }} "$RMQ_PW"' @@ -107,7 +107,7 @@ rabbitmq_consumer_username in (rmq_users.stdout | from_json | map(attribute='user') | list) -- name: "Grant full permissions on vhost '{{ rabbitmq_consumer_vhost }}' to '{{ rabbitmq_consumer_username }}'" +- name: "๐Ÿ” Grant full perms on vhost '{{ rabbitmq_consumer_vhost }}' to consumer user" ansible.builtin.shell: > {{ RABBITMQ_EXEC_SHELL }} 'rabbitmqctl -q set_permissions -p {{ rabbitmq_consumer_vhost | quote }} diff --git a/roles/svc-db-rabbitmq/tasks/main.yml b/roles/svc-db-rabbitmq/tasks/main.yml index c414fafb36..8455e30f48 100644 --- a/roles/svc-db-rabbitmq/tasks/main.yml +++ b/roles/svc-db-rabbitmq/tasks/main.yml @@ -9,6 +9,6 @@ vars: handler_role_name: "sys-svc-compose" -- name: "Initialize dedicated vhost" +- name: "๐ŸŽฌ Initialize dedicated vhost" include_tasks: 02_init.yml when: database_init | bool diff --git a/roles/svc-db-redis/tasks/01_core.yml b/roles/svc-db-redis/tasks/01_core.yml index 96f2dd54ca..e70bd087cf 100644 --- a/roles/svc-db-redis/tasks/01_core.yml +++ b/roles/svc-db-redis/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: "Setup container network for {{ application_id }}" +- name: "๐Ÿ”ง Setup container network for {{ application_id }}" include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/network/routine.yml' ] | path_join }}" vars: compose_handlers_flush: true @@ -9,7 +9,7 @@ application_id: "svc-db-redis" database_consumer_id: "svc-db-redis" -- name: "REDIS | Wait until container is running (not restarting)" +- name: "โณ REDIS | Wait until container is running (not restarting)" ansible.builtin.shell: > container inspect --format '{{ "{{.State.Status}}" }} {{ "{{.State.Restarting}}" }}' {{ REDIS_CONTAINER_ADDRESS }} register: redis_state @@ -22,7 +22,7 @@ (redis_state.stdout is not search('true')) changed_when: false -- name: "REDIS | Confirm engine answers PING (authenticated)" +- name: "โœ… REDIS | Confirm engine answers PING (authenticated)" ansible.builtin.shell: > {{ REDIS_EXEC_SHELL }} '{{ REDIS_CLI }} ping' diff --git a/roles/svc-db-redis/tasks/02_init.yml b/roles/svc-db-redis/tasks/02_init.yml index b72ece80fb..a0b05ebf48 100644 --- a/roles/svc-db-redis/tasks/02_init.yml +++ b/roles/svc-db-redis/tasks/02_init.yml @@ -1,11 +1,11 @@ --- -- name: "Assert correct context" +- name: "โœ… Assert correct context" ansible.builtin.assert: that: - application_id == 'svc-db-redis' - database_consumer_id != 'svc-db-redis' -- name: "Resolve consumer ACL identity for {{ database_consumer_id }}" +- name: "๐Ÿ” Resolve consumer ACL identity for {{ database_consumer_id }}" ansible.builtin.set_fact: redis_acl_username: "{{ lookup('engine', 'redis', database_consumer_id, 'username') }}" redis_acl_password: "{{ lookup('engine', 'redis', database_consumer_id, 'password') | string }}" @@ -13,7 +13,7 @@ changed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "REDIS | Assert consumer credentials are present" +- name: "โœ… REDIS | Assert consumer credentials are present" ansible.builtin.assert: that: - redis_acl_username | length > 0 @@ -24,9 +24,9 @@ '{{ database_consumer_id }}'. Ensure services.redis.shared is true and a password is provisioned for the consumer. -- name: Wait until Redis accepts admin auth +- name: โณ Wait until Redis accepts admin auth block: - - name: "REDIS | Wait for authenticated PING" + - name: "โณ REDIS | Wait for authenticated PING" ansible.builtin.shell: > {{ REDIS_EXEC_SHELL }} '{{ REDIS_CLI }} ping' @@ -38,13 +38,13 @@ no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" rescue: - - name: "REDIS | container logs (last 200 lines)" + - name: "๐Ÿ“ฆ REDIS | container logs (last 200 lines)" ansible.builtin.command: "container logs --tail 200 {{ REDIS_CONTAINER }}" register: dbg_redis_logs changed_when: false failed_when: false - - name: "REDIS | Failure report" + - name: "๐Ÿ“Š REDIS | Failure report" ansible.builtin.debug: msg: redis_container: "{{ REDIS_CONTAINER }}" @@ -52,13 +52,13 @@ redis_port: "{{ REDIS_PORT }}" last_logs: "{{ dbg_redis_logs.stdout | default('') }}" - - name: "REDIS | Fail explicitly after logs" + - name: "๐Ÿ›‘ REDIS | Fail explicitly after logs" ansible.builtin.fail: msg: >- Redis did not become ready for authenticated administration. Last 200 container log lines were printed above. -- name: "REDIS | Read current ACL rules for {{ redis_acl_username }}" +- name: "๐Ÿ“– REDIS | Read current ACL rules for {{ redis_acl_username }}" ansible.builtin.shell: > {{ REDIS_EXEC_SHELL }} '{{ REDIS_CLI }} ACL GETUSER {{ redis_acl_username }}' @@ -67,7 +67,7 @@ failed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "REDIS | Provision ACL user {{ redis_acl_username }} (auth-isolated, full keyspace)" +- name: "๐Ÿ”ง REDIS | Provision ACL user {{ redis_acl_username }} (auth-isolated)" ansible.builtin.shell: > container exec -e REDIS_PASSWORD={{ REDIS_PASSWORD | quote }} diff --git a/roles/svc-db-redis/tasks/main.yml b/roles/svc-db-redis/tasks/main.yml index ba13443d80..632c54db6f 100644 --- a/roles/svc-db-redis/tasks/main.yml +++ b/roles/svc-db-redis/tasks/main.yml @@ -9,6 +9,6 @@ vars: handler_role_name: "sys-svc-compose" -- name: "Provision dedicated Redis ACL user" +- name: "๐Ÿ”ง Provision dedicated Redis ACL user" include_tasks: 02_init.yml when: database_init | bool diff --git a/roles/svc-db-typesense/tasks/01_core.yml b/roles/svc-db-typesense/tasks/01_core.yml index 5a782223f9..aeabcd6414 100644 --- a/roles/svc-db-typesense/tasks/01_core.yml +++ b/roles/svc-db-typesense/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: "Setup container network for {{ application_id }}" +- name: "๐Ÿ”ง Setup container network for {{ application_id }}" include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/network/routine.yml' ] | path_join }}" vars: compose_handlers_flush: true @@ -9,7 +9,7 @@ application_id: "svc-db-typesense" database_consumer_id: "svc-db-typesense" -- name: "TYPESENSE | Wait until container is running (not restarting)" +- name: "โณ TYPESENSE | Wait until container is running (not restarting)" ansible.builtin.shell: > container inspect --format '{{ "{{.State.Status}}" }} {{ "{{.State.Restarting}}" }}' {{ TYPESENSE_CONTAINER_ADDRESS }} register: ts_state @@ -20,7 +20,7 @@ (ts_state.stdout is not search('true')) changed_when: false -- name: "TYPESENSE | Wait until the engine answers /health (inside container)" +- name: "โณ TYPESENSE | Wait until the engine answers /health (inside container)" ansible.builtin.shell: > {{ TYPESENSE_EXEC_SHELL }} 'exec 3<>/dev/tcp/127.0.0.1/8108; printf "GET /health HTTP/1.0\r\n\r\n" >&3; grep -q "200 OK" <&3' diff --git a/roles/svc-db-typesense/tasks/02_init.yml b/roles/svc-db-typesense/tasks/02_init.yml index 73438dccad..155de02a56 100644 --- a/roles/svc-db-typesense/tasks/02_init.yml +++ b/roles/svc-db-typesense/tasks/02_init.yml @@ -1,11 +1,11 @@ --- -- name: "Assert correct context" +- name: "โœ… Assert correct context" ansible.builtin.assert: that: - application_id == 'svc-db-typesense' - database_consumer_id != 'svc-db-typesense' -- name: Resolve consumer typesense provisioning facts +- name: ๐Ÿ” Resolve consumer typesense provisioning facts ansible.builtin.set_fact: typesense_consumer_prefix: "{{ lookup('engine', 'typesense', database_consumer_id, 'prefix') }}" typesense_consumer_key: "{{ lookup('engine', 'typesense', database_consumer_id, 'password') | string }}" @@ -13,7 +13,7 @@ changed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Assert the consumer provisioned an API key" +- name: "โœ… Assert the consumer provisioned an API key" ansible.builtin.assert: that: - typesense_consumer_key | length > 0 @@ -21,9 +21,9 @@ No Typesense API key resolved for consumer '{{ database_consumer_id }}'. The consumer must declare services.typesense.password (shared: true). -- name: Wait until Typesense accepts the admin API key +- name: โณ Wait until Typesense accepts the admin API key block: - - name: "TYPESENSE | Probe /health with admin key (inside container)" + - name: "๐Ÿ” TYPESENSE | Probe /health with admin key (inside container)" ansible.builtin.shell: > {{ TYPESENSE_EXEC_SHELL }} 'exec 3<>/dev/tcp/127.0.0.1/8108; printf "GET /health HTTP/1.0\r\nX-TYPESENSE-API-KEY: {{ TYPESENSE_API_KEY }}\r\n\r\n" >&3; grep -q "200 OK" <&3' @@ -35,13 +35,13 @@ until: ts_admin_ready.rc == 0 rescue: - - name: "TYPESENSE | container logs (last 200 lines)" + - name: "๐Ÿ“ฆ TYPESENSE | container logs (last 200 lines)" ansible.builtin.command: "container logs --tail 200 {{ TYPESENSE_NAME }}" register: dbg_ts_logs changed_when: false failed_when: false - - name: "TYPESENSE | Failure report" + - name: "๐Ÿ“Š TYPESENSE | Failure report" ansible.builtin.debug: msg: typesense_container: "{{ TYPESENSE_NAME }}" @@ -49,13 +49,13 @@ typesense_port: "{{ TYPESENSE_PORT }}" last_logs: "{{ dbg_ts_logs.stdout | default('') }}" - - name: "TYPESENSE | Fail explicitly after logs" + - name: "๐Ÿ›‘ TYPESENSE | Fail explicitly after logs" ansible.builtin.fail: msg: >- Typesense did not become ready for admin API authentication. Last 200 container log lines were printed above. -- name: "Create scoped API key for {{ typesense_consumer_username }} (collections '{{ typesense_consumer_prefix }}_*')" +- name: "๐Ÿ” Create scoped API key for {{ typesense_consumer_username }} (prefix-bound)" ansible.builtin.shell: cmd: > {{ TYPESENSE_EXEC_SHELL_STDIN }} diff --git a/roles/svc-db-typesense/tasks/main.yml b/roles/svc-db-typesense/tasks/main.yml index fae3d009c1..0c86c6adac 100644 --- a/roles/svc-db-typesense/tasks/main.yml +++ b/roles/svc-db-typesense/tasks/main.yml @@ -4,6 +4,6 @@ vars: application_id: svc-db-typesense -- name: "Provision dedicated API key" +- name: "๐Ÿ”ง Provision dedicated API key" include_tasks: 02_init.yml when: database_init | bool diff --git a/roles/svc-dns-unbound/tasks/01_core.yml b/roles/svc-dns-unbound/tasks/01_core.yml index 209c1bded4..2d4832783a 100644 --- a/roles/svc-dns-unbound/tasks/01_core.yml +++ b/roles/svc-dns-unbound/tasks/01_core.yml @@ -1,21 +1,21 @@ --- - include_tasks: utils/once/flag.yml -- name: "Ensure unbound volumes directory exists" +- name: "โœ… Ensure unbound volumes directory exists" ansible.builtin.file: path: "{{ UNBOUND_VOLUMES_DIR }}" state: directory mode: "0755" when: IS_STACK_HOST | bool -- name: "Render unbound.conf" +- name: "๐Ÿ“„ Render unbound.conf" stack_host_template: src: unbound.conf.j2 dest: "{{ UNBOUND_CONF_FILE }}" mode: "0644" when: IS_STACK_HOST | bool -- name: "Setup container network for {{ application_id }}" +- name: "๐Ÿ”ง Setup container network for {{ application_id }}" include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/network/routine.yml' ] | path_join }}" vars: compose_handlers_flush: true @@ -23,7 +23,7 @@ application_id: "svc-dns-unbound" database_consumer_id: "svc-dns-unbound" -- name: "UNBOUND | Wait until container is running (not restarting)" +- name: "โณ UNBOUND | Wait until container is running (not restarting)" ansible.builtin.shell: > container inspect --format '{{ "{{.State.Status}}" }} {{ "{{.State.Restarting}}" }}' {{ UNBOUND_CONTAINER_ADDRESS }} register: unbound_state @@ -34,7 +34,7 @@ (unbound_state.stdout is not search('true')) changed_when: false -- name: "UNBOUND | Confirm the resolver answers (self lookup)" +- name: "โœ… UNBOUND | Confirm the resolver answers (self lookup)" ansible.builtin.shell: > container exec {{ UNBOUND_CONTAINER_ADDRESS }} sh -lc 'drill -p 53 localhost @127.0.0.1 >/dev/null 2>&1 || nslookup -port=53 localhost 127.0.0.1 >/dev/null 2>&1' diff --git a/roles/svc-dns-unbound/tasks/02_init.yml b/roles/svc-dns-unbound/tasks/02_init.yml index 776db7c78d..e865fa1b58 100644 --- a/roles/svc-dns-unbound/tasks/02_init.yml +++ b/roles/svc-dns-unbound/tasks/02_init.yml @@ -1,11 +1,11 @@ --- -- name: "Assert correct context" +- name: "โœ… Assert correct context" ansible.builtin.assert: that: - application_id == 'svc-dns-unbound' - database_consumer_id != 'svc-dns-unbound' -- name: "UNBOUND | Wait until the resolver answers before handing it to {{ database_consumer_id }}" +- name: "โณ UNBOUND | Wait for resolver before handing to {{ database_consumer_id }}" ansible.builtin.shell: > container exec {{ UNBOUND_CONTAINER_ADDRESS }} sh -lc 'drill -p 53 localhost @127.0.0.1 >/dev/null 2>&1 || nslookup -port=53 localhost 127.0.0.1 >/dev/null 2>&1' @@ -15,7 +15,7 @@ until: unbound_consumer_ready.rc == 0 changed_when: false -- name: "UNBOUND | No per-consumer provisioning (isolation: none)" +- name: "๐Ÿšซ UNBOUND | No per-consumer provisioning (isolation: none)" ansible.builtin.debug: msg: >- svc-dns-unbound is a shared recursive/forwarding DNSSEC resolver; consumer diff --git a/roles/svc-dns-unbound/tasks/main.yml b/roles/svc-dns-unbound/tasks/main.yml index f37d9123ea..00b80f8053 100644 --- a/roles/svc-dns-unbound/tasks/main.yml +++ b/roles/svc-dns-unbound/tasks/main.yml @@ -9,6 +9,6 @@ vars: handler_role_name: "sys-svc-compose" -- name: "Provision dedicated resolver slice" +- name: "๐Ÿ”ง Provision dedicated resolver slice" include_tasks: 02_init.yml when: database_init | bool diff --git a/roles/svc-net-wireguard-core/tasks/01_core.yml b/roles/svc-net-wireguard-core/tasks/01_core.yml index 66ca8c440a..7263f1cc77 100644 --- a/roles/svc-net-wireguard-core/tasks/01_core.yml +++ b/roles/svc-net-wireguard-core/tasks/01_core.yml @@ -1,17 +1,17 @@ --- -- name: install wireguard for Arch +- name: ๐Ÿ“ฆ install wireguard for Arch package: name: wireguard-tools state: present when: ansible_facts['os_family'] == "Archlinux" -- name: install wireguard for Ubuntu +- name: ๐Ÿ“ฆ install wireguard for Ubuntu apt: name: wireguard state: present when: ansible_facts['os_family'] == "Debian" -- name: create wireguard-ip.conf +- name: ๐Ÿ“ create wireguard-ip.conf copy: src: "wireguard-ip.conf" dest: /etc/sysctl.d/wireguard-ip.conf @@ -19,7 +19,7 @@ group: root notify: reload sysctl configuration -- name: "deploy {{ WG0_CONF_DEST }}" +- name: "๐Ÿš€ deploy {{ WG0_CONF_DEST }}" copy: src: "{{ [inventory_dir, 'files', inventory_hostname, 'etc/wireguard/wg0.conf' ] | path_join }}" dest: "{{ WG0_CONF_DEST }}" diff --git a/roles/svc-net-wireguard-firewalled/tasks/01_core.yml b/roles/svc-net-wireguard-firewalled/tasks/01_core.yml index eadaf85b09..0c08a0b925 100644 --- a/roles/svc-net-wireguard-firewalled/tasks/01_core.yml +++ b/roles/svc-net-wireguard-firewalled/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: adapt iptable rules +- name: ๐Ÿ”ง adapt iptable rules shell: iptables -A FORWARD -i wg0-client -j ACCEPT && iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE - include_tasks: utils/once/flag.yml diff --git a/roles/svc-opt-keyboard-color/tasks/01_core.yml b/roles/svc-opt-keyboard-color/tasks/01_core.yml index b3fec5eb3b..065926ed81 100644 --- a/roles/svc-opt-keyboard-color/tasks/01_core.yml +++ b/roles/svc-opt-keyboard-color/tasks/01_core.yml @@ -5,7 +5,7 @@ - sys-aur - sys-ctl-alm-compose -- name: Install MSI packages +- name: ๐Ÿ“ฆ Install MSI packages include_role: name: sys-aur-install vars: diff --git a/roles/svc-opt-ssd-hdd/tasks/main.yml b/roles/svc-opt-ssd-hdd/tasks/main.yml index a36796806f..c1b452bb0a 100644 --- a/roles/svc-opt-ssd-hdd/tasks/main.yml +++ b/roles/svc-opt-ssd-hdd/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: Include dependency 'sys-lock' +- name: ๐Ÿ“‚ Include dependency 'sys-lock' include_role: name: sys-lock when: run_once_sys_lock is not defined diff --git a/roles/svc-opt-swapfile/tasks/01_core.yml b/roles/svc-opt-swapfile/tasks/01_core.yml index 66dfb13f7a..005def56d6 100644 --- a/roles/svc-opt-swapfile/tasks/01_core.yml +++ b/roles/svc-opt-swapfile/tasks/01_core.yml @@ -1,12 +1,12 @@ --- -- name: Install ' +- name: ๐Ÿ“ฆ Install ' include_role: name: pkgmgr-install vars: package_name: "{{ SWAPFILE_PKG }}" when: run_once_pkgmgr_install is not defined -- name: Execute create swapfile script +- name: โ–ถ๏ธ Execute create swapfile script shell: "{{ SWAPFILE_PKG }} '{{ SWAPFILE_SIZE }}'" become: true async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}" diff --git a/roles/svc-prx-openresty/tasks/01_core.yml b/roles/svc-prx-openresty/tasks/01_core.yml index cba2953c80..998427c67d 100644 --- a/roles/svc-prx-openresty/tasks/01_core.yml +++ b/roles/svc-prx-openresty/tasks/01_core.yml @@ -3,17 +3,17 @@ - when: DEPLOYMENT_MODE == 'swarm' block: - - name: "Stat the docker socket so the swarm openresty worker can be group-added to it" + - name: "๐Ÿ”Ž Stat the docker socket so the swarm openresty worker can be group-added to it" ansible.builtin.stat: path: /var/run/docker.sock register: _openresty_docker_sock - - name: "Set OPENRESTY_DOCKER_SOCK_GID from the live socket gid" + - name: "๐Ÿ”ง Set OPENRESTY_DOCKER_SOCK_GID from the live socket gid" ansible.builtin.set_fact: OPENRESTY_DOCKER_SOCK_GID: "{{ _openresty_docker_sock.stat.gid }}" when: _openresty_docker_sock.stat.exists | default(false) -- name: "Ensure all openresty bind-mount source dirs exist (must precede swarm stack-deploy)" +- name: "โœ… Ensure openresty bind-mount source dirs exist before swarm stack-deploy" ansible.builtin.file: path: "{{ item }}" state: directory @@ -27,7 +27,7 @@ - "{{ LETSENCRYPT_BASE_PATH }}" - "{{ TLS_SELFSIGNED_BASE_PATH }}" -- name: Ensure base nginx.conf exists (bootstrap) +- name: โœ… Ensure base nginx.conf exists (bootstrap) ansible.builtin.copy: dest: "{{ lookup('nginx','files.configuration') }}" force: false @@ -36,12 +36,12 @@ events {} http { server { listen 8080; return 200; } } -- name: "Setup container network for {{ application_id }}" +- name: "๐Ÿ”ง Setup container network for {{ application_id }}" include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/network/routine.yml' ] | path_join }}" vars: compose_handlers_flush: true -- name: "swarm: add openresty to the docker.sock supplementary group (compose group_add is rejected by docker stack deploy)" +- name: "๐Ÿ”ง Add openresty to docker.sock group for swarm (stack deploy rejects group_add)" ansible.builtin.command: >- container service update --detach=false --group-add {{ OPENRESTY_DOCKER_SOCK_GID | quote }} @@ -52,7 +52,7 @@ - DEPLOYMENT_MODE == 'swarm' - OPENRESTY_DOCKER_SOCK_GID is defined -- name: "Verify that '{{ role_name }}' works" +- name: "โœ… Verify that '{{ role_name }}' works" include_tasks: 02_assert.yml when: MODE_ASSERT_LOCAL | bool diff --git a/roles/svc-prx-openresty/tasks/02_assert.yml b/roles/svc-prx-openresty/tasks/02_assert.yml index 8cc1437846..2762ba43ec 100644 --- a/roles/svc-prx-openresty/tasks/02_assert.yml +++ b/roles/svc-prx-openresty/tasks/02_assert.yml @@ -1,6 +1,6 @@ --- - block: - - name: Wait until OpenResty container is running + - name: โณ Wait until OpenResty container is running command: > container inspect -f '{{ "{{.State.Running}}" }}' {{ OPENRESTY_CONTAINER }} register: openresty_running @@ -9,12 +9,12 @@ retries: 24 delay: 5 - - name: Validate OpenResty configuration (Post-Flight-Check) + - name: โœ… Validate OpenResty configuration (Post-Flight-Check) shell: > container exec {{ OPENRESTY_CONTAINER_ADDRESS }} openresty -t -q register: openresty_test_post changed_when: false failed_when: openresty_test_post.rc != 0 rescue: - - name: "Load OpenResty assert rescue debug routines" + - name: "๐Ÿ“‚ Load OpenResty assert rescue debug routines" include_tasks: 02a_assert_rescue_debug.yml diff --git a/roles/svc-prx-openresty/tasks/02a_assert_rescue_debug.yml b/roles/svc-prx-openresty/tasks/02a_assert_rescue_debug.yml index 40d2e8225a..deb9007ce3 100644 --- a/roles/svc-prx-openresty/tasks/02a_assert_rescue_debug.yml +++ b/roles/svc-prx-openresty/tasks/02a_assert_rescue_debug.yml @@ -1,22 +1,22 @@ --- -- name: Debug containers (before OpenResty restart) +- name: ๐Ÿ› Debug containers (before OpenResty restart) command: container ps -a --format '{{"{{.Names}} {{.Status}}"}}' register: docker_ps changed_when: false failed_when: false -- name: Show docker containers +- name: ๐Ÿ‘๏ธ Show docker containers debug: var: docker_ps.stdout_lines -- name: Dump OpenResty container logs on failure +- name: ๐Ÿ’พ Dump OpenResty container logs on failure command: > container logs --tail=200 {{ OPENRESTY_CONTAINER }} register: openresty_logs changed_when: false failed_when: false -- name: Show OpenResty logs +- name: ๐Ÿ‘๏ธ Show OpenResty logs debug: msg: | ===== OpenResty container logs (last 200 lines) ===== diff --git a/roles/svc-prx-openresty/tasks/main.yml b/roles/svc-prx-openresty/tasks/main.yml index bb6431dc6d..4395d160ef 100644 --- a/roles/svc-prx-openresty/tasks/main.yml +++ b/roles/svc-prx-openresty/tasks/main.yml @@ -2,7 +2,7 @@ - include_tasks: 01_core.yml when: run_once_svc_prx_openresty is not defined -- name: "Reinitialize OpenResty Handler" +- name: "๐ŸŽ›๏ธ Reinitialize OpenResty Handler" # The 'when: run_once_svc_prx_openresty is not defined' prevents otherwise # the handler execution include_tasks: utils/load_handlers.yml diff --git a/roles/svc-storage-nfs-client/tasks/main.yml b/roles/svc-storage-nfs-client/tasks/main.yml index 559eb40a6a..daff7770a6 100644 --- a/roles/svc-storage-nfs-client/tasks/main.yml +++ b/roles/svc-storage-nfs-client/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "Assert NFS server + export base are configured" +- name: "โœ… Assert NFS server + export base are configured" ansible.builtin.assert: that: - storage.nfs.server is defined @@ -12,12 +12,12 @@ group_vars/all/15_storage.yml). Reachable NFS server IP/hostname and the matching export base path are mandatory. -- name: "Install NFS client packages" +- name: "๐Ÿ“ฆ Install NFS client packages" ansible.builtin.package: name: "{{ SVC_STORAGE_NFS_CLIENT_PACKAGES[ansible_facts.os_family] }}" state: present -- name: "Ensure probe mount point exists" +- name: "โœ… Ensure probe mount point exists" ansible.builtin.file: path: "{{ SVC_STORAGE_NFS_CLIENT_PROBE_DIR }}" state: directory @@ -25,7 +25,7 @@ group: root mode: "0700" -- name: "Probe-mount the NFS export" +- name: "๐Ÿ” Probe-mount the NFS export" ansible.posix.mount: path: "{{ SVC_STORAGE_NFS_CLIENT_PROBE_DIR }}" src: "{{ STORAGE_NFS_CLIENT_SRC }}" @@ -36,7 +36,7 @@ failed_when: - svc_storage_nfs_client_probe is failed -- name: "Probe-write a marker to confirm the mount is RW" +- name: "๐Ÿ” Probe-write a marker to confirm the mount is RW" ansible.builtin.copy: dest: "{{ SVC_STORAGE_NFS_CLIENT_PROBE_DIR }}/.svc-storage-nfs-client-probe" content: | @@ -44,12 +44,12 @@ probed-at={{ ansible_facts.date_time.iso8601 }} mode: "0644" -- name: "Unmount probe mount" +- name: "๐Ÿ”— Unmount probe mount" ansible.posix.mount: path: "{{ SVC_STORAGE_NFS_CLIENT_PROBE_DIR }}" state: unmounted -- name: "Detect {{ DIR_VAR_LIB }} pre-mount state" +- name: "๐Ÿ” Detect {{ DIR_VAR_LIB }} pre-mount state" ansible.builtin.script: cmd: "{{ role_path }}/files/premount_state.sh" executable: /bin/bash @@ -58,7 +58,7 @@ register: _svc_storage_nfs_client_premount_state changed_when: false -- name: "Assert no pre-existing local data at {{ DIR_VAR_LIB }} (mount-over would hide it)" +- name: "โœ… Assert no pre-existing local data at {{ DIR_VAR_LIB }} (mount would hide it)" ansible.builtin.assert: that: - (_svc_storage_nfs_client_premount_state.stdout | trim) in ["mounted", "empty"] @@ -67,7 +67,7 @@ would silently hide it. Migrate or remove the local tree manually, then re-run the deploy. -- name: "Ensure infinito state mount point exists" +- name: "โœ… Ensure infinito state mount point exists" ansible.builtin.file: path: "{{ DIR_VAR_LIB }}" state: directory @@ -75,7 +75,7 @@ group: root mode: "0755" -- name: "Persistently mount cluster-shared infinito state from NFS" +- name: "๐Ÿ”— Persistently mount cluster-shared infinito state from NFS" ansible.posix.mount: path: "{{ DIR_VAR_LIB }}" src: "{{ STORAGE_NFS_CLIENT_SRC }}" diff --git a/roles/svc-storage-nfs-server/tasks/01_core.yml b/roles/svc-storage-nfs-server/tasks/01_core.yml index c3ef9e2a6b..3a35322844 100644 --- a/roles/svc-storage-nfs-server/tasks/01_core.yml +++ b/roles/svc-storage-nfs-server/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: "Assert storage.nfs.export_base is set" +- name: "โœ… Assert storage.nfs.export_base is set" ansible.builtin.assert: that: - storage.nfs.export_base is defined @@ -10,23 +10,23 @@ svc-storage-nfs-server requires `storage.nfs.export_base` to be set in group_vars (see group_vars/all/15_storage.yml). -- name: "Resolve the NFS server backend flavor" +- name: "๐Ÿ” Resolve the NFS server backend flavor" ansible.builtin.set_fact: SVC_STORAGE_NFS_SERVER_FLAVOR: "{{ lookup('nfs_flavor') }}" -- name: "Assert the NFS server flavor is kernel or ganesha" +- name: "โœ… Assert the NFS server flavor is kernel or ganesha" ansible.builtin.assert: that: - SVC_STORAGE_NFS_SERVER_FLAVOR in ['kernel', 'ganesha'] fail_msg: "services.nfs-server.flavor must be 'kernel' or 'ganesha' (got '{{ SVC_STORAGE_NFS_SERVER_FLAVOR }}')" -- name: "Include shared NFS export preparation" +- name: "๐Ÿ“‚ Include shared NFS export preparation" ansible.builtin.include_tasks: 03_prepare.yml -- name: "Dispatch NFS backend flavor" +- name: "๐Ÿ“ค Dispatch NFS backend flavor" ansible.builtin.include_tasks: "flavor/{{ SVC_STORAGE_NFS_SERVER_FLAVOR }}/main.yml" -- name: "Include controller-side mount step" +- name: "๐Ÿ“‚ Include controller-side mount step" ansible.builtin.include_tasks: file: 05_controller_mount.yml apply: diff --git a/roles/svc-storage-nfs-server/tasks/03_prepare.yml b/roles/svc-storage-nfs-server/tasks/03_prepare.yml index e0d62fb2fe..b0cffa5448 100644 --- a/roles/svc-storage-nfs-server/tasks/03_prepare.yml +++ b/roles/svc-storage-nfs-server/tasks/03_prepare.yml @@ -1,5 +1,5 @@ --- -- name: "Ensure export base directory exists" +- name: "โœ… Ensure export base directory exists" ansible.builtin.file: path: "{{ storage.nfs.export_base }}" state: directory @@ -7,7 +7,7 @@ group: root mode: "0755" -- name: "Pre-create cluster-shared state subdir under export base" +- name: "๐Ÿ“ Pre-create cluster-shared state subdir under export base" ansible.builtin.file: path: "{{ STORAGE_NFS_STATE_PATH }}" state: directory @@ -15,7 +15,7 @@ group: root mode: "0755" -- name: "Assert the state subdir is strictly nested under the export base" +- name: "โœ… Assert the state subdir is strictly nested under the export base" ansible.builtin.assert: that: - STORAGE_NFS_STATE_PATH != storage.nfs.export_base @@ -23,7 +23,7 @@ STORAGE_NFS_STATE_PATH must be a strict subdir of storage.nfs.export_base; equal paths collide on the two distinct exports (root_squash vs no_root_squash). -- name: "Bind-mount the state subdir onto itself (gives the fsid=0 export root a stable mount boundary under overlayfs DinD)" +- name: "๐Ÿ”ง Bind-mount state subdir onto itself for stable fsid=0 export root boundary" ansible.posix.mount: path: "{{ STORAGE_NFS_STATE_PATH }}" src: "{{ STORAGE_NFS_STATE_PATH }}" @@ -32,7 +32,7 @@ state: mounted when: SVC_STORAGE_NFS_SERVER_FLAVOR == 'kernel' -- name: "Gather facts on swarm members so their IPs become available" +- name: "๐Ÿ“Š Gather facts on swarm members so their IPs become available" ansible.builtin.setup: gather_subset: network delegate_to: "{{ item }}" @@ -40,7 +40,7 @@ loop: "{{ groups['svc-swarm-node'] | default([]) }}" when: hostvars[item].ansible_default_ipv4 is not defined -- name: "Compute swarm-member IPs allowed to mount" +- name: "๐Ÿงฎ Compute swarm-member IPs allowed to mount" ansible.builtin.set_fact: svc_storage_nfs_server_allowed_ips: >- {{ @@ -51,7 +51,7 @@ | list }} -- name: "Assert at least one allowed IP was resolved" +- name: "โœ… Assert at least one allowed IP was resolved" ansible.builtin.assert: that: - svc_storage_nfs_server_allowed_ips | length > 0 diff --git a/roles/svc-storage-nfs-server/tasks/05_controller_mount.yml b/roles/svc-storage-nfs-server/tasks/05_controller_mount.yml index cd16c50198..94f60a7f9a 100644 --- a/roles/svc-storage-nfs-server/tasks/05_controller_mount.yml +++ b/roles/svc-storage-nfs-server/tasks/05_controller_mount.yml @@ -1,5 +1,5 @@ --- -- name: "Detect controller {{ DIR_VAR_LIB }} pre-mount state" +- name: "๐Ÿ” Detect controller {{ DIR_VAR_LIB }} pre-mount state" ansible.builtin.script: cmd: "{{ playbook_dir }}/roles/svc-storage-nfs-client/files/premount_state.sh" executable: /bin/bash @@ -8,7 +8,7 @@ register: _ctrl_premount_state changed_when: false -- name: "Assert no pre-existing local data at controller {{ DIR_VAR_LIB }} (mount-over would hide it)" +- name: "โœ… Assert controller {{ DIR_VAR_LIB }} has no pre-existing data (mount hides it)" ansible.builtin.assert: that: - (_ctrl_premount_state.stdout | trim) in ["mounted", "empty"] @@ -17,7 +17,7 @@ mount-over would silently hide it. Migrate or remove the local tree on the controller, then re-run the deploy. -- name: "Ensure controller mount point exists" +- name: "โœ… Ensure controller mount point exists" ansible.builtin.file: path: "{{ DIR_VAR_LIB }}" state: directory @@ -25,7 +25,7 @@ group: root mode: "0755" -- name: "Ensure NFS client packages are installed on controller for mount.nfs helper" +- name: "โœ… Ensure NFS client packages are installed on controller for mount.nfs helper" ansible.builtin.package: name: "{{ lookup('vars', 'SVC_STORAGE_NFS_CLIENT_PACKAGES')[ansible_os_family] }}" state: present @@ -38,7 +38,7 @@ Fedora: [nfs-utils] Alpine: [nfs-utils] -- name: "Mount cluster-shared infinito state on controller" +- name: "๐Ÿ”— Mount cluster-shared infinito state on controller" ansible.posix.mount: path: "{{ DIR_VAR_LIB }}" src: "{{ STORAGE_NFS_CLIENT_SRC }}" diff --git a/roles/svc-storage-nfs-server/tasks/flavor/ganesha/main.yml b/roles/svc-storage-nfs-server/tasks/flavor/ganesha/main.yml index 4e0434bb23..41b10be2fc 100644 --- a/roles/svc-storage-nfs-server/tasks/flavor/ganesha/main.yml +++ b/roles/svc-storage-nfs-server/tasks/flavor/ganesha/main.yml @@ -1,17 +1,17 @@ --- -- name: "Install userspace nfs-ganesha packages" +- name: "๐Ÿ“ฆ Install userspace nfs-ganesha packages" ansible.builtin.package: name: "{{ SVC_STORAGE_NFS_SERVER_PACKAGES['ganesha'][ansible_os_family] }}" state: present # Debian/Ubuntu ship a broken nfs-ganesha-config.service that wedges the unit # start; mask it so the main nfs-ganesha service comes up. -- name: "Mask the broken nfs-ganesha-config helper unit" +- name: "๐Ÿ”ง Mask the broken nfs-ganesha-config helper unit" ansible.builtin.systemd: name: nfs-ganesha-config.service masked: true -- name: "Ensure the ganesha config directory exists" +- name: "โœ… Ensure the ganesha config directory exists" ansible.builtin.file: path: /etc/ganesha state: directory @@ -19,7 +19,7 @@ group: root mode: "0755" -- name: "Render /etc/ganesha/ganesha.conf" +- name: "๐Ÿ“„ Render /etc/ganesha/ganesha.conf" ansible.builtin.template: # nocheck: stack-host-template (per-host NFS server config (NFS host is its own group, not the stack host)) src: ganesha.conf.j2 dest: /etc/ganesha/ganesha.conf @@ -28,11 +28,11 @@ mode: "0644" notify: "Restart NFS ganesha" -- name: "Enable and start nfs-ganesha" +- name: "๐ŸŸข Enable and start nfs-ganesha" ansible.builtin.systemd: name: "{{ SVC_STORAGE_NFS_SERVER_SERVICE['ganesha'][ansible_os_family] }}" enabled: true state: started -- name: "Flush handlers (ganesha restart applies the rendered export set)" +- name: "๐Ÿšฟ Flush handlers (ganesha restart applies the rendered export set)" ansible.builtin.meta: flush_handlers diff --git a/roles/svc-storage-nfs-server/tasks/flavor/kernel/main.yml b/roles/svc-storage-nfs-server/tasks/flavor/kernel/main.yml index b5aaeb475d..96020b53cd 100644 --- a/roles/svc-storage-nfs-server/tasks/flavor/kernel/main.yml +++ b/roles/svc-storage-nfs-server/tasks/flavor/kernel/main.yml @@ -1,30 +1,30 @@ --- -- name: "Install kernel NFS server packages" +- name: "๐Ÿ“ฆ Install kernel NFS server packages" ansible.builtin.package: name: "{{ SVC_STORAGE_NFS_SERVER_PACKAGES['kernel'][ansible_os_family] }}" state: present -- name: "Ensure the SELinux python binding on RedHat (the seboolean module + selinux fact need it)" +- name: "๐Ÿ“ฆ Install SELinux python binding on RedHat (seboolean module + selinux fact)" ansible.builtin.package: name: python3-libselinux state: present when: ansible_os_family == 'RedHat' -- name: "Re-gather the SELinux fact now the binding is present (RedHat)" +- name: "๐Ÿ“Š Re-gather the SELinux fact now the binding is present (RedHat)" ansible.builtin.setup: gather_subset: - "!all" - selinux when: ansible_os_family == 'RedHat' -- name: "Allow kernel NFS to export read-write under SELinux (enforcing RedHat hosts)" +- name: "๐Ÿ“ค Allow kernel NFS to export read-write under SELinux (enforcing RedHat hosts)" ansible.posix.seboolean: name: nfs_export_all_rw state: true persistent: true when: ansible_facts.get('selinux', {}).get('status', 'disabled') == 'enabled' -- name: "Render /etc/exports" +- name: "๐Ÿ“„ Render /etc/exports" ansible.builtin.template: # nocheck: stack-host-template (per-host NFS server /etc/exports (NFS host is its own group, not the stack host)) src: exports.j2 dest: /etc/exports @@ -33,10 +33,10 @@ mode: "0644" notify: "Reload NFS exports" -- name: "Flush handlers (exports reload before next step)" +- name: "๐Ÿšฟ Flush handlers (exports reload before next step)" ansible.builtin.meta: flush_handlers -- name: "Enable and start the kernel NFS server" +- name: "๐ŸŸข Enable and start the kernel NFS server" ansible.builtin.systemd: name: "{{ SVC_STORAGE_NFS_SERVER_SERVICE['kernel'][ansible_os_family] }}" enabled: true diff --git a/roles/svc-swarm-node/tasks/01_core.yml b/roles/svc-swarm-node/tasks/01_core.yml index e26c702208..4d03fac952 100644 --- a/roles/svc-swarm-node/tasks/01_core.yml +++ b/roles/svc-swarm-node/tasks/01_core.yml @@ -4,13 +4,13 @@ # Consumers like `svc-registry-docker` pull this role via `run_after`; # under universal / server CI they reach it with DEPLOYMENT_MODE='compose' # and no `svc-swarm-manager` group, which would trip the asserts. -- name: "Swarm-only node setup (cluster bootstrap + shared CA anchor)" +- name: "๐Ÿ Swarm-only node setup (cluster bootstrap + shared CA anchor)" when: DEPLOYMENT_MODE == 'swarm' block: - - name: "Bootstrap docker swarm cluster" + - name: "๐Ÿฅพ Bootstrap docker swarm cluster" ansible.builtin.include_tasks: 01a_bootstrap_cluster.yml - - name: "Ensure the shared Root CA is present on every swarm node (manager mints, workers fetch)" + - name: "โœ… Ensure shared Root CA on every swarm node (manager mints, workers fetch)" ansible.builtin.include_role: name: sys-ca-selfsigned when: diff --git a/roles/svc-swarm-node/tasks/01a_bootstrap_cluster.yml b/roles/svc-swarm-node/tasks/01a_bootstrap_cluster.yml index bf86b3936c..1605dc6942 100644 --- a/roles/svc-swarm-node/tasks/01a_bootstrap_cluster.yml +++ b/roles/svc-swarm-node/tasks/01a_bootstrap_cluster.yml @@ -1,11 +1,11 @@ --- -- name: "Ensure dockerd is installed before swarm bootstrap" +- name: "โœ… Ensure dockerd is installed before swarm bootstrap" ansible.builtin.include_role: name: sys-svc-container public: false when: run_once_sys_svc_container is not defined -- name: "Assert at least one host is in svc-swarm-manager" +- name: "โœ… Assert at least one host is in svc-swarm-manager" ansible.builtin.assert: that: - (groups['svc-swarm-manager'] | default([]) | length) >= 1 @@ -18,7 +18,7 @@ Found: {{ groups['svc-swarm-manager'] | default([]) | length }} members. run_once: true -- name: "Assert every svc-swarm-manager member is also in svc-swarm-node" +- name: "โœ… Assert every svc-swarm-manager member is also in svc-swarm-node" ansible.builtin.assert: that: - item in (groups['svc-swarm-node'] | default([])) @@ -28,22 +28,22 @@ loop: "{{ groups['svc-swarm-manager'] | default([]) }}" run_once: true -- name: "Bootstrap manager: init swarm + publish join tokens (first manager only)" +- name: "๐Ÿฅพ Bootstrap manager: init swarm + publish join tokens (first manager only)" ansible.builtin.include_tasks: 02_manager.yml when: inventory_hostname == (groups['svc-swarm-manager'] | first) -- name: "Additional managers: join cluster with manager token" +- name: "๐Ÿ•ธ๏ธ Additional managers: join cluster with manager token" ansible.builtin.include_tasks: 02_manager_join.yml when: - "'svc-swarm-manager' in group_names" - inventory_hostname != (groups['svc-swarm-manager'] | first) -- name: "Worker: include worker-join tasks" +- name: "๐Ÿ“‚ Worker: include worker-join tasks" ansible.builtin.include_tasks: 03_worker.yml when: - "'svc-swarm-node' in group_names" - "'svc-swarm-manager' not in group_names" -- name: "Apply node labels (bootstrap manager dispatches to all nodes)" +- name: "๐Ÿ“Œ Apply node labels (bootstrap manager dispatches to all nodes)" ansible.builtin.include_tasks: 04_labels.yml when: inventory_hostname == (groups['svc-swarm-manager'] | first) diff --git a/roles/svc-swarm-node/tasks/02_manager.yml b/roles/svc-swarm-node/tasks/02_manager.yml index 603a4b8def..0657e6c4cb 100644 --- a/roles/svc-swarm-node/tasks/02_manager.yml +++ b/roles/svc-swarm-node/tasks/02_manager.yml @@ -1,11 +1,11 @@ --- -- name: "Probe local docker swarm state" +- name: "๐Ÿ” Probe local docker swarm state" ansible.builtin.command: container info --format '{{ "{{" }}.Swarm.LocalNodeState{{ "}}" }}' register: docker_swarm_local_state changed_when: false failed_when: docker_swarm_local_state.rc != 0 -- name: "Initialise swarm cluster (only when not already active)" +- name: "๐Ÿ Initialise swarm cluster (only when not already active)" ansible.builtin.command: >- container swarm init {% if swarm.manager.advertise_addr | default('', true) %} @@ -15,22 +15,22 @@ register: docker_swarm_init_result changed_when: docker_swarm_init_result.rc == 0 -- name: "Fetch worker join token" +- name: "โฌ‡๏ธ Fetch worker join token" ansible.builtin.command: container swarm join-token -q worker register: docker_swarm_worker_token changed_when: false -- name: "Fetch manager join token" +- name: "โฌ‡๏ธ Fetch manager join token" ansible.builtin.command: container swarm join-token -q manager register: docker_swarm_manager_token changed_when: false -- name: "Fetch manager swarm-advertise address" +- name: "โฌ‡๏ธ Fetch manager swarm-advertise address" ansible.builtin.command: container info --format '{{ "{{" }}.Swarm.NodeAddr{{ "}}" }}:2377' register: docker_swarm_manager_addr changed_when: false -- name: "Publish tokens + advertise addr as facts (cluster-wide)" +- name: "๐Ÿ“ฃ Publish tokens + advertise addr as facts (cluster-wide)" ansible.builtin.set_fact: svc_swarm_worker_token: "{{ docker_swarm_worker_token.stdout }}" svc_swarm_manager_token: "{{ docker_swarm_manager_token.stdout }}" diff --git a/roles/svc-swarm-node/tasks/02_manager_join.yml b/roles/svc-swarm-node/tasks/02_manager_join.yml index 2fc1bc77f0..92e7b5d580 100644 --- a/roles/svc-swarm-node/tasks/02_manager_join.yml +++ b/roles/svc-swarm-node/tasks/02_manager_join.yml @@ -1,11 +1,11 @@ --- -- name: "Probe local docker swarm state" +- name: "๐Ÿ” Probe local docker swarm state" ansible.builtin.command: container info --format '{{ "{{" }}.Swarm.LocalNodeState{{ "}}" }}' register: docker_swarm_local_state changed_when: false failed_when: docker_swarm_local_state.rc != 0 -- name: "Join swarm cluster as manager (only when not already active)" +- name: "๐Ÿ Join swarm cluster as manager (only when not already active)" ansible.builtin.command: >- container swarm join --token {{ svc_swarm_manager_token }} diff --git a/roles/svc-swarm-node/tasks/03_worker.yml b/roles/svc-swarm-node/tasks/03_worker.yml index 8da8f63bf1..71621a2d6c 100644 --- a/roles/svc-swarm-node/tasks/03_worker.yml +++ b/roles/svc-swarm-node/tasks/03_worker.yml @@ -1,11 +1,11 @@ --- -- name: "Probe local docker swarm state" +- name: "๐Ÿ” Probe local docker swarm state" ansible.builtin.command: container info --format '{{ "{{" }}.Swarm.LocalNodeState{{ "}}" }}' register: docker_swarm_local_state changed_when: false failed_when: docker_swarm_local_state.rc != 0 -- name: "Join swarm cluster as worker (only when not already active)" +- name: "๐Ÿ Join swarm cluster as worker (only when not already active)" ansible.builtin.command: >- container swarm join --token {{ svc_swarm_worker_token }} diff --git a/roles/svc-swarm-node/tasks/04_labels.yml b/roles/svc-swarm-node/tasks/04_labels.yml index 22e1584d8a..389c88d96e 100644 --- a/roles/svc-swarm-node/tasks/04_labels.yml +++ b/roles/svc-swarm-node/tasks/04_labels.yml @@ -1,5 +1,5 @@ --- -- name: "Push node labels for every swarm member" +- name: "โฌ†๏ธ Push node labels for every swarm member" ansible.builtin.command: >- docker node update {% for k, v in hostvars[item].swarm_node_labels.items() %} diff --git a/roles/sys-aur-install/tasks/main.yml b/roles/sys-aur-install/tasks/main.yml index 4c6362f19e..4a148d8a63 100644 --- a/roles/sys-aur-install/tasks/main.yml +++ b/roles/sys-aur-install/tasks/main.yml @@ -1,12 +1,12 @@ --- # nocheck: run-once -- name: Include dependency 'sys-aur' +- name: ๐Ÿ“‚ Include dependency 'sys-aur' include_role: name: sys-aur when: run_once_sys_aur is not defined -- name: Validate sys-aur-install parameters +- name: โœ… Validate sys-aur-install parameters assert: that: - (not (yay_install_upgrade | bool)) or (yay_install_packages | length == 0) @@ -16,7 +16,7 @@ are mutually exclusive). when: (yay_install_packages | length > 0) or (yay_install_upgrade | bool) -- name: Install or upgrade AUR packages via yay +- name: ๐Ÿ“ฆ Install or upgrade AUR packages via yay kewlfft.aur.aur: use: "{{ yay_install_use }}" name: "{{ (not (yay_install_upgrade | bool) and (yay_install_packages | length > 0)) | ternary(yay_install_packages, omit) }}" diff --git a/roles/sys-aur/tasks/01_core.yml b/roles/sys-aur/tasks/01_core.yml index b3ff969608..28711cda56 100644 --- a/roles/sys-aur/tasks/01_core.yml +++ b/roles/sys-aur/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: Include dependencies +- name: ๐Ÿ“‚ Include dependencies include_role: name: "{{ item }}" loop: @@ -9,7 +9,7 @@ - dev-git - dev-base-devel -- name: Install yay build prerequisites +- name: ๐Ÿ“ฆ Install yay build prerequisites become: true package: name: @@ -17,20 +17,20 @@ - git state: present -- name: Ensure the AUR builder primary group exists +- name: โœ… Ensure the AUR builder primary group exists become: true ansible.builtin.group: name: "{{ AUR_BUILDER_GROUP }}" state: present -- name: Create the AUR builder user +- name: ๐Ÿ“ Create the AUR builder user become: true ansible.builtin.user: name: "{{ AUR_BUILDER_USER }}" create_home: true group: "{{ AUR_BUILDER_GROUP }}" -- name: Allow AUR builder to run pacman without password +- name: โ–ถ๏ธ Allow AUR builder to run pacman without password become: true ansible.builtin.lineinfile: path: "{{ AUR_BUILDER_SUDOERS_PATH }}" @@ -38,7 +38,7 @@ create: true validate: "visudo -cf %s" -- name: Clone yay from AUR +- name: โฌ‡๏ธ Clone yay from AUR become: true become_user: "{{ AUR_BUILDER_USER }}" git: @@ -49,13 +49,13 @@ update: true depth: 1 -- name: Check whether yay is present +- name: ๐Ÿ”Ž Check whether yay is present become: true ansible.builtin.stat: path: /usr/bin/yay register: yay_stat -- name: Check whether yay has missing shared libraries (broken) +- name: ๐Ÿ”Ž Check whether yay has missing shared libraries (broken) become: true ansible.builtin.command: bash -lc "ldd /usr/bin/yay 2>/dev/null | grep -q 'not found'" register: yay_ldd_missing @@ -63,7 +63,7 @@ changed_when: false when: yay_stat.stat.exists -- name: Remove broken yay binary so it can be rebuilt +- name: ๐Ÿ—‘๏ธ Remove broken yay binary so it can be rebuilt become: true ansible.builtin.file: path: /usr/bin/yay @@ -72,7 +72,7 @@ - yay_stat.stat.exists - yay_ldd_missing.rc == 0 -- name: Build and install yay +- name: ๐Ÿ”จ Build and install yay become: true become_user: "{{ AUR_BUILDER_USER }}" shell: | @@ -82,7 +82,7 @@ args: creates: /usr/bin/yay -- name: upgrade the system using yay, only act on AUR packages. +- name: ๐Ÿ”„ upgrade the system using yay, only act on AUR packages. include_role: name: sys-aur-install vars: diff --git a/roles/sys-ca-selfsigned/tasks/01_core.yml b/roles/sys-ca-selfsigned/tasks/01_core.yml index 3c074fe4f7..052c8c1aec 100644 --- a/roles/sys-ca-selfsigned/tasks/01_core.yml +++ b/roles/sys-ca-selfsigned/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: "CA | ensure base directory exists" +- name: "โœ… CA | ensure base directory exists" become: true ansible.builtin.file: path: "{{ CA_ROOT.base_dir }}" @@ -8,17 +8,17 @@ owner: root group: root -- name: "CA | ensure openssl is installed" +- name: "โœ… CA | ensure openssl is installed" include_role: name: sys-openssl when: run_once_sys_openssl is not defined -- name: "CA | check openssl availability" +- name: "๐Ÿ”Ž CA | check openssl availability" ansible.builtin.command: "openssl version" register: _openssl_version changed_when: false -- name: "CA | mint the shared Root CA once on the stack host (workers fetch it below)" +- name: "๐Ÿ›๏ธ CA | mint the shared Root CA once on the stack host (workers fetch it below)" ansible.builtin.include_tasks: file: 02_mint.yml apply: @@ -26,17 +26,17 @@ run_once: true delegate_to: "{{ STACK_HOST }}" -- name: "CA | (swarm worker) fetch + install the shared Root CA cert from the stack host" +- name: "โฌ‡๏ธ CA | (swarm worker) fetch + install shared Root CA cert from stack host" become: true when: not (IS_STACK_HOST | bool) block: - - name: "CA | (swarm worker) read the shared Root CA cert from the stack host" + - name: "๐Ÿ CA | (swarm worker) read the shared Root CA cert from the stack host" ansible.builtin.slurp: src: "{{ CA_ROOT.cert_host }}" register: _ca_cert_from_stack_host delegate_to: "{{ STACK_HOST }}" - - name: "CA | (swarm worker) write the shared Root CA cert locally (cert only, never the key)" + - name: "๐Ÿ“„ CA | (swarm worker) write shared Root CA cert locally (cert only, no key)" ansible.builtin.copy: dest: "{{ CA_ROOT.cert_host }}" content: "{{ _ca_cert_from_stack_host.content | b64decode }}" @@ -44,7 +44,7 @@ group: root mode: "0644" -- name: "CA | enforce permissions (certificate)" +- name: "๐Ÿ” CA | enforce permissions (certificate)" become: true ansible.builtin.file: path: "{{ CA_ROOT.cert_host }}" @@ -52,13 +52,13 @@ group: root mode: "0644" -- name: "CA | sanity check: verify certificate is CA:TRUE" +- name: "โœ… CA | sanity check: verify certificate is CA:TRUE" become: true ansible.builtin.command: "openssl x509 -in {{ CA_ROOT.cert_host }} -noout -text" register: _ca_cert_text changed_when: false -- name: "CA | assert certificate contains CA:TRUE" +- name: "โœ… CA | assert certificate contains CA:TRUE" ansible.builtin.assert: that: - (_ca_cert_text.stdout | default('')) is search('CA:TRUE') @@ -66,7 +66,7 @@ Generated certificate does not appear to be a CA certificate (CA:TRUE missing). Please inspect {{ CA_ROOT.cert_host }}. -- name: "CA | install trust helper script (SPOT) on host" +- name: "๐Ÿ“ฆ CA | install trust helper script (SPOT) on host" become: true ansible.builtin.copy: src: "with-ca-trust.sh" @@ -75,7 +75,7 @@ group: root mode: "0755" -- name: "CA | Install Root CA into host trust store" +- name: "๐Ÿ“ฆ CA | Install Root CA into host trust store" become: true ansible.builtin.command: argv: @@ -87,7 +87,7 @@ CA_TRUST_NAME: "{{ DOMAIN_PRIMARY | lower }}" changed_when: true -- name: "TLS | (self_signed) ensure CA trust env vars in {{ FILE_ENVIRONMENT }}" +- name: "โœ… TLS | (self_signed) ensure CA trust env vars in {{ FILE_ENVIRONMENT }}" become: true ansible.builtin.lineinfile: path: "{{ FILE_ENVIRONMENT }}" diff --git a/roles/sys-ca-selfsigned/tasks/02_mint.yml b/roles/sys-ca-selfsigned/tasks/02_mint.yml index 4e585fd5df..358632b078 100644 --- a/roles/sys-ca-selfsigned/tasks/02_mint.yml +++ b/roles/sys-ca-selfsigned/tasks/02_mint.yml @@ -1,17 +1,17 @@ --- -- name: "CA | check if key exists" +- name: "๐Ÿ”Ž CA | check if key exists" ansible.builtin.stat: path: "{{ CA_ROOT.key_host }}" register: _ca_key_stat changed_when: false -- name: "CA | check if cert exists" +- name: "๐Ÿ”Ž CA | check if cert exists" ansible.builtin.stat: path: "{{ CA_ROOT.cert_host }}" register: _ca_cert_stat changed_when: false -- name: "CA | decide whether regeneration is needed" +- name: "๐Ÿค” CA | decide whether regeneration is needed" ansible.builtin.set_fact: _ca_regen_needed: >- {{ @@ -21,7 +21,7 @@ }} changed_when: false -- name: "CA | remove outdated key/cert if regeneration requested/needed" +- name: "๐Ÿ—‘๏ธ CA | remove outdated key/cert if regeneration requested/needed" ansible.builtin.file: path: "{{ item }}" state: absent @@ -30,7 +30,7 @@ - "{{ CA_ROOT.cert_host }}" when: _ca_regen_needed | bool -- name: "CA | render openssl config (v3_ca)" +- name: "๐Ÿ“„ CA | render openssl config (v3_ca)" ansible.builtin.template: # nocheck: stack-host-template (delegated to STACK_HOST + run_once by the parent include) src: "openssl-root-ca.cnf.j2" dest: "{{ CA_ROOT.openssl_conf_host }}" @@ -38,7 +38,7 @@ group: root mode: "0640" -- name: "CA | generate root CA key + cert (self-signed)" +- name: "โš™๏ธ CA | generate root CA key + cert (self-signed)" ansible.builtin.command: argv: - openssl @@ -62,7 +62,7 @@ creates: "{{ CA_ROOT.cert_host }}" when: _ca_regen_needed | bool -- name: "CA | enforce permissions (private key)" +- name: "๐Ÿ” CA | enforce permissions (private key)" ansible.builtin.file: path: "{{ CA_ROOT.key_host }}" owner: root diff --git a/roles/sys-ca-selfsigned/tasks/disable_env.yml b/roles/sys-ca-selfsigned/tasks/disable_env.yml index 965a3ddd60..be41cfc46f 100644 --- a/roles/sys-ca-selfsigned/tasks/disable_env.yml +++ b/roles/sys-ca-selfsigned/tasks/disable_env.yml @@ -1,5 +1,5 @@ --- -- name: "TLS | remove CA trust env vars from {{ FILE_ENVIRONMENT }}" +- name: "๐Ÿ—‘๏ธ TLS | remove CA trust env vars from {{ FILE_ENVIRONMENT }}" become: true ansible.builtin.lineinfile: path: "{{ FILE_ENVIRONMENT }}" diff --git a/roles/sys-cleanup/tasks/main.yml b/roles/sys-cleanup/tasks/main.yml index e7ec806d89..d50269a530 100644 --- a/roles/sys-cleanup/tasks/main.yml +++ b/roles/sys-cleanup/tasks/main.yml @@ -1,11 +1,11 @@ --- -- name: "Cleanup caches and logs (cross-distro: arch/debian/ubuntu/fedora/centos)" +- name: "๐Ÿงน Cleanup caches and logs (cross-distro: arch/debian/ubuntu/fedora/centos)" # CI/container cleanup to prevent disk blow-ups across all supported distros become: true ansible.builtin.script: cleanup_caches.sh changed_when: true -- name: Cleanup journald logs (CI/container only) +- name: ๐Ÿงน Cleanup journald logs (CI/container only) # Prevent disk blow-ups in CI containers due to journald accumulation become: true ansible.builtin.shell: | diff --git a/roles/sys-cli/tasks/main.yml b/roles/sys-cli/tasks/main.yml index e6f440ac7e..99c27717b8 100644 --- a/roles/sys-cli/tasks/main.yml +++ b/roles/sys-cli/tasks/main.yml @@ -1,6 +1,6 @@ --- - block: - - name: Include dependency 'sys-aur' + - name: ๐Ÿ“‚ Include dependency 'sys-aur' include_role: name: sys-aur when: run_once_sys_aur is not defined @@ -9,7 +9,7 @@ when: run_once_sys_cli is not defined -- name: "pkgmgr install infinito" +- name: "๐Ÿ“ฆ pkgmgr install infinito" include_role: name: pkgmgr-install vars: diff --git a/roles/sys-ctl-alm-compose/tasks/01_core.yml b/roles/sys-ctl-alm-compose/tasks/01_core.yml index 158172e6f3..693bf77fdb 100644 --- a/roles/sys-ctl-alm-compose/tasks/01_core.yml +++ b/roles/sys-ctl-alm-compose/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: "Include dependent services for '{{ system_service_id }}'" +- name: "๐Ÿ“‚ Include dependent services for '{{ system_service_id }}'" include_role: name: "{{ item }}" loop: "{{ SYSTEMCTL_ALARM_COMPOSER_SUBSERVICES }}" @@ -12,7 +12,7 @@ system_service_tpl_on_failure: "" system_service_force_linear_sync: false -- name: "Include core service for '{{ system_service_id }}'" +- name: "๐Ÿ“‚ Include core service for '{{ system_service_id }}'" include_role: name: sys-service vars: @@ -23,9 +23,9 @@ system_service_tpl_on_failure: "" # No on failure needed, because it's anyhow the default on failure procedure system_service_force_linear_sync: false -- name: Assert '{{ system_service_id }}' +- name: โœ… Assert '{{ system_service_id }}' block: - - name: Escape instance name for systemctl call + - name: ๐Ÿ”ค Escape instance name for systemctl call ansible.builtin.command: argv: - systemd-escape @@ -33,7 +33,7 @@ register: escaped_name changed_when: false - - name: Start '{{ system_service_id }}' instance + - name: โ–ถ๏ธ Start '{{ system_service_id }}' instance ansible.builtin.systemd: name: "{{ lookup('unit_name',system_service_id, suffix=False) ~ escaped_name.stdout }}.service" state: started diff --git a/roles/sys-ctl-alm-email/tasks/01_core.yml b/roles/sys-ctl-alm-email/tasks/01_core.yml index 75bdd54b97..ac69fc9f84 100644 --- a/roles/sys-ctl-alm-email/tasks/01_core.yml +++ b/roles/sys-ctl-alm-email/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: Include dependencies +- name: ๐Ÿ“‚ Include dependencies include_role: name: "sys-svc-mail" when: not (run_once_sys_svc_mail | default(false) | bool) diff --git a/roles/sys-ctl-alm-telegram/tasks/01_core.yml b/roles/sys-ctl-alm-telegram/tasks/01_core.yml index 31f6b227e3..859d49d52a 100644 --- a/roles/sys-ctl-alm-telegram/tasks/01_core.yml +++ b/roles/sys-ctl-alm-telegram/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Fail if Telegram bot credentials are not set +- name: ๐Ÿ›‘ Fail if Telegram bot credentials are not set assert: that: - TELEGRAM_BOT_TOKEN != "" @@ -18,7 +18,7 @@ # passing the failing unit's name as the instance text. system_service_tpl_on_failure: "{{ lookup('unit_name','sys-ctl-alm-email@', suffix=False) }}%i.service" -- name: install curl +- name: ๐Ÿ“ฆ install curl package: name: curl state: present diff --git a/roles/sys-ctl-cln-anon-volumes/tasks/01_core.yml b/roles/sys-ctl-cln-anon-volumes/tasks/01_core.yml index 29bcf5de79..e5c9281810 100644 --- a/roles/sys-ctl-cln-anon-volumes/tasks/01_core.yml +++ b/roles/sys-ctl-cln-anon-volumes/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Install '{{ SYS_CTL_CLN_ANON_VOLUMES_COMMAND }}' +- name: ๐Ÿ“ฆ Install '{{ SYS_CTL_CLN_ANON_VOLUMES_COMMAND }}' include_role: name: sys-pip-install vars: diff --git a/roles/sys-ctl-cln-bkps/tasks/01_core.yml b/roles/sys-ctl-cln-bkps/tasks/01_core.yml index 59ac87cc24..c6366fd2b3 100644 --- a/roles/sys-ctl-cln-bkps/tasks/01_core.yml +++ b/roles/sys-ctl-cln-bkps/tasks/01_core.yml @@ -1,17 +1,17 @@ --- -- name: Include dependencies +- name: ๐Ÿ“‚ Include dependencies include_role: name: "{{ item }}" loop: - sys-ctl-alm-compose - sys-lock -- name: install lsof +- name: ๐Ÿ“ฆ install lsof package: name: lsof state: present -- name: install psutil via pip +- name: ๐Ÿ“ฆ install psutil via pip include_role: name: sys-pip-install vars: diff --git a/roles/sys-ctl-cln-certs/tasks/01_core.yml b/roles/sys-ctl-cln-certs/tasks/01_core.yml index 244c5e18bb..79073f4f2e 100644 --- a/roles/sys-ctl-cln-certs/tasks/01_core.yml +++ b/roles/sys-ctl-cln-certs/tasks/01_core.yml @@ -1,12 +1,12 @@ --- -- name: Include dependencies +- name: ๐Ÿ“‚ Include dependencies include_role: name: "{{ item }}" loop: - sys-ctl-alm-compose - sys-daemon -- name: "pkgmgr install" +- name: "๐Ÿ“ฆ pkgmgr install" include_role: name: pkgmgr-install vars: diff --git a/roles/sys-ctl-cln-disc-space/tasks/01_core.yml b/roles/sys-ctl-cln-disc-space/tasks/01_core.yml index 64ea7c240b..23324cb7e8 100644 --- a/roles/sys-ctl-cln-disc-space/tasks/01_core.yml +++ b/roles/sys-ctl-cln-disc-space/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Include dependencies +- name: ๐Ÿ“‚ Include dependencies include_role: name: "{{ item }}" loop: diff --git a/roles/sys-ctl-cln-docker/tasks/main.yml b/roles/sys-ctl-cln-docker/tasks/main.yml index 9a0dc773a1..58ee158eab 100644 --- a/roles/sys-ctl-cln-docker/tasks/main.yml +++ b/roles/sys-ctl-cln-docker/tasks/main.yml @@ -1,13 +1,13 @@ --- - block: - - name: Load role to delete anonymous volumes + - name: ๐Ÿงฉ Load role to delete anonymous volumes include_role: name: sys-ctl-cln-anon-volumes vars: system_service_force_flush_instant: true when: run_once_sys_ctl_cln_anon_volumes is not defined - - name: "Register docker prune system service" + - name: "๐Ÿ“ Register docker prune system service" include_role: name: sys-service vars: diff --git a/roles/sys-ctl-cln-faild-bkps/tasks/01_core.yml b/roles/sys-ctl-cln-faild-bkps/tasks/01_core.yml index 63d7848b5a..469e4f1535 100644 --- a/roles/sys-ctl-cln-faild-bkps/tasks/01_core.yml +++ b/roles/sys-ctl-cln-faild-bkps/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: Include dependencies +- name: ๐Ÿ“‚ Include dependencies include_role: name: "{{ item }}" loop: @@ -10,7 +10,7 @@ - sys-ctl-alm-compose - sys-lock -- name: "Install '{{ CLEANUP_FAILED_BACKUPS_PKG }}' via pip" +- name: "๐Ÿ“ฆ Install '{{ CLEANUP_FAILED_BACKUPS_PKG }}' via pip" include_role: name: sys-pip-install vars: diff --git a/roles/sys-ctl-hlth-btrfs/tasks/01_core.yml b/roles/sys-ctl-hlth-btrfs/tasks/01_core.yml index 3ab7fb54cf..8e27e8a311 100644 --- a/roles/sys-ctl-hlth-btrfs/tasks/01_core.yml +++ b/roles/sys-ctl-hlth-btrfs/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Include dependency 'sys-ctl-alm-compose' +- name: ๐Ÿ“‚ Include dependency 'sys-ctl-alm-compose' include_role: name: sys-ctl-alm-compose when: run_once_sys_ctl_alm_compose is not defined diff --git a/roles/sys-ctl-hlth-container/tasks/01_core.yml b/roles/sys-ctl-hlth-container/tasks/01_core.yml index 7d30f8d6ce..81147ff5ff 100644 --- a/roles/sys-ctl-hlth-container/tasks/01_core.yml +++ b/roles/sys-ctl-hlth-container/tasks/01_core.yml @@ -1,10 +1,10 @@ --- -- name: Include dependency 'sys-ctl-alm-compose' +- name: ๐Ÿ“‚ Include dependency 'sys-ctl-alm-compose' include_role: name: sys-ctl-alm-compose when: run_once_sys_ctl_alm_compose is not defined -- name: Include dependency 'sys-ctl-rpr-container-soft' +- name: ๐Ÿ“‚ Include dependency 'sys-ctl-rpr-container-soft' include_role: name: sys-ctl-rpr-container-soft when: run_once_sys_ctl_rpr_container_soft is not defined diff --git a/roles/sys-ctl-hlth-csp/tasks/01_core.yml b/roles/sys-ctl-hlth-csp/tasks/01_core.yml index d2e659ff2f..dcbf1c9203 100644 --- a/roles/sys-ctl-hlth-csp/tasks/01_core.yml +++ b/roles/sys-ctl-hlth-csp/tasks/01_core.yml @@ -1,17 +1,17 @@ --- -- name: "Load docker service required for the 'run' command" +- name: "๐Ÿงฉ Load docker service required for the 'run' command" include_role: name: sys-svc-container public: false when: run_once_sys_svc_container is not defined -- name: Include dependency 'sys-ctl-alm-compose' +- name: ๐Ÿ“‚ Include dependency 'sys-ctl-alm-compose' include_role: name: sys-ctl-alm-compose when: run_once_sys_ctl_alm_compose is not defined # Ensure the CA exists (docker-run-ca requires CA_TRUST_CERT_HOST to exist) -- name: Ensure Root CA exists +- name: โœ… Ensure Root CA exists ansible.builtin.include_role: name: sys-ca-selfsigned when: @@ -19,7 +19,7 @@ - run_once_sys_ca_selfsigned is not defined # Optional: pre-pull once at deploy time (recommended for reliability) -- name: Pull CSP checker image (with retries) +- name: โฌ‡๏ธ Pull CSP checker image (with retries) ansible.builtin.command: argv: - container diff --git a/roles/sys-ctl-hlth-disc-space/tasks/01_core.yml b/roles/sys-ctl-hlth-disc-space/tasks/01_core.yml index 4e1d342902..4d86a588d2 100644 --- a/roles/sys-ctl-hlth-disc-space/tasks/01_core.yml +++ b/roles/sys-ctl-hlth-disc-space/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Include dependency 'sys-ctl-alm-compose' +- name: ๐Ÿ“‚ Include dependency 'sys-ctl-alm-compose' include_role: name: sys-ctl-alm-compose when: run_once_sys_ctl_alm_compose is not defined diff --git a/roles/sys-ctl-hlth-journalctl/tasks/01_core.yml b/roles/sys-ctl-hlth-journalctl/tasks/01_core.yml index 1603a7c26e..142a0ae248 100644 --- a/roles/sys-ctl-hlth-journalctl/tasks/01_core.yml +++ b/roles/sys-ctl-hlth-journalctl/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Include dependency 'sys-ctl-alm-compose' +- name: ๐Ÿ“‚ Include dependency 'sys-ctl-alm-compose' include_role: name: sys-ctl-alm-compose when: run_once_sys_ctl_alm_compose is not defined diff --git a/roles/sys-ctl-hlth-volumes/tasks/01_core.yml b/roles/sys-ctl-hlth-volumes/tasks/01_core.yml index ca64b0d985..8fe625dd0d 100644 --- a/roles/sys-ctl-hlth-volumes/tasks/01_core.yml +++ b/roles/sys-ctl-hlth-volumes/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Include dependency 'sys-ctl-alm-compose' +- name: ๐Ÿ“‚ Include dependency 'sys-ctl-alm-compose' include_role: name: sys-ctl-alm-compose when: run_once_sys_ctl_alm_compose is not defined diff --git a/roles/sys-ctl-hlth-webserver/tasks/01_core.yml b/roles/sys-ctl-hlth-webserver/tasks/01_core.yml index db6e2a5b03..4e009a188e 100644 --- a/roles/sys-ctl-hlth-webserver/tasks/01_core.yml +++ b/roles/sys-ctl-hlth-webserver/tasks/01_core.yml @@ -1,10 +1,10 @@ --- -- name: Include dependencies +- name: ๐Ÿ“‚ Include dependencies include_role: name: sys-ctl-alm-compose when: run_once_sys_ctl_alm_compose is not defined -- name: Install requests via pip +- name: ๐Ÿ“ฆ Install requests via pip include_role: name: sys-pip-install vars: @@ -12,14 +12,14 @@ package_state: present global_install: true -- name: Ensure Root CA exists for self-signed TLS +- name: โœ… Ensure Root CA exists for self-signed TLS include_role: name: sys-ca-selfsigned when: - (TLS_MODE | lower) == 'self_signed' - run_once_sys_ca_selfsigned is not defined -- name: "Flush webserver handlers" +- name: "๐Ÿšฟ Flush webserver handlers" meta: flush_handlers - include_role: diff --git a/roles/sys-ctl-mtn-cert-deploy/tasks/01_core.yml b/roles/sys-ctl-mtn-cert-deploy/tasks/01_core.yml index caba089b68..d305a29fa0 100644 --- a/roles/sys-ctl-mtn-cert-deploy/tasks/01_core.yml +++ b/roles/sys-ctl-mtn-cert-deploy/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: "Ensure cert deploy target directory exists" +- name: "โœ… Ensure cert deploy target directory exists" file: path: "{{ lookup('container', application_id, 'directories.volumes') }}certs" state: directory @@ -22,7 +22,7 @@ --chdir {{ lookup('container', application_id, 'directories.instance') }} --project {{ (lookup('container', application_id, 'directories.instance') | regex_replace('/+$', '')) | basename }} -- name: Include dependency 'sys-ctl-alm-compose' +- name: ๐Ÿ“‚ Include dependency 'sys-ctl-alm-compose' include_role: name: sys-ctl-alm-compose when: run_once_sys_ctl_alm_compose is not defined diff --git a/roles/sys-ctl-mtn-cert-renew/tasks/01_core.yml b/roles/sys-ctl-mtn-cert-renew/tasks/01_core.yml index d674bf834d..93e93bb37e 100644 --- a/roles/sys-ctl-mtn-cert-renew/tasks/01_core.yml +++ b/roles/sys-ctl-mtn-cert-renew/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Include dependencies +- name: ๐Ÿ“‚ Include dependencies include_role: name: "{{ item }}" loop: @@ -7,7 +7,7 @@ - sys-svc-webserver-core - sys-ctl-alm-compose -- name: install certbot +- name: ๐Ÿ“ฆ install certbot package: name: - certbot-nginx diff --git a/roles/sys-ctl-rpr-btrfs-balancer/tasks/01_core.yml b/roles/sys-ctl-rpr-btrfs-balancer/tasks/01_core.yml index b930415672..e2b0d879b5 100644 --- a/roles/sys-ctl-rpr-btrfs-balancer/tasks/01_core.yml +++ b/roles/sys-ctl-rpr-btrfs-balancer/tasks/01_core.yml @@ -1,10 +1,10 @@ --- -- name: Include dependency 'sys-ctl-alm-compose' +- name: ๐Ÿ“‚ Include dependency 'sys-ctl-alm-compose' include_role: name: sys-ctl-alm-compose when: run_once_sys_ctl_alm_compose is not defined -- name: "pkgmgr install" +- name: "๐Ÿ“ฆ pkgmgr install" include_role: name: pkgmgr-install vars: diff --git a/roles/sys-ctl-rpr-container-hard/tasks/01_core.yml b/roles/sys-ctl-rpr-container-hard/tasks/01_core.yml index 6fdbfcc07c..959b8f9a09 100644 --- a/roles/sys-ctl-rpr-container-hard/tasks/01_core.yml +++ b/roles/sys-ctl-rpr-container-hard/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Include dependency 'sys-lock' +- name: ๐Ÿ“‚ Include dependency 'sys-lock' include_role: name: sys-lock when: run_once_sys_lock is not defined diff --git a/roles/sys-ctl-rpr-container-soft/tasks/01_core.yml b/roles/sys-ctl-rpr-container-soft/tasks/01_core.yml index e6ab0d6d7d..c53af45d84 100644 --- a/roles/sys-ctl-rpr-container-soft/tasks/01_core.yml +++ b/roles/sys-ctl-rpr-container-soft/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Include dependency 'sys-lock' +- name: ๐Ÿ“‚ Include dependency 'sys-lock' include_role: name: sys-lock when: run_once_sys_lock is not defined diff --git a/roles/sys-daemon/tasks/01_core.yml b/roles/sys-daemon/tasks/01_core.yml index 84ab778570..1c4c809837 100644 --- a/roles/sys-daemon/tasks/01_core.yml +++ b/roles/sys-daemon/tasks/01_core.yml @@ -1,15 +1,15 @@ --- -- name: Install systemd tools (provides systemd-analyze) +- name: ๐Ÿ“ฆ Install systemd tools (provides systemd-analyze) ansible.builtin.package: name: "systemd" state: present become: true -- name: "reset (if enabled) for {{ role_name}}" +- name: "โ™ป๏ธ reset (if enabled) for {{ role_name}}" include_tasks: 02_reset.yml when: MODE_RESET | bool and run_once_sys_daemon is not defined -- name: Apply systemd manager defaults +- name: ๐Ÿ“Œ Apply systemd manager defaults include_tasks: 03_defaults.yml - include_tasks: utils/once/flag.yml diff --git a/roles/sys-daemon/tasks/02_reset.yml b/roles/sys-daemon/tasks/02_reset.yml index 0691786aec..46cbf911c1 100644 --- a/roles/sys-daemon/tasks/02_reset.yml +++ b/roles/sys-daemon/tasks/02_reset.yml @@ -1,9 +1,9 @@ --- -- name: reload system daemon +- name: ๐Ÿ”„ reload system daemon command: /bin/true notify: "reload system daemon" -- name: "Sanity check SYSTEMD_MANAGER_CONF_DIR" +- name: "โœ… Sanity check SYSTEMD_MANAGER_CONF_DIR" assert: that: - SYSTEMD_MANAGER_CONF_DIR | regex_search('^/etc/systemd/system\.conf\.d/?$') @@ -12,7 +12,7 @@ - MODE_RESET | bool - MODE_ASSERT | bool -- name: "Purge manager drop-in directory (remove)" +- name: "๐Ÿงน Purge manager drop-in directory (remove)" file: path: "{{ SYSTEMD_MANAGER_CONF_DIR }}" state: absent diff --git a/roles/sys-daemon/tasks/03_defaults.yml b/roles/sys-daemon/tasks/03_defaults.yml index 6a7b40894c..f6522fee3f 100644 --- a/roles/sys-daemon/tasks/03_defaults.yml +++ b/roles/sys-daemon/tasks/03_defaults.yml @@ -1,11 +1,11 @@ --- -- name: "Ensure {{ SYSTEMD_MANAGER_CONF_DIR }} exists" +- name: "โœ… Ensure {{ SYSTEMD_MANAGER_CONF_DIR }} exists" file: path: "{{ SYSTEMD_MANAGER_CONF_DIR }}" state: directory mode: "0755" -- name: Deploy systemd manager default timeout settings +- name: ๐Ÿš€ Deploy systemd manager default timeout settings template: # nocheck: stack-host-template (per-host systemd config, not stack-host-only) src: timeouts.conf.j2 dest: "{{ SYSTEMD_MANAGER_CONF_DIR }}/timeouts.conf" diff --git a/roles/sys-dns-cloudflare-records/tasks/main.yml b/roles/sys-dns-cloudflare-records/tasks/main.yml index b84f34930f..9bea664844 100644 --- a/roles/sys-dns-cloudflare-records/tasks/main.yml +++ b/roles/sys-dns-cloudflare-records/tasks/main.yml @@ -1,13 +1,13 @@ --- # nocheck: run-once -- name: Assert token +- name: โœ… Assert token ansible.builtin.assert: that: ["lookup('api', 'cloudflare.api_token') | length > 0"] no_log: "{{ cloudflare_no_log | bool }}" when: MODE_ASSERT | bool -- name: Apply A/AAAA +- name: ๐Ÿ“Œ Apply A/AAAA community.general.cloudflare_dns: api_token: "{{ lookup('api', 'cloudflare.api_token') }}" zone: "{{ item.zone }}" @@ -39,7 +39,7 @@ ('81058' not in (_cf_call.msg | default('') | string)) ) -- name: Apply CNAME/MX/TXT +- name: ๐Ÿ“Œ Apply CNAME/MX/TXT community.general.cloudflare_dns: api_token: "{{ lookup('api', 'cloudflare.api_token') }}" zone: "{{ item.zone }}" @@ -71,7 +71,7 @@ ('81058' not in (_cf_call.msg | default('') | string)) ) -- name: Apply SRV +- name: ๐Ÿ“Œ Apply SRV community.general.cloudflare_dns: api_token: "{{ lookup('api', 'cloudflare.api_token') }}" zone: "{{ item.zone }}" diff --git a/roles/sys-dns-hetzner-rdns/tasks/flavors/cloud.yml b/roles/sys-dns-hetzner-rdns/tasks/flavors/cloud.yml index 8dfb20c11c..a98d4f179a 100644 --- a/roles/sys-dns-hetzner-rdns/tasks/flavors/cloud.yml +++ b/roles/sys-dns-hetzner-rdns/tasks/flavors/cloud.yml @@ -1,6 +1,6 @@ --- # Cloud flavor (hcloud API) -- name: Resolve effective hcloud token +- name: ๐Ÿ” Resolve effective hcloud token set_fact: _hz_token: >- {{ HETZNER_API_TOKEN @@ -9,25 +9,25 @@ }} no_log: "{{ hetzner_no_log | bool }}" -- name: Assert hcloud token present +- name: โœ… Assert hcloud token present ansible.builtin.assert: that: ["_hz_token | length > 0"] fail_msg: "HETZNER_API_TOKEN is required for the Cloud flavor." no_log: "{{ hetzner_no_log | bool }}" when: MODE_ASSERT | bool -- name: Collect hcloud servers if needed (server records without identifier) +- name: ๐Ÿ“Š Collect hcloud servers if needed (server records without identifier) hetzner.hcloud.server_info: api_token: "{{ _hz_token }}" register: _servers_info when: rdns_records | selectattr('resource','equalto','server') | selectattr('identifier','undefined') | list | length > 0 no_log: "{{ hetzner_no_log | bool }}" -- name: Init normalized records list +- name: ๐ŸŽฌ Init normalized records list set_fact: _rdns_records: [] -- name: Normalize records (autofill server.identifier by IPv4) +- name: ๐Ÿ“ Normalize records (autofill server.identifier by IPv4) vars: _match_name: >- {{ @@ -51,7 +51,7 @@ loop: "{{ rdns_records }}" loop_control: { loop_var: rec } -- name: Ensure server identifiers are resolved when required +- name: โœ… Ensure server identifiers are resolved when required assert: that: - > @@ -64,7 +64,7 @@ no_log: "{{ hetzner_no_log | bool }}" when: MODE_ASSERT | bool -- name: Validate records (cloud) +- name: โœ… Validate records (cloud) ansible.builtin.assert: that: - (_rdns_records | default(rdns_records)) | length > 0 @@ -77,7 +77,7 @@ no_log: "{{ hetzner_no_log | bool }}" when: MODE_ASSERT | bool -- name: Apply rDNS via hcloud +- name: ๐Ÿ“Œ Apply rDNS via hcloud hetzner.hcloud.hcloud_rdns: api_token: "{{ _hz_token }}" server: "{{ (item.resource == 'server') | ternary(item.identifier, omit) }}" diff --git a/roles/sys-dns-hetzner-rdns/tasks/flavors/robot.yml b/roles/sys-dns-hetzner-rdns/tasks/flavors/robot.yml index f99945c1e1..c620a6a6cf 100644 --- a/roles/sys-dns-hetzner-rdns/tasks/flavors/robot.yml +++ b/roles/sys-dns-hetzner-rdns/tasks/flavors/robot.yml @@ -1,6 +1,6 @@ --- # Robot flavor (Robot Webservice API) -- name: Assert Robot credentials present +- name: โœ… Assert Robot credentials present ansible.builtin.assert: that: - (HETZNER_ROBOT_USER | default('') | length) > 0 @@ -8,7 +8,7 @@ fail_msg: "Robot credentials required: HETZNER_ROBOT_USER / HETZNER_ROBOT_PASSWORD." when: MODE_ASSERT | bool -- name: Validate records (robot) +- name: โœ… Validate records (robot) ansible.builtin.assert: that: - rdns_records | length > 0 @@ -17,7 +17,7 @@ fail_msg: "Each record must have ip_address and dns_ptr for Robot rDNS." when: MODE_ASSERT | bool -- name: Apply rDNS via Hetzner Robot API +- name: ๐Ÿ“Œ Apply rDNS via Hetzner Robot API vars: hetzner_robot_base_url: "{{ HETZNER_ROBOT_BASE_URL }}" ip_path: "{{ item.ip_address | urlencode }}" diff --git a/roles/sys-dns-hetzner-rdns/tasks/main.yml b/roles/sys-dns-hetzner-rdns/tasks/main.yml index ed97c9ac3f..2eb75959a9 100644 --- a/roles/sys-dns-hetzner-rdns/tasks/main.yml +++ b/roles/sys-dns-hetzner-rdns/tasks/main.yml @@ -2,7 +2,7 @@ # run_once_sys_dns_hetzner_rdns # Decide flavor -- name: Decide which Hetzner flavor to use +- name: ๐Ÿค” Decide which Hetzner flavor to use set_fact: _use_cloud: "{{ (HETZNER_API_TOKEN | length) > 0 }}" _use_robot: >- @@ -12,23 +12,23 @@ }} no_log: "{{ hetzner_no_log | bool }}" -- name: "Note: both Cloud token and Robot creds provided; using Cloud flavor" +- name: "๐Ÿ”‘ Note: both Cloud token and Robot creds provided; using Cloud flavor" debug: msg: "Both HETZNER_API_TOKEN and Robot credentials present โ†’ proceeding with Cloud (hcloud) flavor." when: _use_cloud | bool and _use_robot | bool -- name: Include Cloud flavor (hcloud) +- name: ๐Ÿ“‚ Include Cloud flavor (hcloud) include_tasks: flavors/cloud.yml when: _use_cloud | bool -- name: Include Robot flavor (Robot Webservice) +- name: ๐Ÿ“‚ Include Robot flavor (Robot Webservice) ansible.builtin.include_tasks: file: flavors/robot.yml apply: no_log: "{{ hetzner_no_log | bool }}" when: (not _use_cloud) and _use_robot -- name: Fail if no credentials provided +- name: ๐Ÿ›‘ Fail if no credentials provided fail: msg: >- Neither Cloud nor Robot credentials provided. diff --git a/roles/sys-dns-wildcards/tasks/01_core.yml b/roles/sys-dns-wildcards/tasks/01_core.yml index 675ff2b047..68fc11172d 100644 --- a/roles/sys-dns-wildcards/tasks/01_core.yml +++ b/roles/sys-dns-wildcards/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: "Apply Cloudflare DNS for parent domains" +- name: "๐Ÿ“Œ Apply Cloudflare DNS for parent domains" include_role: name: sys-dns-cloudflare-records vars: diff --git a/roles/sys-front-inj-all/tasks/main.yml b/roles/sys-front-inj-all/tasks/main.yml index 29124066ac..82ee9eedbd 100644 --- a/roles/sys-front-inj-all/tasks/main.yml +++ b/roles/sys-front-inj-all/tasks/main.yml @@ -1,49 +1,49 @@ --- # nocheck: run-once โ€” per-application role: every invocation must (re)apply CDN dirs, inj-*, body_filter.lua for the current `application_id`. -- name: Include dependency 'sys-svc-webserver-core' +- name: ๐Ÿ“‚ Include dependency 'sys-svc-webserver-core' include_role: name: sys-svc-webserver-core vars: compose_repository_pull: false # Deactivated here to don't inhire this -- name: "Setup CDN directories for '{{ domain }}'" +- name: "๐Ÿ”ง Setup CDN directories for '{{ domain }}'" include_role: name: sys-svc-cdn -- name: Build injection facts for '{{ domain }}' +- name: ๐Ÿ”จ Build injection facts for '{{ domain }}' set_fact: inj_enabled: "{{ lookup('applications') | inj_enabled(application_id, SRV_WEB_INJ_COMP_FEATURES_ALL) }}" inj_head_features: "{{ SRV_WEB_INJ_COMP_FEATURES_ALL | inj_features('head') }}" inj_body_features: "{{ SRV_WEB_INJ_COMP_FEATURES_ALL | inj_features('body') }}" -- name: "Activate logout proxy for '{{ domain }}'" +- name: "๐ŸŸข Activate logout proxy for '{{ domain }}'" include_role: name: sys-front-inj-logout public: true when: inj_enabled.logout -- name: "Activate Dashboard iFrame notifier for '{{ domain }}'" +- name: "๐ŸŸข Activate Dashboard iFrame notifier for '{{ domain }}'" include_role: name: sys-front-inj-dashboard public: true when: inj_enabled.dashboard -- name: "Activate Corporate CSS for '{{ domain }}'" +- name: "๐ŸŸข Activate Corporate CSS for '{{ domain }}'" include_role: name: sys-front-inj-css when: inj_enabled.css -- name: "Activate Matomo Tracking for '{{ domain }}'" +- name: "๐ŸŸข Activate Matomo Tracking for '{{ domain }}'" include_role: name: sys-front-inj-matomo when: inj_enabled.matomo -- name: "Activate Javascript for '{{ domain }}'" +- name: "๐ŸŸข Activate Javascript for '{{ domain }}'" include_role: name: sys-front-inj-javascript when: inj_enabled.javascript -- name: "Render body_filter Lua for '{{ application_id }}'" +- name: "๐Ÿ“„ Render body_filter Lua for '{{ application_id }}'" stack_host_template: src: body_filter.lua.j2 dest: "{{ lookup('nginx', 'directories.configuration.lua') }}{{ application_id }}.lua" diff --git a/roles/sys-front-inj-css/tasks/01_core.yml b/roles/sys-front-inj-css/tasks/01_core.yml index e04a38742c..4020f2b88c 100644 --- a/roles/sys-front-inj-css/tasks/01_core.yml +++ b/roles/sys-front-inj-css/tasks/01_core.yml @@ -1,13 +1,13 @@ --- -- name: Generate color palette with colorscheme-generator +- name: โš™๏ธ Generate color palette with colorscheme-generator set_fact: CSS_COLOR_PALETTE: "{{ lookup('colorscheme', CSS_BASE_COLOR, count=CSS_COUNT, shades=CSS_SHADES) }}" -- name: Generate inverted color palette with colorscheme-generator +- name: โš™๏ธ Generate inverted color palette with colorscheme-generator set_fact: CSS_COLOR_PALETTE_INVERTED: "{{ lookup('colorscheme', CSS_BASE_COLOR, count=CSS_COUNT, shades=CSS_SHADES, invert_lightness=True) }}" -- name: "Compute deterministic gradient angle from default.css template mtime" +- name: "๐Ÿงฎ Compute deterministic gradient angle from default.css template mtime" set_fact: CSS_GRADIENT_ANGLE: >- {{ @@ -21,7 +21,7 @@ ) % 360 }} -- name: Deploy default CSS files +- name: ๐Ÿš€ Deploy default CSS files stack_host_template: src: "{{ ['css', css_file ~ '.j2'] | path_join }}" dest: "{{ [lookup('cdn', 'web-svc-cdn').shared.css, css_file] | path_join }}" diff --git a/roles/sys-front-inj-css/tasks/main.yml b/roles/sys-front-inj-css/tasks/main.yml index 05211d0cd9..01dc62e902 100644 --- a/roles/sys-front-inj-css/tasks/main.yml +++ b/roles/sys-front-inj-css/tasks/main.yml @@ -2,7 +2,7 @@ - include_tasks: 01_core.yml when: run_once_sys_front_inj_css is not defined -- name: "Resolve optional app style.css source for '{{ application_id }}'" +- name: "๐Ÿ” Resolve optional app style.css source for '{{ application_id }}'" vars: app_role_dir: "{{ playbook_dir }}/roles/{{ application_id }}" _app_style_src: >- @@ -14,7 +14,7 @@ app_style_src: "{{ _app_style_src }}" app_style_present: "{{ _app_style_src | length > 0 }}" -- name: "Deploy per-app '{{ app_style_src }}' to '{{ css_app_dst }}'" +- name: "๐Ÿš€ Deploy per-app '{{ app_style_src }}' to '{{ css_app_dst }}'" when: app_style_present | bool copy: content: "{{ lookup('template', app_style_src) }}" diff --git a/roles/sys-front-inj-dashboard/tasks/01_core.yml b/roles/sys-front-inj-dashboard/tasks/01_core.yml index 1aa7e7b4a1..72fa722e89 100644 --- a/roles/sys-front-inj-dashboard/tasks/01_core.yml +++ b/roles/sys-front-inj-dashboard/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Deploy {{ INJ_DASHBOARD_JS_FILE_NAME }} +- name: ๐Ÿš€ Deploy {{ INJ_DASHBOARD_JS_FILE_NAME }} stack_host_template: src: "{{ INJ_DASHBOARD_JS_FILE_NAME }}.j2" dest: "{{ INJ_DASHBOARD_JS_FILE_DESTINATION }}" diff --git a/roles/sys-front-inj-dashboard/tasks/main.yml b/roles/sys-front-inj-dashboard/tasks/main.yml index 0711beab73..c57c8a3ed9 100644 --- a/roles/sys-front-inj-dashboard/tasks/main.yml +++ b/roles/sys-front-inj-dashboard/tasks/main.yml @@ -3,15 +3,15 @@ when: run_once_sys_front_inj_dashboard is not defined # --- Build tiny inline initializer (CSP-hashed) --- -- name: "Load iFrame init code for '{{ application_id }}'" +- name: "๐Ÿ“„ Load iFrame init code for '{{ application_id }}'" set_fact: iframe_init_code: "{{ lookup('template','iframe-init_one_liner.js.j2') }}" -- name: "Collapse iFrame init code into one-liner for '{{ application_id }}'" +- name: "๐Ÿ—œ๏ธ Collapse iFrame init code into one-liner for '{{ application_id }}'" set_fact: iframe_init_code_one_liner: "{{ iframe_init_code | to_one_liner }}" -- name: "Append iFrame init CSP hash for '{{ application_id }}'" +- name: "โž• Append iFrame init CSP hash for '{{ application_id }}'" set_fact: webserver_csp_hashes_extra_by_app: >- {{ webserver_csp_hashes_extra_by_app | default({}) diff --git a/roles/sys-front-inj-javascript/tasks/main.yml b/roles/sys-front-inj-javascript/tasks/main.yml index 639ada8565..4647279bc2 100644 --- a/roles/sys-front-inj-javascript/tasks/main.yml +++ b/roles/sys-front-inj-javascript/tasks/main.yml @@ -1,14 +1,14 @@ --- # nocheck: run-once -- name: "Select JavaScript file path for '{{ application_id }}'" +- name: "๐ŸŽฏ Select JavaScript file path for '{{ application_id }}'" set_fact: javascript_file_custom: >- {{ (application_id | abs_role_path_by_application_id ~ '/templates/javascript.js.j2') if lookup('fileglob', application_id | abs_role_path_by_application_id ~ '/templates/javascript.js.j2') else application_id | abs_role_path_by_application_id ~ '/files/javascript.js' }} -- name: "Load JavaScript code for '{{ application_id }}'" +- name: "๐Ÿ“„ Load JavaScript code for '{{ application_id }}'" set_fact: javascript_code: >- {{ lookup( @@ -16,11 +16,11 @@ javascript_file_custom ) }} -- name: "Collapse Javascript code into one-liner for '{{ application_id }}'" +- name: "๐Ÿ—œ๏ธ Collapse Javascript code into one-liner for '{{ application_id }}'" set_fact: javascript_code_one_liner: "{{ javascript_code | to_one_liner }}" -- name: "Append Javascript CSP hash for '{{ application_id }}'" +- name: "โž• Append Javascript CSP hash for '{{ application_id }}'" set_fact: webserver_csp_hashes_extra_by_app: >- {{ webserver_csp_hashes_extra_by_app | default({}) diff --git a/roles/sys-front-inj-logout/tasks/01_core.yml b/roles/sys-front-inj-logout/tasks/01_core.yml index 8e0367a24c..9ab211a8fb 100644 --- a/roles/sys-front-inj-logout/tasks/01_core.yml +++ b/roles/sys-front-inj-logout/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: "deploy the logout.js" +- name: "๐Ÿš€ deploy the logout.js" include_tasks: "02_deploy.yml" - set_fact: diff --git a/roles/sys-front-inj-logout/tasks/02_deploy.yml b/roles/sys-front-inj-logout/tasks/02_deploy.yml index e8390b3ef6..39a8e06d00 100644 --- a/roles/sys-front-inj-logout/tasks/02_deploy.yml +++ b/roles/sys-front-inj-logout/tasks/02_deploy.yml @@ -1,15 +1,15 @@ --- -- name: Deploy logout.js +- name: ๐Ÿš€ Deploy logout.js copy: src: logout.js dest: "{{ INJ_LOGOUT_JS_DESTINATION }}" mode: "0644" -- name: Get stat for logout.js +- name: โฌ‡๏ธ Get stat for logout.js stat: path: "{{ INJ_LOGOUT_JS_DESTINATION }}" register: INJ_LOGOUT_JS_STAT -- name: Set INJ_LOGOUT_JS_VERSION +- name: ๐Ÿ”ง Set INJ_LOGOUT_JS_VERSION set_fact: INJ_LOGOUT_JS_VERSION: "{{ INJ_LOGOUT_JS_STAT.stat.mtime }}" diff --git a/roles/sys-front-inj-logout/tasks/main.yml b/roles/sys-front-inj-logout/tasks/main.yml index 5a3badec9f..32a467c52b 100644 --- a/roles/sys-front-inj-logout/tasks/main.yml +++ b/roles/sys-front-inj-logout/tasks/main.yml @@ -1,19 +1,19 @@ --- -- name: "Load base for '{{ application_id }}'" +- name: "๐Ÿงฉ Load base for '{{ application_id }}'" include_tasks: 01_core.yml when: run_once_sys_front_inj_logout is not defined -- name: "Load logout code for '{{ application_id }}'" +- name: "๐Ÿ“„ Load logout code for '{{ application_id }}'" set_fact: logout_code: "{{ lookup('template', 'logout_one_liner.js.j2') }}" changed_when: false -- name: "Collapse logout code into one-liner for '{{ application_id }}'" +- name: "๐Ÿ—œ๏ธ Collapse logout code into one-liner for '{{ application_id }}'" set_fact: logout_code_one_liner: "{{ logout_code | to_one_liner }}" changed_when: false -- name: "Append logout CSP hash for '{{ application_id }}'" +- name: "โž• Append logout CSP hash for '{{ application_id }}'" set_fact: webserver_csp_hashes_extra_by_app: >- {{ webserver_csp_hashes_extra_by_app | default({}) diff --git a/roles/sys-front-inj-matomo/tasks/inject.yml b/roles/sys-front-inj-matomo/tasks/inject.yml index 9ae0686c32..5b9d6ed511 100644 --- a/roles/sys-front-inj-matomo/tasks/inject.yml +++ b/roles/sys-front-inj-matomo/tasks/inject.yml @@ -1,5 +1,5 @@ --- -- name: "Check if site {{ domain }} is already registered at Matomo" +- name: "๐Ÿ”Ž Check if site {{ domain }} is already registered at Matomo" uri_retry: url: "{{ matomo_index_php_url }}?module=API&method=SitesManager.getSitesIdFromSiteUrl&url={{ lookup('tls', application_id, 'protocols.web') }}://{{ base_domain }}&format=json&token_auth={{ lookup('users', 'administrator').tokens['web-app-matomo'] }}" @@ -11,11 +11,11 @@ failed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Disable Matomo tracking for '{{ domain }}' (Matomo API not ready yet, reapplied on a later pass)" +- name: "๐Ÿ”ด Disable Matomo tracking for '{{ domain }}' (API not ready, reapplied later)" ansible.builtin.set_fact: inj_enabled: "{{ inj_enabled | combine({'matomo': false}) }}" when: site_check.status is not defined or site_check.status != 200 or site_check.json is not defined -- name: "Register site + inject Matomo tracking for '{{ domain }}'" +- name: "๐Ÿ“ Register site + inject Matomo tracking for '{{ domain }}'" ansible.builtin.include_tasks: inject_apply.yml when: site_check.status is defined and site_check.status == 200 and site_check.json is defined diff --git a/roles/sys-front-inj-matomo/tasks/inject_apply.yml b/roles/sys-front-inj-matomo/tasks/inject_apply.yml index 3ef944a9df..671efc3969 100644 --- a/roles/sys-front-inj-matomo/tasks/inject_apply.yml +++ b/roles/sys-front-inj-matomo/tasks/inject_apply.yml @@ -1,15 +1,15 @@ --- -- name: Set matomo_site_id to Null +- name: ๐Ÿ”ง Set matomo_site_id to Null set_fact: matomo_site_id: -- name: Set fact for site ID if site already exists +- name: ๐Ÿ”ง Set fact for site ID if site already exists set_fact: matomo_site_id: "{{ site_check.json[0].idsite }}" when: "(site_check.json | length) > 0" changed_when: false -- name: Add site to Matomo and get ID if not exists +- name: โž• Add site to Matomo and get ID if not exists uri_retry: url: "{{ matomo_index_php_url }}" method: POST @@ -23,21 +23,21 @@ when: "matomo_site_id is not defined or matomo_site_id is none" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Set fact for site ID if site was added +- name: ๐Ÿ”ง Set fact for site ID if site was added set_fact: matomo_site_id: "{{ add_site.json.value }}" when: "matomo_site_id is not defined or matomo_site_id is none" changed_when: false -- name: Load Matomo tracking JS template +- name: ๐Ÿ“„ Load Matomo tracking JS template set_fact: matomo_tracking_code: "{{ lookup('template','matomo-tracking.js.j2') }}" -- name: Collapse Matomo code into one-liner +- name: ๐Ÿ—œ๏ธ Collapse Matomo code into one-liner set_fact: matomo_tracking_code_one_liner: "{{ matomo_tracking_code | to_one_liner }}" -- name: Append Matomo CSP hash +- name: โž• Append Matomo CSP hash set_fact: webserver_csp_hashes_extra_by_app: >- {{ webserver_csp_hashes_extra_by_app | default({}) diff --git a/roles/sys-front-inj-matomo/tasks/main.yml b/roles/sys-front-inj-matomo/tasks/main.yml index ea8e842412..d5c98b2386 100644 --- a/roles/sys-front-inj-matomo/tasks/main.yml +++ b/roles/sys-front-inj-matomo/tasks/main.yml @@ -7,11 +7,11 @@ # the Matomo body snippet (avoiding 'matomo_site_id is undefined') and inject.yml is not run. # See docs/contributing/design/exceptions.md โ€” "Matomo Token Not Yet Available". -- name: "Disable Matomo in inj_enabled for '{{ domain }}' โ€” token not yet available" +- name: "๐Ÿ”ด Disable Matomo in inj_enabled for '{{ domain }}' โ€” token not yet available" ansible.builtin.set_fact: inj_enabled: "{{ inj_enabled | combine({'matomo': false}) }}" when: (lookup('users', 'administrator').tokens['web-app-matomo'] | default('') | string | trim) == "" -- name: "Inject Matomo tracking for '{{ domain }}'" +- name: "๐Ÿ’‰ Inject Matomo tracking for '{{ domain }}'" include_tasks: inject.yml when: inj_enabled.matomo | bool diff --git a/roles/sys-front-tls-letsencrypt/tasks/main.yml b/roles/sys-front-tls-letsencrypt/tasks/main.yml index 646a531656..a4efef527c 100644 --- a/roles/sys-front-tls-letsencrypt/tasks/main.yml +++ b/roles/sys-front-tls-letsencrypt/tasks/main.yml @@ -1,14 +1,14 @@ --- # nocheck: run-once -- name: "Disable self-signed environment" +- name: "๐Ÿ”ด Disable self-signed environment" include_tasks: "{{ [playbook_dir, 'roles/sys-ca-selfsigned/tasks/disable_env.yml' ] | path_join }}" -- name: "TLS | (letsencrypt) resolve via tls (strict)" +- name: "๐Ÿ” TLS | (letsencrypt) resolve via tls (strict)" ansible.builtin.set_fact: _tls: "{{ lookup('tls', application_id) }}" changed_when: false -- name: "TLS | (letsencrypt) assert mode is letsencrypt" +- name: "โœ… TLS | (letsencrypt) assert mode is letsencrypt" ansible.builtin.assert: that: - _tls.enabled | bool @@ -18,7 +18,7 @@ but resolver returned enabled={{ _tls.enabled }}, mode={{ _tls.mode }}. changed_when: false -- name: "TLS | (letsencrypt) check cert files exist" +- name: "๐Ÿ”Ž TLS | (letsencrypt) check cert files exist" ansible.builtin.stat: path: "{{ item }}" register: _le_stat @@ -27,7 +27,7 @@ - "{{ _tls.files.key }}" changed_when: false -- name: "TLS | (letsencrypt) issue cert if missing" +- name: "๐Ÿ“œ TLS | (letsencrypt) issue cert if missing" ansible.builtin.include_role: name: sys-svc-certs vars: @@ -36,7 +36,7 @@ (not _le_stat.results[0].stat.exists | default(false)) or (not _le_stat.results[1].stat.exists | default(false)) -- name: "TLS | (letsencrypt) re-check cert files exist" +- name: "๐Ÿ”Ž TLS | (letsencrypt) re-check cert files exist" ansible.builtin.stat: path: "{{ item }}" register: _le_stat2 @@ -45,7 +45,7 @@ - "{{ _tls.files.key }}" changed_when: false -- name: "TLS | (letsencrypt) fail if still missing" +- name: "๐Ÿ›‘ TLS | (letsencrypt) fail if still missing" ansible.builtin.fail: msg: >- Let's Encrypt certificate files not found after issuance: diff --git a/roles/sys-front-tls-selfsigned/tasks/01_core.yml b/roles/sys-front-tls-selfsigned/tasks/01_core.yml index 2b24056611..2a187b5be1 100644 --- a/roles/sys-front-tls-selfsigned/tasks/01_core.yml +++ b/roles/sys-front-tls-selfsigned/tasks/01_core.yml @@ -9,22 +9,22 @@ # - Instead, we create a local Root CA (sys-ca-selfsigned) and sign the leaf certificate with it. # - The resulting chain is: leaf (app/global) signed by Root CA, and Root CA is installed into trust stores. -- name: "TLS | (self_signed) ensure local Root CA exists (for signing leaf certs)" +- name: "โœ… TLS | (self_signed) ensure local Root CA exists (for signing leaf certs)" ansible.builtin.include_role: name: sys-ca-selfsigned when: run_once_sys_ca_selfsigned is not defined -- name: "TLS | (self_signed) resolve via tls (strict)" +- name: "๐Ÿ” TLS | (self_signed) resolve via tls (strict)" ansible.builtin.set_fact: _tls: "{{ lookup('tls', application_id) }}" changed_when: false -- name: "TLS | (self_signed) plan certificate via cert (strict)" +- name: "๐Ÿ“œ TLS | (self_signed) plan certificate via cert (strict)" ansible.builtin.set_fact: _cert: "{{ lookup('cert', application_id) }}" changed_when: false -- name: "TLS | (self_signed) assert mode is self_signed" +- name: "โœ… TLS | (self_signed) assert mode is self_signed" ansible.builtin.assert: that: - _tls.mode == 'self_signed' @@ -36,7 +36,7 @@ tls.enabled={{ _tls.enabled }}, tls.mode={{ _tls.mode }}, cert.enabled={{ _cert.enabled }}, cert.mode={{ _cert.mode }}. Expected enabled=true, mode=self_signed. -- name: "TLS | (self_signed) compute target paths" +- name: "๐Ÿงฎ TLS | (self_signed) compute target paths" ansible.builtin.set_fact: _ss_domain: "{{ _tls.domains.primary }}" _ss_san: "{{ _cert.domains.san }}" @@ -56,14 +56,14 @@ }} changed_when: false -- name: "TLS | (self_signed) ensure directory exists" +- name: "โœ… TLS | (self_signed) ensure directory exists" become: true ansible.builtin.file: path: "{{ _ss_dir }}" state: directory mode: "0750" -- name: "TLS | (self_signed) render openssl config (SAN aware)" +- name: "๐Ÿ“„ TLS | (self_signed) render openssl config (SAN aware)" become: true ansible.builtin.copy: dest: "{{ _ss_conf }}" @@ -90,20 +90,20 @@ DNS.{{ loop.index }} = {{ d }} {% endfor %} -- name: "TLS | (self_signed) check if cert already exists" +- name: "๐Ÿ”Ž TLS | (self_signed) check if cert already exists" ansible.builtin.stat: path: "{{ _ss_cert }}" register: _ss_cert_stat changed_when: false -- name: "TLS | (self_signed) read existing certificate (if any)" +- name: "๐Ÿ“– TLS | (self_signed) read existing certificate (if any)" ansible.builtin.command: "openssl x509 -in {{ _ss_cert }} -noout -text" register: _ss_cert_text changed_when: false failed_when: false when: _ss_cert_stat.stat.exists | default(false) -- name: "TLS | (self_signed) compute wanted/existing SAN sets" +- name: "๐Ÿงฎ TLS | (self_signed) compute wanted/existing SAN sets" ansible.builtin.set_fact: _ss_wanted_sans: "{{ _ss_san | map('lower') | list | unique | sort }}" _ss_existing_sans: >- @@ -118,7 +118,7 @@ }} changed_when: false -- name: "TLS | (self_signed) generate leaf cert (only when missing or SAN drift)" +- name: "โš™๏ธ TLS | (self_signed) generate leaf cert (only when missing or SAN drift)" ansible.builtin.include_tasks: file: 02_generate_leaf.yml apply: diff --git a/roles/sys-front-tls-selfsigned/tasks/02_generate_leaf.yml b/roles/sys-front-tls-selfsigned/tasks/02_generate_leaf.yml index addacda322..a4c43c7805 100644 --- a/roles/sys-front-tls-selfsigned/tasks/02_generate_leaf.yml +++ b/roles/sys-front-tls-selfsigned/tasks/02_generate_leaf.yml @@ -1,5 +1,5 @@ --- -- name: "TLS | (self_signed) remove outdated cert/key/csr if SAN drift detected" +- name: "๐Ÿ—‘๏ธ TLS | (self_signed) remove outdated cert/key/csr if SAN drift detected" ansible.builtin.file: path: "{{ item }}" state: absent @@ -8,7 +8,7 @@ - "{{ _ss_key }}" - "{{ _ss_csr }}" -- name: "TLS | (self_signed) generate private key (if missing)" +- name: "โš™๏ธ TLS | (self_signed) generate private key (if missing)" ansible.builtin.command: argv: - openssl @@ -19,7 +19,7 @@ args: creates: "{{ _ss_key }}" -- name: "TLS | (self_signed) generate CSR (SAN aware)" +- name: "โš™๏ธ TLS | (self_signed) generate CSR (SAN aware)" ansible.builtin.command: argv: - openssl @@ -34,7 +34,7 @@ args: creates: "{{ _ss_csr }}" -- name: "TLS | (self_signed) sign CSR with local Root CA (creates CA-signed leaf cert)" +- name: "โœ’๏ธ TLS | (self_signed) sign CSR with local Root CA (creates CA-signed leaf cert)" ansible.builtin.command: argv: - openssl diff --git a/roles/sys-front-tls-selfsigned/tasks/main.yml b/roles/sys-front-tls-selfsigned/tasks/main.yml index f9d1f1124d..3d62ba0085 100644 --- a/roles/sys-front-tls-selfsigned/tasks/main.yml +++ b/roles/sys-front-tls-selfsigned/tasks/main.yml @@ -1,6 +1,6 @@ --- # Stack-host only: workers have no CA key, so signing a leaf here would abort the play. -- name: "Execute Role (once)" +- name: "โ–ถ๏ธ Execute Role (once)" include_tasks: 01_core.yml when: - run_once_sys_front_tls_selfsigned is not defined diff --git a/roles/sys-front-tls/tasks/02_http.yml b/roles/sys-front-tls/tasks/02_http.yml index 424211cdb2..05494b1535 100644 --- a/roles/sys-front-tls/tasks/02_http.yml +++ b/roles/sys-front-tls/tasks/02_http.yml @@ -1,12 +1,12 @@ --- -- name: Include dependency 'sys-ctl-mtn-cert-renew' +- name: ๐Ÿ“‚ Include dependency 'sys-ctl-mtn-cert-renew' include_role: name: sys-ctl-mtn-cert-renew when: - run_once_sys_ctl_mtn_cert_renew is not defined - lookup('tls', application_id, 'mode') == 'letsencrypt' -- name: Create HTTP->HTTPS handler per domain +- name: ๐Ÿ“ Create HTTP->HTTPS handler per domain stack_host_template: src: "http.conf.j2" dest: "{{ lookup('nginx', 'files.domain', domain, protocol='http') }}" diff --git a/roles/sys-front-tls/tasks/main.yml b/roles/sys-front-tls/tasks/main.yml index 96e419150a..bb37b4f7e3 100644 --- a/roles/sys-front-tls/tasks/main.yml +++ b/roles/sys-front-tls/tasks/main.yml @@ -4,7 +4,7 @@ # ----------------------------- # Mode: letsencrypt # ----------------------------- -- name: "TLS | (letsencrypt) ensure certs and set paths" +- name: "โœ… TLS | (letsencrypt) ensure certs and set paths" ansible.builtin.include_role: name: sys-front-tls-letsencrypt when: tls_mode_effective == 'letsencrypt' @@ -12,11 +12,11 @@ # ----------------------------- # Mode: self_signed # ----------------------------- -- name: "TLS | (self_signed) ensure certs and set paths" +- name: "โœ… TLS | (self_signed) ensure certs and set paths" ansible.builtin.include_role: name: sys-front-tls-selfsigned when: tls_mode_effective == 'self_signed' -- name: "Load http redirect routines" +- name: "๐Ÿ“‚ Load http redirect routines" include_tasks: 02_http.yml when: lookup('tls', application_id, 'enabled') | bool diff --git a/roles/sys-hostname/tasks/01_core.yml b/roles/sys-hostname/tasks/01_core.yml index 3949590bdc..797d791e1c 100644 --- a/roles/sys-hostname/tasks/01_core.yml +++ b/roles/sys-hostname/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Ensure hostname package is installed +- name: โœ… Ensure hostname package is installed become: true ansible.builtin.package: name: > @@ -11,11 +11,11 @@ when: not DOCKER_IN_CONTAINER | bool - block: - - name: Set system hostname to inventory_hostname (FQDN recommended) + - name: ๐Ÿ”ง Set system hostname to inventory_hostname (FQDN recommended) ansible.builtin.hostname: name: "{{ inventory_hostname }}" - - name: Ensure /etc/hosts contains FQDN + shortname mapping + - name: โœ… Ensure /etc/hosts contains FQDN + shortname mapping ansible.builtin.lineinfile: path: /etc/hosts regexp: "^127\\.0\\.1\\.1\\s+" diff --git a/roles/sys-hostname/tasks/main.yml b/roles/sys-hostname/tasks/main.yml index 1926ad3290..03ac3b19f6 100644 --- a/roles/sys-hostname/tasks/main.yml +++ b/roles/sys-hostname/tasks/main.yml @@ -1,4 +1,4 @@ --- -- name: "Set Hostname (Once)" +- name: "๐Ÿ”ง Set Hostname (Once)" include_tasks: 01_core.yml when: not (run_once_sys_hostname | default(false) | bool) diff --git a/roles/sys-lock/tasks/main.yml b/roles/sys-lock/tasks/main.yml index 3afdf51f0f..35a2186c9f 100644 --- a/roles/sys-lock/tasks/main.yml +++ b/roles/sys-lock/tasks/main.yml @@ -1,6 +1,6 @@ --- - block: - - name: create {{ BIN_LOCK }} + - name: ๐Ÿ“ create {{ BIN_LOCK }} copy: src: sys-lock.py dest: "{{ BIN_LOCK }}" diff --git a/roles/sys-openssl/tasks/01_core.yml b/roles/sys-openssl/tasks/01_core.yml index 18085ddab7..117986e335 100644 --- a/roles/sys-openssl/tasks/01_core.yml +++ b/roles/sys-openssl/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Install OpenSSL +- name: ๐Ÿ“ฆ Install OpenSSL become: true ansible.builtin.package: name: openssl diff --git a/roles/sys-package/tasks/01_core.yml b/roles/sys-package/tasks/01_core.yml index ea6e92a0ec..585d2c88ba 100644 --- a/roles/sys-package/tasks/01_core.yml +++ b/roles/sys-package/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Install additional system packages from inventory +- name: ๐Ÿ“ฆ Install additional system packages from inventory ansible.builtin.package: name: "{{ SYS_PACKAGES }}" state: present diff --git a/roles/sys-pip-install/tasks/01_core.yml b/roles/sys-pip-install/tasks/01_core.yml index 922b013921..65dd4be738 100644 --- a/roles/sys-pip-install/tasks/01_core.yml +++ b/roles/sys-pip-install/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Include dependency 'sys-pip' +- name: ๐Ÿ“‚ Include dependency 'sys-pip' include_role: name: sys-pip when: run_once_sys_pip is not defined diff --git a/roles/sys-pip-install/tasks/main.yml b/roles/sys-pip-install/tasks/main.yml index e58ad5f508..4809ce7808 100644 --- a/roles/sys-pip-install/tasks/main.yml +++ b/roles/sys-pip-install/tasks/main.yml @@ -4,13 +4,13 @@ - include_tasks: 01_core.yml when: run_once_sys_pip_install is not defined -- name: Resolve active Python executable for sys-pip-install +- name: ๐Ÿ” Resolve active Python executable for sys-pip-install ansible.builtin.set_fact: sys_pip_install_python_executable: "{{ ansible_python_interpreter }}" changed_when: false - block: - - name: Probe whether pip for ansible_python_interpreter accepts --break-system-packages + - name: ๐Ÿ” Probe pip for ansible_python_interpreter accepts --break-system-packages ansible.builtin.command: argv: - "{{ sys_pip_install_python_executable }}" @@ -24,14 +24,14 @@ failed_when: false become: "{{ true if global_install | bool else false }}" - - name: Set fact for --break-system-packages support + - name: ๐Ÿ”ง Set fact for --break-system-packages support ansible.builtin.set_fact: sys_pip_install_supports_break_system_packages: "{{ (sys_pip_install_break_system_packages_probe.rc | int) == 0 }}" changed_when: false when: global_install | bool -- name: Check whether selected Python interpreter has 'packaging' +- name: ๐Ÿ”Ž Check whether selected Python interpreter has 'packaging' ansible.builtin.command: argv: - "{{ sys_pip_install_python_executable }}" @@ -42,7 +42,7 @@ changed_when: false failed_when: false -- name: Bootstrap 'packaging' for selected Python interpreter +- name: ๐Ÿฅพ Bootstrap 'packaging' for selected Python interpreter ansible.builtin.command: argv: >- {{ @@ -66,7 +66,7 @@ become: "{{ true if global_install | bool else false }}" when: sys_pip_install_python_packaging_check.rc != 0 -- name: Install or upgrade {{ package_name }} system-wide via pip +- name: ๐Ÿ“ฆ Install or upgrade {{ package_name }} system-wide via pip ansible.builtin.pip: name: "{{ package_name }}" state: "{{ package_state }}" diff --git a/roles/sys-pip/tasks/main.yml b/roles/sys-pip/tasks/main.yml index b4554ffbf9..6db1cfa178 100644 --- a/roles/sys-pip/tasks/main.yml +++ b/roles/sys-pip/tasks/main.yml @@ -4,7 +4,7 @@ name: dev-gcc when: run_once_dev_gcc is not defined - - name: python pip install + - name: ๐Ÿ python pip install ansible.builtin.package: name: >- {{ diff --git a/roles/sys-service-loader/tasks/list_or_shoot.yml b/roles/sys-service-loader/tasks/list_or_shoot.yml index 72665db1d6..427ac71efd 100644 --- a/roles/sys-service-loader/tasks/list_or_shoot.yml +++ b/roles/sys-service-loader/tasks/list_or_shoot.yml @@ -20,13 +20,13 @@ # the standalone fallback when the service-loader is bypassed (tests, # ad-hoc playbooks). -- name: "List post-load roles for service-loader flush" +- name: "๐Ÿ“‹ List post-load roles for service-loader flush" ansible.builtin.set_fact: service_loader_post_run: "{{ (service_loader_post_run | default([])) + list_or_shoot_roles }}" changed_when: false when: (service_loader_preloading | default(false) | bool) -- name: "Shoot post-load roles directly (no preload context active)" +- name: "๐ŸŽฏ Shoot post-load roles directly (no preload context active)" ansible.builtin.include_role: name: "{{ list_or_shoot_role }}" loop: "{{ list_or_shoot_roles }}" diff --git a/roles/sys-service-loader/tasks/load_service.yml b/roles/sys-service-loader/tasks/load_service.yml index 9d673e9eac..f78818772a 100644 --- a/roles/sys-service-loader/tasks/load_service.yml +++ b/roles/sys-service-loader/tasks/load_service.yml @@ -1,20 +1,20 @@ --- -- name: "Load {{ service_key }} in shared service preload context" +- name: "๐Ÿ”Œ Load {{ service_key }} in shared service preload context" block: - - name: "Mark shared service preload context for {{ service_key }}" + - name: "๐Ÿท๏ธ Mark shared service preload context for {{ service_key }}" ansible.builtin.set_fact: service_loader_preloading: true changed_when: false - - name: "Load {{ service_key }} (Once)" + - name: "๐Ÿ”Œ Load {{ service_key }} (Once)" include_tasks: "utils/load_app.yml" vars: load_app_id: "{{ service_role }}" - - name: "Flush handlers after loading {{ service_key }}" + - name: "๐Ÿšฟ Flush handlers after loading {{ service_key }}" meta: flush_handlers always: - - name: "Clear shared service preload context for {{ service_key }}" + - name: "๐Ÿงน Clear shared service preload context for {{ service_key }}" ansible.builtin.set_fact: service_loader_preloading: false changed_when: false diff --git a/roles/sys-service-loader/tasks/main.yml b/roles/sys-service-loader/tasks/main.yml index cb76e2f89a..7950b107ed 100644 --- a/roles/sys-service-loader/tasks/main.yml +++ b/roles/sys-service-loader/tasks/main.yml @@ -15,7 +15,7 @@ # Tasks listed there run with `service_loader_preloading: false`, # so they see the fully preloaded service graph. -- name: "Discover ordered shared services" +- name: "๐Ÿ” Discover ordered shared services" ansible.builtin.set_fact: _ordered_services: >- {{ @@ -26,7 +26,7 @@ ) | first }} -- name: "Load shared service" +- name: "๐Ÿ”Œ Load shared service" include_tasks: load_service.yml vars: service_key: "{{ service_item.id }}" @@ -42,7 +42,7 @@ loop_var: service_item label: "{{ service_item.id }}" -- name: "Run service-loader post-load roles" +- name: "โ–ถ๏ธ Run service-loader post-load roles" ansible.builtin.include_role: name: "{{ post_run_role }}" loop: "{{ service_loader_post_run | unique }}" diff --git a/roles/sys-service-terminator/tasks/01_run_one.yml b/roles/sys-service-terminator/tasks/01_run_one.yml index 18c98e2cbe..3a1c8cf38a 100644 --- a/roles/sys-service-terminator/tasks/01_run_one.yml +++ b/roles/sys-service-terminator/tasks/01_run_one.yml @@ -1,7 +1,7 @@ --- -- name: "Apply state for {{ system_service_run_unit }}" +- name: "๐Ÿ“Œ Apply state for {{ system_service_run_unit }}" block: - - name: "Apply state (retry up to {{ SYS_SERVICE_RUNNER_RETRIES }} times, {{ SYS_SERVICE_RUNNER_DELAY }}s delay)" + - name: "๐Ÿ”„ Apply state (retry up to {{ SYS_SERVICE_RUNNER_RETRIES }} times)" ansible.builtin.systemd: name: "{{ system_service_run_unit }}" state: "{{ SYS_SERVICE_RUNNER_STATE }}" @@ -14,7 +14,7 @@ until: result is not failed rescue: - - name: Show shared diagnostics for failed final-run service + - name: ๐Ÿ‘๏ธ Show shared diagnostics for failed final-run service ansible.builtin.include_role: name: sys-service tasks_from: utils/debug.yml @@ -26,7 +26,7 @@ - "SYS_SERVICE_RUNNER_RETRIES={{ SYS_SERVICE_RUNNER_RETRIES }}" - "SYS_SERVICE_RUNNER_DELAY={{ SYS_SERVICE_RUNNER_DELAY }}" - - name: "docker diagnostics (best-effort via script file)" + - name: "๐Ÿณ docker diagnostics (best-effort via script file)" ansible.builtin.shell: | set -u export SYS_SERVICE_RUNNER_DOCKER_LOG_TAIL="{{ SYS_SERVICE_RUNNER_DOCKER_LOG_TAIL }}" @@ -38,7 +38,7 @@ failed_when: false when: SYS_SERVICE_RUNNER_DOCKER_DIAGNOSTICS | bool - - name: Show docker diagnostics + - name: ๐Ÿ‘๏ธ Show docker diagnostics ansible.builtin.debug: msg: | === docker diagnostics === @@ -46,7 +46,7 @@ {{ sys_runner_docker_diag.stderr | default('') }} when: SYS_SERVICE_RUNNER_DOCKER_DIAGNOSTICS | bool - - name: "Fail with diagnostics" + - name: "๐Ÿ›‘ Fail with diagnostics" ansible.builtin.fail: msg: >- Final-run service failed: {{ system_service_run_unit }}. diff --git a/roles/sys-service-terminator/tasks/02_unlock.yml b/roles/sys-service-terminator/tasks/02_unlock.yml index e9c81dc14d..1b9e8b8af3 100644 --- a/roles/sys-service-terminator/tasks/02_unlock.yml +++ b/roles/sys-service-terminator/tasks/02_unlock.yml @@ -1,5 +1,5 @@ --- -- name: "DEPLOY | Collect {{ SOFTWARE_DOMAIN }} timers (unlock phase)" +- name: "๐Ÿš€ DEPLOY | Collect {{ SOFTWARE_DOMAIN }} timers (unlock phase)" become: true ansible.builtin.command: argv: @@ -12,7 +12,7 @@ changed_when: false failed_when: false -- name: "DEPLOY | Build timer list (unlock phase)" +- name: "๐Ÿš€ DEPLOY | Build timer list (unlock phase)" ansible.builtin.set_fact: deploy_timers_unlock: >- {{ @@ -22,7 +22,7 @@ | list }} -- name: "DEPLOY | Unmask all {{ SOFTWARE_DOMAIN }} timers" +- name: "๐Ÿš€ DEPLOY | Unmask all {{ SOFTWARE_DOMAIN }} timers" become: true ansible.builtin.systemd: name: "{{ item }}" @@ -30,7 +30,7 @@ loop: "{{ deploy_timers_unlock }}" when: deploy_timers_unlock | length > 0 -- name: "DEPLOY | Enable and start all {{ SOFTWARE_DOMAIN }} timers" +- name: "๐Ÿš€ DEPLOY | Enable and start all {{ SOFTWARE_DOMAIN }} timers" become: true ansible.builtin.systemd: name: "{{ item }}" diff --git a/roles/sys-service-terminator/tasks/main.yml b/roles/sys-service-terminator/tasks/main.yml index aafd35d346..aec110d394 100644 --- a/roles/sys-service-terminator/tasks/main.yml +++ b/roles/sys-service-terminator/tasks/main.yml @@ -1,14 +1,14 @@ --- -- name: "Normalize final run list" +- name: "๐Ÿ“ Normalize final run list" ansible.builtin.set_fact: system_service_run_list: "{{ (system_service_run_list | default([])) | unique }}" -- name: "Show final run list (debug)" +- name: "๐Ÿ‘๏ธ Show final run list (debug)" ansible.builtin.debug: var: system_service_run_list when: MODE_DEBUG | bool -- name: "Run collected services" +- name: "โ–ถ๏ธ Run collected services" ansible.builtin.include_tasks: 01_run_one.yml loop: "{{ system_service_run_list }}" loop_control: @@ -16,5 +16,5 @@ label: "{{ system_service_run_unit }}" when: (system_service_run_list | length) > 0 -- name: "Unlock all timers" +- name: "๐Ÿ”“ Unlock all timers" ansible.builtin.include_tasks: 02_unlock.yml diff --git a/roles/sys-service/tasks/01_core.yml b/roles/sys-service/tasks/01_core.yml index cbd954fee6..4cc1cc8b82 100644 --- a/roles/sys-service/tasks/01_core.yml +++ b/roles/sys-service/tasks/01_core.yml @@ -1,16 +1,16 @@ --- -- name: Include dependency 'sys-daemon' +- name: ๐Ÿ“‚ Include dependency 'sys-daemon' include_role: name: sys-daemon when: run_once_sys_daemon is not defined -- name: "Prune old {{ SOFTWARE_NAME }} units (not current version)" +- name: "๐Ÿงน Prune old {{ SOFTWARE_NAME }} units (not current version)" include_tasks: 02_prune.yml -- name: "Stop services and lock timers" +- name: "โน๏ธ Stop services and lock timers" include_tasks: 03_lockdown.yml -- name: "reset (if enabled) for {{ role_name}}" +- name: "โ™ป๏ธ reset (if enabled) for {{ role_name}}" include_tasks: 04_reset.yml when: MODE_RESET | bool diff --git a/roles/sys-service/tasks/02_prune.yml b/roles/sys-service/tasks/02_prune.yml index dab3400e70..f897846892 100644 --- a/roles/sys-service/tasks/02_prune.yml +++ b/roles/sys-service/tasks/02_prune.yml @@ -2,12 +2,12 @@ # Remove/stop/disable systemd units that belong to this SOFTWARE_NAME, # but are not for the current version. -- name: "sys-service | Determine current software/version (lowercase)" +- name: "๐Ÿค” sys-service | Determine current software/version (lowercase)" ansible.builtin.set_fact: sys_service_sw_lc: "{{ SOFTWARE_NAME | string | trim | lower }}" sys_service_ver_lc: "{{ lookup('version') | string | trim | lower }}" -- name: "sys-service | Collect {{ SOFTWARE_NAME }} timers (all versions)" +- name: "๐Ÿ“Š sys-service | Collect {{ SOFTWARE_NAME }} timers (all versions)" become: true ansible.builtin.command: argv: @@ -20,7 +20,7 @@ changed_when: false failed_when: false -- name: "sys-service | Collect {{ SOFTWARE_NAME }} services (all versions)" +- name: "๐Ÿ“Š sys-service | Collect {{ SOFTWARE_NAME }} services (all versions)" become: true ansible.builtin.command: argv: @@ -33,7 +33,7 @@ changed_when: false failed_when: false -- name: "sys-service | Build old-version unit lists (exclude current version)" +- name: "๐Ÿ”จ sys-service | Build old-version unit lists (exclude current version)" ansible.builtin.set_fact: sys_service_old_units_timers: >- {{ @@ -54,7 +54,7 @@ | list }} -- name: "sys-service | Stop old-version services (best-effort)" +- name: "โน๏ธ sys-service | Stop old-version services (best-effort)" become: true ansible.builtin.systemd: name: "{{ item }}" @@ -63,7 +63,7 @@ when: sys_service_old_units_services | length > 0 failed_when: false -- name: "sys-service | Stop old-version timers (best-effort)" +- name: "โน๏ธ sys-service | Stop old-version timers (best-effort)" become: true ansible.builtin.systemd: name: "{{ item }}" @@ -72,7 +72,7 @@ when: sys_service_old_units_timers | length > 0 failed_when: false -- name: "sys-service | Disable old-version services (best-effort)" +- name: "๐Ÿ”ด sys-service | Disable old-version services (best-effort)" become: true ansible.builtin.systemd: name: "{{ item }}" @@ -81,7 +81,7 @@ when: sys_service_old_units_services | length > 0 failed_when: false -- name: "sys-service | Disable old-version timers (best-effort)" +- name: "๐Ÿ”ด sys-service | Disable old-version timers (best-effort)" become: true ansible.builtin.systemd: name: "{{ item }}" @@ -90,7 +90,7 @@ when: sys_service_old_units_timers | length > 0 failed_when: false -- name: "sys-service | Delete old-version unit files" +- name: "๐Ÿ—‘๏ธ sys-service | Delete old-version unit files" become: true ansible.builtin.file: path: "{{ [ DIR_SYSTEM_SERVICE, item ] | path_join }}" @@ -98,7 +98,7 @@ loop: "{{ (sys_service_old_units_services + sys_service_old_units_timers) | unique }}" when: (sys_service_old_units_services | length > 0) or (sys_service_old_units_timers | length > 0) -- name: "sys-service | systemd daemon-reload after pruning" +- name: "๐Ÿ”„ sys-service | systemd daemon-reload after pruning" become: true ansible.builtin.systemd: daemon_reload: true diff --git a/roles/sys-service/tasks/03_lockdown.yml b/roles/sys-service/tasks/03_lockdown.yml index e9442f3b66..1dfe69990c 100644 --- a/roles/sys-service/tasks/03_lockdown.yml +++ b/roles/sys-service/tasks/03_lockdown.yml @@ -1,5 +1,5 @@ --- -- name: "DEPLOY | Collect {{ SOFTWARE_DOMAIN }} timers" +- name: "๐Ÿš€ DEPLOY | Collect {{ SOFTWARE_DOMAIN }} timers" become: true ansible.builtin.command: argv: @@ -12,7 +12,7 @@ changed_when: false failed_when: false -- name: "DEPLOY | Collect {{ SOFTWARE_DOMAIN }} services" +- name: "๐Ÿš€ DEPLOY | Collect {{ SOFTWARE_DOMAIN }} services" become: true ansible.builtin.command: argv: @@ -25,7 +25,7 @@ changed_when: false failed_when: false -- name: "DEPLOY | Build unit lists" +- name: "๐Ÿš€ DEPLOY | Build unit lists" ansible.builtin.set_fact: deploy_timers: >- {{ @@ -42,7 +42,7 @@ | list }} -- name: "DEPLOY | Stop all {{ SOFTWARE_DOMAIN }} services" +- name: "๐Ÿš€ DEPLOY | Stop all {{ SOFTWARE_DOMAIN }} services" become: true ansible.builtin.systemd: name: "{{ item }}" @@ -50,7 +50,7 @@ loop: "{{ deploy_services }}" when: deploy_services | length > 0 -- name: "DEPLOY | Stop all {{ SOFTWARE_DOMAIN }} timers (best-effort)" +- name: "๐Ÿš€ DEPLOY | Stop all {{ SOFTWARE_DOMAIN }} timers (best-effort)" become: true ansible.builtin.systemd: name: "{{ item }}" @@ -58,7 +58,7 @@ loop: "{{ deploy_timers }}" when: deploy_timers | length > 0 -- name: "DEPLOY | Disable all {{ SOFTWARE_DOMAIN }} timers (keep unit files)" +- name: "๐Ÿš€ DEPLOY | Disable all {{ SOFTWARE_DOMAIN }} timers (keep unit files)" become: true ansible.builtin.systemd: name: "{{ item }}" diff --git a/roles/sys-service/tasks/04_reset.yml b/roles/sys-service/tasks/04_reset.yml index ef75a43b5f..9371807ccc 100644 --- a/roles/sys-service/tasks/04_reset.yml +++ b/roles/sys-service/tasks/04_reset.yml @@ -1,10 +1,10 @@ --- -- name: "pkgmgr install '{{ UNIT_SUFFIX_REMOVER_PACKAGE }}'" +- name: "๐Ÿ“ฆ pkgmgr install '{{ UNIT_SUFFIX_REMOVER_PACKAGE }}'" include_role: name: pkgmgr-install vars: package_name: "{{ UNIT_SUFFIX_REMOVER_PACKAGE }}" -- name: Remove all '{{ SYS_SERVICE_SUFFIX }}' files with '{{ UNIT_SUFFIX_REMOVER_PACKAGE }}' +- name: "๐Ÿงน Remove '{{ SYS_SERVICE_SUFFIX }}' files" command: "{{ UNIT_SUFFIX_REMOVER_PACKAGE }} -s '{{ SOFTWARE_NAME }}'" notify: "reload system daemon" diff --git a/roles/sys-service/tasks/05_base.yml b/roles/sys-service/tasks/05_base.yml index a01652a406..8066d1d92a 100644 --- a/roles/sys-service/tasks/05_base.yml +++ b/roles/sys-service/tasks/05_base.yml @@ -1,5 +1,5 @@ --- -- name: "find best matching source for service script" +- name: "๐Ÿ” find best matching source for service script" set_fact: system_service_script_src: >- {{ lookup('first_found', @@ -16,20 +16,20 @@ ) }} when: system_service_copy_files | bool -- name: "Load file logic for '{{ system_service_id }}'" +- name: "๐Ÿ“‚ Load file logic for '{{ system_service_id }}'" include_tasks: 06_files.yml when: - system_service_copy_files | bool - system_service_script_src | default('') | length > 0 -- name: "Load systemctl logic for '{{ system_service_id }}'" +- name: "๐Ÿ“‚ Load systemctl logic for '{{ system_service_id }}'" include_tasks: 07_service.yml -- name: "Load timer logic for '{{ system_service_id }}'" +- name: "๐Ÿ“‚ Load timer logic for '{{ system_service_id }}'" include_tasks: 08_timer.yml when: system_service_timer_enabled | bool -- name: "sys-service | Add '{{ system_service_name }}' to final run list" +- name: "โž• sys-service | Add '{{ system_service_name }}' to final run list" ansible.builtin.set_fact: system_service_run_list: >- {{ diff --git a/roles/sys-service/tasks/06_files.yml b/roles/sys-service/tasks/06_files.yml index db47d92067..5d59a5e0aa 100644 --- a/roles/sys-service/tasks/06_files.yml +++ b/roles/sys-service/tasks/06_files.yml @@ -1,13 +1,13 @@ --- -- name: "create {{ system_service_script_dir }}" +- name: "๐Ÿ“ create {{ system_service_script_dir }}" file: path: "{{ system_service_script_dir }}" state: directory mode: "0755" -- name: "template or copy script" +- name: "๐Ÿ“„ template or copy script" block: - - name: "render template" + - name: "๐Ÿ“„ render template" template: # nocheck: stack-host-template (per-host script for per-host systemd service) src: "{{ system_service_script_src }}" dest: "{{ [system_service_script_dir, (system_service_script_src | basename | regex_replace('\\.j2$', ''))] | path_join }}" @@ -15,7 +15,7 @@ notify: "{{ 'reload system daemon' if system_service_is_template | bool else 'refresh systemctl service' }}" when: system_service_script_src.endswith('.j2') - - name: "copy raw file" + - name: "๐Ÿ“‹ copy raw file" copy: src: "{{ system_service_script_src }}" dest: "{{ [system_service_script_dir, (system_service_script_src | basename)] | path_join }}" diff --git a/roles/sys-service/tasks/07_service.yml b/roles/sys-service/tasks/07_service.yml index 1332c27b97..ccfa779e89 100644 --- a/roles/sys-service/tasks/07_service.yml +++ b/roles/sys-service/tasks/07_service.yml @@ -1,5 +1,5 @@ --- -- name: Resolve systemctl template source +- name: ๐Ÿ” Resolve systemctl template source set_fact: system_service_template_src: >- {{ lookup( @@ -17,7 +17,7 @@ errors='strict' ) }} -- name: Ensure a systemctl template was found +- name: โœ… Ensure a systemctl template was found assert: that: system_service_template_src | length > 0 fail_msg: >- @@ -25,7 +25,7 @@ {{ system_service_role_dir }}/templates/ and {{ role_path }}/templates/. when: MODE_ASSERT | bool -- name: "setup systemctl '{{ system_service_id }}'" +- name: "๐Ÿ”ง setup systemctl '{{ system_service_id }}'" template: # nocheck: stack-host-template (per-host systemd service unit) src: "{{ system_service_template_src }}" dest: "{{ [ DIR_SYSTEM_SERVICE, system_service_name ] | path_join }}" @@ -34,12 +34,12 @@ mode: "0644" notify: "{{ 'reload system daemon' if system_service_is_template | bool else 'refresh systemctl service' }}" -- name: refresh systemctl service when SYS_SERVICE_ALL_ENABLE +- name: ๐Ÿ”„ refresh systemctl service when SYS_SERVICE_ALL_ENABLE block: - - name: reload system daemon + - name: ๐Ÿ”„ reload system daemon command: /bin/true notify: reload system daemon - - name: refresh systemctl service + - name: ๐Ÿ”„ refresh systemctl service command: /bin/true notify: refresh systemctl service when: not system_service_is_template | bool diff --git a/roles/sys-service/tasks/08_timer.yml b/roles/sys-service/tasks/08_timer.yml index d146a527bd..1701ebaaf3 100644 --- a/roles/sys-service/tasks/08_timer.yml +++ b/roles/sys-service/tasks/08_timer.yml @@ -1,15 +1,15 @@ --- -- name: Fail if system_service_id contains "@" +- name: ๐Ÿ›‘ Fail if system_service_id contains "@" assert: that: - "'@' not in system_service_id" fail_msg: "Invalid system_service_id '{{ system_service_id }}' โ†’ must not contain '@'." when: MODE_ASSERT | bool -- name: "Make '{{ system_service_id }}' available for sys-timer" +- name: "๐Ÿ”จ Make '{{ system_service_id }}' available for sys-timer" set_fact: system_service_timer_service: "{{ system_service_id }}" -- name: "include role for sys-timer for {{ system_service_timer_service }}" +- name: "๐Ÿ“‚ include role for sys-timer for {{ system_service_timer_service }}" include_role: name: sys-timer diff --git a/roles/sys-service/tasks/main.yml b/roles/sys-service/tasks/main.yml index 63a04c510f..5a6b983545 100644 --- a/roles/sys-service/tasks/main.yml +++ b/roles/sys-service/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "Reload sys-daemon handlers" +- name: "๐Ÿ”„ Reload sys-daemon handlers" include_tasks: utils/load_handlers.yml vars: handler_role_name: "sys-daemon" @@ -8,10 +8,10 @@ - include_tasks: 01_core.yml when: run_once_sys_service is not defined -- name: "Execute service routines for '{{ system_service_id }}'" +- name: "โ–ถ๏ธ Execute service routines for '{{ system_service_id }}'" block: - - name: "Load base routine for '{{ system_service_id }}'" + - name: "๐Ÿงฉ Load base routine for '{{ system_service_id }}'" include_tasks: 05_base.yml - - name: "Flush system service handlers for '{{ system_service_id }}'" + - name: "๐Ÿšฟ Flush system service handlers for '{{ system_service_id }}'" meta: flush_handlers when: system_service_id is defined diff --git a/roles/sys-service/tasks/utils/debug.yml b/roles/sys-service/tasks/utils/debug.yml index 3adc617700..0408b03139 100644 --- a/roles/sys-service/tasks/utils/debug.yml +++ b/roles/sys-service/tasks/utils/debug.yml @@ -1,5 +1,5 @@ --- -- name: sys-service | Assert service debug unit is defined +- name: โœ… sys-service | Assert service debug unit is defined ansible.builtin.assert: that: - system_service_debug_unit is defined @@ -8,7 +8,7 @@ system_service_debug_unit must be defined for shared service diagnostics. changed_when: false -- name: sys-service | Run shared service debug script +- name: โ–ถ๏ธ sys-service | Run shared service debug script ansible.builtin.script: "{{ role_path }}/files/debug.sh" become: true environment: @@ -23,13 +23,13 @@ changed_when: false failed_when: false -- name: sys-service | Show shared service diagnostics +- name: ๐Ÿ‘๏ธ sys-service | Show shared service diagnostics ansible.builtin.debug: msg: | {{ system_service_debug_result.stdout | default('') }} {{ system_service_debug_result.stderr | default('') }} -- name: sys-service | Fail after shared service diagnostics +- name: ๐Ÿ›‘ sys-service | Fail after shared service diagnostics ansible.builtin.fail: msg: >- {{ diff --git a/roles/sys-stk-backend/tasks/main.yml b/roles/sys-stk-backend/tasks/main.yml index ec11790cee..e2a1daa517 100644 --- a/roles/sys-stk-backend/tasks/main.yml +++ b/roles/sys-stk-backend/tasks/main.yml @@ -1,7 +1,7 @@ --- # run_once_sys_stk_backend: disabled -- name: "Resolve backend context for '{{ application_id }}'" +- name: "๐Ÿ” Resolve backend context for '{{ application_id }}'" ansible.builtin.set_fact: _sys_stk_backend_database_consumer_id: >- {{ database_consumer_id | default(application_id) }} @@ -9,7 +9,7 @@ {{ lookup('database', application_id, 'enabled') | bool }} changed_when: false -- name: "DEBUG | SYS-STK-BACKEND | Application context" +- name: "๐Ÿ› DEBUG | SYS-STK-BACKEND | Application context" ansible.builtin.debug: msg: - "application_id={{ application_id }}" @@ -18,7 +18,7 @@ - "sso_proxy_enabled={{ lookup('sso', application_id, 'is_proxy_gated') }}" when: MODE_DEBUG | bool -- name: "For '{{ application_id }}': Load central RDBMS" +- name: "๐Ÿงฉ For '{{ application_id }}': Load central RDBMS" include_role: name: sys-svc-rdbms public: false @@ -26,7 +26,7 @@ database_consumer_id: "{{ _sys_stk_backend_database_consumer_id }}" when: _sys_stk_backend_database_enabled | bool -- name: "For '{{ application_id }}': Load central object store (per-consumer provisioning)" +- name: "๐Ÿงฉ '{{ application_id }}': load per-consumer central object store" include_role: name: sys-svc-objstore public: false @@ -37,14 +37,14 @@ - lookup('objstore', application_id, 'shared') | bool - application_id != lookup('objstore', application_id, 'id') -- name: "For '{{ application_id }}': Load central engines (per-consumer provisioning)" +- name: "๐Ÿงฉ For '{{ application_id }}': Load central engines (per-consumer provisioning)" include_role: name: sys-svc-engine public: false vars: engine_consumer_id: "{{ application_id }}" -- name: "For '{{ application_id }}': Load sys-svc-compose" +- name: "๐Ÿงฉ For '{{ application_id }}': Load sys-svc-compose" include_role: name: sys-svc-compose vars: @@ -52,13 +52,13 @@ database_consumer_id: "{{ _sys_stk_backend_database_consumer_id }}" - block: - - name: "set sso_proxy_application_id (needed due to lazy-loading issue)" + - name: "๐Ÿ”ง set sso_proxy_application_id (needed due to lazy-loading issue)" set_fact: sso_proxy_application_id: "{{ application_id }}" - - name: "render web-app-keycloak SSO-proxy sidecar config" + - name: "๐Ÿ“„ render web-app-keycloak SSO-proxy sidecar config" include_tasks: "{{ playbook_dir }}/roles/web-app-keycloak/tasks/sso_proxy.yml" when: lookup('sso', application_id, 'is_proxy_gated') | bool -- name: "flush compose and SSO proxy" +- name: "๐Ÿšฟ flush compose and SSO proxy" meta: flush_handlers when: compose_handlers_flush | bool diff --git a/roles/sys-stk-front-base/tasks/01_cloudflare.yml b/roles/sys-stk-front-base/tasks/01_cloudflare.yml index efc554db69..c8ac48537a 100644 --- a/roles/sys-stk-front-base/tasks/01_cloudflare.yml +++ b/roles/sys-stk-front-base/tasks/01_cloudflare.yml @@ -1,16 +1,16 @@ --- # Initialize cache dict (works within the play; persists if fact cache is enabled) -- name: "Ensure cf_zone_ids cache dict exists" +- name: "โœ… Ensure cf_zone_ids cache dict exists" set_fact: cf_zone_ids: "{{ cf_zone_ids | default({}) }}" # Use cached zone_id if available for the apex (to_primary_domain) -- name: "Load cf_zone_id from cache if present" +- name: "๐Ÿ“ฅ Load cf_zone_id from cache if present" set_fact: cf_zone_id: "{{ (cf_zone_ids | default({})).get(domain | to_primary_domain, false) }}" # Only look up from Cloudflare if we still don't have it -- name: "Ensure Cloudflare Zone ID is known for '{{ domain }}'" +- name: "โœ… Ensure Cloudflare Zone ID is known for '{{ domain }}'" vars: cf_api_url: "https://api.cloudflare.com/client/v4/zones" uri_retry: @@ -26,7 +26,7 @@ - not cf_zone_id no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Set fact cf_zone_id and update cache dict" +- name: "๐Ÿ”ง Set fact cf_zone_id and update cache dict" set_fact: cf_zone_id: "{{ cf_zone_lookup_dev.json.result[0].id }}" cf_zone_ids: >- @@ -36,17 +36,17 @@ - not cf_zone_id - cf_zone_lookup_dev.json.result | length > 0 -- name: "Fail if no Cloudflare zone found for {{ domain | to_primary_domain }}" +- name: "๐Ÿ›‘ Fail if no Cloudflare zone found for {{ domain | to_primary_domain }}" ansible.builtin.fail: msg: "No Cloudflare zone found for {{ domain | to_primary_domain }} โ€” aborting!" when: - not cf_zone_id - cf_zone_lookup_dev.json.result | length == 0 -- name: activate cloudflare cache development mode +- name: ๐ŸŸข activate cloudflare cache development mode include_tasks: "cloudflare/02_enable_cf_dev_mode.yml" when: (ENVIRONMENT | lower) == 'development' -- name: purge cloudflare domain cache +- name: ๐Ÿงน purge cloudflare domain cache include_tasks: "cloudflare/01_cleanup.yml" when: MODE_CLEANUP | bool diff --git a/roles/sys-stk-front-base/tasks/cloudflare/01_cleanup.yml b/roles/sys-stk-front-base/tasks/cloudflare/01_cleanup.yml index 5b8753089b..0185c98a34 100644 --- a/roles/sys-stk-front-base/tasks/cloudflare/01_cleanup.yml +++ b/roles/sys-stk-front-base/tasks/cloudflare/01_cleanup.yml @@ -1,5 +1,5 @@ --- -- name: "Purge everything from Cloudflare cache for domain {{ domain }}" +- name: "๐Ÿงน Purge everything from Cloudflare cache for domain {{ domain }}" uri_retry: url: "https://api.cloudflare.com/client/v4/zones/{{ cf_zone_id }}/purge_cache" method: POST diff --git a/roles/sys-stk-front-base/tasks/cloudflare/02_enable_cf_dev_mode.yml b/roles/sys-stk-front-base/tasks/cloudflare/02_enable_cf_dev_mode.yml index 1dbb37561f..d3eeb41ea0 100644 --- a/roles/sys-stk-front-base/tasks/cloudflare/02_enable_cf_dev_mode.yml +++ b/roles/sys-stk-front-base/tasks/cloudflare/02_enable_cf_dev_mode.yml @@ -4,7 +4,7 @@ # Assumes `domain` and (optionally) `cf_zone_id` are available. # Safe to run repeatedly; only changes when the mode is not already "on". -- name: "Read current Cloudflare development_mode setting" +- name: "๐Ÿ“– Read current Cloudflare development_mode setting" uri_retry: url: "https://api.cloudflare.com/client/v4/zones/{{ cf_zone_id }}/settings/development_mode" method: GET @@ -15,7 +15,7 @@ register: cf_dev_mode_current when: ASYNC_ENABLED | bool -- name: "Enable Cloudflare Development Mode" +- name: "๐ŸŸข Enable Cloudflare Development Mode" uri_retry: url: "https://api.cloudflare.com/client/v4/zones/{{ cf_zone_id }}/settings/development_mode" method: PATCH diff --git a/roles/sys-stk-front-base/tasks/main.yml b/roles/sys-stk-front-base/tasks/main.yml index df8b7b680e..2c03571005 100644 --- a/roles/sys-stk-front-base/tasks/main.yml +++ b/roles/sys-stk-front-base/tasks/main.yml @@ -1,11 +1,11 @@ --- - block: - - name: Include dependency 'sys-svc-webserver-https' + - name: ๐Ÿ“‚ Include dependency 'sys-svc-webserver-https' include_role: name: sys-svc-webserver-https when: run_once_sys_svc_webserver_https is not defined - - name: "Load Alias integration" + - name: "๐Ÿ“ฅ Load Alias integration" include_tasks: "utils/load_app.yml" vars: load_app_id: web-opt-rdr-domains @@ -17,7 +17,7 @@ - include_tasks: "01_cloudflare.yml" when: DNS_PROVIDER == "cloudflare" -- name: "Reinitialize OpenResty Handler" +- name: "๐ŸŽ›๏ธ Reinitialize OpenResty Handler" include_tasks: utils/load_handlers.yml vars: handler_role_name: "svc-prx-openresty" diff --git a/roles/sys-stk-front-proxy/tasks/main.yml b/roles/sys-stk-front-proxy/tasks/main.yml index a1acce997d..ff1c828720 100644 --- a/roles/sys-stk-front-proxy/tasks/main.yml +++ b/roles/sys-stk-front-proxy/tasks/main.yml @@ -1,7 +1,7 @@ --- # nocheck: run-once -- name: Freeze front proxy context before nested role loads +- name: ๐ŸงŠ Freeze front proxy context before nested role loads ansible.builtin.set_fact: front_proxy_application_id: "{{ application_id }}" front_proxy_domain: "{{ domain | default(lookup('domain', application_id)) }}" @@ -36,11 +36,11 @@ }} changed_when: false -- name: Bootstrap Frontend Base +- name: ๐Ÿฅพ Bootstrap Frontend Base ansible.builtin.include_role: name: sys-stk-front-base -- name: "TLS | Apply tls layer" +- name: "๐Ÿ“Œ TLS | Apply tls layer" include_role: name: sys-front-tls when: lookup('tls', front_proxy_application_id, 'enabled') | bool @@ -48,18 +48,18 @@ application_id: "{{ front_proxy_application_id }}" domain: "{{ front_proxy_domain }}" -- name: "CSP/INJ | Apply global injections for {{ front_proxy_domain }}" +- name: "๐Ÿ“Œ CSP/INJ | Apply global injections for {{ front_proxy_domain }}" ansible.builtin.include_role: name: sys-front-inj-all vars: application_id: "{{ front_proxy_application_id }}" domain: "{{ front_proxy_domain }}" -- name: Resolve application-specific front proxy template path +- name: ๐Ÿ” Resolve application-specific front proxy template path ansible.builtin.set_fact: front_proxy_application_template: "{{ front_proxy_application_id | abs_role_path_by_application_id }}/templates/proxy.conf.j2" -- name: Resolve front proxy template source +- name: ๐Ÿ” Resolve front proxy template source ansible.builtin.set_fact: front_proxy_template_src: >- {{ @@ -72,7 +72,7 @@ vars: webserver_vhost_flavour: basic -- name: "Deploy NGINX config: '{{ front_proxy_domain }}' -> '{{ front_proxy_domain_conf_dst_resolved }}'" +- name: "๐Ÿš€ Deploy NGINX config for '{{ front_proxy_domain }}'" stack_host_template: src: "{{ front_proxy_template_src }}" dest: "{{ front_proxy_domain_conf_dst_resolved }}" @@ -89,7 +89,7 @@ notify: restart openresty - block: - - name: "Check if {{ lookup('domain', front_proxy_application_id) }} is reachable (only if config unchanged)" + - name: "๐Ÿ” Check if {{ lookup('domain', front_proxy_application_id) }} is reachable" uri_probe: url: "{{ lookup('tls', front_proxy_application_id, 'url.base') }}" status_code: @@ -100,7 +100,7 @@ failed_when: false changed_when: false - - name: Restart NGINX if site is down + - name: ๐Ÿ”„ Restart NGINX if site is down ansible.builtin.command: cmd: "true" notify: restart openresty @@ -109,5 +109,5 @@ - site_check.status not in [200, 301, 302] when: not nginx_conf.changed -- name: "Restart Webserver for '{{ front_proxy_domain_conf_dst_resolved }}'" +- name: "๐Ÿ”„ Restart Webserver for '{{ front_proxy_domain_conf_dst_resolved }}'" ansible.builtin.meta: flush_handlers diff --git a/roles/sys-stk-full/tasks/main.yml b/roles/sys-stk-full/tasks/main.yml index c102515c40..b83f9e579a 100644 --- a/roles/sys-stk-full/tasks/main.yml +++ b/roles/sys-stk-full/tasks/main.yml @@ -1,6 +1,6 @@ --- # nocheck: run-once -- name: "For '{{ application_id }}': freeze full-stack context" +- name: "๐ŸงŠ For '{{ application_id }}': freeze full-stack context" ansible.builtin.set_fact: sys_stk_full_application_id: "{{ application_id }}" sys_stk_full_domain: "{{ lookup('domain', application_id) }}" @@ -15,7 +15,7 @@ }} changed_when: false -- name: "For '{{ application_id }}': include role sys-stk-front-proxy (delegated to openresty host, run-once)" +- name: "๐Ÿ“‚ '{{ application_id }}': include role sys-stk-front-proxy" include_role: name: sys-stk-front-proxy apply: @@ -27,7 +27,7 @@ http_port: "{{ sys_stk_full_http_port }}" when: (groups['svc-prx-openresty'] | default([])) | length > 0 -- name: "For '{{ application_id }}': load docker and db" +- name: "๐Ÿงฉ For '{{ application_id }}': load docker and db" include_role: name: sys-stk-backend vars: diff --git a/roles/sys-sudo/tasks/main.yml b/roles/sys-sudo/tasks/main.yml index 38b6bf2c14..86819a9b39 100644 --- a/roles/sys-sudo/tasks/main.yml +++ b/roles/sys-sudo/tasks/main.yml @@ -1,10 +1,10 @@ --- - block: - - name: Install sudo (Arch/Manjaro) + - name: ๐Ÿ“ฆ Install sudo (Arch/Manjaro) package: name: sudo state: present - - name: run the sudo tasks once + - name: โ–ถ๏ธ run the sudo tasks once set_fact: run_once_sys_sudo: true when: run_once_sys_sudo is not defined diff --git a/roles/sys-svc-cdn/tasks/main.yml b/roles/sys-svc-cdn/tasks/main.yml index 262b047c0c..86c484387e 100644 --- a/roles/sys-svc-cdn/tasks/main.yml +++ b/roles/sys-svc-cdn/tasks/main.yml @@ -1,6 +1,6 @@ --- - block: - - name: Ensure shared root and vendor exist (run once) + - name: โœ… Ensure shared root and vendor exist (run once) ansible.builtin.file: path: "{{ item }}" state: directory @@ -10,7 +10,7 @@ when: - run_once_sys_svc_cdn is not defined -- name: Overwritte CDN handlers with neutral handlers +- name: ๐ŸŽ›๏ธ Overwritte CDN handlers with neutral handlers ansible.builtin.include_tasks: "tasks/utils/load_handlers.yml" loop: - svc-prx-openresty @@ -21,14 +21,14 @@ vars: handler_role_name: "{{ handler_role }}" -- name: Ensure CDN directories exist +- name: โœ… Ensure CDN directories exist file: path: "{{ item }}" state: directory mode: "0755" loop: "{{ CDN_ROLE_DIRS }}" -- name: Ensure 'latest' symlink points to current release +- name: โœ… Ensure 'latest' symlink points to current release file: src: "{{ lookup('cdn', application_id).role.release.root }}" dest: "{{ [lookup('cdn', application_id).role.root, 'latest'] | path_join }}" diff --git a/roles/sys-svc-certbot/tasks/01_core.yml b/roles/sys-svc-certbot/tasks/01_core.yml index 26c0a53f9f..705bbaaa2c 100644 --- a/roles/sys-svc-certbot/tasks/01_core.yml +++ b/roles/sys-svc-certbot/tasks/01_core.yml @@ -1,10 +1,10 @@ --- -- name: install certbot +- name: ๐Ÿ“ฆ install certbot package: name: certbot state: present -- name: "Include tasks for 'No-Webroot-ACME-CHALLENGE-METHOD'" +- name: "๐Ÿ“‚ Include tasks for 'No-Webroot-ACME-CHALLENGE-METHOD'" include_tasks: 02_no_webroot.yml when: - CERTBOT_ACME_CHALLENGE_METHOD != 'webroot' diff --git a/roles/sys-svc-certbot/tasks/02_no_webroot.yml b/roles/sys-svc-certbot/tasks/02_no_webroot.yml index 64ffad0dca..b7ed0cb444 100644 --- a/roles/sys-svc-certbot/tasks/02_no_webroot.yml +++ b/roles/sys-svc-certbot/tasks/02_no_webroot.yml @@ -1,10 +1,10 @@ --- -- name: install certbot DNS plugin +- name: ๐Ÿ“ฆ install certbot DNS plugin package: name: "certbot-dns-{{ CERTBOT_ACME_CHALLENGE_METHOD }}" state: present -- name: Ensure /etc/certbot directory exists +- name: โœ… Ensure /etc/certbot directory exists file: path: "{{ CERTBOT_CREDENTIALS_DIR }}" state: directory @@ -12,7 +12,7 @@ group: root mode: "0755" -- name: Install plugin credentials file +- name: ๐Ÿ“ฆ Install plugin credentials file copy: dest: "{{ CERTBOT_CREDENTIALS_FILE }}" content: | diff --git a/roles/sys-svc-certs/tasks/flavors/_san.yml b/roles/sys-svc-certs/tasks/flavors/_san.yml index 824fda4740..523d183203 100644 --- a/roles/sys-svc-certs/tasks/flavors/_san.yml +++ b/roles/sys-svc-certs/tasks/flavors/_san.yml @@ -1,12 +1,12 @@ --- # Necessary to have this separate file to pass performance tests -- name: Install certbundle +- name: ๐Ÿ“ฆ Install certbundle include_role: name: pkgmgr-install vars: package_name: certbundle -- name: Generate SAN certificate with certbundle +- name: โš™๏ธ Generate SAN certificate with certbundle command: >- certbundle --domains "{{ CURRENT_PLAY_DOMAINS_ALL | join(',') }}" @@ -32,27 +32,27 @@ and 'too many certificates' not in (certbundle_result.stderr | lower | default('')) and 'the service is down for maintenance or had an internal error' not in (certbundle_result.stderr | lower | default('')) -- name: Warn if LetsEncrypt was down +- name: โš ๏ธ Warn if LetsEncrypt was down when: "'the service is down for maintenance or had an internal error' in (certbundle_result.stderr | lower | default(''))" debug: msg: > WARNING: Let's Encrypt responded with "service down for maintenance / internal error". Certificate request skipped; please retry later. -- name: Warn if LE rate limit (exact set) was hit +- name: โš ๏ธ Warn if LE rate limit (exact set) was hit when: "'already issued for this exact set of identifiers in the last' in (certbundle_result.stderr | lower | default(''))" debug: msg: > WARNING: Let's Encrypt rate limit for this exact identifier set was hit. No changes recorded; retry after the indicated time. -- name: Warn if LE rate limit (generic) was hit +- name: โš ๏ธ Warn if LE rate limit (generic) was hit when: "'too many certificates' in (certbundle_result.stderr | lower | default(''))" debug: msg: > WARNING: Let's Encrypt rate limit reached ("too many certificates"). No changes recorded; adjust batching or retry later. -- name: run the san tasks once +- name: โ–ถ๏ธ run the san tasks once set_fact: run_once_san_certs: true diff --git a/roles/sys-svc-certs/tasks/flavors/dedicated.yml b/roles/sys-svc-certs/tasks/flavors/dedicated.yml index 6ef6dd0684..de99fe983d 100644 --- a/roles/sys-svc-certs/tasks/flavors/dedicated.yml +++ b/roles/sys-svc-certs/tasks/flavors/dedicated.yml @@ -1,11 +1,11 @@ --- -- name: "Check if certificate already exists for '{{ domain }}'" +- name: "๐Ÿ”Ž Check if certificate already exists for '{{ domain }}'" cert_check_exists: domain: "{{ domain }}" cert_base_path: "{{ LETSENCRYPT_LIVE_PATH }}" register: cert_check -- name: "receive certificate for '{{ domain }}'" +- name: "๐Ÿ“œ receive certificate for '{{ domain }}'" command: >- certbot certonly --agree-tos --email {{ lookup('users', 'administrator').email }} --non-interactive {% if CERTBOT_ACME_CHALLENGE_METHOD != "webroot" %} diff --git a/roles/sys-svc-certs/tasks/flavors/san.yml b/roles/sys-svc-certs/tasks/flavors/san.yml index b63ec91831..52f631a510 100644 --- a/roles/sys-svc-certs/tasks/flavors/san.yml +++ b/roles/sys-svc-certs/tasks/flavors/san.yml @@ -1,5 +1,5 @@ --- # Neccessary encapsulation to pass performance tests -- name: Include wrapped SAN tasks +- name: ๐Ÿ“‚ Include wrapped SAN tasks include_tasks: "_san.yml" when: run_once_san_certs is not defined diff --git a/roles/sys-svc-certs/tasks/flavors/wildcard.yml b/roles/sys-svc-certs/tasks/flavors/wildcard.yml index a609a64e2a..e66f85e365 100644 --- a/roles/sys-svc-certs/tasks/flavors/wildcard.yml +++ b/roles/sys-svc-certs/tasks/flavors/wildcard.yml @@ -1,17 +1,17 @@ --- - block: - - name: "Load wildcard certificate for domain" + - name: "๐Ÿ“œ Load wildcard certificate for domain" include_tasks: "dedicated.yml" vars: wildcard_domain: true when: - domain.split('.') | length == (DOMAIN_PRIMARY.split('.') | length + 1) and domain.endswith(DOMAIN_PRIMARY) - - name: run the receive_certificate tasks once + - name: โ–ถ๏ธ run the receive_certificate tasks once set_fact: run_once_receive_certificate: true when: run_once_receive_certificate is not defined -- name: "Load dedicated certificate for domain" +- name: "๐Ÿ“œ Load dedicated certificate for domain" include_tasks: "dedicated.yml" vars: wildcard_domain: false diff --git a/roles/sys-svc-certs/tasks/main.yml b/roles/sys-svc-certs/tasks/main.yml index b4dabc263e..f61f11cdee 100644 --- a/roles/sys-svc-certs/tasks/main.yml +++ b/roles/sys-svc-certs/tasks/main.yml @@ -1,13 +1,13 @@ --- - block: - - name: Include dependency 'sys-svc-webserver-https' + - name: ๐Ÿ“‚ Include dependency 'sys-svc-webserver-https' include_role: name: sys-svc-webserver-https when: run_once_sys_svc_webserver_https is not defined - include_tasks: utils/once/flag.yml when: run_once_sys_svc_certs is not defined -- name: "Include flavor '{{ CERTBOT_FLAVOR }}' for '{{ domain }}'" +- name: "๐Ÿ“‚ Include flavor '{{ CERTBOT_FLAVOR }}' for '{{ domain }}'" include_tasks: "{{ [role_path, 'tasks/flavors', CERTBOT_FLAVOR ~'.yml'] | path_join }}" #- name: "Cleanup dedicated cert for '{{ domain }}'" diff --git a/roles/sys-svc-cln-domains/tasks/main.yml b/roles/sys-svc-cln-domains/tasks/main.yml index 601b65b10c..d8a5c82c07 100644 --- a/roles/sys-svc-cln-domains/tasks/main.yml +++ b/roles/sys-svc-cln-domains/tasks/main.yml @@ -1,6 +1,6 @@ --- - block: - - name: Include dependencies + - name: ๐Ÿ“‚ Include dependencies include_role: name: "{{ dependency_role }}" loop: @@ -8,7 +8,7 @@ loop_control: loop_var: dependency_role - - name: Include task to remove deprecated nginx configs + - name: ๐Ÿ“‚ Include task to remove deprecated nginx configs include_tasks: remove_deprecated_nginx_configs.yml loop: "{{ deprecated_domains }}" loop_control: diff --git a/roles/sys-svc-cln-domains/tasks/remove_deprecated_nginx_configs.yml b/roles/sys-svc-cln-domains/tasks/remove_deprecated_nginx_configs.yml index 3c67fd0092..0c50928a19 100644 --- a/roles/sys-svc-cln-domains/tasks/remove_deprecated_nginx_configs.yml +++ b/roles/sys-svc-cln-domains/tasks/remove_deprecated_nginx_configs.yml @@ -1,12 +1,12 @@ --- -- name: Find matching nginx configs for {{ domain }} +- name: ๐Ÿ” Find matching nginx configs for {{ domain }} ansible.builtin.find: paths: "{{ lookup('nginx','directories.configuration.servers') }}" recurse: true patterns: "*.{{ domain }}.conf" register: find_result -- name: Remove wildcard nginx configs for {{ domain }} +- name: ๐Ÿ—‘๏ธ Remove wildcard nginx configs for {{ domain }} ansible.builtin.file: path: "{{ item.path }}" state: absent @@ -14,7 +14,7 @@ when: item is defined notify: restart openresty -- name: Remove exact nginx config for {{ domain }} +- name: ๐Ÿ—‘๏ธ Remove exact nginx config for {{ domain }} ansible.builtin.file: path: "{{ lookup('nginx', 'files.domain', domain) }}" state: absent diff --git a/roles/sys-svc-compose-ca/tasks/01_core.yml b/roles/sys-svc-compose-ca/tasks/01_core.yml index 201b100570..caafd09142 100644 --- a/roles/sys-svc-compose-ca/tasks/01_core.yml +++ b/roles/sys-svc-compose-ca/tasks/01_core.yml @@ -3,7 +3,7 @@ name: sys-ca-selfsigned when: run_once_sys_ca_selfsigned is not defined -- name: "CA trust | ensure directories exist" +- name: "โœ… CA trust | ensure directories exist" become: true ansible.builtin.file: path: "{{ item }}" @@ -14,20 +14,20 @@ - "{{ BIN_CA_TRUST | dirname }}" - "{{ BIN_CA_INJECT | dirname }}" -- name: "CA trust | check CA certificate exists on target host (hard fail if missing)" +- name: "๐Ÿ”Ž CA trust | check CA certificate exists on target host (hard fail if missing)" become: true ansible.builtin.stat: path: "{{ CA_TRUST.cert_host }}" register: _ca_cert_stat -- name: "CA trust | fail if CA certificate missing" +- name: "๐Ÿ›‘ CA trust | fail if CA certificate missing" ansible.builtin.fail: msg: >- CA trust certificate missing on target host: {{ CA_TRUST.cert_host }}. Provision it before running compose CA injection. when: not _ca_cert_stat.stat.exists -- name: "CA trust | install compose CA inject script" +- name: "๐Ÿ“ฆ CA trust | install compose CA inject script" become: true ansible.builtin.copy: src: "compose_ca.py" diff --git a/roles/sys-svc-compose/tasks/01_core.yml b/roles/sys-svc-compose/tasks/01_core.yml index abaf356135..14255f4811 100644 --- a/roles/sys-svc-compose/tasks/01_core.yml +++ b/roles/sys-svc-compose/tasks/01_core.yml @@ -6,16 +6,16 @@ public: false when: run_once_sys_svc_container is not defined -- name: Remove all compose pull locks +- name: ๐Ÿ—‘๏ธ Remove all compose pull locks file: path: "{{ DIR_COMPOSE_PULL_LOCK }}" state: absent -- name: "reset (if enabled) for {{ role_name}}" +- name: "โ™ป๏ธ reset (if enabled) for {{ role_name}}" include_tasks: 02_reset.yml when: MODE_RESET | bool -- name: "create {{ DIR_COMPOSITIONS }}" +- name: "๐Ÿ“ create {{ DIR_COMPOSITIONS }}" file: path: "{{ DIR_COMPOSITIONS }}" state: directory @@ -23,12 +23,12 @@ owner: root group: root -- name: "Ensure compose wrapper system deps (PyYAML)" +- name: "โœ… Ensure compose wrapper system deps (PyYAML)" ansible.builtin.package: name: "{{ sys_svc_compose_pyyaml_package[ansible_os_family] }}" state: present -- name: Install compose wrapper +- name: ๐Ÿ“ฆ Install compose wrapper become: true ansible.builtin.copy: src: "compose.py" @@ -37,7 +37,7 @@ owner: root group: root -- name: Install resolve-container-id helper (Swarm task โ†’ container ID) +- name: ๐Ÿ“ฆ Install resolve-container-id helper (Swarm task โ†’ container ID) become: true ansible.builtin.copy: src: "resolve_container_id.sh" diff --git a/roles/sys-svc-compose/tasks/02_reset.yml b/roles/sys-svc-compose/tasks/02_reset.yml index 7375007ea6..eb2e44a8ed 100644 --- a/roles/sys-svc-compose/tasks/02_reset.yml +++ b/roles/sys-svc-compose/tasks/02_reset.yml @@ -2,16 +2,16 @@ # It is necessary to shut the projects down, when reset is activated. # Otherwise it can lead to this bug: # https://github.com/ansible/ansible/issues/10244 -- name: "pkgmgr install '{{ COMPOSE_DOWN_ALL_PACKAGE }}'" +- name: "๐Ÿ“ฆ pkgmgr install '{{ COMPOSE_DOWN_ALL_PACKAGE }}'" include_role: name: pkgmgr-install vars: package_name: "{{ COMPOSE_DOWN_ALL_PACKAGE }}" -- name: Shutdown all compose instances in '{{ DIR_COMPOSITIONS }}' with '{{ COMPOSE_DOWN_ALL_PACKAGE }}' +- name: "๐Ÿงน Shutdown compose instances in '{{ DIR_COMPOSITIONS }}'" command: "{{ COMPOSE_DOWN_ALL_PACKAGE }} {{ DIR_COMPOSITIONS }}" -- name: "Remove directory '{{ DIR_COMPOSITIONS }}' and all its contents" +- name: "๐Ÿ—‘๏ธ Remove directory '{{ DIR_COMPOSITIONS }}' and all its contents" file: path: "{{ DIR_COMPOSITIONS }}" state: absent diff --git a/roles/sys-svc-compose/tasks/02_stack_host_prep.yml b/roles/sys-svc-compose/tasks/02_stack_host_prep.yml index fcfedc990c..cc8196cc45 100644 --- a/roles/sys-svc-compose/tasks/02_stack_host_prep.yml +++ b/roles/sys-svc-compose/tasks/02_stack_host_prep.yml @@ -1,19 +1,19 @@ --- -- name: "Create all sys-svc-compose directories (including parent directories) for '{{ application_id }}'" +- name: "๐Ÿ“ Create sys-svc-compose dirs (with parents) for '{{ application_id }}'" file: path: "{{ item.value }}" state: directory mode: "0755" with_dict: "{{ lookup('container', application_id, 'directories') }}" -- name: "Include routines to set up a git repository based installation for '{{ application_id }}'." +- name: "๐Ÿ“‚ Include git-repo based installation routines for '{{ application_id }}'." include_tasks: "03_repository.yml" when: compose_repository_pull | bool -- name: "Include file management routines for '{{ application_id }}'." +- name: "๐Ÿ“‚ Include file management routines for '{{ application_id }}'." include_tasks: "04_files.yml" -- name: "Ensure CA trust assets are installed (only when needed)" +- name: "โœ… Ensure CA trust assets are installed (only when needed)" ansible.builtin.include_role: name: sys-svc-compose-ca when: diff --git a/roles/sys-svc-compose/tasks/03_repository.yml b/roles/sys-svc-compose/tasks/03_repository.yml index 5bfd134cc4..c8d74d5aa1 100644 --- a/roles/sys-svc-compose/tasks/03_repository.yml +++ b/roles/sys-svc-compose/tasks/03_repository.yml @@ -1,9 +1,9 @@ --- -- name: Set default compose_repository_path +- name: ๐Ÿ”ง Set default compose_repository_path set_fact: compose_repository_path: "{{ [ lookup('container', application_id, 'directories.services'), 'repository/' ] | path_join }}" -- name: Pull docker repository +- name: โฌ‡๏ธ Pull docker repository git: repo: "{{ compose_repository_url }}" dest: "{{ compose_repository_path }}" diff --git a/roles/sys-svc-compose/tasks/04_files.yml b/roles/sys-svc-compose/tasks/04_files.yml index d4a325060d..59117d7e92 100644 --- a/roles/sys-svc-compose/tasks/04_files.yml +++ b/roles/sys-svc-compose/tasks/04_files.yml @@ -1,5 +1,5 @@ --- -- name: "Find optional Dockerfile for {{ application_id }}" +- name: "๐Ÿ” Find optional Dockerfile for {{ application_id }}" set_fact: dockerfile_src: >- {{ lookup( @@ -14,7 +14,7 @@ ) | default('', true) }} -- name: "Create (optional) Dockerfile for {{ application_id }}" +- name: "๐Ÿ“ Create (optional) Dockerfile for {{ application_id }}" stack_host_template: src: "{{ dockerfile_src }}" dest: "{{ lookup('container', application_id, 'files.dockerfile') }}" @@ -25,7 +25,7 @@ when: - dockerfile_src | default('') | length > 0 -- name: "Create (optional) '{{ lookup('container', application_id, 'files.env') }}'" +- name: "๐Ÿ“ Create (optional) '{{ lookup('container', application_id, 'files.env') }}'" stack_host_template: src: "{{ item }}" dest: "{{ lookup('container', application_id, 'files.env') }}" @@ -41,7 +41,7 @@ skip: true register: env_template -- name: "Create (optional) '{{ lookup('container', application_id, 'files.compose_override') }}'" +- name: "๐Ÿ“ Create (optional) compose override for '{{ application_id }}'" stack_host_template: src: "{{ item }}" dest: "{{ lookup('container', application_id, 'files.compose_override') }}" @@ -54,7 +54,7 @@ - "{{ application_id | abs_role_path_by_application_id }}/files/compose.override.yml" skip: true -- name: "Create (optional) '{{ lookup('container', application_id, 'files.compose') }}'" +- name: "๐Ÿ“ Create (optional) '{{ lookup('container', application_id, 'files.compose') }}'" stack_host_template: src: "{{ item }}" dest: "{{ lookup('container', application_id, 'files.compose') }}" diff --git a/roles/sys-svc-compose/tasks/main.yml b/roles/sys-svc-compose/tasks/main.yml index 586071a09e..5e7c367d8c 100644 --- a/roles/sys-svc-compose/tasks/main.yml +++ b/roles/sys-svc-compose/tasks/main.yml @@ -2,7 +2,7 @@ - include_tasks: 01_core.yml when: run_once_sys_svc_compose is not defined -- name: "Route docker cleanup/health deps through service-loader" +- name: "๐Ÿงญ Route docker cleanup/health deps through service-loader" ansible.builtin.include_role: name: sys-service-loader tasks_from: list_or_shoot.yml @@ -13,7 +13,7 @@ - sys-ctl-hlth-volumes - sys-ctl-rpr-container-hard -- name: "Route svc-bkp-container-2-local through service-loader (when deployed)" +- name: "๐Ÿงญ Route svc-bkp-container-2-local through service-loader (when deployed)" ansible.builtin.include_role: name: sys-service-loader tasks_from: list_or_shoot.yml @@ -22,13 +22,13 @@ - svc-bkp-container-2-local when: "'svc-bkp-container-2-local' in group_names" -- name: "Stack-host-only prep (dirs, repo, files, CA trust) for '{{ application_id }}'" +- name: "๐Ÿ–ฅ๏ธ Stack-host-only prep (dirs, repo, files, CA trust) for '{{ application_id }}'" include_tasks: "02_stack_host_prep.yml" when: IS_STACK_HOST | bool -- name: "Pre-create NFS subdirs declared by '{{ application_id }}' (swarm + NFS backend only)" +- name: "๐Ÿ“ Pre-create NFS subdirs for '{{ application_id }}' (swarm + NFS only)" include_tasks: "utils/nfs_prep.yml" -- name: "Ensure that {{ lookup('container', application_id, 'directories.instance') }} is up" +- name: "โœ… Ensure instance dir for '{{ application_id }}' is up" include_tasks: "utils/up.yml" when: IS_STACK_HOST | bool diff --git a/roles/sys-svc-compose/tasks/utils/_render_one_template.yml b/roles/sys-svc-compose/tasks/utils/_render_one_template.yml index bdeccf034e..6c313a923b 100644 --- a/roles/sys-svc-compose/tasks/utils/_render_one_template.yml +++ b/roles/sys-svc-compose/tasks/utils/_render_one_template.yml @@ -1,5 +1,5 @@ --- -- name: "Ensure parent directory exists for '{{ _tpl.dest }}'" +- name: "โœ… Ensure parent directory exists for '{{ _tpl.dest }}'" ansible.builtin.file: path: "{{ _tpl.dest | dirname }}" state: directory @@ -8,7 +8,7 @@ run_once: true when: (_tpl.when | default(true)) | bool -- name: "Render '{{ _tpl.dest }}' (on manager when swarm)" +- name: "๐Ÿ“„ Render '{{ _tpl.dest }}' (on manager when swarm)" ansible.builtin.template: # nocheck: stack-host-template (structurally STACK_HOST-delegated already (delegate_to + run_once), uses its own swarm-distribution dance) src: "{{ _tpl.src }}" dest: "{{ _tpl.dest }}" diff --git a/roles/sys-svc-compose/tasks/utils/finalize.yml b/roles/sys-svc-compose/tasks/utils/finalize.yml index c5e8360be4..2001f28652 100644 --- a/roles/sys-svc-compose/tasks/utils/finalize.yml +++ b/roles/sys-svc-compose/tasks/utils/finalize.yml @@ -1,8 +1,8 @@ --- -- name: "Flush compose handlers for '{{ application_id }}'" +- name: "๐Ÿšฟ Flush compose handlers for '{{ application_id }}'" meta: flush_handlers -- name: "Post-deploy steps for '{{ application_id }}'" +- name: "๐Ÿš€ Post-deploy steps for '{{ application_id }}'" ansible.builtin.include_tasks: file: post_deploy.yml apply: diff --git a/roles/sys-svc-compose/tasks/utils/network/create.yml b/roles/sys-svc-compose/tasks/utils/network/create.yml index a217c3c419..fe4b5cef89 100644 --- a/roles/sys-svc-compose/tasks/utils/network/create.yml +++ b/roles/sys-svc-compose/tasks/utils/network/create.yml @@ -1,5 +1,5 @@ --- -- name: "Ensure docker overlay network for '{{ network_role_id }}' exists (swarm scope)" +- name: "โœ… Ensure docker overlay network for '{{ network_role_id }}' exists (swarm scope)" community.docker.docker_network: name: "{{ network_role_id | get_entity_name }}" state: present @@ -17,7 +17,7 @@ run_once: true delegate_to: "{{ STACK_HOST }}" -- name: "Ensure docker bridge network for '{{ network_role_id }}' exists (compose mode, no swarm)" +- name: "โœ… Ensure docker bridge network for '{{ network_role_id }}' exists (compose)" community.docker.docker_network: name: "{{ network_role_id | get_entity_name }}" state: present diff --git a/roles/sys-svc-compose/tasks/utils/network/routine.yml b/roles/sys-svc-compose/tasks/utils/network/routine.yml index 23d8234dcb..ae1b7d9a3c 100644 --- a/roles/sys-svc-compose/tasks/utils/network/routine.yml +++ b/roles/sys-svc-compose/tasks/utils/network/routine.yml @@ -1,16 +1,16 @@ --- -- name: "1) Load the dependencies for the Anisble/Docker network management" +- name: "๐Ÿงฉ 1) Load the dependencies for the Anisble/Docker network management" include_role: name: sys-svc-container public: false when: run_once_sys_svc_container is not defined -- name: "2) Create the network" +- name: "๐Ÿ“ 2) Create the network" include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/network/create.yml' ] | path_join }}" vars: network_role_id: "{{ application_id }}" -- name: "3) Include and flush the compose which requires the network" +- name: "๐Ÿ“‚ 3) Include and flush the compose which requires the network" include_role: name: sys-svc-compose vars: diff --git a/roles/sys-svc-compose/tasks/utils/nfs_prep.yml b/roles/sys-svc-compose/tasks/utils/nfs_prep.yml index b37001e1a0..6417ca5172 100644 --- a/roles/sys-svc-compose/tasks/utils/nfs_prep.yml +++ b/roles/sys-svc-compose/tasks/utils/nfs_prep.yml @@ -1,5 +1,5 @@ --- -- name: "Pre-create NFS subdir for '{{ application_id }}' volume '{{ item.key }}' on the NFS server" +- name: "๐Ÿ“ Pre-create NFS subdir for '{{ application_id }}' volume '{{ item.key }}'" ansible.builtin.file: path: "{{ STORAGE_NFS_STATE_PATH }}/{{ item.value.name | default(item.key) }}" state: directory diff --git a/roles/sys-svc-compose/tasks/utils/post_deploy.yml b/roles/sys-svc-compose/tasks/utils/post_deploy.yml index 72653197c8..807a89ec9a 100644 --- a/roles/sys-svc-compose/tasks/utils/post_deploy.yml +++ b/roles/sys-svc-compose/tasks/utils/post_deploy.yml @@ -1,5 +1,5 @@ --- -- name: "Wait until database container for '{{ application_id }}' is healthy" +- name: "โณ Wait until database container for '{{ application_id }}' is healthy" ansible.builtin.command: >- container inspect --format={% raw %}{{.State.Health.Status}}{% endraw %} @@ -13,7 +13,7 @@ - DEPLOYMENT_MODE == 'compose' - lookup('database', application_id, 'enabled') | bool -- name: "Wait until all swarm tasks for '{{ application_id | get_entity_name }}' converge to running" +- name: "โณ Wait until swarm tasks of '{{ application_id | get_entity_name }}' are running" ansible.builtin.script: "{{ [playbook_dir, 'roles/sys-svc-compose/files/swarm_stack_ready.sh'] | path_join }}" environment: STACK: "{{ application_id | get_entity_name }}" diff --git a/roles/sys-svc-compose/tasks/utils/render_replicated_templates.yml b/roles/sys-svc-compose/tasks/utils/render_replicated_templates.yml index 8e963f7464..6918374a51 100644 --- a/roles/sys-svc-compose/tasks/utils/render_replicated_templates.yml +++ b/roles/sys-svc-compose/tasks/utils/render_replicated_templates.yml @@ -1,5 +1,5 @@ --- -- name: "Expand fileglob-driven entries for '{{ application_id }}'" +- name: "๐Ÿ“ค Expand fileglob-driven entries for '{{ application_id }}'" ansible.builtin.set_fact: _role_templates_expanded: >- {%- set out = [] -%} @@ -24,7 +24,7 @@ {%- endfor -%} {{ out }} -- name: "Render and replicate templates for '{{ application_id }}'" +- name: "๐Ÿ“„ Render and replicate templates for '{{ application_id }}'" ansible.builtin.include_tasks: "_render_one_template.yml" loop: "{{ _role_templates_expanded }}" loop_control: diff --git a/roles/sys-svc-compose/tasks/utils/swarm/resolve_host_cid.yml b/roles/sys-svc-compose/tasks/utils/swarm/resolve_host_cid.yml index 241bcdd79d..4443da0a01 100644 --- a/roles/sys-svc-compose/tasks/utils/swarm/resolve_host_cid.yml +++ b/roles/sys-svc-compose/tasks/utils/swarm/resolve_host_cid.yml @@ -11,7 +11,7 @@ # Param: resolve_converge_delay - swarm converge delay seconds (default 2) # Param: resolve_cid_filters - extra `container ps` filters for the cid lookup (default '') # Param: resolve_run_host - host that runs the manager-only queries (default: inventory_hostname) -- name: "resolve_host_cid | wait for '{{ resolve_service_key }}' to converge" +- name: "โณ resolve_host_cid | wait for '{{ resolve_service_key }}' to converge" ansible.builtin.include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/swarm/wait_converged.yml'] | path_join }}" vars: wait_service_key: "{{ resolve_service_key }}" @@ -19,7 +19,7 @@ wait_delay: "{{ resolve_converge_delay | default(2) }}" wait_run_host: "{{ resolve_run_host | default(inventory_hostname) }}" -- name: "resolve_host_cid | resolve hosting node for '{{ resolve_service_key }}'" +- name: "๐Ÿ” resolve_host_cid | resolve hosting node for '{{ resolve_service_key }}'" ansible.builtin.shell: | container service ps {{ lookup('container_service', application_id, resolve_service_key) | quote }} \ --filter desired-state=running \ @@ -29,11 +29,11 @@ delegate_to: "{{ resolve_run_host | default(inventory_hostname) }}" when: DEPLOYMENT_MODE == 'swarm' -- name: "resolve_host_cid | set {{ resolve_output_prefix }}_HOST_NODE" +- name: "๐Ÿ”ง resolve_host_cid | set {{ resolve_output_prefix }}_HOST_NODE" ansible.builtin.set_fact: "{{ resolve_output_prefix }}_HOST_NODE": "{{ (_resolve_node.stdout | trim) if DEPLOYMENT_MODE == 'swarm' else inventory_hostname }}" -- name: "resolve_host_cid | resolve local container id for '{{ resolve_service_key }}'" +- name: "๐Ÿ” resolve_host_cid | resolve local container id for '{{ resolve_service_key }}'" ansible.builtin.shell: | {% if DEPLOYMENT_MODE == 'swarm' %} container ps \ @@ -47,6 +47,6 @@ changed_when: false delegate_to: "{{ lookup('vars', resolve_output_prefix ~ '_HOST_NODE') }}" -- name: "resolve_host_cid | set {{ resolve_output_prefix }}_LOCAL_CID" +- name: "๐Ÿ”ง resolve_host_cid | set {{ resolve_output_prefix }}_LOCAL_CID" ansible.builtin.set_fact: "{{ resolve_output_prefix }}_LOCAL_CID": "{{ _resolve_cid.stdout | trim }}" diff --git a/roles/sys-svc-compose/tasks/utils/swarm/wait_converged.yml b/roles/sys-svc-compose/tasks/utils/swarm/wait_converged.yml index 48ab70983c..b6d6d0d038 100644 --- a/roles/sys-svc-compose/tasks/utils/swarm/wait_converged.yml +++ b/roles/sys-svc-compose/tasks/utils/swarm/wait_converged.yml @@ -8,7 +8,7 @@ # Param: wait_run_host - host that runs the manager-only query (default: inventory_hostname) - when: DEPLOYMENT_MODE == 'swarm' block: - - name: "swarm | wait for '{{ wait_service_key }}' task to converge" + - name: "โณ swarm | wait for '{{ wait_service_key }}' task to converge" ansible.builtin.shell: | container service ps {{ lookup('container_service', application_id, wait_service_key) | quote }} \ --filter desired-state=running \ @@ -22,7 +22,7 @@ delegate_to: "{{ wait_run_host | default(inventory_hostname) }}" rescue: - - name: "swarm | dump '{{ wait_service_key }}' service ps + logs on converge failure" + - name: "๐Ÿ’พ swarm | dump '{{ wait_service_key }}' service ps + logs on converge failure" ansible.builtin.shell: | echo "===== container service ps {{ wait_service_key }} =====" container service ps --no-trunc {{ lookup('container_service', application_id, wait_service_key) | quote }} 2>&1 || true @@ -34,12 +34,12 @@ delegate_to: "{{ wait_run_host | default(inventory_hostname) }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" - - name: "swarm | show '{{ wait_service_key }}' converge diagnostics" + - name: "๐Ÿ‘๏ธ swarm | show '{{ wait_service_key }}' converge diagnostics" ansible.builtin.debug: msg: "{{ (_swarm_converge_dump.stdout | default('')).split('\n') }}" when: not (MASK_CREDENTIALS_IN_LOGS | bool) - - name: "swarm | abort with '{{ wait_service_key }}' converge root cause" + - name: "๐Ÿ›‘ swarm | abort with '{{ wait_service_key }}' converge root cause" ansible.builtin.fail: msg: >- swarm service '{{ wait_service_key }}' did not converge after diff --git a/roles/sys-svc-compose/tasks/utils/up.yml b/roles/sys-svc-compose/tasks/utils/up.yml index fbf5be52c9..bc0ff554e0 100644 --- a/roles/sys-svc-compose/tasks/utils/up.yml +++ b/roles/sys-svc-compose/tasks/utils/up.yml @@ -1,5 +1,5 @@ --- -- name: "Check if any container is running in {{ lookup('container', application_id, 'directories.instance') }}" +- name: "๐Ÿ” Check running containers for '{{ application_id }}'" command: >- compose ps -q --filter status=running args: @@ -23,18 +23,18 @@ - DEPLOYMENT_MODE == 'compose' notify: compose up -- name: "Notify swarm deploy (under DEPLOYMENT_MODE == swarm)" +- name: "๐Ÿ”” Notify swarm deploy (under DEPLOYMENT_MODE == swarm)" ansible.builtin.debug: msg: "Triggering swarm stack deploy for {{ application_id }}" changed_when: true when: DEPLOYMENT_MODE == 'swarm' notify: swarm deploy -- name: "Flush Docker Compose Up Handlers for {{ lookup('container', application_id, 'directories.instance') }}" +- name: "๐Ÿ”„ Flush compose up handlers for '{{ application_id }}'" meta: flush_handlers when: compose_handlers_flush | bool -- name: "Post-deploy steps for '{{ application_id }}'" +- name: "๐Ÿš€ Post-deploy steps for '{{ application_id }}'" ansible.builtin.include_tasks: file: post_deploy.yml apply: diff --git a/roles/sys-svc-container/tasks/01_core.yml b/roles/sys-svc-container/tasks/01_core.yml index 522e0c2360..e47f2a98f2 100644 --- a/roles/sys-svc-container/tasks/01_core.yml +++ b/roles/sys-svc-container/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Resolve Docker package list for current distribution +- name: ๐Ÿ” Resolve Docker package list for current distribution ansible.builtin.set_fact: sys_svc_container_packages: >- {{ @@ -8,7 +8,7 @@ else [] }} -- name: Fail for unsupported distribution in Docker role +- name: ๐Ÿ›‘ Fail for unsupported distribution in Docker role ansible.builtin.assert: that: - (sys_svc_container_packages | length) > 0 @@ -16,21 +16,21 @@ Unsupported distribution for Docker role: {{ ansible_facts['distribution'] }} ({{ ansible_facts['os_family'] }}). -- name: Setup Docker repository on Debian and Ubuntu +- name: ๐Ÿ”ง Setup Docker repository on Debian and Ubuntu include_tasks: 01a_debian.yml when: ansible_facts['distribution'] in ['Debian', 'Ubuntu'] -- name: Setup Docker repository and SDK prerequisites on RedHat family +- name: ๐Ÿ”ง Setup Docker repository and SDK prerequisites on RedHat family include_tasks: 01b_redhat.yml when: ansible_facts['os_family'] == 'RedHat' -- name: Install Docker packages +- name: ๐Ÿ“ฆ Install Docker packages ansible.builtin.package: name: "{{ sys_svc_container_packages }}" state: present notify: container manager restart -- name: Install Docker Python SDK dependencies via pip +- name: ๐Ÿ“ฆ Install Docker Python SDK dependencies via pip include_role: name: sys-pip-install vars: @@ -40,7 +40,7 @@ package_state: present global_install: true -- name: Install container wrapper (container) +- name: ๐Ÿ“ฆ Install container wrapper (container) become: true ansible.builtin.copy: src: container.py @@ -49,50 +49,50 @@ owner: root group: root -- name: "Assert that required services are available" +- name: "โœ… Assert that required services are available" include_tasks: "02_assert_requirements.yml" when: MODE_ASSERT | bool -- name: "Load docker in docker procedures" +- name: "๐Ÿงฉ Load docker in docker procedures" include_tasks: "03_docker_in_docker.yml" when: DOCKER_IN_CONTAINER | bool -- name: Restart and enable docker service +- name: ๐Ÿ”„ Restart and enable docker service meta: flush_handlers -- name: Ensure docker service is enabled and running +- name: โœ… Ensure docker service is enabled and running ansible.builtin.service: name: docker.service state: started enabled: true -- name: Wait for docker socket to be available +- name: โณ Wait for docker socket to be available ansible.builtin.wait_for: path: /var/run/docker.sock state: present timeout: 60 -- name: "Overwrite when DOCKER_IN_CONTAINER is true" +- name: "โœ๏ธ Overwrite when DOCKER_IN_CONTAINER is true" block: - - name: Get docker bridge gateway + - name: โฌ‡๏ธ Get docker bridge gateway docker_bridge_gateway: register: gw changed_when: false - - name: "Set docker bridge gateway fact to '{{ gw.gateway }}'" + - name: "๐Ÿ”ง Set docker bridge gateway fact to '{{ gw.gateway }}'" set_fact: DOCKER_REACH_HOST: "{{ gw.gateway }}" changed_when: false when: DOCKER_IN_CONTAINER | bool -- name: Setup Swapfile to prevent OOM Failures +- name: ๐Ÿ”ง Setup Swapfile to prevent OOM Failures # @ See https://en.wikipedia.org/wiki/Out_of_memory include_tasks: "utils/load_app.yml" vars: load_app_id: "svc-opt-swapfile" when: run_once_svc_opt_swapfile is not defined -- name: "Load reset tasks when MODE_RESET is enabled" +- name: "๐Ÿ“‚ Load reset tasks when MODE_RESET is enabled" include_tasks: "04_reset.yml" when: MODE_RESET | bool diff --git a/roles/sys-svc-container/tasks/01a_debian.yml b/roles/sys-svc-container/tasks/01a_debian.yml index 43f8d93bc7..efd66520dc 100644 --- a/roles/sys-svc-container/tasks/01a_debian.yml +++ b/roles/sys-svc-container/tasks/01a_debian.yml @@ -1,5 +1,5 @@ --- -- name: Ensure Docker apt key and sources are consistent +- name: โœ… Ensure Docker apt key and sources are consistent ansible.builtin.script: cmd: >- {{ role_path }}/files/apt_repo.sh @@ -10,7 +10,7 @@ register: sys_svc_container_docker_repo_setup changed_when: "'changed=1' in sys_svc_container_docker_repo_setup.stdout" -- name: Configure Docker apt repository +- name: ๐Ÿ”ง Configure Docker apt repository ansible.builtin.apt_repository: repo: >- deb [arch={{ SYS_SVC_CONTAINER_DPKG_ARCH_BY_ANSIBLE_ARCH.get(ansible_facts['architecture'], ansible_facts['architecture']) }} diff --git a/roles/sys-svc-container/tasks/01b_redhat.yml b/roles/sys-svc-container/tasks/01b_redhat.yml index b9d6638416..7a074b467e 100644 --- a/roles/sys-svc-container/tasks/01b_redhat.yml +++ b/roles/sys-svc-container/tasks/01b_redhat.yml @@ -1,5 +1,5 @@ --- -- name: Configure Docker yum repository +- name: ๐Ÿ”ง Configure Docker yum repository get_url_retry: url: "https://download.docker.com/linux/{{ SYS_SVC_CONTAINER_DOCKER_REPO_DISTRO_BY_DISTRIBUTION[ansible_facts['distribution']] }}/docker-ce.repo" dest: /etc/yum.repos.d/docker-ce.repo diff --git a/roles/sys-svc-container/tasks/02_assert_requirements.yml b/roles/sys-svc-container/tasks/02_assert_requirements.yml index 745ffca7d8..5ca99e9e74 100644 --- a/roles/sys-svc-container/tasks/02_assert_requirements.yml +++ b/roles/sys-svc-container/tasks/02_assert_requirements.yml @@ -1,31 +1,31 @@ --- -- name: Gather service facts +- name: ๐Ÿ“Š Gather service facts ansible.builtin.service_facts: -- name: Assert systemd is available +- name: โœ… Assert systemd is available ansible.builtin.assert: that: - ansible_facts['service_mgr'] == "systemd" fail_msg: > systemd is not available. This role requires systemd (service manager = {{ ansible_facts['service_mgr'] }}). -- name: Read PID 1 process name +- name: ๐Ÿ“– Read PID 1 process name ansible.builtin.slurp: src: /proc/1/comm register: pid1_comm -- name: Fail if PID1 is not systemd +- name: ๐Ÿ›‘ Fail if PID1 is not systemd ansible.builtin.assert: that: - pid1_comm.content | b64decode | trim == "systemd" fail_msg: "PID 1 is not systemd (PID1={{ pid1_comm.content | b64decode | trim }}). Docker service management will hang." -- name: Check docker socket +- name: ๐Ÿ”Ž Check docker socket ansible.builtin.stat: path: /var/run/docker.sock register: docker_sock -- name: Assert docker service exists +- name: โœ… Assert docker service exists ansible.builtin.assert: that: - "'docker.service' in ansible_facts.services" diff --git a/roles/sys-svc-container/tasks/03_docker_in_docker.yml b/roles/sys-svc-container/tasks/03_docker_in_docker.yml index 1d63d4137e..01cc3a6e1d 100644 --- a/roles/sys-svc-container/tasks/03_docker_in_docker.yml +++ b/roles/sys-svc-container/tasks/03_docker_in_docker.yml @@ -1,20 +1,20 @@ --- -- name: Ensure '{{ SYS_SVC_DOCKER_DIR }}' exists +- name: โœ… Ensure '{{ SYS_SVC_DOCKER_DIR }}' exists file: path: "{{ SYS_SVC_DOCKER_DIR }}" state: directory mode: "0755" -- name: Install fuse-overlayfs in container +- name: ๐Ÿ“ฆ Install fuse-overlayfs in container ansible.builtin.package: name: fuse-overlayfs state: present notify: container manager restart -- name: Compute and set Docker daemon MTU (container) +- name: ๐Ÿงฎ Compute and set Docker daemon MTU (container) include_tasks: "_mtu.yml" -- name: Configure docker daemon storage driver (container) +- name: ๐Ÿ”ง Configure docker daemon storage driver (container) ansible.builtin.template: # nocheck: stack-host-template (per-host docker daemon config, runs on every container-host) src: daemon.json.j2 dest: "{{ SYS_SVC_DOCKER_DAEMON }}" @@ -26,7 +26,7 @@ # bridge MTU (1500) exceeds the deployer eth0 MTU (automtu-picked, typically 1400). # Without this, TCP packets forwarded from a 1500-MTU veth through the lower-MTU eth0 # hit PMTU blackholes because outer Docker NATs ICMP Frag Needed. -- name: Check if TCP MSS clamp to PMTU is already present (container) +- name: ๐Ÿ”Ž Check if TCP MSS clamp to PMTU is already present (container) ansible.builtin.command: argv: - iptables @@ -46,7 +46,7 @@ changed_when: false failed_when: false -- name: Ensure TCP MSS clamping to PMTU on FORWARD (container) +- name: โœ… Ensure TCP MSS clamping to PMTU on FORWARD (container) ansible.builtin.command: argv: - iptables diff --git a/roles/sys-svc-container/tasks/04_reset.yml b/roles/sys-svc-container/tasks/04_reset.yml index e605f9f715..5b92a7adca 100644 --- a/roles/sys-svc-container/tasks/04_reset.yml +++ b/roles/sys-svc-container/tasks/04_reset.yml @@ -1,10 +1,10 @@ --- -- name: Gather containers +- name: ๐Ÿ“Š Gather containers community.docker.docker_host_info: containers: true register: docker_info -- name: Remove containers (stops running ones) +- name: ๐Ÿ—‘๏ธ Remove containers (stops running ones) community.docker.docker_container: name: "{{ (item.Names | default([item.Name]))[0] | regex_replace('^/','') }}" state: absent @@ -14,7 +14,7 @@ label: "{{ (item.Names | default([item.Name]))[0] }}" when: docker_info.containers | length > 0 -- name: Trigger Docker restart +- name: โšก Trigger Docker restart ansible.builtin.debug: msg: "MODE_RESET is enabled โ†’ restarting Docker" notify: container manager restart diff --git a/roles/sys-svc-container/tasks/_mtu.yml b/roles/sys-svc-container/tasks/_mtu.yml index 90f93dad8f..cda04572f4 100644 --- a/roles/sys-svc-container/tasks/_mtu.yml +++ b/roles/sys-svc-container/tasks/_mtu.yml @@ -1,19 +1,19 @@ --- -- name: Install automtu via pip (system-wide) +- name: ๐Ÿ“ฆ Install automtu via pip (system-wide) include_role: name: sys-pip-install vars: package_name: automtu global_install: true -- name: Ensure 'ip' and 'ping' commands are available for automtu +- name: โœ… Ensure 'ip' and 'ping' commands are available for automtu ansible.builtin.package: name: - "{{ SYS_SVC_CONTAINER_IPROUTE_PACKAGE_BY_OS_FAMILY.get(ansible_facts['os_family'], 'iproute2') }}" - "{{ SYS_SVC_CONTAINER_PING_PACKAGE_BY_OS_FAMILY.get(ansible_facts['os_family'], 'iputils-ping') }}" state: present -- name: Detect safe Docker MTU +- name: ๐Ÿ” Detect safe Docker MTU ansible.builtin.command: argv: - "{{ ansible_python_interpreter }}" @@ -28,7 +28,7 @@ register: automtu_mtu changed_when: false -- name: Assert automtu returned an integer MTU +- name: โœ… Assert automtu returned an integer MTU ansible.builtin.assert: that: - automtu_mtu.stdout is match('^[0-9]+$') @@ -36,7 +36,7 @@ - (automtu_mtu.stdout | int) <= 9000 fail_msg: "automtu returned unexpected MTU output: '{{ automtu_mtu.stdout | default('') }}'" -- name: Set docker daemon MTU fact +- name: ๐Ÿ”ง Set docker daemon MTU fact ansible.builtin.set_fact: SYS_DOCKER_DAEMONM_MTU: "{{ automtu_mtu.stdout | int }}" changed_when: false diff --git a/roles/sys-svc-dns/tasks/01_core.yml b/roles/sys-svc-dns/tasks/01_core.yml index 9e70d55dc0..f46b92b92d 100644 --- a/roles/sys-svc-dns/tasks/01_core.yml +++ b/roles/sys-svc-dns/tasks/01_core.yml @@ -1,18 +1,18 @@ --- -- name: "Validate the Cloudflare API token" +- name: "โœ… Validate the Cloudflare API token" fail: msg: > API.cloudflare.api_token must be set (via lookup('api', 'cloudflare.api_token')) and cannot be empty! when: (lookup('api', 'cloudflare.api_token') | trim) == '' -- name: "Apply apex A/AAAA for base domains" +- name: "๐Ÿ“Œ Apply apex A/AAAA for base domains" include_tasks: 02_apex.yml loop: "{{ SYS_SVC_DNS_BASE_DOMAINS | list }}" loop_control: loop_var: base_domain label: "{{ base_domain }}" -- name: "Ensure all CAA records are present" +- name: "โœ… Ensure all CAA records are present" community.general.cloudflare_dns: api_token: "{{ lookup('api', 'cloudflare.api_token') }}" zone: "{{ item.0 }}" @@ -29,7 +29,7 @@ async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}" poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}" -- name: "Ensure wildcard parent DNS (*.parent) exists" +- name: "โœ… Ensure wildcard parent DNS (*.parent) exists" include_role: name: sys-dns-wildcards vars: diff --git a/roles/sys-svc-dns/tasks/02_apex.yml b/roles/sys-svc-dns/tasks/02_apex.yml index 1ad82d6815..1eb8732907 100644 --- a/roles/sys-svc-dns/tasks/02_apex.yml +++ b/roles/sys-svc-dns/tasks/02_apex.yml @@ -1,5 +1,5 @@ --- -- name: "Ensure A @ for {{ base_domain }}" +- name: "โœ… Ensure A @ for {{ base_domain }}" community.general.cloudflare_dns: api_token: "{{ lookup('api', 'cloudflare.api_token') }}" zone: "{{ base_domain }}" @@ -12,7 +12,7 @@ async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}" poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}" -- name: "Ensure AAAA @ for {{ base_domain }} with '{{ networks.internet.ip6 | default('None') }}" +- name: "โœ… AAAA @ for {{ base_domain }} = {{ networks.internet.ip6 | default('None') }}" community.general.cloudflare_dns: api_token: "{{ lookup('api', 'cloudflare.api_token') }}" zone: "{{ base_domain }}" diff --git a/roles/sys-svc-engine/tasks/main.yml b/roles/sys-svc-engine/tasks/main.yml index 71fff70660..85a6484909 100644 --- a/roles/sys-svc-engine/tasks/main.yml +++ b/roles/sys-svc-engine/tasks/main.yml @@ -1,11 +1,11 @@ --- # nocheck: run-once -- name: "For '{{ application_id }}': Freeze engine consumer id" +- name: "๐ŸงŠ For '{{ application_id }}': Freeze engine consumer id" ansible.builtin.set_fact: _engine_consumer_id: "{{ engine_consumer_id | default(application_id) }}" changed_when: false -- name: "For '{{ _engine_consumer_id }}': Provision shared engines on their central providers" +- name: "๐Ÿ”ง Provision shared engines for '{{ _engine_consumer_id }}'" include_tasks: provision.yml loop: "{{ ['rabbitmq', 'elasticsearch', 'typesense'] }}" loop_control: diff --git a/roles/sys-svc-engine/tasks/provision.yml b/roles/sys-svc-engine/tasks/provision.yml index edc092dc81..cd8f164820 100644 --- a/roles/sys-svc-engine/tasks/provision.yml +++ b/roles/sys-svc-engine/tasks/provision.yml @@ -1,9 +1,9 @@ --- -- name: "Provision '{{ _engine_consumer_id }}' on engine provider '{{ _engine_provider_role }}'" +- name: "๐Ÿ”ง Provision '{{ _engine_consumer_id }}' on '{{ _engine_provider_role }}'" vars: _engine_provider_role: "svc-db-{{ _engine_type }}" block: - - name: "Load engine provider '{{ _engine_provider_role }}' (lazy)" + - name: "๐Ÿงฉ Load engine provider '{{ _engine_provider_role }}' (lazy)" ansible.builtin.include_role: name: "{{ _engine_provider_role }}" vars: @@ -15,7 +15,7 @@ default='__missing__' ) == '__missing__' - - name: "Initialize '{{ _engine_consumer_id }}' on provider '{{ _engine_provider_role }}'" + - name: "๐ŸŽฌ Initialize '{{ _engine_consumer_id }}' on '{{ _engine_provider_role }}'" ansible.builtin.include_role: name: "{{ _engine_provider_role }}" vars: diff --git a/roles/sys-svc-journalctl/tasks/main.yml b/roles/sys-svc-journalctl/tasks/main.yml index c7fba19ce1..9386b7e10d 100644 --- a/roles/sys-svc-journalctl/tasks/main.yml +++ b/roles/sys-svc-journalctl/tasks/main.yml @@ -1,13 +1,13 @@ --- - block: - - name: Include dependency 'sys-ctl-hlth-journalctl' + - name: ๐Ÿ“‚ Include dependency 'sys-ctl-hlth-journalctl' include_role: name: sys-ctl-hlth-journalctl when: run_once_sys_ctl_hlth_journalctl is not defined - include_tasks: utils/once/flag.yml when: run_once_sys_svc_journalctl is not defined -- name: copy journald.conf +- name: ๐Ÿ“‹ copy journald.conf template: # nocheck: stack-host-template (per-host /etc/systemd/journald.conf, not stack-host-only) src: templates/journald.conf.j2 dest: /etc/systemd/journald.conf diff --git a/roles/sys-svc-mail-msmtp/tasks/disable.yml b/roles/sys-svc-mail-msmtp/tasks/disable.yml index 1395ee520c..44802960c4 100644 --- a/roles/sys-svc-mail-msmtp/tasks/disable.yml +++ b/roles/sys-svc-mail-msmtp/tasks/disable.yml @@ -1,18 +1,18 @@ --- -- name: "Ensure msmtp-mta is absent (conflicts with postfix smtp-forwarder)" +- name: "โœ… Ensure msmtp-mta is absent (conflicts with postfix smtp-forwarder)" package: name: - "{{ SYS_SVC_MAIL_MSMTP_PACKAGES.mta }}" state: absent when: SYS_SVC_MAIL_MSMTP_PACKAGES.mta != '' -- name: Inspect /usr/bin/sendmail path before cleanup +- name: ๐Ÿ”Ž Inspect /usr/bin/sendmail path before cleanup stat: path: /usr/bin/sendmail follow: false register: sys_svc_mail_msmtp_sendmail_stat -- name: Remove msmtp-managed sendmail compatibility link +- name: ๐Ÿ—‘๏ธ Remove msmtp-managed sendmail compatibility link file: path: /usr/bin/sendmail state: absent diff --git a/roles/sys-svc-mail-msmtp/tasks/enable.yml b/roles/sys-svc-mail-msmtp/tasks/enable.yml index 57d8c55639..5f8f9960f6 100644 --- a/roles/sys-svc-mail-msmtp/tasks/enable.yml +++ b/roles/sys-svc-mail-msmtp/tasks/enable.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: "Assert {{ DIR_VAR_LIB }} is cluster-shared in swarm mode (skip on dedicated NFS server / non-swarm hosts)" +- name: "โœ… Assert {{ DIR_VAR_LIB }} is cluster-shared in swarm mode" ansible.builtin.assert: that: - (DEPLOYMENT_MODE == 'compose') or ('svc-storage-nfs-client' in group_names) or ('svc-storage-nfs-server' in group_names) @@ -12,34 +12,34 @@ `svc-storage-nfs-client` group, unless this host is the dedicated NFS server (svc-storage-nfs-server). -- name: Enable EPEL repository on EL distributions +- name: ๐ŸŸข Enable EPEL repository on EL distributions package: name: epel-release state: present when: ansible_facts['distribution'] in SYS_SVC_MAIL_MSMTP_EPEL_DISTRIBUTIONS -- name: Install msmtp base package +- name: ๐Ÿ“ฆ Install msmtp base package package: name: "{{ SYS_SVC_MAIL_MSMTP_PACKAGES.base }}" state: present -- name: Ensure system CA certificates are installed +- name: โœ… Ensure system CA certificates are installed package: name: ca-certificates state: present -- name: "Disable SMTP to avoid port conflicts" +- name: "๐Ÿ”ด Disable SMTP to avoid port conflicts" include_tasks: "{{ [playbook_dir, 'roles/sys-svc-mail-smtp/tasks/disable.yml' ] | path_join }}" - when: lookup('email').external | bool block: - - name: Install msmtp-mta when Mailu is used and package exists on distro + - name: ๐Ÿ“ฆ Install msmtp-mta when Mailu is used and package exists on distro package: name: "{{ SYS_SVC_MAIL_MSMTP_PACKAGES.mta }}" state: present when: SYS_SVC_MAIL_MSMTP_PACKAGES.mta != '' - - name: Provide sendmail compatibility link when msmtp-mta is unavailable + - name: ๐Ÿ“ง Provide sendmail compatibility link when msmtp-mta is unavailable file: src: /usr/bin/msmtp dest: /usr/bin/sendmail @@ -47,13 +47,13 @@ force: true when: SYS_SVC_MAIL_MSMTP_PACKAGES.mta == '' -- name: Probe CA bundle candidate paths for msmtp TLS trust file +- name: ๐Ÿ” Probe CA bundle candidate paths for msmtp TLS trust file ansible.builtin.stat: path: "{{ item }}" loop: "{{ SYS_SVC_MAIL_MSMTP_CA_BUNDLE_CANDIDATES }}" register: _sys_svc_mail_msmtp_ca_probe -- name: Select first existing CA bundle path for msmtp +- name: ๐ŸŽฏ Select first existing CA bundle path for msmtp ansible.builtin.set_fact: sys_svc_mail_msmtp_ca_bundle: >- {{ @@ -66,13 +66,13 @@ ) | default(SYS_SVC_MAIL_MSMTP_CA_BUNDLE_CANDIDATES | first, true) }} -- name: configure msmtprc.conf.j2 +- name: ๐Ÿ”ง configure msmtprc.conf.j2 template: # nocheck: stack-host-template (per-host /root/.msmtprc, not stack-host-only) src: "msmtprc.conf.j2" dest: "/root/.msmtprc" mode: 600 -- name: "Route hlth-msmtp through service-loader so it runs after web-app-mailu compose-up" +- name: "๐Ÿ”„ Route hlth-msmtp via service-loader (after mailu compose-up)" ansible.builtin.include_role: name: sys-service-loader tasks_from: list_or_shoot.yml diff --git a/roles/sys-svc-mail-msmtp/tasks/main.yml b/roles/sys-svc-mail-msmtp/tasks/main.yml index 7fcbbab443..f0e853d4b2 100644 --- a/roles/sys-svc-mail-msmtp/tasks/main.yml +++ b/roles/sys-svc-mail-msmtp/tasks/main.yml @@ -1,4 +1,4 @@ --- -- name: "Load MSMTP (once)" +- name: "๐Ÿ”Œ Load MSMTP (once)" include_tasks: enable.yml when: not (run_once_sys_svc_mail_msmtp | default(false) | bool) diff --git a/roles/sys-svc-mail-smtp/tasks/disable.yml b/roles/sys-svc-mail-smtp/tasks/disable.yml index c84ee8b00a..ccf6d2e935 100644 --- a/roles/sys-svc-mail-smtp/tasks/disable.yml +++ b/roles/sys-svc-mail-smtp/tasks/disable.yml @@ -1,13 +1,13 @@ --- - block: - - name: Stop and disable postfix if present (avoid port 25 conflicts) + - name: โน๏ธ Stop and disable postfix if present (avoid port 25 conflicts) service: name: postfix state: stopped enabled: false failed_when: false - - name: Remove postfix when external SMTP is used (conflicts with msmtp-mta) + - name: ๐Ÿ—‘๏ธ Remove postfix when external SMTP is used (conflicts with msmtp-mta) package: name: - postfix diff --git a/roles/sys-svc-mail-smtp/tasks/enable.yml b/roles/sys-svc-mail-smtp/tasks/enable.yml index 9bf76c362f..2dbe65d087 100644 --- a/roles/sys-svc-mail-smtp/tasks/enable.yml +++ b/roles/sys-svc-mail-smtp/tasks/enable.yml @@ -1,38 +1,38 @@ --- - include_tasks: utils/once/flag.yml -- name: "Disable MSMTP to avoid port conflicts" +- name: "๐Ÿ”ด Disable MSMTP to avoid port conflicts" include_role: name: sys-svc-mail-msmtp tasks_from: disable.yml -- name: Include dependency 'sys-daemon' +- name: ๐Ÿ“‚ Include dependency 'sys-daemon' include_role: name: sys-daemon when: run_once_sys_daemon is not defined -- name: "Install local SMTP relay (Postfix)" +- name: "๐Ÿ“ฆ Install local SMTP relay (Postfix)" package: name: - postfix - postfix-lmdb state: present -- name: "Configure Postfix as localhost-only relay" +- name: "๐Ÿ”ง Configure Postfix as localhost-only relay" ansible.builtin.template: # nocheck: stack-host-template (per-host postfix localhost-relay config) src: "postfix-main.cf.j2" dest: "/etc/postfix/main.cf" mode: "0644" notify: restart postfix -- name: "Deploy postfix aliases" +- name: "๐Ÿš€ Deploy postfix aliases" ansible.builtin.template: # nocheck: stack-host-template (per-host postfix aliases) src: "aliases.j2" dest: "/etc/postfix/aliases" mode: "0644" notify: restart postfix -- name: "Build alias database" +- name: "๐Ÿ”จ Build alias database" ansible.builtin.command: newaliases changed_when: false notify: restart postfix diff --git a/roles/sys-svc-mail-smtp/tasks/main.yml b/roles/sys-svc-mail-smtp/tasks/main.yml index abf906d391..b4f6e968ce 100644 --- a/roles/sys-svc-mail-smtp/tasks/main.yml +++ b/roles/sys-svc-mail-smtp/tasks/main.yml @@ -1,4 +1,4 @@ --- -- name: "Load SMTP (once)" +- name: "๐Ÿ”Œ Load SMTP (once)" include_tasks: enable.yml when: not (run_once_sys_svc_mail_smtp | default(false) | bool) diff --git a/roles/sys-svc-mail/tasks/01_core.yml b/roles/sys-svc-mail/tasks/01_core.yml index 707611d6b9..8e6d1848b1 100644 --- a/roles/sys-svc-mail/tasks/01_core.yml +++ b/roles/sys-svc-mail/tasks/01_core.yml @@ -1,12 +1,12 @@ --- - include_tasks: utils/once/flag.yml -- name: Include dependencies +- name: ๐Ÿ“‚ Include dependencies include_role: name: "sys-hostname" when: not (run_once_sys_hostname | default(false) | bool) -- name: "Assert Mailu was preloaded before configuring external mail" +- name: "โœ… Assert Mailu was preloaded before configuring external mail" ansible.builtin.assert: that: - run_once_web_app_mailu is defined @@ -19,14 +19,14 @@ - "'web-app-mailu' in group_names" - MODE_ASSERT_LOCAL | bool -- name: Setup emails via localhost +- name: ๐Ÿ”ง Setup emails via localhost include_role: name: sys-svc-mail-smtp when: - run_once_sys_svc_mail_smtp is not defined - not (lookup('email').external | bool) -- name: Setup msmtp client +- name: ๐Ÿ”ง Setup msmtp client include_role: name: sys-svc-mail-msmtp when: diff --git a/roles/sys-svc-mail/tasks/main.yml b/roles/sys-svc-mail/tasks/main.yml index c345b5674c..7ab5d4ed60 100644 --- a/roles/sys-svc-mail/tasks/main.yml +++ b/roles/sys-svc-mail/tasks/main.yml @@ -1,4 +1,4 @@ --- -- name: "Load Mail (once)" +- name: "๐Ÿ”Œ Load Mail (once)" include_tasks: 01_core.yml when: not (run_once_sys_svc_mail | default(false) | bool) diff --git a/roles/sys-svc-objstore/tasks/main.yml b/roles/sys-svc-objstore/tasks/main.yml index 78083fd961..4c3edd78ca 100644 --- a/roles/sys-svc-objstore/tasks/main.yml +++ b/roles/sys-svc-objstore/tasks/main.yml @@ -1,11 +1,11 @@ --- # nocheck: run-once -- name: "For '{{ application_id }}': Freeze object-store consumer id" +- name: "๐ŸงŠ For '{{ application_id }}': Freeze object-store consumer id" ansible.builtin.set_fact: _objstore_consumer_id: "{{ objstore_consumer_id | default(application_id) }}" changed_when: false -- name: "For '{{ _objstore_consumer_id }}': Provision on the central object-store provider" +- name: "๐Ÿ“ For '{{ _objstore_consumer_id }}': Provision on central object-store" vars: _provider_role: "{{ lookup('objstore', _objstore_consumer_id, 'id') }}" when: lookup('objstore', _objstore_consumer_id, 'shared') | bool @@ -13,7 +13,7 @@ # Consumers that are registry providers themselves can be preloaded before # the object-store provider (same loader bucket, alphabetical topo-order), # so load the provider lazily instead of asserting the preload. - - name: "Load object-store provider '{{ _provider_role }}' (lazy)" + - name: "๐Ÿงฉ Load object-store provider '{{ _provider_role }}' (lazy)" ansible.builtin.include_role: name: "{{ _provider_role }}" vars: @@ -30,7 +30,7 @@ default='__missing__' ) == '__missing__' - - name: "Initialize '{{ _objstore_consumer_id }}' on the provider '{{ _provider_role }}'" + - name: "๐ŸŽฌ Init '{{ _objstore_consumer_id }}' on provider '{{ _provider_role }}'" ansible.builtin.include_role: name: "{{ _provider_role }}" vars: diff --git a/roles/sys-svc-rdbms/tasks/dedicated.yml b/roles/sys-svc-rdbms/tasks/dedicated.yml index 8a8ec2047f..10090c371a 100644 --- a/roles/sys-svc-rdbms/tasks/dedicated.yml +++ b/roles/sys-svc-rdbms/tasks/dedicated.yml @@ -1,16 +1,16 @@ --- -- name: "Ensure env dir exists: {{ _container_env_dir }}" +- name: "โœ… Ensure env dir exists: {{ _container_env_dir }}" ansible.builtin.file: path: "{{ _container_env_dir }}" state: directory mode: "0755" -- name: "For '{{ application_id }}/{{ _database_consumer_id }}': Create {{ _database_env }}" +- name: "๐Ÿ“„ For '{{ application_id }}/{{ _database_consumer_id }}': Create env file" stack_host_template: src: "env/{{ _database_type }}.env.j2" dest: "{{ _database_env }}" notify: compose up -- name: "For '{{ application_id }}/{{ _database_consumer_id }}': Apply postgres-specific dedicated setup" +- name: "๐Ÿ”ง For '{{ application_id }}/{{ _database_consumer_id }}': Apply postgres setup" include_tasks: dedicated_postgres.yml when: _database_type == 'postgres' diff --git a/roles/sys-svc-rdbms/tasks/dedicated_postgres.yml b/roles/sys-svc-rdbms/tasks/dedicated_postgres.yml index f4a63e2cbb..75b67ea566 100644 --- a/roles/sys-svc-rdbms/tasks/dedicated_postgres.yml +++ b/roles/sys-svc-rdbms/tasks/dedicated_postgres.yml @@ -1,11 +1,11 @@ --- - block: - - name: "Ensure initdb.d dir exists: {{ _database_initdb_dir }}" + - name: "โœ… Ensure initdb.d dir exists: {{ _database_initdb_dir }}" ansible.builtin.file: path: "{{ _database_initdb_dir }}" state: directory mode: "0755" - - name: "For '{{ application_id }}/{{ _database_consumer_id }}': Render extensions.sql for dedicated postgres" + - name: "๐Ÿ“„ For '{{ application_id }}/{{ _database_consumer_id }}': Render extensions.sql" stack_host_template: src: "initdb.d/extensions.sql.j2" dest: "{{ _database_initdb_dir }}extensions.sql" @@ -14,12 +14,12 @@ when: (_database_extensions | length) > 0 - block: - - name: "Ensure postgres build dir exists: {{ _database_build_dir }}" + - name: "โœ… Ensure postgres build dir exists: {{ _database_build_dir }}" ansible.builtin.file: path: "{{ _database_build_dir }}" state: directory mode: "0755" - - name: "For '{{ application_id }}/{{ _database_consumer_id }}': Render Dockerfile for dedicated postgres with custom libraries" + - name: "๐Ÿ“„ For '{{ application_id }}/{{ _database_consumer_id }}': Render libs Dockerfile" stack_host_template: src: "{{ playbook_dir }}/roles/svc-db-postgres/templates/Dockerfile.j2" dest: "{{ _database_build_dir }}Dockerfile" diff --git a/roles/sys-svc-rdbms/tasks/main.yml b/roles/sys-svc-rdbms/tasks/main.yml index e539cc7d0d..7442bfedda 100644 --- a/roles/sys-svc-rdbms/tasks/main.yml +++ b/roles/sys-svc-rdbms/tasks/main.yml @@ -1,11 +1,11 @@ --- # nocheck: run-once -- name: "For '{{ application_id }}': Freeze database consumer id before provider includes" +- name: "๐Ÿ“ For '{{ application_id }}': Freeze database consumer id before includes" set_fact: _database_consumer_id: "{{ database_consumer_id | default(application_id) }}" changed_when: false -- name: "For '{{ application_id }}/{{ _database_consumer_id }}': Resolve shared database mode" +- name: "๐Ÿ” For '{{ application_id }}/{{ _database_consumer_id }}': Resolve shared mode" set_fact: _sys_svc_rdbms_consumer_local: "{{ lookup('database', _database_consumer_id, 'local') | bool }}" _sys_svc_rdbms_central_db_enabled: >- @@ -13,13 +13,13 @@ and (groups[lookup('database', _database_consumer_id, 'id')] | default([])) | length > 0 }} changed_when: false -- name: "For '{{ application_id }}/{{ _database_consumer_id }}': Apply dedicated database setup" +- name: "๐Ÿ”ง For '{{ application_id }}/{{ _database_consumer_id }}': Apply dedicated setup" include_tasks: dedicated.yml when: _sys_svc_rdbms_consumer_local | bool -- name: Central Database Logic +- name: ๐Ÿ—„๏ธ Central Database Logic block: - - name: "For '{{ application_id }}': Assert shared database provider was preloaded" + - name: "โœ… For '{{ application_id }}': Assert shared database provider was preloaded" ansible.builtin.assert: that: - >- @@ -33,7 +33,7 @@ sys-service-loader before sys-svc-rdbms ran. when: MODE_ASSERT_LOCAL | bool - - name: "For '{{ application_id }}': Initialize dedicated database on preloaded provider" + - name: "๐ŸŽฌ For '{{ application_id }}': Init dedicated db on preloaded provider" ansible.builtin.include_role: name: "{{ _database_provider_role }}" vars: @@ -42,7 +42,7 @@ compose_repository_pull: false database_consumer_id: "{{ _database_consumer_id }}" - - name: "For '{{ application_id }}': Add Entry for Backup Procedure" + - name: "โž• For '{{ application_id }}': Add Entry for Backup Procedure" include_tasks: "{{ playbook_dir }}/roles/svc-bkp-container-2-local/tasks/04_seed-database-to-backup.yml" when: - "'svc-bkp-container-2-local' in group_names" diff --git a/roles/sys-svc-ssh/tasks/01_core.yml b/roles/sys-svc-ssh/tasks/01_core.yml index 752e1a7a8d..16278b875d 100644 --- a/roles/sys-svc-ssh/tasks/01_core.yml +++ b/roles/sys-svc-ssh/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Install OpenSSH client +- name: ๐Ÿ“ฆ Install OpenSSH client package: name: >- {{ diff --git a/roles/sys-svc-ssh/tasks/main.yml b/roles/sys-svc-ssh/tasks/main.yml index d201fa8c54..289785c622 100644 --- a/roles/sys-svc-ssh/tasks/main.yml +++ b/roles/sys-svc-ssh/tasks/main.yml @@ -1,4 +1,4 @@ --- -- name: "Load SSH (once)" +- name: "๐Ÿ”Œ Load SSH (once)" include_tasks: 01_core.yml when: not (run_once_sys_svc_ssh | default(false) | bool) diff --git a/roles/sys-svc-sshd/tasks/01_core.yml b/roles/sys-svc-sshd/tasks/01_core.yml index e99dd61254..af48694a4b 100644 --- a/roles/sys-svc-sshd/tasks/01_core.yml +++ b/roles/sys-svc-sshd/tasks/01_core.yml @@ -1,15 +1,15 @@ --- -- name: Include dependency 'sys-daemon' +- name: ๐Ÿ“‚ Include dependency 'sys-daemon' include_role: name: sys-daemon when: run_once_sys_daemon is not defined -- name: Include dependency 'user-administrator' +- name: ๐Ÿ“‚ Include dependency 'user-administrator' include_role: name: user-administrator when: run_once_user_administrator is not defined -- name: create sshd_config +- name: ๐Ÿ“ create sshd_config template: # nocheck: stack-host-template (per-host sshd_config) src: "sshd_config.j2" dest: /etc/ssh/sshd_config diff --git a/roles/sys-svc-sshd/tasks/utils/rescue_ssh_restart.yml b/roles/sys-svc-sshd/tasks/utils/rescue_ssh_restart.yml index 6708a34f95..388698259a 100644 --- a/roles/sys-svc-sshd/tasks/utils/rescue_ssh_restart.yml +++ b/roles/sys-svc-sshd/tasks/utils/rescue_ssh_restart.yml @@ -1,5 +1,5 @@ --- -- name: Show shared diagnostics for failed SSH restart +- name: ๐Ÿ‘๏ธ Show shared diagnostics for failed SSH restart ansible.builtin.include_role: name: sys-service tasks_from: utils/debug.yml @@ -12,7 +12,7 @@ failed_stderr={{ sys_svc_sshd_restart_result.stderr | default('') }} failed_result={{ sys_svc_sshd_restart_result | to_nice_json }} -- name: Validate sshd_config after failed restart +- name: โœ… Validate sshd_config after failed restart ansible.builtin.command: argv: - sshd @@ -23,7 +23,7 @@ changed_when: false failed_when: false -- name: Show sshd_config validation after failed restart +- name: ๐Ÿ‘๏ธ Show sshd_config validation after failed restart ansible.builtin.debug: msg: | === sshd -t -f /etc/ssh/sshd_config === @@ -31,7 +31,7 @@ {{ sys_svc_sshd_config_check.stdout | default('') }} {{ sys_svc_sshd_config_check.stderr | default('') }} -- name: Fail SSH restart with diagnostics +- name: ๐Ÿ›‘ Fail SSH restart with diagnostics ansible.builtin.fail: msg: >- Restart of {{ sys_svc_sshd_service_unit }} failed. diff --git a/roles/sys-svc-webserver-core/tasks/01a_manager_setup.yml b/roles/sys-svc-webserver-core/tasks/01a_manager_setup.yml index 7ed13fe07e..c100d3719b 100644 --- a/roles/sys-svc-webserver-core/tasks/01a_manager_setup.yml +++ b/roles/sys-svc-webserver-core/tasks/01a_manager_setup.yml @@ -1,37 +1,37 @@ --- -- name: "cleanup (if enabled)" +- name: "๐Ÿงน cleanup (if enabled)" include_tasks: 02_cleanup.yml when: > MODE_CLEANUP | bool or MODE_RESET | bool -- name: "reset (if enabled) for {{ role_name }}" +- name: "โ™ป๏ธ reset (if enabled) for {{ role_name }}" include_tasks: 03_reset.yml when: MODE_RESET | bool -- name: "Include tasks to create directories" +- name: "๐Ÿ“‚ Include tasks to create directories" include_tasks: 04_directories.yml -- name: Load OpenResty +- name: ๐Ÿ”Œ Load OpenResty include_tasks: "utils/load_app.yml" vars: load_app_id: svc-prx-openresty -- name: Deploy OpenResty NGINX Base Configuration +- name: ๐Ÿš€ Deploy OpenResty NGINX Base Configuration stack_host_template: src: nginx.conf.j2 dest: "{{ lookup('nginx', 'files.configuration') }}" notify: restart openresty -- name: Deploy OpenResty default server configuration +- name: ๐Ÿš€ Deploy OpenResty default server configuration stack_host_template: src: default_server.conf.j2 dest: "{{ [lookup('nginx', 'directories.configuration.global'), 'default_server.conf'] | path_join }}" notify: restart openresty -- name: Flush OpenResty Base Setup +- name: ๐Ÿšฟ Flush OpenResty Base Setup meta: flush_handlers -- name: "Assert for '{{ role_name }}'" +- name: "โœ… Assert for '{{ role_name }}'" include_tasks: 05_assert.yml when: MODE_ASSERT_LOCAL | bool diff --git a/roles/sys-svc-webserver-core/tasks/02_cleanup.yml b/roles/sys-svc-webserver-core/tasks/02_cleanup.yml index 9fa08ea083..2e904e1e7d 100644 --- a/roles/sys-svc-webserver-core/tasks/02_cleanup.yml +++ b/roles/sys-svc-webserver-core/tasks/02_cleanup.yml @@ -1,5 +1,5 @@ --- -- name: Cleanup all NGINX cache directories +- name: ๐Ÿงน Cleanup all NGINX cache directories become: true ansible.builtin.file: path: "{{ item.value }}" diff --git a/roles/sys-svc-webserver-core/tasks/03_reset.yml b/roles/sys-svc-webserver-core/tasks/03_reset.yml index b68202f957..104fcd0138 100644 --- a/roles/sys-svc-webserver-core/tasks/03_reset.yml +++ b/roles/sys-svc-webserver-core/tasks/03_reset.yml @@ -1,5 +1,5 @@ --- -- name: Delete NGINX config paths +- name: ๐Ÿ—‘๏ธ Delete NGINX config paths file: path: "{{ item }}" state: absent diff --git a/roles/sys-svc-webserver-core/tasks/04_directories.yml b/roles/sys-svc-webserver-core/tasks/04_directories.yml index e0b8e7f7b4..d2932f4604 100644 --- a/roles/sys-svc-webserver-core/tasks/04_directories.yml +++ b/roles/sys-svc-webserver-core/tasks/04_directories.yml @@ -1,5 +1,5 @@ --- -- name: Ensure all required NGINX host directories exist (single task) +- name: โœ… Ensure all required NGINX host directories exist (single task) become: true ansible.builtin.file: path: "{{ item.path }}" diff --git a/roles/sys-svc-webserver-core/tasks/05_assert.yml b/roles/sys-svc-webserver-core/tasks/05_assert.yml index 93218bf395..3a910959ac 100644 --- a/roles/sys-svc-webserver-core/tasks/05_assert.yml +++ b/roles/sys-svc-webserver-core/tasks/05_assert.yml @@ -1,10 +1,10 @@ --- -- name: Stat nginx.conf +- name: ๐Ÿ”Ž Stat nginx.conf ansible.builtin.stat: path: "{{ lookup('nginx','files.configuration') }}" register: nginx_conf_stat -- name: Assert nginx.conf is a file +- name: โœ… Assert nginx.conf is a file ansible.builtin.assert: that: - nginx_conf_stat.stat.exists @@ -14,12 +14,12 @@ but it is missing or not a file (type mismatch). This would break docker bind mounts. # Optional but very useful: conf.d must be a directory -- name: Stat conf.d directory +- name: ๐Ÿ”Ž Stat conf.d directory ansible.builtin.stat: path: "{{ lookup('nginx','directories.configuration.base') }}" register: nginx_confd_stat -- name: Assert conf.d is a directory +- name: โœ… Assert conf.d is a directory ansible.builtin.assert: that: - nginx_confd_stat.stat.exists @@ -29,7 +29,7 @@ but it is missing or not a directory. -- name: "Assert default webserver responds with 404 for {{ DOMAIN_TEST }}" +- name: "โœ… Assert default webserver responds with 404 for {{ DOMAIN_TEST }}" uri_retry: url: "http://{{ DOMAIN_TEST }}:80/" method: GET @@ -39,7 +39,7 @@ timeout: 10 register: default_vhost_check -- name: Assert default webserver response body +- name: โœ… Assert default webserver response body ansible.builtin.assert: that: - default_vhost_check.status == 404 diff --git a/roles/sys-svc-webserver-core/tasks/main.yml b/roles/sys-svc-webserver-core/tasks/main.yml index 62a0b5bbfe..4c6a84b0b5 100644 --- a/roles/sys-svc-webserver-core/tasks/main.yml +++ b/roles/sys-svc-webserver-core/tasks/main.yml @@ -2,7 +2,7 @@ - include_tasks: 01_core.yml when: run_once_sys_svc_webserver_core is not defined -- name: "Route webserver health deps through service-loader" +- name: "๐Ÿงญ Route webserver health deps through service-loader" ansible.builtin.include_role: name: sys-service-loader tasks_from: list_or_shoot.yml diff --git a/roles/sys-svc-webserver-https/tasks/01_core.yml b/roles/sys-svc-webserver-https/tasks/01_core.yml index 82abac8fd8..34518acea5 100644 --- a/roles/sys-svc-webserver-https/tasks/01_core.yml +++ b/roles/sys-svc-webserver-https/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: Include dependencies +- name: ๐Ÿ“‚ Include dependencies include_role: name: "{{ item }}" loop: diff --git a/roles/sys-timer/tasks/main.yml b/roles/sys-timer/tasks/main.yml index cf6329ab4d..498b0f85d0 100644 --- a/roles/sys-timer/tasks/main.yml +++ b/roles/sys-timer/tasks/main.yml @@ -1,13 +1,13 @@ --- # nocheck: run-once -- name: create {{ sys_timer_file }} +- name: ๐Ÿ“ create {{ sys_timer_file }} template: # nocheck: stack-host-template (per-host systemd unit, every managed host gets timers) src: dummy.timer.j2 dest: "{{ [ DIR_SYSTEM_SERVICE, sys_timer_file ] | path_join }}" register: dummy_timer -- name: "deploy timer" +- name: "๐Ÿš€ deploy timer" systemd: daemon_reload: true name: "{{ sys_timer_file }}" diff --git a/roles/sys-token-store/tasks/01_core.yml b/roles/sys-token-store/tasks/01_core.yml index 4ec6fe4104..6478a5325a 100644 --- a/roles/sys-token-store/tasks/01_core.yml +++ b/roles/sys-token-store/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: "Ensure base directory (single-writer via STACK_HOST)" +- name: "โœ… Ensure base directory (single-writer via STACK_HOST)" ansible.builtin.file: path: "{{ DIR_SECRETS }}" state: directory @@ -10,7 +10,7 @@ run_once: true become: true -- name: "Ensure store file exists (single-writer via STACK_HOST)" +- name: "โœ… Ensure store file exists (single-writer via STACK_HOST)" ansible.builtin.file: path: "{{ FILE_TOKENS }}" state: touch @@ -21,7 +21,7 @@ run_once: true become: true -- name: "Load existing store" +- name: "๐Ÿงฉ Load existing store" ansible.builtin.import_tasks: 02_load.yml - include_tasks: utils/once/flag.yml diff --git a/roles/sys-token-store/tasks/02_load.yml b/roles/sys-token-store/tasks/02_load.yml index 2ad4219334..393cb17b51 100644 --- a/roles/sys-token-store/tasks/02_load.yml +++ b/roles/sys-token-store/tasks/02_load.yml @@ -1,5 +1,5 @@ --- -- name: "Read token store from host" +- name: "๐Ÿ“– Read token store from host" ansible.builtin.slurp: src: "{{ FILE_TOKENS }}" register: sys_token_store_raw @@ -7,7 +7,7 @@ no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" become: true -- name: "Parse store YAML" +- name: "๐Ÿ”Ž Parse store YAML" ansible.builtin.set_fact: sys_token_store_data: >- {{ @@ -21,7 +21,7 @@ }} no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Normalize users dict" +- name: "๐Ÿ“ Normalize users dict" ansible.builtin.set_fact: sys_token_store_users: "{{ sys_token_store_data.users | default({}, true) }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" diff --git a/roles/sys-token-store/tasks/main.yml b/roles/sys-token-store/tasks/main.yml index 8ec1f00ed6..7dfc1fd751 100644 --- a/roles/sys-token-store/tasks/main.yml +++ b/roles/sys-token-store/tasks/main.yml @@ -1,4 +1,4 @@ --- -- name: "Execute Role (once)" +- name: "โ–ถ๏ธ Execute Role (once)" ansible.builtin.import_tasks: 01_core.yml when: run_once_sys_token_store is not defined diff --git a/roles/sys-token-store/tasks/write.yml b/roles/sys-token-store/tasks/write.yml index a9686dee80..7870cebfee 100644 --- a/roles/sys-token-store/tasks/write.yml +++ b/roles/sys-token-store/tasks/write.yml @@ -4,21 +4,21 @@ # sys_token_store_app # sys_token_store_token # must be non-empty -- name: "Ensure store exists" +- name: "โœ… Ensure store exists" ansible.builtin.import_tasks: 01_core.yml -- name: "Normalize incoming token" +- name: "๐Ÿ“ Normalize incoming token" ansible.builtin.set_fact: sys_token_store_token_effective: "{{ sys_token_store_token | string | trim }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Abort if token is empty (do not persist empties)" +- name: "๐Ÿ›‘ Abort if token is empty (do not persist empties)" ansible.builtin.assert: that: - sys_token_store_token_effective != '' fail_msg: "sys_token_store_token is empty โ€“ refusing to persist empty token." -- name: "Build merged structure" +- name: "๐Ÿ”จ Build merged structure" ansible.builtin.set_fact: sys_token_store_users_merged: >- {{ @@ -39,7 +39,7 @@ }} no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Persist store (idempotent, single-writer via STACK_HOST)" +- name: "๐Ÿ’พ Persist store (idempotent, single-writer via STACK_HOST)" ansible.builtin.copy: dest: "{{ FILE_TOKENS }}" owner: "{{ SYS_TOKEN_STORE_OWNER }}" diff --git a/roles/sys-util-git-pull/tasks/main.yml b/roles/sys-util-git-pull/tasks/main.yml index 3368291835..28f44894da 100644 --- a/roles/sys-util-git-pull/tasks/main.yml +++ b/roles/sys-util-git-pull/tasks/main.yml @@ -1,6 +1,6 @@ --- # nocheck: run-once -- name: Run sys-util-git-pull helper (verbose) +- name: โ–ถ๏ธ Run sys-util-git-pull helper (verbose) script: >- sys_util_git_pull.py --repo-url "{{ sys_util_git_pull_repo_url }}" diff --git a/roles/sys-version/tasks/main.yml b/roles/sys-version/tasks/main.yml index 86083b3b41..cf5e8a60fb 100644 --- a/roles/sys-version/tasks/main.yml +++ b/roles/sys-version/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: Ensure system version is set in environment file +- name: โœ… Ensure system version is set in environment file ansible.builtin.lineinfile: path: "{{ FILE_ENVIRONMENT }}" regexp: "^{{ INFINITO_VERSION_ENV_NAME }}=" diff --git a/roles/test-e2e-playwright/tasks/01_setup.yml b/roles/test-e2e-playwright/tasks/01_setup.yml index 5baeab144d..6f2cc68cec 100644 --- a/roles/test-e2e-playwright/tasks/01_setup.yml +++ b/roles/test-e2e-playwright/tasks/01_setup.yml @@ -1,28 +1,28 @@ --- -- name: Ensure shared Playwright project dir exists +- name: โœ… Ensure shared Playwright project dir exists ansible.builtin.file: path: "{{ TEST_E2E_PLAYWRIGHT_SHARED_DIR }}" state: directory mode: "0755" -- name: Render shared package.json from central template +- name: ๐Ÿ“„ Render shared package.json from central template ansible.builtin.template: # nocheck: stack-host-template (per-host playwright stage dir, runs on every test host) src: "{{ playbook_dir }}/roles/test-e2e-playwright/templates/package.json.j2" dest: "{{ TEST_E2E_PLAYWRIGHT_SHARED_DIR }}/package.json" mode: "0644" -- name: Probe shared install stamp +- name: ๐Ÿ” Probe shared install stamp ansible.builtin.stat: path: "{{ TEST_E2E_PLAYWRIGHT_SHARED_STAMP }}" register: _playwright_shared_stamp_stat -- name: Read shared install stamp +- name: ๐Ÿ“– Read shared install stamp ansible.builtin.slurp: src: "{{ TEST_E2E_PLAYWRIGHT_SHARED_STAMP }}" register: _playwright_shared_stamp_content when: _playwright_shared_stamp_stat.stat.exists -- name: Decide whether the shared install is up to date +- name: ๐Ÿค” Decide whether the shared install is up to date ansible.builtin.set_fact: _playwright_shared_install_needed: >- {{ @@ -31,10 +31,10 @@ != TEST_E2E_PLAYWRIGHT_VERSION) }} -- name: Provision the shared Playwright install (image pull + npm install + stamp) +- name: ๐Ÿ”ง Provision the shared Playwright install (image pull + npm install + stamp) when: _playwright_shared_install_needed | bool block: - - name: Pull Playwright image if missing (shared install pass) + - name: โฌ‡๏ธ Pull Playwright image if missing (shared install pass) ansible.builtin.command: argv: - container @@ -47,7 +47,7 @@ delay: 5 until: _playwright_shared_pull.rc == 0 - - name: Install @playwright/test into the shared dir (once per host per version) + - name: ๐Ÿ“ฆ Install @playwright/test into the shared dir (once per host per version) ansible.builtin.command: argv: - container @@ -71,7 +71,7 @@ delay: 5 until: _playwright_shared_install.rc == 0 - - name: Write shared install stamp + - name: โœ๏ธ Write shared install stamp ansible.builtin.copy: dest: "{{ TEST_E2E_PLAYWRIGHT_SHARED_STAMP }}" content: "{{ TEST_E2E_PLAYWRIGHT_VERSION }}" diff --git a/roles/test-e2e-playwright/tasks/01a_orchestrate.yml b/roles/test-e2e-playwright/tasks/01a_orchestrate.yml index 89765ca3a2..463c8c4741 100644 --- a/roles/test-e2e-playwright/tasks/01a_orchestrate.yml +++ b/roles/test-e2e-playwright/tasks/01a_orchestrate.yml @@ -1,27 +1,27 @@ --- -- name: Ensure staging base dir exists +- name: โœ… Ensure staging base dir exists ansible.builtin.file: path: "{{ TEST_E2E_PLAYWRIGHT_STAGE_BASE_DIR }}" state: directory mode: "0755" -- name: Ensure reports base dir exists +- name: โœ… Ensure reports base dir exists ansible.builtin.file: path: "{{ TEST_E2E_PLAYWRIGHT_REPORTS_BASE_DIR }}" state: directory mode: "0755" -- name: Prepare shared @playwright/test install +- name: ๐Ÿงฐ Prepare shared @playwright/test install ansible.builtin.include_tasks: 01_setup.yml -- name: Run Playwright for each detected role +- name: โ–ถ๏ธ Run Playwright for each detected role ansible.builtin.include_tasks: 02_run_one.yml loop: "{{ TEST_E2E_PLAYWRIGHT_APPS }}" loop_control: loop_var: application_id label: "{{ application_id }}" -- name: Fail if there were Playwright failures +- name: ๐Ÿ›‘ Fail if there were Playwright failures ansible.builtin.fail: msg: "Playwright failed for roles: {{ _playwright_failures }}" when: (_playwright_failures | default([])) | length > 0 diff --git a/roles/test-e2e-playwright/tasks/02_run_one.yml b/roles/test-e2e-playwright/tasks/02_run_one.yml index 7c8eaad71c..57bfc44a7f 100644 --- a/roles/test-e2e-playwright/tasks/02_run_one.yml +++ b/roles/test-e2e-playwright/tasks/02_run_one.yml @@ -1,5 +1,5 @@ --- -- name: Define per-role paths +- name: ๐Ÿ“Œ Define per-role paths ansible.builtin.set_fact: _playwright_env_template: "{{ playbook_dir }}/roles/{{ application_id }}/templates/playwright.env.j2" _playwright_files_dir: "{{ playbook_dir }}/roles/{{ application_id }}/files/playwright" @@ -14,7 +14,7 @@ _playwright_ca_wrapper_host: "{{ CA_TRUST.wrapper_host }}" _playwright_ca_trust_name: "{{ CA_TRUST.trust_name }}" -- name: Validate CA_TRUST configuration for self-signed TLS +- name: โœ… Validate CA_TRUST configuration for self-signed TLS ansible.builtin.fail: msg: >- TLS_MODE=self_signed requires CA_TRUST.cert_host, CA_TRUST.wrapper_host and CA_TRUST.trust_name @@ -27,97 +27,97 @@ (_playwright_ca_trust_name | length == 0) ) -- name: Check CA certificate for Playwright injection +- name: ๐Ÿ”Ž Check CA certificate for Playwright injection ansible.builtin.stat: path: "{{ _playwright_ca_cert_host }}" register: _playwright_ca_cert_stat when: _playwright_ca_required | bool -- name: Check CA wrapper for Playwright injection +- name: ๐Ÿ”Ž Check CA wrapper for Playwright injection ansible.builtin.stat: path: "{{ _playwright_ca_wrapper_host }}" register: _playwright_ca_wrapper_stat when: _playwright_ca_required | bool -- name: Fail if CA certificate is missing on host +- name: ๐Ÿ›‘ Fail if CA certificate is missing on host ansible.builtin.fail: msg: >- TLS_MODE=self_signed requires CA injection, but certificate is missing: {{ _playwright_ca_cert_host }} when: (_playwright_ca_required | bool) and not (_playwright_ca_cert_stat.stat.exists | default(false)) -- name: Fail if CA wrapper script is missing on host +- name: ๐Ÿ›‘ Fail if CA wrapper script is missing on host ansible.builtin.fail: msg: >- TLS_MODE=self_signed requires CA injection, but wrapper script is missing: {{ _playwright_ca_wrapper_host }} when: (_playwright_ca_required | bool) and not (_playwright_ca_wrapper_stat.stat.exists | default(false)) -- name: Assert required Playwright env template exists +- name: โœ… Assert required Playwright env template exists ansible.builtin.stat: path: "{{ _playwright_env_template }}" register: _env_template_stat delegate_to: localhost -- name: Fail if Playwright env template is missing +- name: ๐Ÿ›‘ Fail if Playwright env template is missing ansible.builtin.fail: msg: "Missing Playwright env template: {{ _playwright_env_template }}" when: not _env_template_stat.stat.exists -- name: Assert required Playwright spec exists +- name: โœ… Assert required Playwright spec exists ansible.builtin.stat: path: "{{ _playwright_spec_src }}" register: _spec_stat delegate_to: localhost -- name: Fail if Playwright spec is missing +- name: ๐Ÿ›‘ Fail if Playwright spec is missing ansible.builtin.fail: msg: "Missing Playwright spec file: {{ _playwright_spec_src }}" when: not _spec_stat.stat.exists -- name: Check optional application vars file +- name: ๐Ÿ”Ž Check optional application vars file ansible.builtin.stat: path: "{{ playbook_dir }}/roles/{{ application_id }}/vars/main.yml" register: _playwright_app_vars_stat delegate_to: localhost -- name: Load optional application vars +- name: โš™๏ธ Load optional application vars ansible.builtin.include_vars: file: "{{ playbook_dir }}/roles/{{ application_id }}/vars/main.yml" when: _playwright_app_vars_stat.stat.exists # Clean stage dir for deterministic results -- name: Recreate staging directory +- name: ๐Ÿ“ Recreate staging directory ansible.builtin.file: path: "{{ _playwright_stage_dir }}" state: absent -- name: Create staging directory +- name: ๐Ÿ“ Create staging directory ansible.builtin.file: path: "{{ _playwright_stage_dir }}" state: directory mode: "0755" -- name: Create staging tests directory +- name: ๐Ÿ“ Create staging tests directory ansible.builtin.file: path: "{{ _playwright_stage_tests_dir }}" state: directory mode: "0755" -- name: Check central default package.json template +- name: ๐Ÿ”Ž Check central default package.json template ansible.builtin.stat: path: "{{ _playwright_default_package_template }}" register: _default_package_stat delegate_to: localhost -- name: Fail when central default package.json template is missing +- name: ๐Ÿ›‘ Fail when central default package.json template is missing ansible.builtin.fail: msg: "Missing central Playwright package.json template: {{ _playwright_default_package_template }}" when: not _default_package_stat.stat.exists # The `container` wrapper insists the image is present locally before # `run`. Pull it explicitly so a pruned cache doesn't fail the stage. -- name: Pull Playwright image if missing +- name: โฌ‡๏ธ Pull Playwright image if missing ansible.builtin.command: argv: - container @@ -130,43 +130,43 @@ delay: 5 until: _playwright_pull.rc == 0 -- name: Render package.json from template +- name: ๐Ÿ“„ Render package.json from template ansible.builtin.template: # nocheck: stack-host-template (per-host playwright stage dir, runs on every test host) src: "{{ _playwright_default_package_template }}" dest: "{{ _playwright_stage_dir }}/package.json" mode: "0644" -- name: Check central default playwright.config.js +- name: ๐Ÿ”Ž Check central default playwright.config.js ansible.builtin.stat: path: "{{ _playwright_default_config_js }}" register: _default_config_stat delegate_to: localhost -- name: Fail when central default playwright.config.js is missing +- name: ๐Ÿ›‘ Fail when central default playwright.config.js is missing ansible.builtin.fail: msg: "Missing central Playwright config: {{ _playwright_default_config_js }}" when: not _default_config_stat.stat.exists -- name: Copy central default playwright.config.js +- name: ๐Ÿ“‹ Copy central default playwright.config.js ansible.builtin.copy: src: "{{ _playwright_default_config_js }}" dest: "{{ _playwright_stage_dir }}/playwright.config.js" mode: "0644" -- name: Copy role Playwright tree (spec + companions + addons/ + fixtures/) into staging tests directory +- name: ๐Ÿ“‹ Copy Playwright tree (spec + companions + addons/ + fixtures/) to staging ansible.builtin.copy: src: "{{ _playwright_files_dir }}/" dest: "{{ _playwright_stage_tests_dir }}/" mode: "0644" directory_mode: "0755" -- name: Create staging fixtures directory +- name: ๐Ÿ“ Create staging fixtures directory ansible.builtin.file: path: "{{ _playwright_stage_tests_dir }}/fixtures" state: directory mode: "0755" -- name: Copy role Playwright binary fixtures into staging fixtures directory +- name: ๐Ÿ“‹ Copy role Playwright binary fixtures into staging fixtures directory ansible.builtin.copy: src: "{{ item }}" dest: "{{ _playwright_stage_tests_dir }}/fixtures/{{ item | basename }}" @@ -176,13 +176,13 @@ # Stage the shared service-gating helper next to the spec so the spec can # `require("./service-gating")`. -- name: Copy shared service-gating helper into staging tests directory +- name: ๐Ÿ“‹ Copy shared service-gating helper into staging tests directory ansible.builtin.copy: src: "{{ playbook_dir }}/roles/test-e2e-playwright/files/service-gating.js" dest: "{{ _playwright_stage_tests_dir }}/service-gating.js" mode: "0644" -- name: Copy shared addon-gating helper into staging tests directory +- name: ๐Ÿ“‹ Copy shared addon-gating helper into staging tests directory ansible.builtin.copy: src: "{{ playbook_dir }}/roles/test-e2e-playwright/files/addon-gating.js" dest: "{{ _playwright_stage_tests_dir }}/addon-gating.js" @@ -195,19 +195,19 @@ # semantics by listing the tree explicitly via fileglob; the recursive # variant is achieved by chaining one task per depth level so we keep # Ansible-idempotent file copies (no `synchronize`/rsync dependency). -- name: Create staging personas directory +- name: ๐Ÿ“ Create staging personas directory ansible.builtin.file: path: "{{ _playwright_stage_tests_dir }}/personas" state: directory mode: "0755" -- name: Create staging personas/utils directory +- name: ๐Ÿ“ Create staging personas/utils directory ansible.builtin.file: path: "{{ _playwright_stage_tests_dir }}/personas/utils" state: directory mode: "0755" -- name: Copy persona-flow runners into staging personas directory +- name: ๐Ÿ“‹ Copy persona-flow runners into staging personas directory ansible.builtin.copy: src: "{{ item }}" dest: "{{ _playwright_stage_tests_dir }}/personas/{{ item | basename }}" @@ -215,7 +215,7 @@ with_fileglob: - "{{ playbook_dir }}/roles/test-e2e-playwright/files/personas/*.js" -- name: Copy persona helper modules into staging personas/utils directory +- name: ๐Ÿ“‹ Copy persona helper modules into staging personas/utils directory ansible.builtin.copy: src: "{{ item }}" dest: "{{ _playwright_stage_tests_dir }}/personas/utils/{{ item | basename }}" @@ -224,14 +224,14 @@ - "{{ playbook_dir }}/roles/test-e2e-playwright/files/personas/utils/*.js" # Keep /volume mount stable even if the source project does not define one. -- name: Ensure staging volume directory exists +- name: โœ… Ensure staging volume directory exists ansible.builtin.file: path: "{{ _playwright_stage_dir }}/volume" state: directory mode: "0755" # Render templates/playwright.env.j2 -> .env in staging directory -- name: Render .env from templates/playwright.env.j2 +- name: ๐Ÿ“„ Render .env from templates/playwright.env.j2 ansible.builtin.copy: dest: "{{ _playwright_stage_dir }}/.env" mode: "0644" @@ -247,7 +247,7 @@ # canonical landing surface lives elsewhere. 5xx is the only signal # that the service is genuinely unhealthy. # follow_redirects:none ensures we check the app itself, not its redirect target. -- name: Wait until application is ready (any non-error response) +- name: โณ Wait until application is ready (any non-error response) uri_retry: url: "{{ lookup('tls', application_id, 'url.base') }}" status_code: "{{ range(100, 500) | list }}" @@ -259,18 +259,18 @@ until: _wait_result.status is defined and _wait_result.status | int < 500 when: test_e2e_playwright_wait_enabled | bool -- name: Ensure reports dir exists +- name: โœ… Ensure reports dir exists ansible.builtin.file: path: "{{ _playwright_reports_dir }}" state: directory mode: "0755" -- name: Collect host disk diagnostics before Playwright +- name: ๐Ÿ“Š Collect host disk diagnostics before Playwright ansible.builtin.script: "{{ role_path }}/files/dump_disk_diagnostics.sh" changed_when: false when: MODE_DEBUG | bool -- name: Run Playwright container +- name: โ–ถ๏ธ Run Playwright container ansible.builtin.command: argv: >- {{ @@ -307,7 +307,7 @@ changed_when: false failed_when: false -- name: Print Playwright output (on failure) +- name: ๐Ÿ’ฌ Print Playwright output (on failure) ansible.builtin.debug: msg: | stdout: @@ -318,12 +318,12 @@ when: _playwright_run.rc != 0 changed_when: false -- name: Record failure +- name: ๐Ÿ“ Record failure ansible.builtin.set_fact: _playwright_failures: "{{ (_playwright_failures | default([])) + [application_id] }}" when: _playwright_run.rc != 0 -- name: Archive Playwright reports for this variant + pass +- name: ๐Ÿ—„๏ธ Archive Playwright reports for this variant + pass ansible.builtin.script: >- {{ role_path }}/files/archive_playwright_reports.sh {{ _playwright_reports_dir | quote }} diff --git a/roles/test-e2e-playwright/tasks/main.yml b/roles/test-e2e-playwright/tasks/main.yml index c6231bb593..41c04266a8 100644 --- a/roles/test-e2e-playwright/tasks/main.yml +++ b/roles/test-e2e-playwright/tasks/main.yml @@ -1,10 +1,10 @@ --- -- name: Show detected Playwright roles +- name: ๐Ÿ‘๏ธ Show detected Playwright roles ansible.builtin.debug: msg: "Playwright-enabled roles: {{ TEST_E2E_PLAYWRIGHT_APPS }}" changed_when: false -- name: Playwright orchestration (run once on the primary manager) +- name: โ–ถ๏ธ Playwright orchestration (run once on the primary manager) # block: delegate_to/run_once propagate to include_tasks children only via block block: - ansible.builtin.include_tasks: 01a_orchestrate.yml diff --git a/roles/update/tasks/arch.yml b/roles/update/tasks/arch.yml index 424a158f7c..1cf7843036 100644 --- a/roles/update/tasks/arch.yml +++ b/roles/update/tasks/arch.yml @@ -1,5 +1,5 @@ --- -- name: "update (pacman) | refresh pacman cache and upgrade all installed packages" +- name: "๐Ÿ”„ update (pacman) | refresh pacman cache and upgrade all installed packages" community.general.pacman: update_cache: true upgrade: true diff --git a/roles/update/tasks/debian.yml b/roles/update/tasks/debian.yml index 470e0ae72a..49f86694c4 100644 --- a/roles/update/tasks/debian.yml +++ b/roles/update/tasks/debian.yml @@ -1,5 +1,5 @@ --- -- name: "update (apt) | refresh apt cache and dist-upgrade all installed packages" +- name: "๐Ÿ”„ update (apt) | refresh apt cache and dist-upgrade all installed packages" ansible.builtin.apt: update_cache: true upgrade: dist diff --git a/roles/update/tasks/fedora.yml b/roles/update/tasks/fedora.yml index b177ace33c..34b19baac2 100644 --- a/roles/update/tasks/fedora.yml +++ b/roles/update/tasks/fedora.yml @@ -1,5 +1,5 @@ --- -- name: "update (dnf) | refresh dnf cache and upgrade all installed packages" +- name: "๐Ÿ”„ update (dnf) | refresh dnf cache and upgrade all installed packages" ansible.builtin.dnf: name: "*" state: latest diff --git a/roles/update/tasks/main.yml b/roles/update/tasks/main.yml index e1cb56b8fe..3d4b5a3df8 100644 --- a/roles/update/tasks/main.yml +++ b/roles/update/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "update | dispatch to per-package-family task file" +- name: "๐Ÿ”„ update | dispatch to per-package-family task file" block: - include_tasks: "{{ _update_distro_file }}" vars: diff --git a/roles/update/tasks/unsupported.yml b/roles/update/tasks/unsupported.yml index 23dc43ce70..eb979509ab 100644 --- a/roles/update/tasks/unsupported.yml +++ b/roles/update/tasks/unsupported.yml @@ -1,5 +1,5 @@ --- -- name: "update | fail loudly when no per-distro implementation exists" +- name: "๐Ÿ”„ update | fail loudly when no per-distro implementation exists" ansible.builtin.fail: msg: >- The 'update' role has no per-distro task file for diff --git a/roles/user-administrator/tasks/01_core.yml b/roles/user-administrator/tasks/01_core.yml index f41d8d83fe..d5dbcb3d33 100644 --- a/roles/user-administrator/tasks/01_core.yml +++ b/roles/user-administrator/tasks/01_core.yml @@ -1,16 +1,16 @@ --- -- name: Fail if administrator authorized_keys is empty +- name: ๐Ÿ›‘ Fail if administrator authorized_keys is empty ansible.builtin.fail: msg: >- lookup('users', 'administrator').authorized_keys must contain at least one SSH public key. when: lookup('users', 'administrator').authorized_keys | length == 0 -- name: Include dependency 'sys-sudo' +- name: ๐Ÿ“‚ Include dependency 'sys-sudo' include_role: name: sys-sudo when: run_once_sys_sudo is not defined -- name: create administrator +- name: ๐Ÿ“ create administrator user: name: administrator update_password: on_create @@ -21,7 +21,7 @@ ssh_key_bits: 8192 no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "set correct rights for {{ DIR_HOME_ADMINISTRATOR }}" +- name: "๐Ÿ”ง set correct rights for {{ DIR_HOME_ADMINISTRATOR }}" file: path: "{{ DIR_HOME_ADMINISTRATOR }}" state: directory @@ -29,7 +29,7 @@ group: administrator mode: "0700" -- name: grant administrator sudo rights with password +- name: ๐Ÿ” grant administrator sudo rights with password copy: src: "administrator" dest: /etc/sudoers.d/administrator @@ -37,7 +37,7 @@ owner: root group: root -- name: "embed user routines for {{ role_path | basename }}" +- name: "๐Ÿ‘ค embed user routines for {{ role_path | basename }}" include_role: name: user vars: diff --git a/roles/user-backup/tasks/01_core.yml b/roles/user-backup/tasks/01_core.yml index cdb005d9f5..2f2429f2a1 100644 --- a/roles/user-backup/tasks/01_core.yml +++ b/roles/user-backup/tasks/01_core.yml @@ -1,17 +1,17 @@ --- - include_tasks: utils/once/flag.yml -- name: create backup user +- name: ๐Ÿ“ create backup user user: name: backup create_home: true -- name: Include dependency 'sys-svc-sshd' +- name: ๐Ÿ“‚ Include dependency 'sys-svc-sshd' include_role: name: sys-svc-sshd when: run_once_sys_svc_sshd is not defined -- name: grant backup sudo rights +- name: ๐Ÿ” grant backup sudo rights copy: src: "backup" dest: /etc/sudoers.d/backup diff --git a/roles/user-backup/tasks/02_permissions_ssh.yml b/roles/user-backup/tasks/02_permissions_ssh.yml index fed1123001..465b23f795 100644 --- a/roles/user-backup/tasks/02_permissions_ssh.yml +++ b/roles/user-backup/tasks/02_permissions_ssh.yml @@ -1,5 +1,5 @@ --- -- name: "Ensure backup home directory exists" +- name: "โœ… Ensure backup home directory exists" ansible.builtin.file: path: "{{ USER_BACKUP_HOME }}" state: directory @@ -7,7 +7,7 @@ group: backup mode: "0700" -- name: "create {{ USER_BACKUP_WRAPPER_DST }}" +- name: "๐Ÿ“ create {{ USER_BACKUP_WRAPPER_DST }}" ansible.builtin.template: # nocheck: stack-host-template (per-host backup user wrapper, lives in backup home on every backed-up host) src: "ssh-wrapper.sh.j2" dest: "{{ USER_BACKUP_WRAPPER_DST }}" @@ -15,7 +15,7 @@ group: backup mode: "0700" -- name: "Write authorized_keys for 'backup' via shared user role (wrapped)" +- name: "โœ๏ธ Write authorized_keys for 'backup' via shared user role (wrapped)" ansible.builtin.include_role: name: user vars: diff --git a/roles/user-backup/tasks/03_permissions_folders.yml b/roles/user-backup/tasks/03_permissions_folders.yml index 7d6b9d989d..7e38f3fecf 100644 --- a/roles/user-backup/tasks/03_permissions_folders.yml +++ b/roles/user-backup/tasks/03_permissions_folders.yml @@ -1,10 +1,10 @@ --- -- name: Install ACL utilities +- name: ๐Ÿ“ฆ Install ACL utilities ansible.builtin.package: name: acl state: present -- name: Ensure backups root exists and owned by backup +- name: โœ… Ensure backups root exists and owned by backup file: path: "{{ DIR_BACKUPS }}" state: directory @@ -12,7 +12,7 @@ group: backup mode: "0700" -- name: Grant ACL rwx on backups root to backup user +- name: ๐Ÿ” Grant ACL rwx on backups root to backup user ansible.posix.acl: path: "{{ DIR_BACKUPS }}" entity: backup @@ -20,7 +20,7 @@ permissions: rwx state: present -- name: Set default ACL (inherit) for backup user under backups root +- name: ๐Ÿ”ง Set default ACL (inherit) for backup user under backups root ansible.posix.acl: path: "{{ DIR_BACKUPS }}" entity: backup @@ -29,7 +29,7 @@ default: true state: present -- name: Default ACL for backup user (inherit) +- name: ๐Ÿ” Default ACL for backup user (inherit) ansible.posix.acl: path: "{{ DIR_BACKUPS }}" etype: user @@ -38,7 +38,7 @@ default: true state: present -- name: Default ACL for group -> none +- name: ๐Ÿ” Default ACL for group -> none ansible.posix.acl: path: "{{ DIR_BACKUPS }}" etype: group @@ -46,7 +46,7 @@ default: true state: present -- name: Default ACL for other -> none +- name: ๐Ÿ” Default ACL for other -> none ansible.posix.acl: path: "{{ DIR_BACKUPS }}" etype: other @@ -54,12 +54,12 @@ default: true state: present -- name: Fix ownership level 0..2 directories to backup:backup +- name: ๐Ÿ“ Fix ownership level 0..2 directories to backup:backup ansible.builtin.shell: > find "{{ DIR_BACKUPS }}" -mindepth 0 -maxdepth 2 -xdev -type d -exec chown backup:backup {} + changed_when: false -- name: Fix perms level 0..2 directories to 0700 +- name: ๐Ÿ“ Fix perms level 0..2 directories to 0700 ansible.builtin.shell: > find "{{ DIR_BACKUPS }}" -mindepth 0 -maxdepth 2 -xdev -type d -exec chmod 700 {} + changed_when: false diff --git a/roles/user-root/tasks/01_core.yml b/roles/user-root/tasks/01_core.yml index c8d3fa2722..02ea2e12a1 100644 --- a/roles/user-root/tasks/01_core.yml +++ b/roles/user-root/tasks/01_core.yml @@ -1,14 +1,14 @@ --- -- name: Check if the SSH key for root already exists +- name: ๐Ÿ”Ž Check if the SSH key for root already exists ansible.builtin.stat: path: "{{ USER_ROOT_SSH_KEY_PUBLIC }}" register: ssh_key -- name: "Include routine to create {{ USER_ROOT_SSH_KEY_PUBLIC }}" +- name: "๐Ÿ“‚ Include routine to create {{ USER_ROOT_SSH_KEY_PUBLIC }}" include_tasks: 02_ssh.yml when: not ssh_key.stat.exists -- name: "embed user routines for {{ role_path | basename }}" +- name: "๐Ÿ‘ค embed user routines for {{ role_path | basename }}" include_role: name: user vars: @@ -26,7 +26,7 @@ ) }} -- name: "create {{ DIR_SCRIPTS_ROOT }}" +- name: "๐Ÿ“ create {{ DIR_SCRIPTS_ROOT }}" file: path: "{{ DIR_SCRIPTS_ROOT }}" state: directory diff --git a/roles/user-root/tasks/02_ssh.yml b/roles/user-root/tasks/02_ssh.yml index 4310dbb769..c3135140f3 100644 --- a/roles/user-root/tasks/02_ssh.yml +++ b/roles/user-root/tasks/02_ssh.yml @@ -1,10 +1,10 @@ --- -- name: "Include SSH for user root" +- name: "๐Ÿ“‚ Include SSH for user root" include_role: name: "sys-svc-ssh" when: not (run_once_sys_svc_ssh | default(false) | bool) -- name: Ensure '{{ USER_ROOT_SSH_DIR }}' exists +- name: โœ… Ensure '{{ USER_ROOT_SSH_DIR }}' exists file: path: "{{ USER_ROOT_SSH_DIR }}" state: directory @@ -12,17 +12,17 @@ group: root mode: "0700" -- name: Generate a SSH key for root if it does not exist +- name: โš™๏ธ Generate a SSH key for root if it does not exist community.crypto.openssh_keypair: path: "{{ USER_ROOT_SSH_KEY_PRIVATE }}" type: rsa size: 4096 -- name: Display the public SSH key +- name: ๐Ÿ‘๏ธ Display the public SSH key command: "cat {{ USER_ROOT_SSH_KEY_PUBLIC }}" register: public_key changed_when: false -- name: Output the public SSH key +- name: ๐Ÿ”‘ Output the public SSH key debug: msg: "{{ public_key.stdout }}" diff --git a/roles/user-root/tasks/main.yml b/roles/user-root/tasks/main.yml index b2925baedd..c7178ed8c1 100644 --- a/roles/user-root/tasks/main.yml +++ b/roles/user-root/tasks/main.yml @@ -1,4 +1,4 @@ --- -- name: "Execute Role (once)" +- name: "โ–ถ๏ธ Execute Role (once)" include_tasks: 01_core.yml when: run_once_user_root is not defined diff --git a/roles/user-workstation/tasks/01_core.yml b/roles/user-workstation/tasks/01_core.yml index 95d196b9a7..339eca0ea3 100644 --- a/roles/user-workstation/tasks/01_core.yml +++ b/roles/user-workstation/tasks/01_core.yml @@ -1,21 +1,21 @@ --- -- name: Validate WORKSTATION_USER is defined +- name: โœ… Validate WORKSTATION_USER is defined ansible.builtin.fail: msg: "WORKSTATION_USER must be defined (e.g. WORKSTATION_USER: biber)." when: WORKSTATION_USER is not defined or (WORKSTATION_USER | string | length) == 0 -- name: Validate lookup('users', WORKSTATION_USER) exists +- name: โœ… Validate lookup('users', WORKSTATION_USER) exists ansible.builtin.fail: msg: "lookup('users', '{{ WORKSTATION_USER }}') must resolve to a user entry." when: lookup('users', WORKSTATION_USER, none) is none -- name: Ensure primary group exists +- name: โœ… Ensure primary group exists ansible.builtin.group: name: "{{ USER_WORKSTATION_USERNAME }}" gid: "{{ USER_WORKSTATION_GID | default(omit) }}" state: present -- name: Create workstation user +- name: ๐Ÿ“ Create workstation user ansible.builtin.user: name: "{{ USER_WORKSTATION_USERNAME }}" uid: "{{ USER_WORKSTATION_UID }}" @@ -31,13 +31,13 @@ }} no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Deploy workstation user environment via shared user role +- name: ๐Ÿš€ Deploy workstation user environment via shared user role ansible.builtin.include_role: name: user vars: user_key: "{{ USER_WORKSTATION_KEY }}" -- name: Enable sudo via sudoers drop-in (optional) +- name: ๐ŸŸข Enable sudo via sudoers drop-in (optional) ansible.builtin.template: # nocheck: stack-host-template (per-host workstation sudoers drop-in) src: sudoers.j2 dest: "/etc/sudoers.d/{{ USER_WORKSTATION_USERNAME }}" diff --git a/roles/user/tasks/01_ssh_authorized_keys.yml b/roles/user/tasks/01_ssh_authorized_keys.yml index 1666925f19..23fbf6b1a4 100644 --- a/roles/user/tasks/01_ssh_authorized_keys.yml +++ b/roles/user/tasks/01_ssh_authorized_keys.yml @@ -1,5 +1,5 @@ --- -- name: Validate user authorized_keys is a list when defined +- name: โœ… Validate user authorized_keys is a list when defined ansible.builtin.fail: msg: >- Invalid SSH key configuration for user key '{{ user_key }}'. @@ -8,7 +8,7 @@ - user_config_effective.authorized_keys is defined - user_config_effective.authorized_keys is string or user_config_effective.authorized_keys is not iterable -- name: Ensure SSH directory exists for '{{ user_username }}' +- name: โœ… Ensure SSH directory exists for '{{ user_username }}' ansible.builtin.file: path: "{{ user_home }}/.ssh" state: directory @@ -18,7 +18,7 @@ when: - user_config_effective.authorized_keys is defined -- name: Write authorized_keys for '{{ user_username }}' +- name: โœ๏ธ Write authorized_keys for '{{ user_username }}' ansible.builtin.copy: dest: "{{ user_home }}/.ssh/authorized_keys" content: | diff --git a/roles/user/tasks/main.yml b/roles/user/tasks/main.yml index bc951fe727..ad047a36d8 100644 --- a/roles/user/tasks/main.yml +++ b/roles/user/tasks/main.yml @@ -1,7 +1,7 @@ --- # nocheck: run-once -- name: Deploy shell dotfiles +- name: ๐Ÿš€ Deploy shell dotfiles ansible.builtin.template: # nocheck: stack-host-template (per-host user dotfiles, shared user role runs on every host) src: "{{ dotfile }}.j2" dest: "{{ user_home }}/.{{ dotfile }}" @@ -15,5 +15,5 @@ loop_var: dotfile label: ".{{ dotfile }}" -- name: Manage SSH authorized_keys (SPOT-only) +- name: ๐Ÿ”ง Manage SSH authorized_keys (SPOT-only) ansible.builtin.include_tasks: 01_ssh_authorized_keys.yml diff --git a/roles/web-app-akaunting/tasks/main.yml b/roles/web-app-akaunting/tasks/main.yml index 688055eff4..641f06109e 100644 --- a/roles/web-app-akaunting/tasks/main.yml +++ b/roles/web-app-akaunting/tasks/main.yml @@ -1,14 +1,14 @@ --- -- name: "Akaunting | Check if first run (marker exists?)" +- name: "๐Ÿ”Ž Akaunting | Check if first run (marker exists?)" ansible.builtin.stat: path: "{{ AKAUNTING_SETUP_MARKER }}" register: akaunting_marker_stat -- name: "Akaunting | Decide if setup should be enabled" +- name: "๐Ÿค” Akaunting | Decide if setup should be enabled" ansible.builtin.set_fact: akaunting_setup_enabled: "{{ not akaunting_marker_stat.stat.exists }}" -- name: "For '{{ application_id }}': load docker, db and proxy" +- name: "๐Ÿงฉ For '{{ application_id }}': load docker, db and proxy" include_role: name: sys-stk-full vars: @@ -17,7 +17,7 @@ compose_repository_ref: "{{ AKAUNTING_REF }}" compose_handlers_flush: true -- name: "Akaunting | Create first-run marker to disable future setup" +- name: "๐Ÿ“ Akaunting | Create first-run marker to disable future setup" ansible.builtin.file: path: "{{ AKAUNTING_SETUP_MARKER }}" state: touch diff --git a/roles/web-app-baserow/tasks/02_manager_ops.yml b/roles/web-app-baserow/tasks/02_manager_ops.yml index 097b59d51c..0dde813800 100644 --- a/roles/web-app-baserow/tasks/02_manager_ops.yml +++ b/roles/web-app-baserow/tasks/02_manager_ops.yml @@ -1,5 +1,5 @@ --- -- name: "Run Baserow Django migrations before bootstrapping users" +- name: "โ–ถ๏ธ Run Baserow Django migrations before bootstrapping users" ansible.builtin.shell: cmd: >- container exec -i @@ -19,7 +19,7 @@ delay: 5 until: baserow_migrate_result.rc == 0 -- name: "Restart Baserow application after applying migrations (compose mode)" +- name: "๐Ÿ”„ Restart Baserow application after applying migrations (compose mode)" ansible.builtin.command: "container restart {{ BASEROW_APP_CONTAINER_ADDRESS | quote }}" register: baserow_restart_after_migrate changed_when: baserow_restart_after_migrate.rc == 0 @@ -27,7 +27,7 @@ - baserow_migrate_result.changed - DEPLOYMENT_MODE == 'compose' -- name: "Restart Baserow application after applying migrations (swarm mode)" +- name: "๐Ÿ”„ Restart Baserow application after applying migrations (swarm mode)" ansible.builtin.command: "container service update --force {{ lookup('container_service', application_id, BASEROW_SERVICE_NAME) }}" register: baserow_swarm_restart changed_when: baserow_swarm_restart.rc == 0 @@ -36,7 +36,7 @@ - baserow_migrate_result.changed - DEPLOYMENT_MODE == 'swarm' -- name: "Bootstrap Baserow Django superuser '{{ BASEROW_BOOTSTRAP_ADMIN_USERNAME }}' (idempotent)" +- name: "๐ŸŽฌ Bootstrap Baserow superuser '{{ BASEROW_BOOTSTRAP_ADMIN_USERNAME }}'" ansible.builtin.shell: cmd: >- container exec -i diff --git a/roles/web-app-baserow/tasks/main.yml b/roles/web-app-baserow/tasks/main.yml index 54761b1160..a15ee2363e 100644 --- a/roles/web-app-baserow/tasks/main.yml +++ b/roles/web-app-baserow/tasks/main.yml @@ -1,11 +1,11 @@ --- -- name: "For '{{ application_id }}': load docker, db and proxy" +- name: "๐Ÿงฉ For '{{ application_id }}': load docker, db and proxy" include_role: name: sys-stk-full vars: compose_handlers_flush: false -- name: "Stage trusted-header SSO build-context files for {{ application_id }}" +- name: "๐ŸŽฌ Stage trusted-header SSO build-context files for {{ application_id }}" stack_host_copy: src: "{{ item.src }}" dest: "{{ [ lookup('container', application_id, 'directories.instance'), item.dest ] | path_join }}" @@ -15,9 +15,9 @@ - { src: "sso/infinito_sso.py", dest: "infinito_sso.py" } - { src: "sso/settings_patch.py", dest: "settings_patch.py" } -- name: "Flush compose handlers for {{ application_id }}" +- name: "๐Ÿšฟ Flush compose handlers for {{ application_id }}" ansible.builtin.meta: flush_handlers -- name: "Baserow manager-side operations (file deploys + container exec)" +- name: "๐Ÿ‘” Baserow manager-side operations (file deploys + container exec)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-bigbluebutton/tasks/01_core.yml b/roles/web-app-bigbluebutton/tasks/01_core.yml index 3f16310b99..4fbbfb8edb 100644 --- a/roles/web-app-bigbluebutton/tasks/01_core.yml +++ b/roles/web-app-bigbluebutton/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: "load docker, proxy for '{{ application_id }}'" +- name: "๐Ÿงฉ load docker, proxy for '{{ application_id }}'" include_role: name: sys-stk-full vars: @@ -20,7 +20,7 @@ } ) | trim }} -- name: "Include Seed routines for '{{ application_id }}' database backup" +- name: "๐Ÿ“‚ Include Seed routines for '{{ application_id }}' database backup" include_tasks: "{{ [ playbook_dir, 'roles/svc-bkp-container-2-local/tasks/04_seed-database-to-backup.yml' ] | path_join }}" vars: database_consumer_id: "{{ application_id }}" @@ -35,14 +35,14 @@ - "'svc-bkp-container-2-local' in group_names" - IS_STACK_HOST | bool -- name: configure websocket_upgrade.conf +- name: ๐Ÿ”ง configure websocket_upgrade.conf copy: src: "websocket_upgrade.conf" dest: "{{ [ lookup('nginx','directories.configuration.maps'), 'websocket_upgrade.conf' ] | path_join }}" when: IS_STACK_HOST | bool notify: restart openresty -- name: "BBB manager-side operations (compose render + container exec)" +- name: "๐Ÿ‘” BBB manager-side operations (compose render + container exec)" include_tasks: 01a_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-bigbluebutton/tasks/01a_manager_ops.yml b/roles/web-app-bigbluebutton/tasks/01a_manager_ops.yml index c364beba0d..460b3f1ab4 100644 --- a/roles/web-app-bigbluebutton/tasks/01a_manager_ops.yml +++ b/roles/web-app-bigbluebutton/tasks/01a_manager_ops.yml @@ -1,31 +1,31 @@ --- -- name: "Set BBB Facts" +- name: "๐Ÿ”ง Set BBB Facts" set_fact: BBB_ENV_FILE_LINK: "{{ [compose_repository_path, '.env'] | path_join }}" BBB_ENV_FILE_ORIGINE: "{{ lookup('container', application_id, 'files.env') }}" BBB_COMPOSE_FILE_ORIGINE: "{{ [compose_repository_path, 'docker-compose.yml'] | path_join }}" BBB_COMPOSE_FILE_FINAL: "{{ [lookup('container', application_id, 'directories.instance'), 'compose.yml'] | path_join }}" -- name: Write compose.override.yml for BigBlueButton +- name: โœ๏ธ Write compose.override.yml for BigBlueButton stack_host_template: src: compose.override.yml.j2 dest: "{{ [lookup('container', application_id, 'directories.instance'), 'compose.override.yml'] | path_join }}" notify: compose up -- name: Create symbolic link from .env file to target location +- name: ๐Ÿ“ Create symbolic link from .env file to target location file: src: "{{ BBB_ENV_FILE_ORIGINE }}" dest: "{{ BBB_ENV_FILE_LINK }}" state: link -- name: "Setup compose.yml file" +- name: "๐Ÿ”ง Setup compose.yml file" include_tasks: "02_compose.yml" -- name: flush docker service +- name: ๐Ÿšฟ flush docker service meta: flush_handlers -- name: "Ensure PostgreSQL password matches POSTGRESQL_SECRET" +- name: "โœ… Ensure PostgreSQL password matches POSTGRESQL_SECRET" ansible.builtin.include_tasks: "02a_postgres_password_sync.yml" -- name: "Setup administrator" +- name: "๐Ÿ”ง Setup administrator" include_tasks: "03_administrator.yml" diff --git a/roles/web-app-bigbluebutton/tasks/02_compose.yml b/roles/web-app-bigbluebutton/tasks/02_compose.yml index dbab0e998f..a80562ab5b 100644 --- a/roles/web-app-bigbluebutton/tasks/02_compose.yml +++ b/roles/web-app-bigbluebutton/tasks/02_compose.yml @@ -1,4 +1,4 @@ --- -- name: "Bootstrap bigbluebutton compose project (compose-mode only)" +- name: "๐Ÿฅพ Bootstrap bigbluebutton compose project (compose-mode only)" include_tasks: 02b_bootstrap_compose_project.yml when: DEPLOYMENT_MODE == "compose" diff --git a/roles/web-app-bigbluebutton/tasks/02a_postgres_password_sync.yml b/roles/web-app-bigbluebutton/tasks/02a_postgres_password_sync.yml index 7c96fcd407..75c7907a1f 100644 --- a/roles/web-app-bigbluebutton/tasks/02a_postgres_password_sync.yml +++ b/roles/web-app-bigbluebutton/tasks/02a_postgres_password_sync.yml @@ -1,5 +1,5 @@ --- -- name: "Wait until PostgreSQL is ready" +- name: "โณ Wait until PostgreSQL is ready" ansible.builtin.shell: > container exec -i {{ BBB_POSTGRES_CONTAINER_ADDRESS | quote }} pg_isready -U postgres @@ -9,7 +9,7 @@ until: pg_ready.rc == 0 changed_when: false -- name: "Wait for PostgreSQL to accept SQL after initdb restarts" +- name: "โณ Wait for PostgreSQL to accept SQL after initdb restarts" ansible.builtin.shell: > container exec -i {{ BBB_POSTGRES_CONTAINER_ADDRESS | quote }} psql -U postgres -d postgres -tAc "SELECT 1;" @@ -19,7 +19,7 @@ until: pg_sql_ready.rc == 0 and (pg_sql_ready.stdout | trim) == '1' changed_when: false -- name: "Ensure PostgreSQL password matches POSTGRESQL_SECRET" +- name: "โœ… Ensure PostgreSQL password matches POSTGRESQL_SECRET" ansible.builtin.shell: > container exec -i {{ BBB_POSTGRES_CONTAINER_ADDRESS | quote }} psql -U postgres -d postgres diff --git a/roles/web-app-bigbluebutton/tasks/02b_bootstrap_compose_project.yml b/roles/web-app-bigbluebutton/tasks/02b_bootstrap_compose_project.yml index 30cb9bde7b..4f379160eb 100644 --- a/roles/web-app-bigbluebutton/tasks/02b_bootstrap_compose_project.yml +++ b/roles/web-app-bigbluebutton/tasks/02b_bootstrap_compose_project.yml @@ -1,20 +1,20 @@ --- # include-gated: when: DEPLOYMENT_MODE == "compose" -- name: "create compose.yml for bigbluebutton" +- name: "๐Ÿ“ create compose.yml for bigbluebutton" command: cmd: bash ./scripts/generate-compose chdir: "{{ compose_repository_path }}" -- name: Slurp compose.yml from remote host +- name: ๐Ÿณ Slurp compose.yml from remote host slurp: src: "{{ BBB_COMPOSE_FILE_ORIGINE }}" register: compose_slurp -- name: Transform compose.yml with compose_mods +- name: ๐Ÿณ Transform compose.yml with compose_mods copy: content: "{{ compose_slurp.content | b64decode | compose_mods(compose_repository_path, lookup('container', application_id, 'files.env')) }}" dest: "{{ BBB_COMPOSE_FILE_FINAL }}" notify: - compose up -- name: Prebuild etherpad image +- name: ๐Ÿ”จ Prebuild etherpad image # `compose build --network=host` is no longer accepted by current # docker-compose; the legacy flag was dropped. Prebuild remains # required for local-test correctness. diff --git a/roles/web-app-bigbluebutton/tasks/03_administrator.yml b/roles/web-app-bigbluebutton/tasks/03_administrator.yml index 5e76e83682..f85eb38baf 100644 --- a/roles/web-app-bigbluebutton/tasks/03_administrator.yml +++ b/roles/web-app-bigbluebutton/tasks/03_administrator.yml @@ -1,5 +1,5 @@ --- -- name: "Wait until Greenlight is reachable via Nginx" +- name: "โณ Wait until Greenlight is reachable via Nginx" uri_retry: url: "{{ lookup('tls', application_id, 'url.base') }}" validate_certs: true @@ -13,7 +13,7 @@ delay: 5 changed_when: false -- name: "Ensure Greenlight admin (B64-safe, idempotent)" +- name: "โœ… Ensure Greenlight admin (B64-safe, idempotent)" ansible.builtin.command: argv: - container diff --git a/roles/web-app-bigbluebutton/tasks/main.yml b/roles/web-app-bigbluebutton/tasks/main.yml index 4acfde8624..30813584f0 100644 --- a/roles/web-app-bigbluebutton/tasks/main.yml +++ b/roles/web-app-bigbluebutton/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "Execute Role (once)" +- name: "โ–ถ๏ธ Execute Role (once)" include_tasks: 01_core.yml when: run_once_web_app_bigbluebutton is not defined vars: diff --git a/roles/web-app-bluesky/tasks/01_core.yml b/roles/web-app-bluesky/tasks/01_core.yml index eccfde861f..d6403fe18b 100644 --- a/roles/web-app-bluesky/tasks/01_core.yml +++ b/roles/web-app-bluesky/tasks/01_core.yml @@ -7,18 +7,18 @@ # handlers, otherwise `compose build` fires against a missing build context. # Pre-create the services directory and clone the repo here, before any # compose-touching include. -- name: "Pre-compose web-enabled staging (services dir + social-app + login-broker)" +- name: "๐Ÿณ Pre-compose web-enabled staging (services dir + social-app + login-broker)" block: - - name: "Ensure social-app services directory exists" + - name: "โœ… Ensure social-app services directory exists" ansible.builtin.file: path: "{{ BLUESKY_SOCIAL_APP_DIR | dirname }}" state: directory mode: "0755" - - name: "Clone social-app build context (pre-compose)" + - name: "โฌ‡๏ธ Clone social-app build context (pre-compose)" ansible.builtin.include_tasks: "03_social_app.yml" - - name: "Stage login-broker build context (pre-compose)" + - name: "๐ŸŽฌ Stage login-broker build context (pre-compose)" ansible.builtin.include_tasks: "06_login_broker.yml" when: BLUESKY_WEB_ENABLED | bool @@ -31,7 +31,7 @@ # the oauth2-proxy keeps restart-looping with "is a directory". Heal # that corruption defensively before sys-stk-backend pulls the # oauth2-proxy template back in. -- name: "Heal oauth2-proxy cfg bind-mount corruption (if it became a directory in a prior deploy)" +- name: "๐Ÿงน Heal oauth2-proxy cfg bind-mount (if it became a directory in a prior deploy)" ansible.builtin.shell: >- if [ -d "{{ BLUESKY_SSO_PROXY_CFG_PATH }}" ]; then container stop "{{ BLUESKY_SSO_PROXY_CONTAINER }}" 2>/dev/null || true; @@ -49,13 +49,13 @@ # sidecar config via web-app-keycloak/tasks/sso_proxy.yml. Without # this, the sidecar starts with /oauth2-proxy.cfg as an empty # bind-mounted directory and restart-loops. -- name: "include sys-stk-backend role" +- name: "๐Ÿ“‚ include sys-stk-backend role" include_role: name: sys-stk-backend vars: compose_handlers_flush: false -- name: "Include front proxy for {{ BLUESKY_API_DOMAIN }}:{{ BLUESKY_API_PORT }}" +- name: "๐Ÿ“‚ Include front proxy for {{ BLUESKY_API_DOMAIN }}:{{ BLUESKY_API_PORT }}" include_role: name: sys-stk-front-proxy vars: @@ -64,7 +64,7 @@ webserver_proxy_service_key: "{{ 'pds' if DEPLOYMENT_MODE == 'swarm' else (application_id | get_entity_name) }}" proxy_internal_port: "{{ lookup('config', application_id, 'services.api.ports.internal.http') if DEPLOYMENT_MODE == 'swarm' else '' }}" -- name: "Include front proxy for {{ BLUESKY_WEB_DOMAIN }} (broker when oauth2 enabled, stock social-app otherwise)" +- name: "๐Ÿ“‚ Front proxy {{ BLUESKY_WEB_DOMAIN }} (broker if oauth2, else social-app)" include_role: name: sys-stk-front-proxy vars: @@ -85,7 +85,7 @@ }} when: BLUESKY_WEB_ENABLED | bool -- name: "Include front proxy for {{ BLUESKY_VIEW_DOMAIN_FINAL }}:{{ BLUESKY_VIEW_PORT }}" +- name: "๐Ÿ“‚ Front proxy for {{ BLUESKY_VIEW_DOMAIN_FINAL }}:{{ BLUESKY_VIEW_PORT }}" include_role: name: sys-stk-front-proxy vars: @@ -95,10 +95,10 @@ proxy_internal_port: "{{ lookup('config', application_id, 'services.view.ports.internal.http') if DEPLOYMENT_MODE == 'swarm' else '' }}" when: BLUESKY_VIEW_ENABLED | bool -- name: "Execute PDS routines" +- name: "โ–ถ๏ธ Execute PDS routines" ansible.builtin.include_tasks: "02_pds.yml" -- name: "Create native PDS administrator (oauth2 disabled, no broker handoff to auto-provision)" +- name: "๐Ÿ“ Create native PDS administrator (oauth2 disabled, no broker auto-provision)" ansible.builtin.include_tasks: "07_native_admin.yml" when: - BLUESKY_WEB_ENABLED | bool @@ -107,11 +107,11 @@ # 03_social_app already ran before sys-svc-compose (above) so that the # compose build handler finds the cloned context. -- name: "DNS for Bluesky" +- name: "๐ŸŒ DNS for Bluesky" include_tasks: "04_dns.yml" when: DNS_PROVIDER | lower == 'cloudflare' -- name: Resolve redirect_domain_mappings now (before include_role) +- name: ๐Ÿ” Resolve redirect_domain_mappings now (before include_role) set_fact: BLUESKY_REDIRECT_DOMAIN_MAPPINGS: >- {{ @@ -119,12 +119,12 @@ + ( (BLUESKY_VIEW_ENABLED | bool) | ternary([], [ {'source': BLUESKY_VIEW_DOMAIN_LOCAL, 'target': BLUESKY_API_DOMAIN } ]) ) }} -- name: "Redirect deactivated BlueSky Services to {{ BLUESKY_API_DOMAIN }}" +- name: "๐Ÿ› ๏ธ Redirect deactivated BlueSky Services to {{ BLUESKY_API_DOMAIN }}" include_tasks: "utils/load_app.yml" vars: load_app_id: "web-opt-rdr-domains" redirect_domain_mappings: "{{ BLUESKY_REDIRECT_DOMAIN_MAPPINGS }}" web_opt_rdr_domains_logout_enabled: true -- name: "Flush handlers for '{{ role_name }}'" +- name: "๐Ÿšฟ Flush handlers for '{{ role_name }}'" meta: flush_handlers diff --git a/roles/web-app-bluesky/tasks/02_pds.yml b/roles/web-app-bluesky/tasks/02_pds.yml index 07d00d7867..5aee337327 100644 --- a/roles/web-app-bluesky/tasks/02_pds.yml +++ b/roles/web-app-bluesky/tasks/02_pds.yml @@ -2,7 +2,7 @@ # The following lines should be removed when the following issue is closed: # https://github.com/bluesky-social/pds/issues/52 -- name: Download pdsadmin tarball +- name: โฌ‡๏ธ Download pdsadmin tarball get_url_retry: url: "https://github.com/lhaig/pdsadmin/releases/download/v1.0.0-dev/pdsadmin_Linux_x86_64.tar.gz" dest: "{{ BLUESKY_PDSADMIN_TMP_TAR }}" @@ -11,20 +11,20 @@ - compose up - compose build -- name: Create {{ BLUESKY_PDSADMIN_DIR }} +- name: ๐Ÿ“ Create {{ BLUESKY_PDSADMIN_DIR }} file: path: "{{ BLUESKY_PDSADMIN_DIR }}" state: directory mode: "0755" -- name: Extract pdsadmin tarball +- name: ๐Ÿ“ค Extract pdsadmin tarball unarchive: src: "{{ BLUESKY_PDSADMIN_TMP_TAR }}" dest: "{{ BLUESKY_PDSADMIN_DIR }}" remote_src: true mode: "0755" -- name: Ensure pdsadmin is executable +- name: โœ… Ensure pdsadmin is executable file: path: "{{ BLUESKY_PDSADMIN_FILE }}" mode: "0755" diff --git a/roles/web-app-bluesky/tasks/03_social_app.yml b/roles/web-app-bluesky/tasks/03_social_app.yml index 2bbbee0320..b8f35a71b2 100644 --- a/roles/web-app-bluesky/tasks/03_social_app.yml +++ b/roles/web-app-bluesky/tasks/03_social_app.yml @@ -1,5 +1,5 @@ --- -- name: clone social app repository +- name: โฌ‡๏ธ clone social app repository git: repo: "{{ BLUESKY_SOCIAL_APP_REPOSITORY }}" dest: "{{ BLUESKY_SOCIAL_APP_DIR }}" @@ -9,13 +9,13 @@ - compose up - compose build -- name: Force BAPP_CONFIG_URL to same-origin /config +- name: ๐Ÿ’ช Force BAPP_CONFIG_URL to same-origin /config ansible.builtin.replace: path: "{{ BLUESKY_GEOLOCATION_PATH }}" regexp: "^\\s*const\\s+BAPP_CONFIG_URL\\s*=\\s*.*$" replace: "const BAPP_CONFIG_URL = '/config'" -- name: Force IPCC_URL to same-origin /ipcc +- name: ๐Ÿ’ช Force IPCC_URL to same-origin /ipcc ansible.builtin.replace: path: "{{ BLUESKY_GEOLOCATION_PATH }}" regexp: "^\\s*const\\s+IPCC_URL\\s*=\\s*.*$" diff --git a/roles/web-app-bluesky/tasks/04_dns.yml b/roles/web-app-bluesky/tasks/04_dns.yml index bb7f69349b..04e1c0134d 100644 --- a/roles/web-app-bluesky/tasks/04_dns.yml +++ b/roles/web-app-bluesky/tasks/04_dns.yml @@ -1,5 +1,5 @@ --- -- name: "DNS (Cloudflare) for Bluesky โ€“ base records" +- name: "๐ŸŒ DNS (Cloudflare) for Bluesky โ€“ base records" include_role: name: sys-dns-cloudflare-records when: DNS_PROVIDER | lower == 'cloudflare' diff --git a/roles/web-app-bluesky/tasks/06_login_broker.yml b/roles/web-app-bluesky/tasks/06_login_broker.yml index 8a45c495c0..a78b69102f 100644 --- a/roles/web-app-bluesky/tasks/06_login_broker.yml +++ b/roles/web-app-bluesky/tasks/06_login_broker.yml @@ -5,13 +5,13 @@ # (see `services.bluesky-broker` in templates/compose.yml.j2). This # task only owns the on-disk staging. -- name: "Ensure broker build-context parent directory exists" +- name: "โœ… Ensure broker build-context parent directory exists" ansible.builtin.file: path: "{{ BLUESKY_BROKER_BUILD_CONTEXT | dirname }}" state: directory mode: "0755" -- name: "Copy login-broker source into the broker build-context dir" +- name: "๐Ÿ“‹ Copy login-broker source into the broker build-context dir" ansible.builtin.copy: src: "{{ BLUESKY_BROKER_SRC_DIR }}/" dest: "{{ BLUESKY_BROKER_BUILD_CONTEXT }}/" diff --git a/roles/web-app-bluesky/tasks/07_native_admin.yml b/roles/web-app-bluesky/tasks/07_native_admin.yml index 1f7b9df3ae..d755cc3ca4 100644 --- a/roles/web-app-bluesky/tasks/07_native_admin.yml +++ b/roles/web-app-bluesky/tasks/07_native_admin.yml @@ -1,5 +1,5 @@ --- -- name: "Wait for PDS XRPC to come up at {{ BLUESKY_PDS_INTERNAL_URL }}/xrpc/_health" +- name: "โณ Wait for PDS XRPC to come up at {{ BLUESKY_PDS_INTERNAL_URL }}/xrpc/_health" uri_retry: url: "{{ BLUESKY_PDS_INTERNAL_URL }}/xrpc/_health" method: GET @@ -10,7 +10,7 @@ delay: 2 until: bluesky_pds_health.status == 200 -- name: "Create native PDS administrator account (idempotent)" +- name: "๐Ÿ“ Create native PDS administrator account (idempotent)" uri_retry: url: "{{ BLUESKY_PDS_INTERNAL_URL }}/xrpc/com.atproto.server.createAccount" method: POST diff --git a/roles/web-app-bluesky/tasks/main.yml b/roles/web-app-bluesky/tasks/main.yml index 85e62d902d..2a7d870dde 100644 --- a/roles/web-app-bluesky/tasks/main.yml +++ b/roles/web-app-bluesky/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "Execute Role (once)" +- name: "โ–ถ๏ธ Execute Role (once)" include_tasks: 01_core.yml when: run_once_web_app_bluesky is not defined vars: diff --git a/roles/web-app-bookwyrm/tasks/01_core.yml b/roles/web-app-bookwyrm/tasks/01_core.yml index bdac345ff6..4bd5228121 100644 --- a/roles/web-app-bookwyrm/tasks/01_core.yml +++ b/roles/web-app-bookwyrm/tasks/01_core.yml @@ -1,13 +1,13 @@ --- - include_tasks: utils/once/flag.yml -- name: "load docker, db/redis and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db/redis and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: compose_handlers_flush: false -- name: "Stage trusted-header SSO build-context files for {{ application_id }}" +- name: "๐ŸŽฌ Stage trusted-header SSO build-context files for {{ application_id }}" stack_host_copy: src: "{{ item.src }}" dest: "{{ [ lookup('container', application_id, 'directories.instance'), item.dest ] | path_join }}" @@ -16,5 +16,5 @@ - { src: "sso/header_auth.py", dest: "header_auth.py" } - { src: "sso/settings_patch.py", dest: "settings_patch.py" } -- name: "Flush compose handlers for {{ application_id }}" +- name: "๐Ÿšฟ Flush compose handlers for {{ application_id }}" ansible.builtin.meta: flush_handlers diff --git a/roles/web-app-bridgy-fed/tasks/01_core.yml b/roles/web-app-bridgy-fed/tasks/01_core.yml index 17cbfdd5c9..183ce05cfd 100644 --- a/roles/web-app-bridgy-fed/tasks/01_core.yml +++ b/roles/web-app-bridgy-fed/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: "Load docker and front proxy for {{ application_id }}" +- name: "๐Ÿงฉ Load docker and front proxy for {{ application_id }}" include_role: name: sys-stk-full vars: diff --git a/roles/web-app-bridgy-fed/tasks/main.yml b/roles/web-app-bridgy-fed/tasks/main.yml index ee733177bb..93e35dc3c1 100644 --- a/roles/web-app-bridgy-fed/tasks/main.yml +++ b/roles/web-app-bridgy-fed/tasks/main.yml @@ -1,4 +1,4 @@ --- -- name: "Include core routines for '{{ application_id }}'" +- name: "๐Ÿ“‚ Include core routines for '{{ application_id }}'" include_tasks: "01_core.yml" when: run_once_web_app_bridgy_fed is not defined diff --git a/roles/web-app-chess/tasks/01_core.yml b/roles/web-app-chess/tasks/01_core.yml index 41308d73e5..9f16835b11 100644 --- a/roles/web-app-chess/tasks/01_core.yml +++ b/roles/web-app-chess/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: diff --git a/roles/web-app-chess/tasks/main.yml b/roles/web-app-chess/tasks/main.yml index a50bb3672f..52c030e56e 100644 --- a/roles/web-app-chess/tasks/main.yml +++ b/roles/web-app-chess/tasks/main.yml @@ -1,4 +1,4 @@ --- -- name: "Include core routines for '{{ application_id }}'" +- name: "๐Ÿ“‚ Include core routines for '{{ application_id }}'" include_tasks: "01_core.yml" when: run_once_web_app_chess is not defined diff --git a/roles/web-app-confluence/tasks/main.yml b/roles/web-app-confluence/tasks/main.yml index ba1ce0b8eb..639a4b883b 100644 --- a/roles/web-app-confluence/tasks/main.yml +++ b/roles/web-app-confluence/tasks/main.yml @@ -1,6 +1,6 @@ --- - block: - - name: "load docker, db and proxy for {{ application_id }}" + - name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: diff --git a/roles/web-app-dashboard/tasks/01_core.yml b/roles/web-app-dashboard/tasks/01_core.yml index da2e030d9d..47375469d7 100644 --- a/roles/web-app-dashboard/tasks/01_core.yml +++ b/roles/web-app-dashboard/tasks/01_core.yml @@ -1,11 +1,11 @@ --- - include_tasks: utils/once/flag.yml -- name: "Include JS routines" +- name: "๐Ÿ“‚ Include JS routines" include_tasks: "02_javascript.yml" when: IS_STACK_HOST | bool -- name: "load docker, proxy for '{{ application_id }}'" +- name: "๐Ÿงฉ load docker, proxy for '{{ application_id }}'" include_role: name: sys-stk-full vars: @@ -13,6 +13,6 @@ compose_repository_pull: false webserver_extra_configuration: "{{ lookup('template', 'nginx/sso.html.conf.j2') }}" -- name: "Dashboard manager-side operations (file deploys + container exec)" +- name: "๐Ÿ‘” Dashboard manager-side operations (file deploys + container exec)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-dashboard/tasks/02_javascript.yml b/roles/web-app-dashboard/tasks/02_javascript.yml index 596b072d43..d38c015166 100644 --- a/roles/web-app-dashboard/tasks/02_javascript.yml +++ b/roles/web-app-dashboard/tasks/02_javascript.yml @@ -1,11 +1,11 @@ --- -- name: Ensure {{ DASHBOARD_JS_SERVER_DIR }} exists +- name: โœ… Ensure {{ DASHBOARD_JS_SERVER_DIR }} exists file: path: "{{ DASHBOARD_JS_SERVER_DIR }}" state: directory mode: "0755" -- name: "Include file specific JS Routines" +- name: "๐Ÿ“‚ Include file specific JS Routines" include_tasks: "_javascript_file.yml" loop: "{{ DASHBOARD_JS_FILES }}" loop_control: diff --git a/roles/web-app-dashboard/tasks/02_manager_ops.yml b/roles/web-app-dashboard/tasks/02_manager_ops.yml index 8dccad00c2..9a20ee2ace 100644 --- a/roles/web-app-dashboard/tasks/02_manager_ops.yml +++ b/roles/web-app-dashboard/tasks/02_manager_ops.yml @@ -1,20 +1,20 @@ --- -- name: "Check if host-specific config.yaml exists in {{ DASHBOARD_CONFIG_INV_PATH }}" +- 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 +- name: ๐Ÿ“„ Load menu categories include_vars: file: "menu_categories.yml" -- name: Load docker cards +- name: ๐Ÿงฉ Load docker cards set_fact: portfolio_cards: "{{ lookup('docker_cards', 'roles') }}" -- name: Probe Simple Icons reachability per card slug (on the stack host) +- name: ๐Ÿ” Probe Simple Icons reachability per card slug (on the stack host) uri_retry: url: "{{ DASHBOARD_SIMPLEICONS_SYNC_URL_BASE }}{{ item }}.svg" method: HEAD @@ -29,7 +29,7 @@ when: DASHBOARD_SIMPLEICONS_ENABLED | bool changed_when: false -- name: "Load Dashboard Brand logos" +- name: "๐Ÿ“„ Load Dashboard Brand logos" set_fact: portfolio_cards: >- {{ portfolio_cards | add_simpleicon_source( @@ -41,11 +41,11 @@ when: DASHBOARD_SIMPLEICONS_ENABLED | bool changed_when: false -- name: Group docker cards +- 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)" +- name: "๐Ÿ“„ Render Dashboard config.yaml (local + swarm peers)" ansible.builtin.include_tasks: file: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/render_replicated_templates.yml'] | path_join }}" vars: @@ -53,12 +53,12 @@ - src: "{{ DASHBOARD_CONFIG_INV_PATH if config_file.stat.exists else DASHBOARD_CONFIG_YML_SRC_FILE }}" dest: "{{ DASHBOARD_CONFIG_YML_DEST }}" -- name: Load rendered dashboard config before first compose start +- 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 +- name: ๐Ÿ“Š Collect branding asset URLs served by the shared file service set_fact: dashboard_branding_asset_urls: >- {{ @@ -92,7 +92,7 @@ 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 +- name: โณ Wait for dashboard branding assets before first compose start uri_retry: url: "{{ item }}" status_code: 200 @@ -107,24 +107,24 @@ delegate_to: "{{ STACK_HOST }}" run_once: true -- name: "Flush compose handlers" +- name: "๐Ÿšฟ Flush compose handlers" meta: flush_handlers -- name: "Ensure Simple Icons is reachable and refresh dashboard cards" +- 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 + - 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 + - name: ๐Ÿšฟ Flush handlers after loading shared Simple Icons service meta: flush_handlers - - name: Refresh dashboard cards after Simple Icons becomes reachable + - name: ๐Ÿ”„ Refresh dashboard cards after Simple Icons becomes reachable include_tasks: "03_simpleicons_refresh.yml" -- name: Wait for Dashboard HTTP endpoint (required so all logos can be downloaded during initialization) +- 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 diff --git a/roles/web-app-dashboard/tasks/03_simpleicons_refresh.yml b/roles/web-app-dashboard/tasks/03_simpleicons_refresh.yml index 76a730c5ee..fa6b3ef249 100644 --- a/roles/web-app-dashboard/tasks/03_simpleicons_refresh.yml +++ b/roles/web-app-dashboard/tasks/03_simpleicons_refresh.yml @@ -1,5 +1,5 @@ --- -- name: Wait for a known Simple Icons asset before rebuilding dashboard cards +- name: โณ Wait for a known Simple Icons asset before rebuilding dashboard cards uri_retry: url: "{{ DASHBOARD_SIMPLEICONS_SYNC_URL_BASE }}keycloak.svg" status_code: 200 @@ -9,7 +9,7 @@ delay: 5 until: simpleicons_http.status == 200 -- name: Probe Simple Icons reachability per card slug (on the stack host) +- name: ๐Ÿ” Probe Simple Icons reachability per card slug (on the stack host) uri_retry: url: "{{ DASHBOARD_SIMPLEICONS_SYNC_URL_BASE }}{{ item }}.svg" method: HEAD @@ -23,7 +23,7 @@ run_once: true changed_when: false -- name: Reload docker cards once Simple Icons is reachable +- name: ๐Ÿ”„ Reload docker cards once Simple Icons is reachable set_fact: portfolio_cards: >- {{ portfolio_cards | add_simpleicon_source( @@ -34,11 +34,11 @@ DASHBOARD_SIMPLEICONS_URL_BASE) }} changed_when: false -- name: Regroup docker cards after Simple Icons refresh +- name: ๐Ÿณ Regroup docker cards after Simple Icons refresh set_fact: portfolio_menu_data: "{{ lookup('docker_cards_grouped', portfolio_cards, portfolio_menu_categories) }}" -- name: "Refresh Dashboard config.yaml after Simple Icons is reachable (local + swarm peers)" +- name: "๐Ÿ”„ Refresh Dashboard config.yaml once Simple Icons is reachable (local + swarm)" ansible.builtin.include_tasks: file: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/render_replicated_templates.yml'] | path_join }}" vars: @@ -46,5 +46,5 @@ - src: "{{ DASHBOARD_CONFIG_INV_PATH if config_file.stat.exists else DASHBOARD_CONFIG_YML_SRC_FILE }}" dest: "{{ DASHBOARD_CONFIG_YML_DEST }}" -- name: Flush compose handlers after Simple Icons refresh +- name: ๐Ÿšฟ Flush compose handlers after Simple Icons refresh meta: flush_handlers diff --git a/roles/web-app-dashboard/tasks/_javascript_file.yml b/roles/web-app-dashboard/tasks/_javascript_file.yml index 5e7d04db6a..fb10bce650 100644 --- a/roles/web-app-dashboard/tasks/_javascript_file.yml +++ b/roles/web-app-dashboard/tasks/_javascript_file.yml @@ -1,16 +1,16 @@ --- -- name: Deploy {{ js_file_name }} +- name: ๐Ÿš€ Deploy {{ js_file_name }} stack_host_template: src: "javascript/{{ js_file_name }}.j2" dest: "{{ DASHBOARD_JS_SERVER_DIR }}/{{ js_file_name }}" mode: "0644" -- name: Get stat for {{ js_file_name }} +- name: โฌ‡๏ธ Get stat for {{ js_file_name }} stat: path: "{{ DASHBOARD_JS_SERVER_DIR }}/{{ js_file_name }}" register: javascript_file_stat -- name: Update javascript_file_version with highest mtime +- name: ๐Ÿ”„ Update javascript_file_version with highest mtime set_fact: javascript_file_version: >- {{ [ (javascript_file_version | default(0) | int), (javascript_file_stat.stat.mtime | int) ] | max }} diff --git a/roles/web-app-decidim/tasks/01_setup.yml b/roles/web-app-decidim/tasks/01_setup.yml index 6324e2ccd2..7f48d0f696 100644 --- a/roles/web-app-decidim/tasks/01_setup.yml +++ b/roles/web-app-decidim/tasks/01_setup.yml @@ -1,12 +1,12 @@ --- -- name: "Decidim | Resolve hosting node + container ID ({{ DEPLOYMENT_MODE }})" +- name: "๐Ÿ” Decidim | Resolve hosting node + container ID ({{ DEPLOYMENT_MODE }})" ansible.builtin.include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/swarm/resolve_host_cid.yml'] | path_join }}" vars: resolve_service_key: decidim resolve_output_prefix: DECIDIM resolve_compose_cid: "{{ DECIDIM_CONTAINER }}" -- name: "Decidim | Wait for web container to be healthy" +- name: "โณ Decidim | Wait for web container to be healthy" ansible.builtin.shell: > container inspect --format '{{ "{{.State.Health.Status}}" }}' {{ DECIDIM_LOCAL_CID | quote }} @@ -17,7 +17,7 @@ until: (decidim_health.stdout | trim) == 'healthy' delegate_to: "{{ DECIDIM_HOST_NODE }}" -- name: "Decidim | Run database migrations" +- name: "โ–ถ๏ธ Decidim | Run database migrations" ansible.builtin.shell: > # nocheck: container-exec-resolver DECIDIM_LOCAL_CID resolved at delegate_to runtime container exec -e RAILS_ENV={{ ENVIRONMENT | quote }} {{ DECIDIM_LOCAL_CID | quote }} @@ -26,7 +26,7 @@ changed_when: decidim_migrate_result.stdout_lines | default([]) | length > 0 delegate_to: "{{ DECIDIM_HOST_NODE }}" -- name: "Decidim | Seed database on first deploy" +- name: "๐ŸŒฑ Decidim | Seed database on first deploy" ansible.builtin.shell: > # nocheck: container-exec-resolver DECIDIM_LOCAL_CID resolved at delegate_to runtime container exec -e RAILS_ENV={{ ENVIRONMENT | quote }} {{ DECIDIM_LOCAL_CID | quote }} @@ -36,7 +36,7 @@ failed_when: false delegate_to: "{{ DECIDIM_HOST_NODE }}" -- name: "Decidim | Set organization host" +- name: "๐Ÿ”ง Decidim | Set organization host" ansible.builtin.shell: > # nocheck: container-exec-resolver DECIDIM_LOCAL_CID resolved at delegate_to runtime container exec -i -e RAILS_ENV={{ ENVIRONMENT | quote }} -e DECIDIM_ORG_HOST={{ domain | quote }} @@ -48,7 +48,7 @@ changed_when: "'Organization host set to' in decidim_org_result.stdout" delegate_to: "{{ DECIDIM_HOST_NODE }}" -- name: "Decidim | Ensure administrator user exists with correct credentials" +- name: "โœ… Decidim | Ensure administrator user exists with correct credentials" ansible.builtin.shell: > # nocheck: container-exec-resolver DECIDIM_LOCAL_CID resolved at delegate_to runtime container exec -i -e RAILS_ENV={{ ENVIRONMENT | quote }} -e DECIDIM_ADMIN_EMAIL={{ lookup('users', 'administrator').email | quote }} @@ -62,7 +62,7 @@ changed_when: "'Admin user ready' in decidim_admin_result.stdout" delegate_to: "{{ DECIDIM_HOST_NODE }}" -- name: "Decidim | Configure OIDC omniauth settings in organization" +- name: "๐Ÿ”ง Decidim | Configure OIDC omniauth settings in organization" ansible.builtin.shell: > # nocheck: container-exec-resolver DECIDIM_LOCAL_CID resolved at delegate_to runtime container exec -i -e RAILS_ENV={{ ENVIRONMENT | quote }} {{ DECIDIM_LOCAL_CID | quote }} diff --git a/roles/web-app-decidim/tasks/02_manager_ops.yml b/roles/web-app-decidim/tasks/02_manager_ops.yml index eca6a0263d..4c541706b1 100644 --- a/roles/web-app-decidim/tasks/02_manager_ops.yml +++ b/roles/web-app-decidim/tasks/02_manager_ops.yml @@ -1,12 +1,12 @@ --- -- name: "Render allowed_hosts initializer for {{ application_id }}" +- name: "๐Ÿ“„ Render allowed_hosts initializer for {{ application_id }}" stack_host_template: src: "allowed_hosts.rb.j2" dest: "{{ lookup('container', application_id, 'directories.instance') }}allowed_hosts.rb" mode: "0644" notify: compose up -- name: "Deploy '{{ DECIDIM_PATCH_SCRIPT_HOST_ABS }}'" +- name: "๐Ÿš€ Deploy '{{ DECIDIM_PATCH_SCRIPT_HOST_ABS }}'" copy: src: "{{ DECIDIM_PATCH_SCRIPT_FILE }}" dest: "{{ DECIDIM_PATCH_SCRIPT_HOST_ABS }}" @@ -14,7 +14,7 @@ - compose build - compose up -- name: "Deploy '{{ DECIDIM_PATCH_RUBY_HOST_ABS }}'" +- name: "๐Ÿš€ Deploy '{{ DECIDIM_PATCH_RUBY_HOST_ABS }}'" copy: src: "{{ DECIDIM_PATCH_RUBY_DIR }}/" dest: "{{ DECIDIM_PATCH_RUBY_HOST_ABS }}/" @@ -22,8 +22,8 @@ - compose build - compose up -- name: "flush handlers of compose" +- name: "๐Ÿšฟ flush handlers of compose" meta: flush_handlers -- name: "Run Decidim setup routines" +- name: "โ–ถ๏ธ Run Decidim setup routines" include_tasks: 01_setup.yml diff --git a/roles/web-app-decidim/tasks/main.yml b/roles/web-app-decidim/tasks/main.yml index 829c80c477..60c256ed3a 100644 --- a/roles/web-app-decidim/tasks/main.yml +++ b/roles/web-app-decidim/tasks/main.yml @@ -1,10 +1,10 @@ --- -- name: "load docker, proxy and db for '{{ application_id }}'" +- name: "๐Ÿงฉ load docker, proxy and db for '{{ application_id }}'" include_role: name: sys-stk-full vars: compose_handlers_flush: false -- name: "Decidim manager-side operations (file deploys + container exec)" +- name: "๐Ÿ‘” Decidim manager-side operations (file deploys + container exec)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-discourse/tasks/01_core.yml b/roles/web-app-discourse/tasks/01_core.yml index b687a7bd8e..a88c4870be 100644 --- a/roles/web-app-discourse/tasks/01_core.yml +++ b/roles/web-app-discourse/tasks/01_core.yml @@ -2,14 +2,14 @@ # Required to be set on the top so global frontend service loading can rely on run_once guards. - include_tasks: utils/once/flag.yml -- name: "reset (if enabled) for {{ role_name}}" +- name: "โ™ป๏ธ reset (if enabled) for {{ role_name}}" include_tasks: 02_reset.yml when: MODE_RESET | bool -- name: "Setup '{{ application_id }}' docker" +- name: "๐Ÿ”ง Setup '{{ application_id }}' docker" include_tasks: 03_docker.yml -- name: "Setup '{{ application_id }}' network" +- name: "๐Ÿ”ง Setup '{{ application_id }}' network" include_tasks: 05_network.yml when: - IS_STACK_HOST | bool diff --git a/roles/web-app-discourse/tasks/02_reset.yml b/roles/web-app-discourse/tasks/02_reset.yml index baeffbe619..79c23a27a6 100644 --- a/roles/web-app-discourse/tasks/02_reset.yml +++ b/roles/web-app-discourse/tasks/02_reset.yml @@ -1,5 +1,5 @@ --- -- name: "Disconnect DB container from Discourse networks" +- name: "๐Ÿ—„๏ธ Disconnect DB container from Discourse networks" ansible.builtin.command: cmd: "container network disconnect {{ discourse_network_item }} {{ lookup('database', application_id, 'container') }}" loop: @@ -17,7 +17,7 @@ ('no such container' not in (disc_net_disconnect.stderr | default('') | lower)) and ('not found' not in (disc_net_disconnect.stderr | default('') | lower)) -- name: "destroy container '{{ DISCOURSE_CONTAINER }}'" +- name: "๐Ÿ“ฆ destroy container '{{ DISCOURSE_CONTAINER }}'" ansible.builtin.command: cmd: "./launcher destroy {{ DISCOURSE_CONTAINER }}" chdir: "{{ DISCOURSE_REPOSITORY_DIR }}" diff --git a/roles/web-app-discourse/tasks/03_docker.yml b/roles/web-app-discourse/tasks/03_docker.yml index 06b3bcff7b..410a5a8e37 100644 --- a/roles/web-app-discourse/tasks/03_docker.yml +++ b/roles/web-app-discourse/tasks/03_docker.yml @@ -1,10 +1,10 @@ --- # which is necessary for building -- name: install which +- name: ๐Ÿ“ฆ install which package: name: which state: present -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: @@ -12,7 +12,7 @@ webserver_vhost_flavour: "basic" application_id: "web-app-discourse" -- name: "Create the discourse network so the launcher can attach --network={{ DISCOURSE_NETWORK }}" +- name: "๐Ÿ“ Create discourse network {{ DISCOURSE_NETWORK }} for launcher to attach" include_tasks: file: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/network/create.yml'] | path_join }}" apply: @@ -21,6 +21,6 @@ vars: network_role_id: "{{ application_id }}" -- name: "Run the standalone Discourse launcher container" +- name: "โ–ถ๏ธ Run the standalone Discourse launcher container" include_tasks: 04_launcher.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-discourse/tasks/04_launcher.yml b/roles/web-app-discourse/tasks/04_launcher.yml index 38bbb6f9e6..a93c956a99 100644 --- a/roles/web-app-discourse/tasks/04_launcher.yml +++ b/roles/web-app-discourse/tasks/04_launcher.yml @@ -1,5 +1,5 @@ --- -- name: Pull Discourse docker repository +- name: โฌ‡๏ธ Pull Discourse docker repository git: repo: "{{ DISCOURSE_REPOSITORY_URL }}" dest: "{{ DISCOURSE_REPOSITORY_DIR }}" @@ -13,20 +13,20 @@ notify: recreate discourse become: true -- name: set chmod 700 for '{{ DISCOURSE_CONTAINERS_DIR }}' +- name: ๐Ÿ”ง set chmod 700 for '{{ DISCOURSE_CONTAINERS_DIR }}' ansible.builtin.file: path: "{{ DISCOURSE_CONTAINERS_DIR }}" mode: "700" state: directory -- name: "copy configuration to '{{ DISCOURSE_APPLICATION_YML_DEST }}'" +- name: "๐Ÿ“‹ copy configuration to '{{ DISCOURSE_APPLICATION_YML_DEST }}'" stack_host_template: src: config.yml.j2 dest: "{{ DISCOURSE_APPLICATION_YML_DEST }}" mode: "0640" notify: recreate discourse -- name: "Verify that '{{ DISCOURSE_CONTAINER }}' is running" +- name: "โœ… Verify that '{{ DISCOURSE_CONTAINER }}' is running" ansible.builtin.command: argv: - container @@ -42,12 +42,12 @@ failed_when: docker_ps.rc != 0 notify: recreate discourse -- name: Load discourse handlers explicitly +- name: ๐Ÿ“‚ Load discourse handlers explicitly # In the CI somehow, the postgres application id was used, # local it behaved normal. I hope this solves the anomaly. include_tasks: utils/load_handlers.yml vars: handler_role_name: "web-app-discourse" -- name: flush, to recreate discourse app +- name: ๐Ÿšฟ flush, to recreate discourse app meta: flush_handlers diff --git a/roles/web-app-discourse/tasks/05_network.yml b/roles/web-app-discourse/tasks/05_network.yml index 021680721f..466f83958b 100644 --- a/roles/web-app-discourse/tasks/05_network.yml +++ b/roles/web-app-discourse/tasks/05_network.yml @@ -1,5 +1,5 @@ --- -- name: "Connect '{{ DISCOURSE_CONTAINER }}' to network '{{ DISCOURSE_PG_NETWORK }}'" +- name: "๐Ÿ“ฆ Connect '{{ DISCOURSE_CONTAINER }}' to network '{{ DISCOURSE_PG_NETWORK }}'" command: > container network connect {{ DISCOURSE_PG_NETWORK }} {{ DISCOURSE_CONTAINER }} register: network_connect @@ -8,7 +8,7 @@ DISCOURSE_ERROR_ALREADY_IN_NET not in network_connect.stderr changed_when: network_connect.rc == 0 -- name: "Remove {{ DISCOURSE_NETWORK }} from {{ lookup('database', application_id, 'container') }}" +- name: "๐Ÿงน Remove {{ DISCOURSE_NETWORK }} from DB container {{ application_id }}" command: > container network disconnect {{ DISCOURSE_NETWORK }} {{ lookup('database', application_id, 'container') }} register: network_disconnect diff --git a/roles/web-app-discourse/tasks/main.yml b/roles/web-app-discourse/tasks/main.yml index fc293d153a..9e4c55e275 100644 --- a/roles/web-app-discourse/tasks/main.yml +++ b/roles/web-app-discourse/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "Setup {{ application_id }}" +- name: "๐Ÿ”ง Setup {{ application_id }}" include_tasks: 01_core.yml when: run_once_web_app_discourse is not defined vars: diff --git a/roles/web-app-erpnext/tasks/01_core.yml b/roles/web-app-erpnext/tasks/01_core.yml index 4f6a5132d4..78866d25ea 100644 --- a/roles/web-app-erpnext/tasks/01_core.yml +++ b/roles/web-app-erpnext/tasks/01_core.yml @@ -1,12 +1,12 @@ --- - include_tasks: utils/once/flag.yml -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: compose_handlers_flush: true -- name: "ERPNext manager-side operations (file deploys + container exec)" +- name: "๐Ÿ‘” ERPNext manager-side operations (file deploys + container exec)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-erpnext/tasks/02_bench_bootstrap.yml b/roles/web-app-erpnext/tasks/02_bench_bootstrap.yml index 09e476d3b4..2ec73f9edd 100644 --- a/roles/web-app-erpnext/tasks/02_bench_bootstrap.yml +++ b/roles/web-app-erpnext/tasks/02_bench_bootstrap.yml @@ -1,5 +1,5 @@ --- -- name: "probe site_config.json for '{{ ERPNEXT_SITE_NAME }}'" +- name: "๐Ÿ” probe site_config.json for '{{ ERPNEXT_SITE_NAME }}'" ansible.builtin.shell: | set -eo pipefail container exec {{ ERPNEXT_BACKEND_CONTAINER_ADDRESS }} \ @@ -8,10 +8,10 @@ changed_when: false failed_when: false -- name: "Bootstrap ERPNext site when missing (create + restart + wait for backend)" +- name: "๐Ÿฅพ Bootstrap ERPNext site when missing (create + restart + wait for backend)" when: erpnext_site_probe.rc != 0 block: - - name: "bench new-site --install-app erpnext '{{ ERPNEXT_SITE_NAME }}'" + - name: "๐Ÿ“ฆ bench new-site --install-app erpnext '{{ ERPNEXT_SITE_NAME }}'" ansible.builtin.shell: | set -euo pipefail container exec -i \ @@ -39,7 +39,7 @@ # Long-lived Frappe containers cache the app set at startup; without a restart they # 500 on /login after install-app erpnext. - - name: "restart Frappe containers to pick up newly-installed app" + - name: "๐Ÿ”„ restart Frappe containers to pick up newly-installed app" ansible.builtin.shell: | set -euo pipefail container restart \ @@ -51,7 +51,7 @@ {{ ERPNEXT_QUEUE_LONG_CONTAINER }} changed_when: false - - name: "wait for {{ ERPNEXT_BACKEND_CONTAINER }} gunicorn TCP port after restart" + - name: "โณ wait for {{ ERPNEXT_BACKEND_CONTAINER }} gunicorn TCP port after restart" ansible.builtin.shell: | set -eo pipefail container exec {{ ERPNEXT_BACKEND_CONTAINER_ADDRESS }} \ @@ -62,7 +62,7 @@ delay: 5 until: erpnext_backend_ready_post_restart.rc == 0 -- name: "ensure encryption_key on site '{{ ERPNEXT_SITE_NAME }}'" +- name: "โœ… ensure encryption_key on site '{{ ERPNEXT_SITE_NAME }}'" ansible.builtin.shell: | set -euo pipefail container exec {{ ERPNEXT_BACKEND_CONTAINER_ADDRESS }} bash -c ' @@ -71,7 +71,7 @@ ' changed_when: false -- name: "apply API-bot user + bypass setup wizard" +- name: "๐Ÿ“Œ apply API-bot user + bypass setup wizard" ansible.builtin.shell: | set -euo pipefail container exec -i \ diff --git a/roles/web-app-erpnext/tasks/02_manager_ops.yml b/roles/web-app-erpnext/tasks/02_manager_ops.yml index 7e49194a24..e309d78492 100644 --- a/roles/web-app-erpnext/tasks/02_manager_ops.yml +++ b/roles/web-app-erpnext/tasks/02_manager_ops.yml @@ -1,5 +1,5 @@ --- -- name: "wait for {{ ERPNEXT_BACKEND_CONTAINER }} gunicorn TCP port" +- name: "โณ wait for {{ ERPNEXT_BACKEND_CONTAINER }} gunicorn TCP port" ansible.builtin.shell: | set -eo pipefail container exec {{ ERPNEXT_BACKEND_CONTAINER_ADDRESS }} \ @@ -10,15 +10,15 @@ delay: 5 until: erpnext_backend_ready.rc == 0 -- name: "bench bootstrap" +- name: "๐Ÿฅพ bench bootstrap" include_tasks: 02_bench_bootstrap.yml -- name: "configure OIDC" +- name: "๐Ÿ”ง configure OIDC" include_tasks: 03_oidc.yml when: ERPNEXT_OIDC_ENABLED -- name: "configure LDAP" +- name: "๐Ÿ”ง configure LDAP" include_tasks: 04_ldap.yml when: ERPNEXT_LDAP_ENABLED -- name: "configure outbound email" +- name: "๐Ÿ”ง configure outbound email" include_tasks: 05_email.yml when: ERPNEXT_EMAIL_ENABLED diff --git a/roles/web-app-erpnext/tasks/03_oidc.yml b/roles/web-app-erpnext/tasks/03_oidc.yml index db80c5faf4..f449502422 100644 --- a/roles/web-app-erpnext/tasks/03_oidc.yml +++ b/roles/web-app-erpnext/tasks/03_oidc.yml @@ -1,5 +1,5 @@ --- -- name: "apply Social Login Key for Keycloak" +- name: "๐Ÿ“Œ apply Social Login Key for Keycloak" ansible.builtin.shell: | set -euo pipefail container exec -i \ @@ -20,7 +20,7 @@ changed_when: "'OIDC_SLK_CHANGED' in erpnext_oidc_apply.stdout" timeout: 60 -- name: "restart the Frappe backend when the Social Login Key changed so --preload workers re-render the SSO button" +- name: "๐Ÿ”„ Restart Frappe backend on Social Login Key change to re-render SSO button" ansible.builtin.shell: | set -euo pipefail container restart {{ ERPNEXT_BACKEND_CONTAINER }} @@ -28,7 +28,7 @@ when: "'OIDC_SLK_CHANGED' in erpnext_oidc_apply.stdout" timeout: 120 -- name: "wait for {{ ERPNEXT_BACKEND_CONTAINER }} gunicorn TCP port after OIDC restart" +- name: "โณ wait for {{ ERPNEXT_BACKEND_CONTAINER }} gunicorn TCP port after OIDC restart" ansible.builtin.shell: | set -eo pipefail container exec {{ ERPNEXT_BACKEND_CONTAINER_ADDRESS }} \ diff --git a/roles/web-app-erpnext/tasks/04_ldap.yml b/roles/web-app-erpnext/tasks/04_ldap.yml index 1d4eb009b2..37ce2599eb 100644 --- a/roles/web-app-erpnext/tasks/04_ldap.yml +++ b/roles/web-app-erpnext/tasks/04_ldap.yml @@ -1,5 +1,5 @@ --- -- name: "apply LDAP Settings doctype" +- name: "๐Ÿ“Œ apply LDAP Settings doctype" ansible.builtin.shell: | set -euo pipefail container exec -i \ diff --git a/roles/web-app-erpnext/tasks/05_email.yml b/roles/web-app-erpnext/tasks/05_email.yml index cabf7dfa17..2ce60ec822 100644 --- a/roles/web-app-erpnext/tasks/05_email.yml +++ b/roles/web-app-erpnext/tasks/05_email.yml @@ -1,5 +1,5 @@ --- -- name: "apply outbound Email Account (Mailu SMTP; inbound IMAP deferred)" +- name: "๐Ÿ“Œ apply outbound Email Account (Mailu SMTP; inbound IMAP deferred)" ansible.builtin.shell: | set -euo pipefail container exec -i \ diff --git a/roles/web-app-espocrm/tasks/01_patch_config.yml b/roles/web-app-espocrm/tasks/01_patch_config.yml index 3adf706687..97184b4662 100644 --- a/roles/web-app-espocrm/tasks/01_patch_config.yml +++ b/roles/web-app-espocrm/tasks/01_patch_config.yml @@ -1,5 +1,5 @@ --- -- name: "Patch EspoCRM DB config key '{{ item.key }}' (idempotent)" +- name: "๐Ÿฉน Patch EspoCRM DB config key '{{ item.key }}' (idempotent)" ansible.builtin.shell: >- container exec -i --user root -e CONFIG_KEY={{ item.key }} @@ -16,7 +16,7 @@ notify: compose up no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Ensure siteUrl matches canonical domain +- name: โœ… Ensure siteUrl matches canonical domain ansible.builtin.shell: cmd: >- container exec -i --user {{ ESPOCRM_USER }} diff --git a/roles/web-app-espocrm/tasks/02_manager_ops.yml b/roles/web-app-espocrm/tasks/02_manager_ops.yml index 79b85a3a49..e15644c962 100644 --- a/roles/web-app-espocrm/tasks/02_manager_ops.yml +++ b/roles/web-app-espocrm/tasks/02_manager_ops.yml @@ -1,5 +1,5 @@ --- -- name: "Deploy '{{ ESPOCRM_ENTRYPOINT_SCRIPT_HOST_ABS }}'" +- name: "๐Ÿš€ Deploy '{{ ESPOCRM_ENTRYPOINT_SCRIPT_HOST_ABS }}'" copy: src: "{{ ESPOCRM_ENTRYPOINT_SCRIPT_FILE }}" dest: "{{ ESPOCRM_ENTRYPOINT_SCRIPT_HOST_ABS }}" @@ -7,7 +7,7 @@ - compose up - compose build -- name: "Deploy '{{ ESPOCRM_SCRIPT_SEED_HOST_ABS }}'" +- name: "๐Ÿš€ Deploy '{{ ESPOCRM_SCRIPT_SEED_HOST_ABS }}'" copy: src: "{{ ESPOCRM_SCRIPT_SEED_FILE }}" dest: "{{ ESPOCRM_SCRIPT_SEED_HOST_ABS }}" @@ -15,20 +15,20 @@ - compose up - compose build -- name: "Docker Compose Up for '{{ application_id }}'" +- name: "๐Ÿณ Docker Compose Up for '{{ application_id }}'" meta: flush_handlers -- name: Check if config.php exists in EspoCRM +- name: ๐Ÿ”Ž Check if config.php exists in EspoCRM shell: > container exec --user root {{ ESPOCRM_CONTAINER_ADDRESS }} test -f {{ ESPOCRM_CONFIG_FILE_PRIVATE }} register: config_file_exists changed_when: false failed_when: false -- name: Patch EspoCRM config.php +- name: ๐Ÿฉน Patch EspoCRM config.php include_tasks: 01_patch_config.yml when: config_file_exists.rc == 0 -- name: Run EspoCRM upgrade +- name: โ–ถ๏ธ Run EspoCRM upgrade shell: > container exec --user {{ ESPOCRM_USER }} {{ ESPOCRM_CONTAINER_ADDRESS }} php command.php upgrade -y @@ -36,12 +36,12 @@ changed_when: "'Upgrading' in espocrm_upgrade.stdout or 'successfully' in espocrm_upgrade.stdout" failed_when: false -- name: Run flag setter as root (fallback) +- name: โ–ถ๏ธ Run flag setter as root (fallback) shell: > container exec --user root {{ ESPOCRM_CONTAINER_ADDRESS }} php {{ ESPOCRM_SCRIPT_SEED_DOCKER }} register: flags_result_root changed_when: "'CHANGED' in flags_result_root.stdout" -- name: Flush handlers to make DB available before password reset +- name: ๐Ÿšฟ Flush handlers to make DB available before password reset meta: flush_handlers diff --git a/roles/web-app-espocrm/tasks/main.yml b/roles/web-app-espocrm/tasks/main.yml index 47aee724ab..bb21de28f5 100644 --- a/roles/web-app-espocrm/tasks/main.yml +++ b/roles/web-app-espocrm/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: @@ -8,6 +8,6 @@ webserver_vhost_flavour: "ws_generic" webserver_client_max_body_size: "100m" -- name: "EspoCRM manager-side operations (file deploys + container exec)" +- name: "๐Ÿ‘” EspoCRM manager-side operations (file deploys + container exec)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-fediwall/tasks/01_core.yml b/roles/web-app-fediwall/tasks/01_core.yml index 37ea08f8c7..aaf023e8e1 100644 --- a/roles/web-app-fediwall/tasks/01_core.yml +++ b/roles/web-app-fediwall/tasks/01_core.yml @@ -1,12 +1,12 @@ --- -- name: "load docker, proxy for '{{ application_id }}'" +- name: "๐Ÿงฉ load docker, proxy for '{{ application_id }}'" include_role: name: sys-stk-full vars: compose_handlers_flush: false compose_repository_pull: false -- name: "Fediwall manager-side operations (file deploys + container exec)" +- name: "๐Ÿ‘” Fediwall manager-side operations (file deploys + container exec)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-fediwall/tasks/02_manager_ops.yml b/roles/web-app-fediwall/tasks/02_manager_ops.yml index aa48a1c706..ec9eae99c1 100644 --- a/roles/web-app-fediwall/tasks/02_manager_ops.yml +++ b/roles/web-app-fediwall/tasks/02_manager_ops.yml @@ -1,11 +1,11 @@ --- -- name: "Ensure Fediwall build dir '{{ FEDIWALL_BUILD_DIR_ABS }}' exists" +- name: "โœ… Ensure Fediwall build dir '{{ FEDIWALL_BUILD_DIR_ABS }}' exists" file: path: "{{ FEDIWALL_BUILD_DIR_ABS }}" state: directory mode: "0755" -- name: "Download Fediwall {{ FEDIWALL_UPSTREAM_VERSION }} release tarball" +- name: "โฌ‡๏ธ Download Fediwall {{ FEDIWALL_UPSTREAM_VERSION }} release tarball" get_url_retry: url: "{{ FEDIWALL_UPSTREAM_TARBALL_URL }}" dest: "{{ FEDIWALL_TARBALL_FILE }}" @@ -14,13 +14,13 @@ - compose build - compose up -- name: "Ensure Fediwall upstream dir '{{ FEDIWALL_UPSTREAM_DIR_ABS }}' exists" +- name: "โœ… Ensure Fediwall upstream dir '{{ FEDIWALL_UPSTREAM_DIR_ABS }}' exists" file: path: "{{ FEDIWALL_UPSTREAM_DIR_ABS }}" state: directory mode: "0755" -- name: "Extract Fediwall tarball into '{{ FEDIWALL_UPSTREAM_DIR_ABS }}'" +- name: "๐Ÿ“ค Extract Fediwall tarball into '{{ FEDIWALL_UPSTREAM_DIR_ABS }}'" unarchive: src: "{{ FEDIWALL_TARBALL_FILE }}" dest: "{{ FEDIWALL_UPSTREAM_DIR_ABS }}" @@ -31,18 +31,18 @@ - compose build - compose up -- name: "Wipe Fediwall dist tree '{{ FEDIWALL_DIST_DIR_ABS }}' (so removed slugs disappear)" +- name: "๐Ÿงน Wipe Fediwall dist tree '{{ FEDIWALL_DIST_DIR_ABS }}' to drop removed slugs" file: path: "{{ FEDIWALL_DIST_DIR_ABS }}" state: absent -- name: "Recreate Fediwall dist tree '{{ FEDIWALL_DIST_DIR_ABS }}'" +- name: "๐Ÿ“ Recreate Fediwall dist tree '{{ FEDIWALL_DIST_DIR_ABS }}'" file: path: "{{ FEDIWALL_DIST_DIR_ABS }}" state: directory mode: "0755" -- name: "Stage upstream Fediwall files into per-slug folder '{{ wall.slug }}'" +- name: "๐ŸŽฌ Stage upstream Fediwall files into per-slug folder '{{ wall.slug }}'" copy: # nocheck: stack-host-consumer (02_manager_ops.yml is parent-gated by IS_STACK_HOST in 01_core.yml:11) src: "{{ FEDIWALL_UPSTREAM_DIR_ABS }}/" dest: "{{ [ FEDIWALL_DIST_DIR_ABS, wall.slug ] | path_join }}/" @@ -56,7 +56,7 @@ - compose build - compose up -- name: "Render per-slug Fediwall wall-config.json for '{{ wall.slug }}'" +- name: "๐Ÿ“„ Render per-slug Fediwall wall-config.json for '{{ wall.slug }}'" stack_host_template: src: "wall-config.json.j2" dest: "{{ [ FEDIWALL_DIST_DIR_ABS, wall.slug, 'wall-config.json' ] | path_join }}" @@ -69,7 +69,7 @@ - compose build - compose up -- name: "Render Fediwall root link list at '{{ FEDIWALL_DIST_DIR_ABS }}/index.html'" +- name: "๐Ÿ“„ Render Fediwall root link list at '{{ FEDIWALL_DIST_DIR_ABS }}/index.html'" stack_host_template: src: "index.html.j2" dest: "{{ [ FEDIWALL_DIST_DIR_ABS, 'index.html' ] | path_join }}" @@ -78,5 +78,5 @@ - compose build - compose up -- name: "flush compose for '{{ application_id }}'" +- name: "๐Ÿšฟ flush compose for '{{ application_id }}'" meta: flush_handlers diff --git a/roles/web-app-fediwall/tasks/main.yml b/roles/web-app-fediwall/tasks/main.yml index 17f88f5eef..f40a49dd22 100644 --- a/roles/web-app-fediwall/tasks/main.yml +++ b/roles/web-app-fediwall/tasks/main.yml @@ -1,4 +1,4 @@ --- -- name: "Include core routines for '{{ application_id }}'" +- name: "๐Ÿ“‚ Include core routines for '{{ application_id }}'" include_tasks: "01_core.yml" when: run_once_web_app_fediwall is not defined diff --git a/roles/web-app-fider/tasks/01_setup_oidc.yml b/roles/web-app-fider/tasks/01_setup_oidc.yml index f735bd84b3..cb988bb2c7 100644 --- a/roles/web-app-fider/tasks/01_setup_oidc.yml +++ b/roles/web-app-fider/tasks/01_setup_oidc.yml @@ -1,12 +1,12 @@ --- -- name: "Resolve {{ application_id }} hosting node + container id" +- name: "๐Ÿ” Resolve {{ application_id }} hosting node + container id" ansible.builtin.include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/swarm/resolve_host_cid.yml'] | path_join }}" vars: resolve_service_key: fider resolve_output_prefix: FIDER resolve_compose_cid: "{{ FIDER_CONTAINER }}" -- name: "Wait for {{ application_id }} HTTP endpoint (compose host-port)" +- 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') }}" @@ -14,7 +14,7 @@ timeout: 300 when: DEPLOYMENT_MODE == 'compose' -- name: "Wait for {{ application_id }} HTTP endpoint (swarm in-container)" +- 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 }} wget -qO- http://127.0.0.1:{{ FIDER_CONTAINER_PORT }}/_health @@ -26,7 +26,7 @@ delegate_to: "{{ FIDER_HOST_NODE }}" when: DEPLOYMENT_MODE == 'swarm' -- name: "Fider | Check if tenant is already initialized" +- name: "๐Ÿ”Ž Fider | Check if tenant is already initialized" database_query: config: "{{ lookup('database', application_id) }}" query_file: "{{ role_path }}/files/sql/count-tenants.sql" @@ -35,7 +35,7 @@ register: fider_tenant_count changed_when: false -- name: "Fider | Bootstrap initial tenant via API (compose host-port)" +- 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 @@ -46,7 +46,7 @@ - DEPLOYMENT_MODE == 'compose' - (fider_tenant_count.rows[0][0] | int) == 0 -- name: "Fider | Bootstrap initial tenant via API (swarm in-container)" +- name: "๐Ÿฅพ Fider | Bootstrap initial tenant via API (swarm in-container)" ansible.builtin.shell: > # nocheck: container-exec-resolver runtime-resolved CID, delegated to the hosting node container exec {{ FIDER_LOCAL_CID | quote }} wget -qO- --header='Content-Type: application/json' @@ -59,7 +59,7 @@ - DEPLOYMENT_MODE == 'swarm' - (fider_tenant_count.rows[0][0] | int) == 0 -- name: "Fider | Create admin user (bypass email verification)" +- 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" @@ -69,14 +69,14 @@ mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" changed_when: true -- name: "Fider | Activate tenant (set status=1 to bypass email confirmation)" +- 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 -- name: "Fider | Configure Keycloak as OIDC provider in database" +- name: "๐Ÿ”ง Fider | Configure Keycloak as OIDC provider in database" database_query: config: "{{ lookup('database', application_id) }}" query_file: "{{ role_path }}/files/sql/configure-oidc-provider.sql" diff --git a/roles/web-app-fider/tasks/main.yml b/roles/web-app-fider/tasks/main.yml index 717219e96d..58ed6559cf 100644 --- a/roles/web-app-fider/tasks/main.yml +++ b/roles/web-app-fider/tasks/main.yml @@ -1,11 +1,11 @@ --- -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: compose_handlers_flush: true -- name: "Fider | OIDC setup" +- name: "๐Ÿ”ง Fider | OIDC setup" include_tasks: 01_setup_oidc.yml when: - FIDER_OIDC_ENABLED | bool diff --git a/roles/web-app-flowise/tasks/01_core.yml b/roles/web-app-flowise/tasks/01_core.yml index 1867c6bf0d..532a80d566 100644 --- a/roles/web-app-flowise/tasks/01_core.yml +++ b/roles/web-app-flowise/tasks/01_core.yml @@ -1,13 +1,13 @@ --- - include_tasks: utils/once/flag.yml -- name: "load docker and db for {{ application_id }}" +- name: "๐Ÿงฉ load docker and db for {{ application_id }}" include_role: name: sys-stk-backend vars: compose_handlers_flush: false -- name: "Render Flowise LiteLLM config (local + swarm peers)" +- name: "๐Ÿ“„ Render Flowise LiteLLM config (local + swarm peers)" ansible.builtin.include_tasks: file: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/render_replicated_templates.yml'] | path_join }}" vars: @@ -15,10 +15,10 @@ - src: "litellm.config.yaml.j2" dest: "{{ FLOWISE_LITELLM_CONFIG_PATH_HOST }}" -- name: "flush handlers of compose" +- name: "๐Ÿšฟ flush handlers of compose" meta: flush_handlers -- name: "Include role sys-stk-front-proxy for '{{ application_id }}'" +- name: "๐Ÿ“‚ Include role sys-stk-front-proxy for '{{ application_id }}'" include_role: name: sys-stk-front-proxy vars: diff --git a/roles/web-app-flowise/tasks/main.yml b/roles/web-app-flowise/tasks/main.yml index a3425c1e43..6c03f15442 100644 --- a/roles/web-app-flowise/tasks/main.yml +++ b/roles/web-app-flowise/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "Execute Role (once)" +- name: "โ–ถ๏ธ Execute Role (once)" include_tasks: 01_core.yml when: run_once_web_app_flowise is not defined vars: diff --git a/roles/web-app-friendica/tasks/01_core.yml b/roles/web-app-friendica/tasks/01_core.yml index 8de5824f8c..989ccf839c 100644 --- a/roles/web-app-friendica/tasks/01_core.yml +++ b/roles/web-app-friendica/tasks/01_core.yml @@ -1,12 +1,12 @@ --- - include_tasks: utils/once/flag.yml -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: compose_handlers_flush: false -- name: "Friendica manager-side operations (file deploys + container exec)" +- name: "๐Ÿ‘” Friendica manager-side operations (file deploys + container exec)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-friendica/tasks/02_ldap.yml b/roles/web-app-friendica/tasks/02_ldap.yml index 75e58f548a..62a06a237b 100644 --- a/roles/web-app-friendica/tasks/02_ldap.yml +++ b/roles/web-app-friendica/tasks/02_ldap.yml @@ -1,5 +1,5 @@ --- -- name: "Render Friendica LDAP config (local + swarm peers)" +- name: "๐Ÿ“„ Render Friendica LDAP config (local + swarm peers)" ansible.builtin.include_tasks: file: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/render_replicated_templates.yml'] | path_join }}" vars: diff --git a/roles/web-app-friendica/tasks/02_manager_ops.yml b/roles/web-app-friendica/tasks/02_manager_ops.yml index 4fcbb9b57a..5a9b8ccd42 100644 --- a/roles/web-app-friendica/tasks/02_manager_ops.yml +++ b/roles/web-app-friendica/tasks/02_manager_ops.yml @@ -1,12 +1,12 @@ --- -- name: Integrate LDAP +- name: ๐Ÿ”— Integrate LDAP include_tasks: 02_ldap.yml when: FRIENDICA_LDAP_ENABLED | bool -- name: "flush handlers to ensure that '{{ FRIENDICA_CONTAINER }}' is up before executing container tasks" +- name: "๐Ÿ”„ Flush handlers so '{{ FRIENDICA_CONTAINER }}' is up before container tasks" meta: flush_handlers -- name: "Remove stale ldapauth.config.php leftover when LDAP is disabled" +- name: "๐Ÿ—‘๏ธ Remove stale ldapauth.config.php leftover when LDAP is disabled" shell: > container exec --user root {{ FRIENDICA_CONTAINER_ADDRESS }} rm -f {{ FRIENDICA_LDAP_CONFIG_DOCKER }} @@ -14,22 +14,22 @@ changed_when: friendica_ldap_config_cleanup.rc == 0 when: not (FRIENDICA_LDAP_ENABLED | bool) -- name: Check if Friendica local.config.php exists +- name: ๐Ÿ”Ž Check if Friendica local.config.php exists shell: > container exec --user {{ FRIENDICA_USER }} {{ FRIENDICA_CONTAINER_ADDRESS }} test -f {{ FRIENDICA_CONFIG_FILE }} register: friendica_config_exists changed_when: false failed_when: false -- name: Patch Friendica local.config.php with updated DB credentials +- name: ๐Ÿฉน Patch Friendica local.config.php with updated DB credentials ansible.builtin.include_tasks: file: 03_patch_config.yml apply: notify: compose up when: friendica_config_exists.rc == 0 -- name: Add Friendica Add Ons +- name: โž• Add Friendica Add Ons include_tasks: 04_addons.yml -- name: Bootstrap Friendica administrator user (only when no LDAP provider is wired to provision them) +- name: "๐ŸŽฌ Bootstrap Friendica admin user (only when no LDAP provider provisions them)" include_tasks: 06_user_bootstrap.yml when: not (FRIENDICA_LDAP_ENABLED | bool) diff --git a/roles/web-app-friendica/tasks/03_patch_config.yml b/roles/web-app-friendica/tasks/03_patch_config.yml index 80579f0e69..497df923af 100644 --- a/roles/web-app-friendica/tasks/03_patch_config.yml +++ b/roles/web-app-friendica/tasks/03_patch_config.yml @@ -1,5 +1,5 @@ --- -- name: Patch Friendica local.config.php (DB host, name, user, system.url) +- name: ๐Ÿฉน Patch Friendica local.config.php (DB host, name, user, system.url) shell: > container exec --user {{ FRIENDICA_USER }} {{ FRIENDICA_CONTAINER_ADDRESS }} sed -ri @@ -10,7 +10,7 @@ -e "s#('url'\s*=>\s*')[^']*(',)#\1{{ FRIENDICA_BASE_URL | sed_escape('#') }}\2#" {{ FRIENDICA_CONFIG_FILE }} -- name: Patch Friendica local.config.php (DB password) +- name: ๐Ÿฉน Patch Friendica local.config.php (DB password) shell: > container exec --user {{ FRIENDICA_USER }} -e PATCH_PASSWORD={{ lookup('database', application_id, 'password') | sed_escape('/') | quote }} diff --git a/roles/web-app-friendica/tasks/04_addons.yml b/roles/web-app-friendica/tasks/04_addons.yml index 6f049c238a..fef23e9615 100644 --- a/roles/web-app-friendica/tasks/04_addons.yml +++ b/roles/web-app-friendica/tasks/04_addons.yml @@ -1,8 +1,8 @@ --- -- name: flush handlers to ensure that friendica is up before friendica addon configuration +- name: ๐Ÿ”„ flush handlers so friendica is up before addon configuration meta: flush_handlers -- name: Build friendica_addons from meta/addons/ declarations +- name: ๐Ÿ”จ Build friendica_addons from meta/addons/ declarations set_fact: friendica_addons: >- {{ @@ -16,7 +16,7 @@ loop_control: label: "{{ item.key }}" -- name: Wait until Friendica console + composer vendor tree is fully populated +- name: โณ Wait until Friendica console + composer vendor tree is fully populated shell: > container exec -i --user {{ FRIENDICA_USER }} --workdir {{ FRIENDICA_APPLICATION_DIR }} @@ -29,7 +29,7 @@ delay: 2 until: friendica_console_ready.rc == 0 -- name: Wait until Friendica database is ready and populated +- name: โณ Wait until Friendica database is ready and populated shell: > container exec -i --user {{ FRIENDICA_USER }} --workdir {{ FRIENDICA_APPLICATION_DIR }} @@ -45,7 +45,7 @@ - "'not ready' not in (friendica_db_ready.stderr | default(''))" - "'not populated' not in (friendica_db_ready.stderr | default(''))" -- name: Ensure Friendica DB schema is current +- name: โœ… Ensure Friendica DB schema is current shell: > container exec -i --user {{ FRIENDICA_USER }} --workdir {{ FRIENDICA_APPLICATION_DIR }} @@ -54,7 +54,7 @@ register: friendica_dbstructure_update changed_when: "'No tables need to be changed' not in friendica_dbstructure_update.stdout" -- name: "Patch upstream friendica-addons/ldapauth autocreate return shape" +- name: "๐Ÿฉน Patch upstream friendica-addons/ldapauth autocreate return shape" script: >- shell/patch_ldapauth_autocreate.sh "container exec -i --user root {{ FRIENDICA_CONTAINER_ADDRESS }}" @@ -65,7 +65,7 @@ changed_when: "'PATCHED' in friendica_ldapauth_patch.stdout" when: FRIENDICA_LDAP_ENABLED | bool -- name: Ensure Friendica addons are in sync +- name: โœ… Ensure Friendica addons are in sync script: >- shell/sync_addon.sh "container exec -i --user {{ FRIENDICA_USER }} --workdir {{ FRIENDICA_APPLICATION_DIR }} {{ FRIENDICA_CONTAINER_ADDRESS }} {{ FRIENDICA_APPLICATION_DIR @@ -83,7 +83,7 @@ loop_control: label: "{{ item.name }}" -- name: Wait until Friendica `hook` table is provisioned +- name: โณ Wait until Friendica `hook` table is provisioned ansible.builtin.shell: >- container exec -i --user {{ FRIENDICA_USER }} --workdir {{ FRIENDICA_APPLICATION_DIR }} {{ FRIENDICA_CONTAINER_ADDRESS }} php -- args: @@ -97,7 +97,7 @@ when: FRIENDICA_LDAP_ENABLED | bool # First-install `addon enable ldapauth` empirically lands `enabled=1` without persisting Hook::register() rows; this task verifies and recycles to recover. -- name: Verify ldapauth hooks are registered (re-cycle if missing) +- name: โœ… Verify ldapauth hooks are registered (re-cycle if missing) ansible.builtin.shell: >- container exec -i --user {{ FRIENDICA_USER }} --workdir {{ FRIENDICA_APPLICATION_DIR }} {{ FRIENDICA_CONTAINER_ADDRESS }} php -- ldapauth 2 args: @@ -105,7 +105,7 @@ changed_when: false when: FRIENDICA_LDAP_ENABLED | bool -- name: "Run per-addon integration hooks for enabled addons" +- name: "โ–ถ๏ธ Run per-addon integration hooks for enabled addons" include_tasks: "addons/{{ item.name }}.yml" loop: "{{ friendica_addons | selectattr('enabled') | list }}" loop_control: diff --git a/roles/web-app-friendica/tasks/06_user_bootstrap.yml b/roles/web-app-friendica/tasks/06_user_bootstrap.yml index 764fe3a5e4..b9c6d12cca 100644 --- a/roles/web-app-friendica/tasks/06_user_bootstrap.yml +++ b/roles/web-app-friendica/tasks/06_user_bootstrap.yml @@ -1,5 +1,5 @@ --- -- name: "Check whether Friendica administrator user already exists" +- name: "๐Ÿ”Ž Check whether Friendica administrator user already exists" shell: >- container exec -i --user {{ FRIENDICA_USER }} --workdir {{ FRIENDICA_APPLICATION_DIR }} @@ -9,7 +9,7 @@ changed_when: false failed_when: false -- name: "Pre-create Friendica administrator user" +- name: "๐Ÿ“ Pre-create Friendica administrator user" shell: >- container exec -i --user {{ FRIENDICA_USER }} --workdir {{ FRIENDICA_APPLICATION_DIR }} diff --git a/roles/web-app-funkwhale/tasks/main.yml b/roles/web-app-funkwhale/tasks/main.yml index 5f04244316..af07ce74a9 100644 --- a/roles/web-app-funkwhale/tasks/main.yml +++ b/roles/web-app-funkwhale/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: diff --git a/roles/web-app-fusiondirectory/meta/domains.yml b/roles/web-app-fusiondirectory/meta/domains.yml index 1118760826..54be754693 100644 --- a/roles/web-app-fusiondirectory/meta/domains.yml +++ b/roles/web-app-fusiondirectory/meta/domains.yml @@ -1,4 +1,4 @@ --- canonical: -- fd.{{ DOMAIN_PRIMARY }} + - fd.{{ DOMAIN_PRIMARY }} aliases: [] diff --git a/roles/web-app-fusiondirectory/tasks/main.yml b/roles/web-app-fusiondirectory/tasks/main.yml index 2d0d5b0710..221c08ef7a 100644 --- a/roles/web-app-fusiondirectory/tasks/main.yml +++ b/roles/web-app-fusiondirectory/tasks/main.yml @@ -1,4 +1,4 @@ --- -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full diff --git a/roles/web-app-gitea/tasks/01_core.yml b/roles/web-app-gitea/tasks/01_core.yml index 899d8e597d..5ffade9cec 100644 --- a/roles/web-app-gitea/tasks/01_core.yml +++ b/roles/web-app-gitea/tasks/01_core.yml @@ -1,12 +1,12 @@ --- - include_tasks: utils/once/flag.yml -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: compose_handlers_flush: true -- name: "Gitea manager-side operations (file deploys + container exec)" +- name: "๐Ÿ‘” Gitea manager-side operations (file deploys + container exec)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-gitea/tasks/02_database.yml b/roles/web-app-gitea/tasks/02_database.yml index 9a02def934..0acaacff73 100644 --- a/roles/web-app-gitea/tasks/02_database.yml +++ b/roles/web-app-gitea/tasks/02_database.yml @@ -1,27 +1,27 @@ --- -- name: Flush handlers to ensure Gitea is up before DB patch +- name: ๐Ÿšฟ Flush handlers to ensure Gitea is up before DB patch meta: flush_handlers -- name: Patch Gitea DB host in app.ini +- name: ๐Ÿฉน Patch Gitea DB host in app.ini shell: > container exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER_ADDRESS }} sed -ri "s|^(HOST\s*=\s*).*$|\1{{ lookup('database', application_id, 'host') | sed_escape('|') }}:{{ lookup('database', application_id, 'port') | sed_escape('|') }}|" {{ GITEA_CONFIG }} notify: compose up -- name: Patch Gitea DB name in app.ini +- name: ๐Ÿฉน Patch Gitea DB name in app.ini shell: > container exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER_ADDRESS }} sed -ri "s|^(NAME\s*=\s*).*$|\1{{ lookup('database', application_id, 'name') | sed_escape('|') }}|" {{ GITEA_CONFIG }} notify: compose up -- name: Patch Gitea DB user in app.ini +- name: ๐Ÿฉน Patch Gitea DB user in app.ini shell: > container exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER_ADDRESS }} sed -ri "s|^(USER\s*=\s*).*$|\1{{ lookup('database', application_id, 'username') | sed_escape('|') }}|" {{ GITEA_CONFIG }} notify: compose up -- name: Patch Gitea DB password in app.ini +- name: ๐Ÿฉน Patch Gitea DB password in app.ini shell: > container exec -i --user {{ GITEA_USER }} -e PATCH_VALUE={{ lookup('database', application_id, 'password') | sed_escape('|') | quote }} @@ -29,5 +29,5 @@ sh -c 'sed -ri "s|^(PASSWD\s*=\s*).*$|\1${PATCH_VALUE}|" {{ GITEA_CONFIG }}' notify: compose up -- name: "Flush database patches" +- name: "๐Ÿšฟ Flush database patches" meta: flush_handlers diff --git a/roles/web-app-gitea/tasks/02_manager_ops.yml b/roles/web-app-gitea/tasks/02_manager_ops.yml index a765d9d7ec..53ac301316 100644 --- a/roles/web-app-gitea/tasks/02_manager_ops.yml +++ b/roles/web-app-gitea/tasks/02_manager_ops.yml @@ -1,15 +1,15 @@ --- -- name: Wait for Gitea HTTP endpoint +- name: โณ Wait for Gitea HTTP endpoint wait_for: host: "{{ DOCKER_REACH_HOST }}" port: "{{ lookup('config', application_id, 'services.gitea.ports.local.http') }}" delay: 5 timeout: 300 -- name: Patch Gitea database settings in app.ini +- name: ๐Ÿฉน Patch Gitea database settings in app.ini include_tasks: 02_database.yml -- name: "Wait for Gitea app.ini to be present after redeploy" +- name: "โณ Wait for Gitea app.ini to be present after redeploy" shell: | container exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER_ADDRESS }} \ test -f {{ GITEA_CONFIG }} @@ -19,14 +19,14 @@ delay: 2 until: gitea_config_ready.rc == 0 -- name: "Run DB migrations inside Gitea container" +- name: "โ–ถ๏ธ Run DB migrations inside Gitea container" shell: | container exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER_ADDRESS }} \ /app/gitea/gitea migrate -c {{ GITEA_CONFIG }} register: migrate changed_when: "'migrations completed' in migrate.stdout" -- name: "Create initial admin user" +- name: "๐Ÿ“ Create initial admin user" shell: | container exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER_ADDRESS }} \ /app/gitea/gitea admin user create \ @@ -39,7 +39,7 @@ changed_when: "'has been successfully created' in create_admin.stdout" failed_when: create_admin.rc != 0 and 'user already exists' not in create_admin.stderr -- name: "Wait until Gitea setup and migrations are ready" +- name: "โณ Wait until Gitea setup and migrations are ready" uri_retry: url: "http://{{ DOCKER_REACH_HOST }}:{{ lookup('config', application_id, 'services.gitea.ports.local.http') }}/api/v1/version" method: GET @@ -51,13 +51,13 @@ delay: 5 when: (GITEA_OIDC_ENABLED | bool) or (GITEA_LDAP_ENABLED | bool) -- name: Execute Setup Routines +- name: โ–ถ๏ธ Execute Setup Routines include_tasks: 03_setup.yml -- name: Execute Cleanup Routines +- name: โ–ถ๏ธ Execute Cleanup Routines include_tasks: 04_cleanup.yml when: MODE_CLEANUP | bool -- name: Include DNS role to register Gitea domain(s) +- name: ๐Ÿ“‚ Include DNS role to register Gitea domain(s) include_role: name: sys-dns-cloudflare-records vars: diff --git a/roles/web-app-gitea/tasks/03_setup.yml b/roles/web-app-gitea/tasks/03_setup.yml index 00c97a21c9..772fb23857 100644 --- a/roles/web-app-gitea/tasks/03_setup.yml +++ b/roles/web-app-gitea/tasks/03_setup.yml @@ -1,7 +1,7 @@ --- -- name: Execute OIDC Setup Routine +- name: โ–ถ๏ธ Execute OIDC Setup Routine include_tasks: setup/oidc.yml when: GITEA_OIDC_ENABLED | bool -- name: Execute LDAP Setup Routine +- name: โ–ถ๏ธ Execute LDAP Setup Routine include_tasks: setup/ldap.yml when: GITEA_LDAP_ENABLED | bool diff --git a/roles/web-app-gitea/tasks/04_cleanup.yml b/roles/web-app-gitea/tasks/04_cleanup.yml index 9656e10435..bd79fefdcc 100644 --- a/roles/web-app-gitea/tasks/04_cleanup.yml +++ b/roles/web-app-gitea/tasks/04_cleanup.yml @@ -1,7 +1,7 @@ --- -- name: Execute OIDC Cleanup Routine +- name: โ–ถ๏ธ Execute OIDC Cleanup Routine include_tasks: cleanup/oidc.yml when: not (GITEA_OIDC_ENABLED | bool) -- name: Execute LDAP Cleanup Routine +- name: โ–ถ๏ธ Execute LDAP Cleanup Routine include_tasks: cleanup/ldap.yml when: not (GITEA_LDAP_ENABLED | bool) diff --git a/roles/web-app-gitea/tasks/cleanup/ldap.yml b/roles/web-app-gitea/tasks/cleanup/ldap.yml index ec930e75ab..a69f938cce 100644 --- a/roles/web-app-gitea/tasks/cleanup/ldap.yml +++ b/roles/web-app-gitea/tasks/cleanup/ldap.yml @@ -1,5 +1,5 @@ --- -- name: "Lookup existing LDAP auth source ID" +- name: "๐Ÿ” Lookup existing LDAP auth source ID" shell: | container exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER_ADDRESS }} \ gitea admin auth list \ @@ -8,7 +8,7 @@ failed_when: false changed_when: false -- name: "Delete existing LDAP auth source if present" +- name: "๐Ÿ—‘๏ธ Delete existing LDAP auth source if present" shell: | container exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER_ADDRESS }} \ gitea admin auth delete --id {{ ldap_source_id_raw.stdout }} diff --git a/roles/web-app-gitea/tasks/cleanup/oidc.yml b/roles/web-app-gitea/tasks/cleanup/oidc.yml index 1e1c22c6b4..9c8de2ccc9 100644 --- a/roles/web-app-gitea/tasks/cleanup/oidc.yml +++ b/roles/web-app-gitea/tasks/cleanup/oidc.yml @@ -1,5 +1,5 @@ --- -- name: "Lookup existing OIDC auth source ID" +- name: "๐Ÿ” Lookup existing OIDC auth source ID" shell: | container exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER_ADDRESS }} \ gitea admin auth list \ @@ -8,7 +8,7 @@ failed_when: false changed_when: false -- name: "Delete existing OIDC auth source if present" +- name: "๐Ÿ—‘๏ธ Delete existing OIDC auth source if present" shell: | container exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER_ADDRESS }} \ gitea admin auth delete --id {{ oidc_source_id_raw.stdout }} diff --git a/roles/web-app-gitea/tasks/setup/ldap.yml b/roles/web-app-gitea/tasks/setup/ldap.yml index 3e0fa058d5..c42241ed60 100644 --- a/roles/web-app-gitea/tasks/setup/ldap.yml +++ b/roles/web-app-gitea/tasks/setup/ldap.yml @@ -1,5 +1,5 @@ --- -- name: "Add LDAP Authentication Source" +- name: "โž• Add LDAP Authentication Source" shell: | container exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER_ADDRESS }} \ gitea admin auth add-ldap \ @@ -7,7 +7,7 @@ register: ldap_manage failed_when: ldap_manage.rc != 0 and "login source already exists" not in ldap_manage.stderr -- name: "Lookup existing LDAP auth source ID" +- name: "๐Ÿ” Lookup existing LDAP auth source ID" shell: | container exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER_ADDRESS }} \ gitea admin auth list \ @@ -20,11 +20,11 @@ - ldap_source_id_raw.stdout == "" changed_when: false -- name: "Set LDAP source ID fact" +- name: "๐Ÿ”ง Set LDAP source ID fact" set_fact: ldap_source_id: "{{ ldap_source_id_raw.stdout }}" -- name: "Update LDAP Authentication Source" +- name: "๐Ÿ”„ Update LDAP Authentication Source" shell: | container exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER_ADDRESS }} \ gitea admin auth update-ldap \ diff --git a/roles/web-app-gitea/tasks/setup/oidc.yml b/roles/web-app-gitea/tasks/setup/oidc.yml index 207bfddc09..b0412f10f8 100644 --- a/roles/web-app-gitea/tasks/setup/oidc.yml +++ b/roles/web-app-gitea/tasks/setup/oidc.yml @@ -1,5 +1,5 @@ --- -- name: "Add Keycloak OIDC Provider" +- name: "โž• Add Keycloak OIDC Provider" shell: | container exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER_ADDRESS }} \ gitea admin auth add-oauth \ @@ -12,7 +12,7 @@ register: oidc_manage failed_when: oidc_manage.rc != 0 and "login source already exists" not in oidc_manage.stderr -- name: "Lookup existing Keycloak auth source ID" +- name: "๐Ÿ” Lookup existing Keycloak auth source ID" shell: | container exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER_ADDRESS }} \ /app/gitea/gitea admin auth list \ @@ -25,11 +25,11 @@ - oidc_source_id_raw.stdout == "" changed_when: false -- name: "Set Keycloak source ID fact" +- name: "๐Ÿ”ง Set Keycloak source ID fact" set_fact: oidc_source_id: "{{ oidc_source_id_raw.stdout }}" -- name: "Update Keycloak OIDC Provider" +- name: "๐Ÿ”„ Update Keycloak OIDC Provider" shell: | container exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER_ADDRESS }} \ gitea admin auth update-oauth \ diff --git a/roles/web-app-gitlab/tasks/01_core.yml b/roles/web-app-gitlab/tasks/01_core.yml index 6ddfd26222..79b8024ec4 100644 --- a/roles/web-app-gitlab/tasks/01_core.yml +++ b/roles/web-app-gitlab/tasks/01_core.yml @@ -1,6 +1,6 @@ --- - include_tasks: utils/once/flag.yml -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full diff --git a/roles/web-app-gitlab/tasks/main.yml b/roles/web-app-gitlab/tasks/main.yml index 6751d8396a..32aa4ce5ca 100644 --- a/roles/web-app-gitlab/tasks/main.yml +++ b/roles/web-app-gitlab/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "Execute Role (once)" +- name: "โ–ถ๏ธ Execute Role (once)" include_tasks: 01_core.yml when: run_once_web_app_gitlab is not defined vars: diff --git a/roles/web-app-hugo/tasks/01_core.yml b/roles/web-app-hugo/tasks/01_core.yml index 7d0a60e3c4..5140fadf57 100644 --- a/roles/web-app-hugo/tasks/01_core.yml +++ b/roles/web-app-hugo/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: "Assert exactly one canonical domain (V1 single-site scope)" +- name: "โœ… Assert exactly one canonical domain (V1 single-site scope)" ansible.builtin.assert: that: - lookup('config', application_id, 'domains.canonical') | length == 1 @@ -9,7 +9,7 @@ Multi-canonical-domain support is deferred to a follow-up requirement. -- name: "load docker, proxy for '{{ application_id }}'" +- name: "๐Ÿงฉ load docker, proxy for '{{ application_id }}'" include_role: name: sys-stk-full vars: diff --git a/roles/web-app-jenkins/tasks/main.yml b/roles/web-app-jenkins/tasks/main.yml index 45c9199a67..c31873ea12 100644 --- a/roles/web-app-jenkins/tasks/main.yml +++ b/roles/web-app-jenkins/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full @@ -7,7 +7,7 @@ # `/opt/compose/jenkins/` (its sys-svc-compose include creates the # instance directory). Rendering before that fails with # `Destination directory /opt/compose/jenkins does not exist`. -- name: "Render Jenkins JCasC config" +- name: "๐Ÿ“„ Render Jenkins JCasC config" stack_host_template: src: casc.yaml.j2 dest: "{{ JENKINS_CASC_FILE }}" @@ -22,7 +22,7 @@ # compose build context (`build: { context: . }`). Without this, the # `docker compose build` step fails with `failed to calculate checksum # of ref ...: "/plugins.txt": not found`. -- name: "Stage Jenkins build-context sidecar files into the compose dir" +- name: "๐ŸŽฌ Stage Jenkins build-context sidecar files into the compose dir" stack_host_copy: src: "{{ item }}" dest: "{{ [ lookup('container', application_id, 'directories.instance'), item ] | path_join }}" diff --git a/roles/web-app-jira/tasks/main.yml b/roles/web-app-jira/tasks/main.yml index ae34eaa28d..fa685fa5bf 100644 --- a/roles/web-app-jira/tasks/main.yml +++ b/roles/web-app-jira/tasks/main.yml @@ -1,6 +1,6 @@ --- - block: - - name: "load docker, db and proxy for {{ application_id }}" + - name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: diff --git a/roles/web-app-jitsi/tasks/01_core.yml b/roles/web-app-jitsi/tasks/01_core.yml index e0afcf3ce9..82c9c60687 100644 --- a/roles/web-app-jitsi/tasks/01_core.yml +++ b/roles/web-app-jitsi/tasks/01_core.yml @@ -1,12 +1,12 @@ --- - include_tasks: utils/once/flag.yml -- name: "load docker and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: compose_handlers_flush: false -- name: "Jitsi manager-side operations (file deploys + container exec)" +- name: "๐Ÿ‘” Jitsi manager-side operations (file deploys + container exec)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-jitsi/tasks/02_manager_ops.yml b/roles/web-app-jitsi/tasks/02_manager_ops.yml index 5e47c790d3..6bd6721d22 100644 --- a/roles/web-app-jitsi/tasks/02_manager_ops.yml +++ b/roles/web-app-jitsi/tasks/02_manager_ops.yml @@ -1,5 +1,5 @@ --- -- name: "ensure jitsi bind-mount source dirs exist (swarm rejects a replica if a bind source is missing)" +- name: "โœ… ensure jitsi bind-mount source dirs exist (swarm needs bind source)" ansible.builtin.file: path: "{{ item }}" state: directory @@ -13,7 +13,7 @@ - "{{ [lookup('container', 'web-app-jitsi', 'directories.volumes'), 'config'] | path_join }}" - "{{ [lookup('container', 'web-app-jitsi', 'directories.volumes'), 'transcripts'] | path_join }}" -- name: "stage prosody LDAP authentication override (mod_auth_ldap2)" +- name: "๐ŸŽฌ stage prosody LDAP authentication override (mod_auth_ldap2)" stack_host_template: src: prosody-ldap.cfg.lua.j2 dest: "{{ JITSI_PROSODY_CONFIG_HOST_PATH }}/conf.d/ldap.cfg.lua" @@ -21,5 +21,5 @@ notify: compose up when: JITSI_LDAP_ENABLED -- name: "flush handlers so Jitsi containers start with rendered env" +- name: "๐Ÿšฟ flush handlers so Jitsi containers start with rendered env" meta: flush_handlers diff --git a/roles/web-app-joomla/tasks/01_config.yml b/roles/web-app-joomla/tasks/01_config.yml index 301cadf9dc..de9a289c9f 100644 --- a/roles/web-app-joomla/tasks/01_config.yml +++ b/roles/web-app-joomla/tasks/01_config.yml @@ -1,5 +1,5 @@ --- -- name: "Render php-upload.ini for Joomla" +- name: "๐Ÿ“„ Render php-upload.ini for Joomla" stack_host_template: src: php-upload.ini.j2 dest: "{{ JOOMLA_UPLOAD_CONFIG }}" diff --git a/roles/web-app-joomla/tasks/02_install.yml b/roles/web-app-joomla/tasks/02_install.yml index 49d6a4adce..5ecf7ddf3f 100644 --- a/roles/web-app-joomla/tasks/02_install.yml +++ b/roles/web-app-joomla/tasks/02_install.yml @@ -5,7 +5,7 @@ # on `simplexml_load_file(): failed to load /var/www/html/plugins/actionlog/joomla/joomla.xml` # if it runs before the plugin tarball has finished extracting. Waiting for that # specific manifest is the cheapest end-of-extract marker. -- name: "Wait for Joomla files to exist" +- name: "โณ Wait for Joomla files to exist" shell: > container exec {{ JOOMLA_CONTAINER_ADDRESS }} test -f /var/www/html/plugins/actionlog/joomla/joomla.xml register: joomla_files @@ -15,7 +15,7 @@ until: joomla_files.rc == 0 # (Optional) specifically wait for the CLI installer script -- name: "Check for CLI installer" +- name: "๐Ÿ”Ž Check for CLI installer" shell: > container exec {{ JOOMLA_CONTAINER_ADDRESS }} test -f {{ JOOMLA_INSTALLER_CLI_FILE }} register: has_installer @@ -23,7 +23,7 @@ failed_when: false # Only if not already installed (no configuration.php) -- name: "Check if Joomla is already installed" +- name: "๐Ÿ”Ž Check if Joomla is already installed" shell: > container exec {{ JOOMLA_CONTAINER_ADDRESS }} test -f {{ JOOMLA_CONFIG_FILE }} register: joomla_installed @@ -46,7 +46,7 @@ # # Scoped by the same `joomla_installed.rc != 0` guard as before so a # genuine existing install is never touched. -- name: "Joomla CLI install (rm stub + install in one retry loop for image-init race)" +- name: "๐Ÿ“ฆ Joomla CLI install (rm stub + install in one retry loop for image-init race)" ansible.builtin.command: # NOTE: argv[0] must be `bash`, not `sh`. On Debian/Ubuntu CI runners # `/bin/sh` is dash, which does not support `set -o pipefail` and aborts @@ -132,7 +132,7 @@ # Joomla 5.x CLI installer intermittently fails to remove the installation folder # (non-fatal โ€” install itself completed). Force-remove as root to finish cleanup. -- name: "Force-remove installation folder (root)" +- name: "๐Ÿ’ช Force-remove installation folder (root)" shell: > container exec {{ JOOMLA_CONTAINER_ADDRESS }} rm -rf /var/www/html/installation changed_when: false diff --git a/roles/web-app-joomla/tasks/02_manager_ops.yml b/roles/web-app-joomla/tasks/02_manager_ops.yml index b8702f6476..f41d42bae1 100644 --- a/roles/web-app-joomla/tasks/02_manager_ops.yml +++ b/roles/web-app-joomla/tasks/02_manager_ops.yml @@ -1,5 +1,5 @@ --- -- name: Include install routines +- name: ๐Ÿ“‚ Include install routines include_tasks: "{{ joomla_step }}" loop: - 02_install.yml @@ -8,11 +8,11 @@ loop_control: loop_var: joomla_step -- name: Include assert routines +- name: ๐Ÿ“‚ Include assert routines include_tasks: "05_assert.yml" when: MODE_ASSERT_LOCAL | bool -- name: Reset Admin Password +- name: โ™ป๏ธ Reset Admin Password # Skip on a fresh install: the CLI installer above already set the admin # password via --admin-password, so an immediate reset is redundant. It # also races: Joomla's CLI bootstraps a fresh session per invocation and @@ -23,6 +23,6 @@ include_tasks: 06_reset_admin_password.yml when: joomla_installed.rc == 0 -- name: "Install plg_system_keycloak (native OIDC)" +- name: "๐Ÿ“ฆ Install plg_system_keycloak (native OIDC)" include_tasks: 07_oidc_plugin.yml when: lookup('config', application_id, 'addons.plg_system_keycloak.enabled') | bool diff --git a/roles/web-app-joomla/tasks/03_debug.yml b/roles/web-app-joomla/tasks/03_debug.yml index 03363f7143..06d260b0a9 100644 --- a/roles/web-app-joomla/tasks/03_debug.yml +++ b/roles/web-app-joomla/tasks/03_debug.yml @@ -1,5 +1,5 @@ --- -- name: "Toggle Joomla debug flags safely (configuration.php)" +- name: "๐Ÿ› Toggle Joomla debug flags safely (configuration.php)" shell: > container exec -i -e J_CONFIG_FILE={{ JOOMLA_CONFIG_FILE | quote }} diff --git a/roles/web-app-joomla/tasks/04_patch.yml b/roles/web-app-joomla/tasks/04_patch.yml index f7da97b73d..ed13cab1c4 100644 --- a/roles/web-app-joomla/tasks/04_patch.yml +++ b/roles/web-app-joomla/tasks/04_patch.yml @@ -1,5 +1,5 @@ --- -- name: "Ensure configuration.php DB settings match inventory" +- name: "โœ… Ensure configuration.php DB settings match inventory" shell: > container exec -i -e J_CONFIG_FILE={{ JOOMLA_CONFIG_FILE | quote }} diff --git a/roles/web-app-joomla/tasks/05_assert.yml b/roles/web-app-joomla/tasks/05_assert.yml index 7bedb6e1fe..33b717368c 100644 --- a/roles/web-app-joomla/tasks/05_assert.yml +++ b/roles/web-app-joomla/tasks/05_assert.yml @@ -1,5 +1,5 @@ --- -- name: "PHP lint configuration.php" +- name: "๐Ÿงน PHP lint configuration.php" shell: > container exec {{ JOOMLA_CONTAINER_ADDRESS }} php -l {{ JOOMLA_CONFIG_FILE }} changed_when: false diff --git a/roles/web-app-joomla/tasks/06_reset_admin_password.yml b/roles/web-app-joomla/tasks/06_reset_admin_password.yml index 7e7ff5a163..6a9405dce5 100644 --- a/roles/web-app-joomla/tasks/06_reset_admin_password.yml +++ b/roles/web-app-joomla/tasks/06_reset_admin_password.yml @@ -8,7 +8,7 @@ # to race on first post-install invocation. A short retry loop with a # small delay tolerates this without masking a genuine failure (a truly # missing user keeps failing after all retries). -- name: "Reset Joomla admin password (non-interactive CLI)" +- name: "โ™ป๏ธ Reset Joomla admin password (non-interactive CLI)" shell: > container exec {{ JOOMLA_CONTAINER_ADDRESS }} php {{ JOOMLA_CLI_FILE | quote }} user:reset-password diff --git a/roles/web-app-joomla/tasks/07_oidc_plugin.yml b/roles/web-app-joomla/tasks/07_oidc_plugin.yml index 9fceeed215..4007e4df9f 100644 --- a/roles/web-app-joomla/tasks/07_oidc_plugin.yml +++ b/roles/web-app-joomla/tasks/07_oidc_plugin.yml @@ -5,19 +5,19 @@ # Dockerfile) so the host never needs PHP/Composer and we never # trigger a `docker run` outside the project's compose stack. -- name: "Define OIDC plugin paths" +- name: "๐Ÿ“Œ Define OIDC plugin paths" ansible.builtin.set_fact: JOOMLA_OIDC_PLUGIN_HOST_DIR: "{{ role_path }}/files/joomla-oidc-plugin" JOOMLA_OIDC_PLUGIN_BUILD_DIR: "/tmp/plg_system_keycloak" JOOMLA_OIDC_PLUGIN_ZIP: "/tmp/plg_system_keycloak.zip" -- name: "Reset plugin build dir inside Joomla container" +- name: "โ™ป๏ธ Reset plugin build dir inside Joomla container" ansible.builtin.shell: > container exec {{ JOOMLA_CONTAINER_ADDRESS }} rm -rf {{ JOOMLA_OIDC_PLUGIN_BUILD_DIR | quote }} changed_when: false failed_when: false -- name: "Copy plugin source into Joomla container" +- name: "๐Ÿ“‹ Copy plugin source into Joomla container" ansible.builtin.command: argv: - container @@ -26,7 +26,7 @@ - "{{ JOOMLA_CONTAINER }}:{{ JOOMLA_OIDC_PLUGIN_BUILD_DIR }}/" changed_when: true -- name: "composer install (vendor jumbojett/openid-connect-php inside container)" +- name: "๐Ÿ“ฆ composer install (vendor jumbojett/openid-connect-php inside container)" ansible.builtin.shell: > container exec -e COMPOSER_HOME=/tmp/composer-home @@ -43,7 +43,7 @@ # PHP's memory limit. Pre-creating the cache tree with www-data # ownership stops the loop and lets `extension:install` actually # perform the install. -- name: "Ensure Joomla cache directories are writable by the web user" +- name: "โœ… Ensure Joomla cache directories are writable by the web user" ansible.builtin.shell: "container exec {{ JOOMLA_CONTAINER_ADDRESS }} bash -lc 'mkdir -p /var/www/html/administrator/cache /var/www/html/cache /var/www/html/tmp && chown -R {{ JOOMLA_WEB_USER }}:{{ JOOMLA_WEB_USER }} /var/www/html/administrator/cache /var/www/html/cache /var/www/html/tmp && chmod -R u+rwX /var/www/html/administrator/cache /var/www/html/cache /var/www/html/tmp'" @@ -56,7 +56,7 @@ # ZIP and installing from the ZIP works reliably. We package via PHP # (ZipArchive) so we don't have to install a `zip` CLI inside the # joomla image just for this step. -- name: "Package plugin into a ZIP for Joomla CLI install" +- name: "๐Ÿ—œ๏ธ Package plugin into a ZIP for Joomla CLI install" ansible.builtin.shell: > container exec -i -e J_ZIP={{ JOOMLA_OIDC_PLUGIN_ZIP | quote }} @@ -66,7 +66,7 @@ stdin: "{{ lookup('file', role_path ~ '/files/php/package_plugin.php') }}" changed_when: true -- name: "Install plg_system_keycloak via Joomla CLI" +- name: "๐Ÿ“ฆ Install plg_system_keycloak via Joomla CLI" ansible.builtin.shell: > container exec --user {{ JOOMLA_WEB_USER | quote }} {{ JOOMLA_CONTAINER_ADDRESS }} php -d memory_limit=512M {{ JOOMLA_CLI_FILE | quote }} @@ -82,14 +82,14 @@ # `extension:list`, then pass it to `extension:enable`. The grep-awk # pipe is shell-form because Ansible argv mode doesn't let pipes # through. -- name: "Resolve plg_system_keycloak extension ID" +- name: "๐Ÿ” Resolve plg_system_keycloak extension ID" ansible.builtin.shell: "container exec --user {{ JOOMLA_WEB_USER }} {{ JOOMLA_CONTAINER_ADDRESS }} php -d memory_limit=512M {{ JOOMLA_CLI_FILE }} extension:list | awk '/plg_system_keycloak/ {print $2; exit}'" register: plugin_id_lookup changed_when: false failed_when: plugin_id_lookup.stdout | trim | length == 0 -- name: "Enable plg_system_keycloak via Joomla CLI" +- name: "๐ŸŸข Enable plg_system_keycloak via Joomla CLI" ansible.builtin.shell: > container exec --user {{ JOOMLA_WEB_USER | quote }} {{ JOOMLA_CONTAINER_ADDRESS }} php -d memory_limit=512M {{ JOOMLA_CLI_FILE | quote }} diff --git a/roles/web-app-joomla/tasks/main.yml b/roles/web-app-joomla/tasks/main.yml index 769d7b5d37..d26681fb8d 100644 --- a/roles/web-app-joomla/tasks/main.yml +++ b/roles/web-app-joomla/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "Include role sys-stk-front-proxy for {{ application_id }}" +- name: "๐Ÿ“‚ Include role sys-stk-front-proxy for {{ application_id }}" include_role: name: sys-stk-front-proxy loop: "{{ JOOMLA_DOMAINS }}" @@ -9,18 +9,18 @@ http_port: "{{ lookup('config', application_id, 'services.joomla.ports.local.http') }}" webserver_client_max_body_size: "{{ JOOMLA_POST_MAX_SIZE }}" -- name: "load docker and db for {{ application_id }}" +- name: "๐Ÿงฉ load docker and db for {{ application_id }}" include_role: name: sys-stk-backend vars: compose_handlers_flush: false -- name: Include PHP Config tasks +- name: ๐Ÿ“‚ Include PHP Config tasks include_tasks: 01_config.yml -- name: flush docker service +- name: ๐Ÿšฟ flush docker service meta: flush_handlers -- name: "Joomla manager-side operations (install, assert, reset admin, OIDC plugin)" +- name: "๐Ÿ‘” Joomla manager-side operations (install, assert, reset admin, OIDC plugin)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-keycloak/tasks/01_core.yml b/roles/web-app-keycloak/tasks/01_core.yml index ad495e0553..00f0f38c83 100644 --- a/roles/web-app-keycloak/tasks/01_core.yml +++ b/roles/web-app-keycloak/tasks/01_core.yml @@ -1,20 +1,20 @@ --- - include_tasks: utils/once/flag.yml -- name: "Load cleanup routine for '{{ application_id }}'" +- name: "๐Ÿ“‚ Load cleanup routine for '{{ application_id }}'" include_tasks: 02_cleanup.yml when: MODE_CLEANUP | bool -- name: "Load init routine for '{{ application_id }}'" +- name: "๐Ÿ“‚ Load init routine for '{{ application_id }}'" include_tasks: 03_init.yml -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: compose_handlers_flush: true webserver_extra_configuration: "{{ lookup('template', 'nginx/helper_iframes.conf.j2') }}" -- name: "Keycloak manager-side operations (file deploys + container exec)" +- name: "๐Ÿ‘” Keycloak manager-side operations (file deploys + container exec)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-keycloak/tasks/02_cleanup.yml b/roles/web-app-keycloak/tasks/02_cleanup.yml index 8569964005..8123b094ad 100644 --- a/roles/web-app-keycloak/tasks/02_cleanup.yml +++ b/roles/web-app-keycloak/tasks/02_cleanup.yml @@ -1,5 +1,5 @@ --- -- name: "remove directory {{ KEYCLOAK_REALM_IMPORT_DIR_HOST }}" +- name: "๐Ÿ—‘๏ธ remove directory {{ KEYCLOAK_REALM_IMPORT_DIR_HOST }}" ansible.builtin.file: path: "{{ KEYCLOAK_REALM_IMPORT_DIR_HOST }}" state: absent diff --git a/roles/web-app-keycloak/tasks/02_manager_ops.yml b/roles/web-app-keycloak/tasks/02_manager_ops.yml index c8afa6be75..0dad452fa9 100644 --- a/roles/web-app-keycloak/tasks/02_manager_ops.yml +++ b/roles/web-app-keycloak/tasks/02_manager_ops.yml @@ -1,18 +1,18 @@ --- -- name: "Load Login routines for '{{ application_id }}'" +- name: "๐Ÿ“‚ Load Login routines for '{{ application_id }}'" include_tasks: 04_login.yml -- name: Ensure jq is installed +- name: โœ… Ensure jq is installed become: true package: name: jq state: present -- name: "Keycloak | Manager-side updates delegated to the hosting node" +- name: "๐Ÿ‘” Keycloak | Manager-side updates delegated to the hosting node" include_tasks: file: 02a_manager_ops_on_host.yml apply: delegate_to: "{{ KEYCLOAK_HOST_NODE }}" -- name: "Flush handlers before leaving Keycloak scope" +- name: "๐Ÿšฟ Flush handlers before leaving Keycloak scope" meta: flush_handlers diff --git a/roles/web-app-keycloak/tasks/02a_manager_ops_on_host.yml b/roles/web-app-keycloak/tasks/02a_manager_ops_on_host.yml index 2c060af665..7e5923e2d7 100644 --- a/roles/web-app-keycloak/tasks/02a_manager_ops_on_host.yml +++ b/roles/web-app-keycloak/tasks/02a_manager_ops_on_host.yml @@ -1,6 +1,6 @@ --- -- name: "Load one-shot realm import routines for '{{ application_id }}'" +- name: "๐Ÿ“‚ Load one-shot realm import routines for '{{ application_id }}'" include_tasks: 05_realm_import.yml -- name: "Apply Keycloak object updates on the live Keycloak host" +- name: "๐Ÿ“Œ Apply Keycloak object updates on the live Keycloak host" include_tasks: 02b_updates.yml diff --git a/roles/web-app-keycloak/tasks/02b_update_routines.yml b/roles/web-app-keycloak/tasks/02b_update_routines.yml index 163f01afa8..357f3265bf 100644 --- a/roles/web-app-keycloak/tasks/02b_update_routines.yml +++ b/roles/web-app-keycloak/tasks/02b_update_routines.yml @@ -1,37 +1,37 @@ --- -- name: "Load Client Update routines for '{{ application_id }}'" +- name: "๐Ÿ“‚ Load Client Update routines for '{{ application_id }}'" include_tasks: update/01_client.yml -- name: "Load Mail Update routines for '{{ application_id }} - {{ KEYCLOAK_REALM }}'" +- name: "๐Ÿ“‚ Load Mail Update routines for '{{ application_id }} - {{ KEYCLOAK_REALM }}'" include_tasks: update/02_mail_realm.yml -- name: "Load Mail Update routines for '{{ application_id }} - master'" +- name: "๐Ÿ“‚ Load Mail Update routines for '{{ application_id }} - master'" include_tasks: update/03_mail_master.yml -- name: "Load RBAC Update routines for '{{ application_id }}'" +- name: "๐Ÿ“‚ Load RBAC Update routines for '{{ application_id }}'" include_tasks: update/04_rbac_client_scope.yml -- name: "Load LDAP shared-federation routines for '{{ application_id }}'" +- name: "๐Ÿ“‚ Load LDAP shared-federation routines for '{{ application_id }}'" include_tasks: update/05_ldap_shared.yml when: - KEYCLOAK_LDAP_ENABLED | bool - KEYCLOAK_LDAP_SHARED | bool -- name: "Remove LDAP federation routines for '{{ application_id }}' when LDAP is disabled" +- name: "๐Ÿงน Remove LDAP federation routines for '{{ application_id }}' when LDAP disabled" include_tasks: update/05_ldap_disabled.yml when: not KEYCLOAK_LDAP_ENABLED | bool -- name: "Load reCAPTCHA Update routines for '{{ application_id }}'" +- name: "๐Ÿ“‚ Load reCAPTCHA Update routines for '{{ application_id }}'" include_tasks: update/06_recaptcha.yml when: KEYCLOAK_RECAPTCHA_ENABLED | bool -- name: "Load UserProfile (declarative) Update routines for '{{ application_id }}'" +- name: "๐Ÿ“‚ Load UserProfile (declarative) Update routines for '{{ application_id }}'" include_tasks: update/07_userprofile.yml -- name: "Load Realm User provisioning routines for '{{ application_id }}'" +- name: "๐Ÿ“‚ Load Realm User provisioning routines for '{{ application_id }}'" include_tasks: update/08_users_realm.yml when: not KEYCLOAK_LDAP_ENABLED | bool -- name: "Load Users Update routines for '{{ application_id }}' (emailVerified)" +- name: "๐Ÿ“‚ Load Users Update routines for '{{ application_id }}' (emailVerified)" include_tasks: update/08_users_email_verified.yml when: KEYCLOAK_USER_EMAILS_VERIFIED | bool diff --git a/roles/web-app-keycloak/tasks/02b_updates.yml b/roles/web-app-keycloak/tasks/02b_updates.yml index 7f70338974..80f775f418 100644 --- a/roles/web-app-keycloak/tasks/02b_updates.yml +++ b/roles/web-app-keycloak/tasks/02b_updates.yml @@ -1,24 +1,24 @@ --- -- name: "Keycloak | Apply object updates, recovering from cross-node reschedules" +- name: "๐Ÿ“Œ Keycloak | Apply object updates, recovering from cross-node reschedules" vars: kc_update_max_attempts: 5 block: - - name: "Load all Keycloak object-update routines for '{{ application_id }}'" + - name: "๐Ÿ“‚ Load all Keycloak object-update routines for '{{ application_id }}'" include_tasks: 02b_update_routines.yml rescue: - - name: "Keycloak updates | Re-raise failure unchanged in compose (no swarm recovery)" + - name: "๐Ÿณ Keycloak updates | Re-raise failure unchanged in compose (no swarm recovery)" ansible.builtin.fail: msg: "{{ ansible_failed_result.msg | default('Keycloak object update failed') }}" when: DEPLOYMENT_MODE == 'compose' - - name: "Keycloak updates | Fail after exhausting cross-node recovery retries" + - name: "๐Ÿ›‘ Keycloak updates | Fail after exhausting cross-node recovery retries" ansible.builtin.fail: msg: >- Keycloak object updates failed after {{ kc_update_max_attempts }} cross-node recovery attempts: {{ ansible_failed_result.msg | default('see above') }} when: (kc_update_attempt | default(0) | int) + 1 >= (kc_update_max_attempts | int) - - name: "Keycloak updates | Re-resolve hosting node + live container id (recovery)" + - name: "๐Ÿ” Keycloak updates | Re-resolve hosting node + live container id (recovery)" ansible.builtin.include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/swarm/resolve_host_cid.yml'] | path_join }}" vars: resolve_service_key: "{{ entity_name }}" @@ -26,7 +26,7 @@ resolve_compose_cid: "{{ lookup('container_address', application_id, entity_name) }}" resolve_run_host: "{{ STACK_HOST if DEPLOYMENT_MODE == 'swarm' else inventory_hostname }}" - - name: "Keycloak updates | Retry object updates on the freshly resolved node" + - name: "๐Ÿ” Keycloak updates | Retry object updates on the freshly resolved node" ansible.builtin.include_tasks: file: 02b_updates.yml apply: diff --git a/roles/web-app-keycloak/tasks/03_init.yml b/roles/web-app-keycloak/tasks/03_init.yml index e91309d386..da85ac3fe5 100644 --- a/roles/web-app-keycloak/tasks/03_init.yml +++ b/roles/web-app-keycloak/tasks/03_init.yml @@ -1,15 +1,15 @@ --- -- name: "Resolve reserved usernames for '{{ application_id }}' at task runtime" +- name: "๐Ÿ” Resolve reserved usernames for '{{ application_id }}' at task runtime" set_fact: KEYCLOAK_RESERVED_USERNAMES_LIST: "{{ lookup('users') | reserved_usernames }}" KEYCLOAK_RESERVED_USERNAMES_REGEX: >- {{ (lookup('users') | reserved_usernames) | join('|') }} -- name: "Render Keycloak realm dictionary for '{{ application_id }}' at task runtime" +- name: "๐Ÿ“„ Render Keycloak realm dictionary for '{{ application_id }}' at task runtime" set_fact: KEYCLOAK_DICTIONARY_REALM_RAW: "{{ lookup('template', 'import/realm.json.j2') }}" -- name: "Parse Keycloak realm dictionary for '{{ application_id }}'" +- name: "๐Ÿ”Ž Parse Keycloak realm dictionary for '{{ application_id }}'" set_fact: KEYCLOAK_DICTIONARY_REALM: >- {{ @@ -18,7 +18,7 @@ else (KEYCLOAK_DICTIONARY_REALM_RAW | from_json) }} -- name: "Extract Keycloak user profile payload for '{{ application_id }}'" +- name: "๐Ÿ“ค Extract Keycloak user profile payload for '{{ application_id }}'" set_fact: KEYCLOAK_USER_PROFILE_OBJECT: >- {{ @@ -29,7 +29,7 @@ | from_json }} -- name: "Build Keycloak user profile config payload for '{{ application_id }}'" +- name: "๐Ÿ”จ Build Keycloak user profile config payload for '{{ application_id }}'" set_fact: KEYCLOAK_USER_PROFILE_CONFIG_PAYLOAD: >- {{ @@ -42,13 +42,13 @@ } }} -- name: "create directory {{ KEYCLOAK_REALM_IMPORT_DIR_HOST }}" +- name: "๐Ÿ“ create directory {{ KEYCLOAK_REALM_IMPORT_DIR_HOST }}" file: path: "{{ KEYCLOAK_REALM_IMPORT_DIR_HOST }}" state: directory mode: "0755" -- name: "Copy REALM import file '{{ KEYCLOAK_REALM_IMPORT_FILE_SRC }}' to '{{ KEYCLOAK_REALM_IMPORT_FILE_DST }}'" +- name: "๐Ÿ“‹ Copy REALM import file to '{{ KEYCLOAK_REALM_IMPORT_FILE_DST }}'" stack_host_template: src: "{{ KEYCLOAK_REALM_IMPORT_FILE_SRC }}" dest: "{{ KEYCLOAK_REALM_IMPORT_FILE_DST }}" diff --git a/roles/web-app-keycloak/tasks/04_login.yml b/roles/web-app-keycloak/tasks/04_login.yml index 66b23447f3..f2131242eb 100644 --- a/roles/web-app-keycloak/tasks/04_login.yml +++ b/roles/web-app-keycloak/tasks/04_login.yml @@ -1,5 +1,5 @@ --- -- name: "Keycloak login | Wait for keycloak container to be running" +- name: "โณ Keycloak login | Wait for keycloak container to be running" ansible.builtin.shell: > container inspect -f '{{ "{{" }}.State.Running{{ "}}" }}' {{ lookup('container_address', application_id, entity_name) }} @@ -12,7 +12,7 @@ delegate_to: "{{ inventory_hostname }}" when: DEPLOYMENT_MODE == 'compose' -- name: "Keycloak login | Resolve hosting node + container id" +- name: "๐Ÿ” Keycloak login | Resolve hosting node + container id" ansible.builtin.include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/swarm/resolve_host_cid.yml'] | path_join }}" vars: resolve_service_key: "{{ entity_name }}" @@ -22,7 +22,7 @@ resolve_converge_delay: 5 resolve_cid_filters: "--filter health=healthy" -- name: "Keycloak login | Wait for keycloak container to be healthy" +- name: "โณ Keycloak login | Wait for keycloak container to be healthy" ansible.builtin.shell: > container inspect --format '{{ "{{" }}.State.Health.Status{{ "}}" }}' {{ KEYCLOAK_LOCAL_CID | quote }} @@ -33,7 +33,7 @@ changed_when: false delegate_to: "{{ KEYCLOAK_HOST_NODE }}" -- name: Try login with permanent admin (uses container ENV) +- name: ๐Ÿ”‘ Try login with permanent admin (uses container ENV) ansible.builtin.shell: | # nocheck: container-exec-resolver KEYCLOAK_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell container exec -i {{ KEYCLOAK_LOCAL_CID | quote }} sh -lc ' {{ KEYCLOAK_KCADM }} config credentials \ @@ -47,7 +47,7 @@ failed_when: false delegate_to: "{{ KEYCLOAK_HOST_NODE }}" -- name: Ensure permanent Keycloak admin exists (bootstrap path when permanent login fails) +- name: โœ… Ensure permanent Keycloak admin exists (bootstrap when login fails) ansible.builtin.include_tasks: file: 04_login_bootstrap_admin.yml apply: diff --git a/roles/web-app-keycloak/tasks/04_login_bootstrap_admin.yml b/roles/web-app-keycloak/tasks/04_login_bootstrap_admin.yml index b3e674c001..27dd347fad 100644 --- a/roles/web-app-keycloak/tasks/04_login_bootstrap_admin.yml +++ b/roles/web-app-keycloak/tasks/04_login_bootstrap_admin.yml @@ -1,5 +1,5 @@ --- -- name: Login with bootstrap admin (uses container ENV) +- name: ๐Ÿ”‘ Login with bootstrap admin (uses container ENV) ansible.builtin.shell: | # nocheck: container-exec-resolver KEYCLOAK_LOCAL_CID resolved at delegate_to runtime container exec -i {{ KEYCLOAK_LOCAL_CID | quote }} sh -lc ' {{ KEYCLOAK_KCADM }} config credentials \ @@ -14,7 +14,7 @@ delay: 5 until: kc_login_bootstrap.rc == 0 -- name: Ensure permanent admin user exists (create if missing) +- name: โœ… Ensure permanent admin user exists (create if missing) ansible.builtin.shell: | # nocheck: container-exec-resolver KEYCLOAK_LOCAL_CID resolved at delegate_to runtime container exec -i {{ KEYCLOAK_LOCAL_CID | quote }} sh -lc ' {{ KEYCLOAK_KCADM }} create users -r master \ @@ -30,7 +30,7 @@ ) changed_when: kc_create_perm_admin.rc == 0 -- name: Set permanent admin password (by username, no ID needed) +- name: ๐Ÿ”ง Set permanent admin password (by username, no ID needed) ansible.builtin.shell: | # nocheck: container-exec-resolver KEYCLOAK_LOCAL_CID resolved at delegate_to runtime container exec -i {{ KEYCLOAK_LOCAL_CID | quote }} sh -lc ' {{ KEYCLOAK_KCADM }} set-password -r master \ @@ -39,7 +39,7 @@ ' changed_when: true -- name: Grant global admin via master realm role 'admin' +- name: ๐Ÿ” Grant global admin via master realm role 'admin' ansible.builtin.shell: | # nocheck: container-exec-resolver KEYCLOAK_LOCAL_CID resolved at delegate_to runtime container exec -i {{ KEYCLOAK_LOCAL_CID | quote }} sh -lc ' {{ KEYCLOAK_KCADM }} add-roles -r master \ @@ -51,7 +51,7 @@ kc_grant_master_admin.stdout | length > 0) failed_when: false -- name: Verify login with permanent admin (after creation) +- name: โœ… Verify login with permanent admin (after creation) ansible.builtin.shell: | # nocheck: container-exec-resolver KEYCLOAK_LOCAL_CID resolved at delegate_to runtime container exec -i {{ KEYCLOAK_LOCAL_CID | quote }} sh -lc ' {{ KEYCLOAK_KCADM }} config credentials \ diff --git a/roles/web-app-keycloak/tasks/05_realm_import.yml b/roles/web-app-keycloak/tasks/05_realm_import.yml index 3920dcfe58..4a7f4728aa 100644 --- a/roles/web-app-keycloak/tasks/05_realm_import.yml +++ b/roles/web-app-keycloak/tasks/05_realm_import.yml @@ -1,18 +1,18 @@ --- -- name: Check whether the imported realm already exists +- name: ๐Ÿ”Ž Check whether the imported realm already exists shell: > {{ KEYCLOAK_EXEC_KCADM }} get realms/{{ KEYCLOAK_REALM }} register: keycloak_imported_realm_probe changed_when: false failed_when: false -- name: "Keycloak realm-import | Import missing realm + re-check login" +- name: "๐Ÿ“‚ Keycloak realm-import | Import missing realm + re-check login" when: - KEYCLOAK_REALM_IMPORT_ENABLED | bool - keycloak_imported_realm_probe.rc != 0 block: - - name: "Keycloak realm-import | Run the import path ({{ DEPLOYMENT_MODE }})" + - name: "โ–ถ๏ธ Keycloak realm-import | Run the import path ({{ DEPLOYMENT_MODE }})" ansible.builtin.include_tasks: "05_realm_import/{{ DEPLOYMENT_MODE }}.yml" - - name: "Keycloak realm-import | Re-run login/bootstrap checks after import" + - name: "โ–ถ๏ธ Keycloak realm-import | Re-run login/bootstrap checks after import" ansible.builtin.include_tasks: 04_login.yml diff --git a/roles/web-app-keycloak/tasks/05_realm_import/compose.yml b/roles/web-app-keycloak/tasks/05_realm_import/compose.yml index b9fa704d3d..43292417a7 100644 --- a/roles/web-app-keycloak/tasks/05_realm_import/compose.yml +++ b/roles/web-app-keycloak/tasks/05_realm_import/compose.yml @@ -1,6 +1,6 @@ --- # include-gated: when: DEPLOYMENT_MODE == "compose" -- name: "Keycloak realm-import | Stop running keycloak (compose)" +- name: "โน๏ธ Keycloak realm-import | Stop running keycloak (compose)" ansible.builtin.shell: | set -euo pipefail compose stop keycloak @@ -9,7 +9,7 @@ executable: /bin/bash changed_when: true -- name: "Keycloak realm-import | Import realm into the database (compose)" +- name: "๐Ÿ“‚ Keycloak realm-import | Import realm into the database (compose)" ansible.builtin.shell: | set -euo pipefail compose run --rm --no-deps \ @@ -20,7 +20,7 @@ executable: /bin/bash changed_when: true -- name: "Keycloak realm-import | Restart keycloak after import (compose)" +- name: "๐Ÿ”„ Keycloak realm-import | Restart keycloak after import (compose)" ansible.builtin.shell: | set -euo pipefail compose up -d --force-recreate keycloak diff --git a/roles/web-app-keycloak/tasks/05_realm_import/swarm.yml b/roles/web-app-keycloak/tasks/05_realm_import/swarm.yml index 8893ab4f05..e91489c011 100644 --- a/roles/web-app-keycloak/tasks/05_realm_import/swarm.yml +++ b/roles/web-app-keycloak/tasks/05_realm_import/swarm.yml @@ -2,14 +2,14 @@ # All `container service` commands must run on the swarm manager # (workers cannot view or modify cluster state), so delegate every # task in this file to STACK_HOST. -- name: "Keycloak realm-import | Scale keycloak service to 0 replicas" +- name: "๐Ÿ“ Keycloak realm-import | Scale keycloak service to 0 replicas" ansible.builtin.shell: > container service update --detach --replicas 0 {{ lookup('container_service', application_id, entity_name) | quote }} changed_when: true delegate_to: "{{ STACK_HOST }}" -- name: "Keycloak realm-import | Wait until no running task remains" +- name: "โณ Keycloak realm-import | Wait until no running task remains" ansible.builtin.shell: | container service ps {{ lookup('container_service', application_id, entity_name) | quote }} \ --filter desired-state=running \ @@ -21,7 +21,7 @@ until: kc_swarm_drained.rc == 0 delegate_to: "{{ STACK_HOST }}" -- name: "Keycloak realm-import | Run one-shot import job" +- name: "โ–ถ๏ธ Keycloak realm-import | Run one-shot import job" ansible.builtin.shell: | set -euo pipefail JOB={{ lookup('container_service', application_id, entity_name) | quote }}_import @@ -38,7 +38,7 @@ changed_when: true delegate_to: "{{ STACK_HOST }}" -- name: "Keycloak realm-import | Wait for import job to complete" +- name: "โณ Keycloak realm-import | Wait for import job to complete" ansible.builtin.shell: | container service ps {{ lookup('container_service', application_id, entity_name) }}_import \ --no-trunc \ @@ -51,7 +51,7 @@ until: kc_import_done.rc == 0 delegate_to: "{{ STACK_HOST }}" -- name: "Keycloak realm-import | Remove one-shot import service" +- name: "๐Ÿ—‘๏ธ Keycloak realm-import | Remove one-shot import service" ansible.builtin.shell: > container service rm {{ lookup('container_service', application_id, entity_name) }}_import @@ -59,7 +59,7 @@ failed_when: false delegate_to: "{{ STACK_HOST }}" -- name: "Keycloak realm-import | Scale keycloak back to nominal replicas" +- name: "๐Ÿ“ Keycloak realm-import | Scale keycloak back to nominal replicas" ansible.builtin.shell: > container service update --detach --replicas {{ groups[application_id] | default([inventory_hostname]) | length }} @@ -67,7 +67,7 @@ changed_when: true delegate_to: "{{ STACK_HOST }}" -- name: "Keycloak realm-import | Wait until replicas converge X/X and stay stable" +- name: "โณ Keycloak realm-import | Wait until replicas converge X/X and stay stable" ansible.builtin.shell: | set -euo pipefail SVC={{ lookup('container_service', application_id, entity_name) | quote }} @@ -81,7 +81,7 @@ until: kc_replicas_converged.rc == 0 delegate_to: "{{ STACK_HOST }}" -- name: "Keycloak realm-import | Confirm replicas stay X/X for consecutive polls" +- name: "โœ… Keycloak realm-import | Confirm replicas stay X/X for consecutive polls" ansible.builtin.script: "{{ role_path }}/files/wait_replicas_stable.sh" environment: SVC: "{{ lookup('container_service', application_id, entity_name) }}" @@ -93,7 +93,7 @@ until: kc_replicas_stable.rc == 0 delegate_to: "{{ STACK_HOST }}" -- name: "Keycloak realm-import | Re-resolve hosting node + container id after scale-up" +- name: "๐Ÿ” Keycloak realm-import | Re-resolve hosting node + container id after scale-up" ansible.builtin.include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/swarm/resolve_host_cid.yml'] | path_join }}" vars: resolve_service_key: "{{ entity_name }}" diff --git a/roles/web-app-keycloak/tasks/assert/05_ldap.yml b/roles/web-app-keycloak/tasks/assert/05_ldap.yml index 9d45a6924d..9a2647a834 100644 --- a/roles/web-app-keycloak/tasks/assert/05_ldap.yml +++ b/roles/web-app-keycloak/tasks/assert/05_ldap.yml @@ -13,7 +13,7 @@ # Initialize variables (MUST exist before any when/assert) # --------------------------------------------------------------------------- -- name: Assert | Initialize LDAP assert variables +- name: โœ… Assert | Initialize LDAP assert variables set_fact: ldap_cmp_id_assert: "" desired_group_mapper_raw_assert: {} @@ -26,13 +26,13 @@ # Resolve LDAP component id (authoritative, client-side filtered) # --------------------------------------------------------------------------- -- name: Assert | Fetch components (JSON) +- name: โœ… Assert | Fetch components (JSON) shell: > {{ KEYCLOAK_EXEC_KCADM }} get components -r {{ KEYCLOAK_REALM }} --format json register: kc_components_assert changed_when: false -- name: Assert | Resolve LDAP component id (client-side filter) +- name: โœ… Assert | Resolve LDAP component id (client-side filter) set_fact: ldap_cmp_id_assert: >- {{ @@ -49,7 +49,7 @@ }} changed_when: false -- name: Assert | LDAP component exists +- name: โœ… Assert | LDAP component exists assert: that: - ldap_cmp_id_assert not in ["", "null"] @@ -59,7 +59,7 @@ # Load ldap-roles mapper from dictionary (desired state) # --------------------------------------------------------------------------- -- name: Assert | Load desired ldap-roles mapper from dictionary +- name: โœ… Assert | Load desired ldap-roles mapper from dictionary set_fact: desired_group_mapper_raw_assert: >- {{ @@ -74,7 +74,7 @@ }} changed_when: false -- name: Assert | ldap-roles mapper exists in dictionary +- name: โœ… Assert | ldap-roles mapper exists in dictionary assert: that: - desired_group_mapper_raw_assert | length > 0 @@ -84,14 +84,14 @@ # Extract desired groups.path (dictionary) # --------------------------------------------------------------------------- -- name: Assert | Extract desired groups.path +- name: โœ… Assert | Extract desired groups.path when: desired_group_mapper_raw_assert | length > 0 set_fact: desired_groups_path_assert: "{{ (desired_group_mapper_raw_assert.config['groups.path'] | default([])) | first | default('') | trim }}" desired_groups_top_assert: "{{ desired_groups_path_assert.lstrip('/') | split('/') | first | default('') }}" changed_when: false -- name: Assert | groups.path defined when mapper exists +- name: โœ… Assert | groups.path defined when mapper exists when: desired_group_mapper_raw_assert | length > 0 assert: that: @@ -102,7 +102,7 @@ # Verify ldap-roles mapper instances in Keycloak (actual state) # --------------------------------------------------------------------------- -- name: Assert | List ldap-roles mappers under LDAP component (client-side) +- name: โœ… Assert | List ldap-roles mappers under LDAP component (client-side) set_fact: grp_mapper_ids_assert: >- {{ @@ -118,7 +118,7 @@ }} changed_when: false -- name: Assert | Exactly one ldap-roles mapper exists +- name: โœ… Assert | Exactly one ldap-roles mapper exists assert: that: - grp_mapper_ids_assert | length == 1 @@ -130,16 +130,16 @@ # Verify top-level group for groups.path exists # --------------------------------------------------------------------------- -- name: Assert | Verify top-level group exists when groups.path is set +- name: โœ… Assert | Verify top-level group exists when groups.path is set when: desired_groups_top_assert | length > 0 block: - - name: Assert | Fetch groups (JSON) + - name: โœ… Assert | Fetch groups (JSON) shell: > {{ KEYCLOAK_EXEC_KCADM }} get groups -r {{ KEYCLOAK_REALM }} --format json register: kc_groups_assert changed_when: false - - name: Assert | Resolve top-level group id + - name: โœ… Assert | Resolve top-level group id set_fact: groups_top_id_assert: >- {{ @@ -154,7 +154,7 @@ }} changed_when: false - - name: Assert | Top-level group exists + - name: โœ… Assert | Top-level group exists assert: that: - groups_top_id_assert not in ["", "null"] @@ -166,7 +166,7 @@ # Final summary (debug only) # --------------------------------------------------------------------------- -- name: Assert | LDAP summary +- name: โœ… Assert | LDAP summary debug: msg: ldap_component_id: "{{ ldap_cmp_id_assert }}" diff --git a/roles/web-app-keycloak/tasks/sso_proxy.yml b/roles/web-app-keycloak/tasks/sso_proxy.yml index 094beb33e2..4617a4920b 100644 --- a/roles/web-app-keycloak/tasks/sso_proxy.yml +++ b/roles/web-app-keycloak/tasks/sso_proxy.yml @@ -15,7 +15,7 @@ # `web-app-keycloak`'s own config โ€” that is why the static scan cannot # see the cross-role config path. -- name: "SSO-proxy | sanity-check consumer is in the resolved list" +- name: "โœ… SSO-proxy | sanity-check consumer is in the resolved list" ansible.builtin.assert: that: - sso_proxy_application_id in (lookup('sso_proxy_consumers') | flatten) @@ -27,7 +27,7 @@ falsy. Fix the consumer's meta/services.yml. when: MODE_DEBUG | bool -- name: "SSO-proxy | render upstream-config for '{{ sso_proxy_application_id }}'" +- name: "๐Ÿ“„ SSO-proxy | render upstream-config for '{{ sso_proxy_application_id }}'" stack_host_template: src: "{{ playbook_dir }}/roles/web-app-keycloak/templates/sso_proxy/oauth2-proxy-keycloak.cfg.j2" dest: >- diff --git a/roles/web-app-keycloak/tasks/update/01_client.yml b/roles/web-app-keycloak/tasks/update/01_client.yml index b496fa76e1..d36cb9bd97 100644 --- a/roles/web-app-keycloak/tasks/update/01_client.yml +++ b/roles/web-app-keycloak/tasks/update/01_client.yml @@ -1,5 +1,5 @@ --- -- name: "Update Client settings" +- name: "๐Ÿ”„ Update Client settings" vars: kc_object_kind: "client" kc_lookup_value: "{{ KEYCLOAK_CLIENT_ID }}" diff --git a/roles/web-app-keycloak/tasks/update/02_mail_realm.yml b/roles/web-app-keycloak/tasks/update/02_mail_realm.yml index f5b33b02ef..52a4c6a07c 100644 --- a/roles/web-app-keycloak/tasks/update/02_mail_realm.yml +++ b/roles/web-app-keycloak/tasks/update/02_mail_realm.yml @@ -1,5 +1,5 @@ --- -- name: "Update {{ KEYCLOAK_REALM }} REALM mail settings from realm dictionary" +- name: "๐Ÿ”„ Update {{ KEYCLOAK_REALM }} REALM mail settings from realm dictionary" keycloak_kcadm_update: object_kind: "realm" lookup_field: "id" diff --git a/roles/web-app-keycloak/tasks/update/03_mail_master.yml b/roles/web-app-keycloak/tasks/update/03_mail_master.yml index a28997fada..2c939c58c9 100644 --- a/roles/web-app-keycloak/tasks/update/03_mail_master.yml +++ b/roles/web-app-keycloak/tasks/update/03_mail_master.yml @@ -1,5 +1,5 @@ --- -- name: "Update Master REALM mail settings from realm dictionary" +- name: "๐Ÿ”„ Update Master REALM mail settings from realm dictionary" keycloak_kcadm_update: object_kind: "realm" lookup_field: "id" diff --git a/roles/web-app-keycloak/tasks/update/04_rbac_client_scope.yml b/roles/web-app-keycloak/tasks/update/04_rbac_client_scope.yml index e5bd4b5e73..542ce6c9b0 100644 --- a/roles/web-app-keycloak/tasks/update/04_rbac_client_scope.yml +++ b/roles/web-app-keycloak/tasks/update/04_rbac_client_scope.yml @@ -1,5 +1,5 @@ --- -- name: Ensure RBAC client scope exists +- name: โœ… Ensure RBAC client scope exists shell: | cat <<'JSON' | {{ KEYCLOAK_EXEC_KCADM }} create client-scopes -r {{ KEYCLOAK_REALM }} -f - {{ @@ -15,12 +15,12 @@ failed_when: create_rbac_scope.rc != 0 and ('already exists' not in (create_rbac_scope.stderr | lower)) no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Get all client scopes +- name: โฌ‡๏ธ Get all client scopes shell: "{{ KEYCLOAK_EXEC_KCADM }} get client-scopes -r {{ KEYCLOAK_REALM }} --format json" register: all_scopes changed_when: false -- name: Extract RBAC scope id +- name: ๐Ÿ“ค Extract RBAC scope id set_fact: scope_id_rbac: >- {{ ( @@ -29,12 +29,12 @@ | list | first | default({}) ).id | default('') }} -- name: Get all clients (avoid --query and jq; tolerate noisy stdout) +- name: โฌ‡๏ธ Get all clients (avoid --query and jq; tolerate noisy stdout) shell: "{{ KEYCLOAK_EXEC_KCADM }} get clients -r {{ KEYCLOAK_REALM }} --format json" register: all_clients changed_when: false -- name: Extract application client id +- name: ๐Ÿ“ค Extract application client id set_fact: app_client_id: >- {{ ( @@ -43,7 +43,7 @@ | list | first | default({}) ).id | default('') }} -- name: Sanity check IDs +- name: โœ… Sanity check IDs assert: that: - scope_id_rbac | length > 0 @@ -51,7 +51,7 @@ fail_msg: "Could not determine client or scope ID." when: MODE_ASSERT_LOCAL | bool -- name: Get current optional client scopes +- name: โฌ‡๏ธ Get current optional client scopes shell: > {{ KEYCLOAK_EXEC_KCADM }} get clients/{{ app_client_id }}/optional-client-scopes @@ -59,7 +59,7 @@ register: opt_scopes changed_when: false -- name: Get current default client scopes +- name: โฌ‡๏ธ Get current default client scopes shell: > {{ KEYCLOAK_EXEC_KCADM }} get clients/{{ app_client_id }}/default-client-scopes @@ -67,7 +67,7 @@ register: def_scopes changed_when: false -- name: Decide where RBAC scope is currently assigned +- name: ๐Ÿค” Decide where RBAC scope is currently assigned set_fact: has_rbac_optional: >- {{ (opt_scopes.stdout | kcadm_json @@ -82,7 +82,7 @@ # being explicitly granted โ€” and the `groups` scope is dropped from the # granted scope set when `include.in.token.scope=false`, leaving userinfo # without the claim. -- name: Remove RBAC scope from optional client scopes (if present) +- name: ๐Ÿ—‘๏ธ Remove RBAC scope from optional client scopes (if present) when: has_rbac_optional shell: > {{ KEYCLOAK_EXEC_KCADM }} delete @@ -92,7 +92,7 @@ changed_when: true failed_when: remove_opt.rc != 0 -- name: Ensure RBAC scope assigned as default (only if missing) +- name: โœ… Ensure RBAC scope assigned as default (only if missing) when: not has_rbac_default shell: > {{ KEYCLOAK_EXEC_KCADM }} update diff --git a/roles/web-app-keycloak/tasks/update/05_ldap.yml b/roles/web-app-keycloak/tasks/update/05_ldap.yml index 13bec3c34c..788dc38dc4 100644 --- a/roles/web-app-keycloak/tasks/update/05_ldap.yml +++ b/roles/web-app-keycloak/tasks/update/05_ldap.yml @@ -1,5 +1,5 @@ --- -- name: "Update REALM settings (merge LDAP component .config)" +- name: "๐Ÿ”„ Update REALM settings (merge LDAP component .config)" keycloak_kcadm_update: object_kind: "component" lookup_value: "{{ KEYCLOAK_LDAP_CMP_NAME }}" @@ -17,13 +17,13 @@ assert_mode: "{{ MODE_ASSERT }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Fetch components (JSON) +- name: โฌ‡๏ธ Fetch components (JSON) shell: > {{ KEYCLOAK_EXEC_KCADM }} get components -r {{ KEYCLOAK_REALM }} --format json register: kc_components changed_when: false -- name: Resolve LDAP component id (client-side filter; avoid unreliable --query) +- name: ๐Ÿ” Resolve LDAP component id (client-side filter; avoid unreliable --query) set_fact: ldap_cmp_id: >- {{ @@ -40,13 +40,13 @@ }} changed_when: false -- name: Assert LDAP component id resolved +- name: โœ… Assert LDAP component id resolved assert: that: ["ldap_cmp_id not in ['', 'null']"] fail_msg: "LDAP component '{{ KEYCLOAK_LDAP_CMP_NAME }}' not found in Keycloak." when: MODE_ASSERT_LOCAL | bool -- name: Pull LDAP component from dictionary (by name) +- name: โฌ‡๏ธ Pull LDAP component from dictionary (by name) set_fact: ldap_component_tpl: >- {{ @@ -56,7 +56,7 @@ }} changed_when: false -- name: Sanity check dictionary LDAP component +- name: โœ… Sanity check dictionary LDAP component assert: that: - ldap_component_tpl | length > 0 @@ -64,7 +64,7 @@ fail_msg: "LDAP component '{{ KEYCLOAK_LDAP_CMP_NAME }}' not found in KEYCLOAK_DICTIONARY_REALM." when: MODE_ASSERT_LOCAL | bool -- name: Extract mapper 'ldap-roles' from template (raw) +- name: ๐Ÿ“ค Extract mapper 'ldap-roles' from template (raw) set_fact: desired_group_mapper_raw: >- {{ @@ -77,13 +77,13 @@ }} changed_when: false -- name: Ensure mapper exists in dictionary +- name: โœ… Ensure mapper exists in dictionary assert: that: ["desired_group_mapper_raw | length > 0"] fail_msg: "'ldap-roles' mapper not found in dictionary under LDAP component." when: MODE_ASSERT_LOCAL | bool -- name: Build clean mapper payload (drop id/subComponents) +- name: ๐Ÿ”จ Build clean mapper payload (drop id/subComponents) set_fact: desired_group_mapper: >- {{ @@ -94,7 +94,7 @@ }} changed_when: false -- name: Extract desired groups.path (if any) +- name: ๐Ÿ“ค Extract desired groups.path (if any) set_fact: desired_groups_path: "{{ (desired_group_mapper.config['groups.path'] | default([])) | first | default('') | trim }}" desired_groups_top: "{{ ((desired_group_mapper.config['groups.path'] | default([])) | first | default('') | trim).lstrip('/') | split('/') | first | default('') @@ -105,7 +105,7 @@ # groups.path handling (optional) - do not repeat WHEN; use include_tasks # --------------------------------------------------------------------------- -- name: Ensure groups.path.group is correct (only when groups.path is configured) +- name: โœ… Ensure groups.path.group is correct (only when groups.path is configured) include_tasks: ldap/groups_path.yml when: desired_groups_top | length > 0 @@ -114,7 +114,7 @@ # Canonical choice is deterministic: keep the lexicographically smallest id. # --------------------------------------------------------------------------- -- name: List all existing 'ldap-roles' mapper ids under LDAP component (client-side filter) +- name: ๐Ÿ” List 'ldap-roles' mapper ids under LDAP component (client-side filter) set_fact: grp_mapper_ids: >- {{ @@ -135,7 +135,7 @@ }} changed_when: false -- name: Delete duplicate 'ldap-roles' mappers (keep canonical first) +- name: ๐Ÿ—‘๏ธ Delete duplicate 'ldap-roles' mappers (keep canonical first) when: grp_mapper_ids | length > 1 shell: > {{ KEYCLOAK_EXEC_KCADM }} delete components/{{ item }} -r {{ KEYCLOAK_REALM }} @@ -145,13 +145,13 @@ failed_when: del_dupes.rc != 0 no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Refresh components (JSON) after dedupe (authoritative) +- name: ๐Ÿ”„ Refresh components (JSON) after dedupe (authoritative) shell: > {{ KEYCLOAK_EXEC_KCADM }} get components -r {{ KEYCLOAK_REALM }} --format json register: kc_components_after_dedupe changed_when: false -- name: Set canonical mapper id (after dedupe) +- name: ๐Ÿ”ง Set canonical mapper id (after dedupe) set_fact: grp_mapper_id: >- {{ @@ -174,10 +174,10 @@ }} changed_when: false -- name: "Create canonical 'ldap-roles' mapper when missing" +- name: "๐Ÿ“ Create canonical 'ldap-roles' mapper when missing" when: (grp_mapper_id | trim) in ["", "null"] block: - - name: Create 'ldap-roles' mapper if missing + - name: ๐Ÿ“ Create 'ldap-roles' mapper if missing ansible.builtin.shell: >- printf '%s' {{ (desired_group_mapper | ldap_roles_mapper_payload(ldap_cmp_id | trim)) | quote }} | {{ KEYCLOAK_EXEC_KCADM }} create components -r {{ KEYCLOAK_REALM }} -f - @@ -186,13 +186,13 @@ failed_when: create_mapper.rc != 0 and ('already exists' not in (create_mapper.stderr | lower)) no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" - - name: Refresh components (JSON) after create (authoritative) + - name: ๐Ÿ”„ Refresh components (JSON) after create (authoritative) shell: > {{ KEYCLOAK_EXEC_KCADM }} get components -r {{ KEYCLOAK_REALM }} --format json register: kc_components_after_create changed_when: false - - name: Set canonical mapper id after create + - name: ๐Ÿ”ง Set canonical mapper id after create set_fact: grp_mapper_id: >- {{ @@ -215,7 +215,7 @@ }} changed_when: false -- name: Update 'ldap-roles' mapper config (merge only .config) +- name: ๐Ÿ”„ Update 'ldap-roles' mapper config (merge only .config) when: (grp_mapper_id | trim) not in ["", "null"] keycloak_kcadm_update: object_kind: "component" diff --git a/roles/web-app-keycloak/tasks/update/05_ldap_disabled.yml b/roles/web-app-keycloak/tasks/update/05_ldap_disabled.yml index f8f0956663..b234b743ec 100644 --- a/roles/web-app-keycloak/tasks/update/05_ldap_disabled.yml +++ b/roles/web-app-keycloak/tasks/update/05_ldap_disabled.yml @@ -1,11 +1,11 @@ --- -- name: "Fetch existing Keycloak components for '{{ KEYCLOAK_REALM }}'" +- name: "โฌ‡๏ธ Fetch existing Keycloak components for '{{ KEYCLOAK_REALM }}'" shell: > {{ KEYCLOAK_EXEC_KCADM }} get components -r {{ KEYCLOAK_REALM }} --format json register: kc_components_without_ldap changed_when: false -- name: "Resolve LDAP federation component ids for '{{ KEYCLOAK_REALM }}'" +- name: "๐Ÿ” Resolve LDAP federation component ids for '{{ KEYCLOAK_REALM }}'" set_fact: ldap_cmp_ids_without_ldap: >- {{ @@ -19,7 +19,7 @@ }} changed_when: false -- name: "Delete LDAP federation components from realm '{{ KEYCLOAK_REALM }}' when LDAP is disabled" +- name: "๐Ÿงน Delete LDAP federation components from realm '{{ KEYCLOAK_REALM }}'" shell: > {{ KEYCLOAK_EXEC_KCADM }} delete components/{{ item }} -r {{ KEYCLOAK_REALM }} loop: "{{ ldap_cmp_ids_without_ldap }}" diff --git a/roles/web-app-keycloak/tasks/update/05_ldap_shared.yml b/roles/web-app-keycloak/tasks/update/05_ldap_shared.yml index 08234e8fc5..230d5d6cd9 100644 --- a/roles/web-app-keycloak/tasks/update/05_ldap_shared.yml +++ b/roles/web-app-keycloak/tasks/update/05_ldap_shared.yml @@ -1,10 +1,10 @@ --- -- name: "Load LDAP Update routines for '{{ application_id }}'" +- name: "๐Ÿ“‚ Load LDAP Update routines for '{{ application_id }}'" include_tasks: 05_ldap.yml -- name: Assert Keycloak LDAP configuration +- name: โœ… Assert Keycloak LDAP configuration include_tasks: "{{ role_path }}/tasks/assert/05_ldap.yml" when: MODE_ASSERT_LOCAL | bool -- name: "Load per-app group-ldap-mapper routines for '{{ application_id }}'" +- name: "๐Ÿ“‚ Load per-app group-ldap-mapper routines for '{{ application_id }}'" include_tasks: 05c_per_app_mappers.yml diff --git a/roles/web-app-keycloak/tasks/update/05c_per_app_mappers.yml b/roles/web-app-keycloak/tasks/update/05c_per_app_mappers.yml index 95855551ec..3e44daf593 100644 --- a/roles/web-app-keycloak/tasks/update/05c_per_app_mappers.yml +++ b/roles/web-app-keycloak/tasks/update/05c_per_app_mappers.yml @@ -28,16 +28,16 @@ # `files/scripts/per_app_mapper/` so the shell logic lives outside the # YAML structure and stays easy to lint and reuse. -- name: "per-app mappers: flush pending handlers before mutating the shared mapper" +- name: "๐Ÿšฟ per-app mappers: flush pending handlers before mutating the shared mapper" ansible.builtin.meta: flush_handlers -- name: "per-app mappers: show deployed apps with rbac (all / current run)" +- name: "๐Ÿ‘๏ธ per-app mappers: show deployed apps with rbac (all / current run)" ansible.builtin.debug: msg: all_deployed: "{{ KEYCLOAK_RBAC_ALL_APP_IDS }}" current_run: "{{ KEYCLOAK_RBAC_RUN_APP_IDS }}" -- name: "per-app mappers: delete shared 'ldap-roles' mapper if present" +- name: "๐Ÿ—‘๏ธ per-app mappers: delete shared 'ldap-roles' mapper if present" ansible.builtin.script: cmd: "files/scripts/per_app_mapper/delete_default_ldap_roles_mapper.sh" executable: /bin/bash @@ -49,7 +49,7 @@ failed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "per-app mappers: purge stale flat / orphan Keycloak groups under /" +- name: "๐Ÿงน Purge stale flat / orphan groups under /" ansible.builtin.script: cmd: "files/scripts/per_app_mapper/purge_root_orphans.sh" executable: /bin/bash @@ -62,7 +62,7 @@ failed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "per-app mappers: ensure Keycloak group and mapper per rbac app in current run" +- name: "โœ… per-app mappers: ensure Keycloak group and mapper per rbac app in current run" include_tasks: ldap/per_app_mapper_one.yml vars: kc_app_id: "{{ rbac_app }}" diff --git a/roles/web-app-keycloak/tasks/update/06_recaptcha.yml b/roles/web-app-keycloak/tasks/update/06_recaptcha.yml index 1690d649a6..ccab4763fb 100644 --- a/roles/web-app-keycloak/tasks/update/06_recaptcha.yml +++ b/roles/web-app-keycloak/tasks/update/06_recaptcha.yml @@ -1,5 +1,5 @@ --- -- name: "Extract Google reCAPTCHA config from realm dictionary" +- name: "๐Ÿ“ค Extract Google reCAPTCHA config from realm dictionary" set_fact: kc_recaptcha_cfg: >- {{ @@ -9,14 +9,14 @@ | first | default({}, true) }} -- name: "Sanity check: reCAPTCHA config exists in dictionary" +- name: "โœ… Sanity check: reCAPTCHA config exists in dictionary" assert: that: - kc_recaptcha_cfg | length > 0 fail_msg: "Google reCAPTCHA config not found in KEYCLOAK_DICTIONARY_REALM.authenticatorConfig." when: MODE_ASSERT_LOCAL | bool -- name: "Fetch executions of 'registration form' flow" +- name: "โฌ‡๏ธ Fetch executions of 'registration form' flow" shell: > {{ KEYCLOAK_EXEC_KCADM }} get "authentication/flows/registration%20form/executions" @@ -24,7 +24,7 @@ register: kc_reg_exec changed_when: false -- name: "Extract reCAPTCHA authenticator config id" +- name: "๐Ÿ“ค Extract reCAPTCHA authenticator config id" set_fact: kc_recaptcha_cfg_id: >- {{ @@ -34,7 +34,7 @@ | first | default('') }} -- name: "Update Google reCAPTCHA authenticator config from dictionary" +- name: "๐Ÿ”„ Update Google reCAPTCHA authenticator config from dictionary" when: kc_recaptcha_cfg_id | length > 0 shell: | cat <<'JSON' | {{ KEYCLOAK_EXEC_KCADM }} update authentication/config/{{ kc_recaptcha_cfg_id }} -r {{ KEYCLOAK_REALM }} -f - diff --git a/roles/web-app-keycloak/tasks/update/07_userprofile.yml b/roles/web-app-keycloak/tasks/update/07_userprofile.yml index a252a01d1b..40b9faad72 100644 --- a/roles/web-app-keycloak/tasks/update/07_userprofile.yml +++ b/roles/web-app-keycloak/tasks/update/07_userprofile.yml @@ -9,7 +9,7 @@ # directly and writes through correctly. We piping the JSON via # kcadm.sh update users/profile -f -. -- name: "Push UserProfileProvider config via realms/{{ KEYCLOAK_REALM }}/users/profile" +- name: "โฌ†๏ธ Push UserProfileProvider config via realms/{{ KEYCLOAK_REALM }}/users/profile" ansible.builtin.shell: > {{ KEYCLOAK_EXEC_KCADM }} update users/profile -r {{ KEYCLOAK_REALM | quote }} -f - diff --git a/roles/web-app-keycloak/tasks/update/08_users_email_verified.yml b/roles/web-app-keycloak/tasks/update/08_users_email_verified.yml index d890ae77bb..b3ac9c29c8 100644 --- a/roles/web-app-keycloak/tasks/update/08_users_email_verified.yml +++ b/roles/web-app-keycloak/tasks/update/08_users_email_verified.yml @@ -5,7 +5,7 @@ # - username is ALWAYS stored in users..username # - dict key is ignored completely -- name: "Set emailVerified=true for all configured users in realm '{{ KEYCLOAK_REALM }}'" +- name: "๐Ÿ”ง Set emailVerified=true for users in realm '{{ KEYCLOAK_REALM }}'" ansible.builtin.script: set_email_verified.sh environment: KEYCLOAK_EXEC_CONTAINER: "{{ KEYCLOAK_EXEC_CONTAINER }}" diff --git a/roles/web-app-keycloak/tasks/update/08_users_realm.yml b/roles/web-app-keycloak/tasks/update/08_users_realm.yml index 4c04d676f6..9c7e7c6d66 100644 --- a/roles/web-app-keycloak/tasks/update/08_users_realm.yml +++ b/roles/web-app-keycloak/tasks/update/08_users_realm.yml @@ -5,7 +5,7 @@ # or app-driven in the normal full-stack setup. Use Keycloak's configured admin # credential so the seeded realm user and the login tests share the same secret. -- name: "Ensure administrator exists in realm '{{ KEYCLOAK_REALM }}' when LDAP is disabled" +- name: "โœ… Ensure administrator exists in realm '{{ KEYCLOAK_REALM }}'" ansible.builtin.script: ensure_realm_user.sh environment: KEYCLOAK_EXEC_CONTAINER: "{{ KEYCLOAK_EXEC_CONTAINER }}" diff --git a/roles/web-app-keycloak/tasks/update/ldap/groups_path.yml b/roles/web-app-keycloak/tasks/update/ldap/groups_path.yml index 87c2b75f6a..1ffa9b4aa9 100644 --- a/roles/web-app-keycloak/tasks/update/ldap/groups_path.yml +++ b/roles/web-app-keycloak/tasks/update/ldap/groups_path.yml @@ -3,13 +3,13 @@ # This file is included ONLY when desired_groups_top is non-empty. # Do not add an additional "when: desired_groups_top | length > 0" here. -- name: Fetch groups (JSON) +- name: โฌ‡๏ธ Fetch groups (JSON) shell: > {{ KEYCLOAK_EXEC_KCADM }} get groups -r {{ KEYCLOAK_REALM }} --format json register: kc_groups changed_when: false -- name: Resolve existing top-level group id for groups.path +- name: ๐Ÿ” Resolve existing top-level group id for groups.path set_fact: groups_top_id: >- {{ @@ -24,7 +24,7 @@ }} changed_when: false -- name: Create top-level group for groups.path if missing +- name: ๐Ÿ“ Create top-level group for groups.path if missing when: groups_top_id in ["", "null"] shell: > {{ KEYCLOAK_EXEC_KCADM }} create groups -r {{ KEYCLOAK_REALM }} -s name={{ desired_groups_top }} @@ -32,13 +32,13 @@ changed_when: create_groups_top.rc == 0 failed_when: create_groups_top.rc != 0 and ('already exists' not in (create_groups_top.stderr | lower)) -- name: Refresh groups (JSON) after potential create (authoritative) +- name: ๐Ÿ”„ Refresh groups (JSON) after potential create (authoritative) shell: > {{ KEYCLOAK_EXEC_KCADM }} get groups -r {{ KEYCLOAK_REALM }} --format json register: kc_groups_refresh changed_when: false -- name: Refresh existing top-level group id for groups.path (authoritative) +- name: ๐Ÿ”„ Refresh existing top-level group id for groups.path (authoritative) set_fact: groups_top_id: >- {{ @@ -53,14 +53,14 @@ }} changed_when: false -- name: Assert top-level group for groups.path exists now +- name: โœ… Assert top-level group for groups.path exists now when: MODE_ASSERT_LOCAL | bool assert: that: - groups_top_id not in ["", "null"] fail_msg: "Top-level group '{{ desired_groups_top }}' for groups.path could not be resolved." -- name: Inject groups.path.group into desired mapper config (force correct parent group id) +- name: ๐Ÿ“„ Inject groups.path.group into mapper config (force parent group id) set_fact: desired_group_mapper: >- {{ diff --git a/roles/web-app-keycloak/tasks/update/ldap/per_app_mapper_one.yml b/roles/web-app-keycloak/tasks/update/ldap/per_app_mapper_one.yml index baf7912aa8..c83977f967 100644 --- a/roles/web-app-keycloak/tasks/update/ldap/per_app_mapper_one.yml +++ b/roles/web-app-keycloak/tasks/update/ldap/per_app_mapper_one.yml @@ -4,7 +4,7 @@ # is delegated to a dedicated `.sh` under # `files/scripts/per_app_mapper/` so this YAML stays a thin orchestrator. -- name: "per-app mapper [{{ kc_app_id }}]: resolve groups.path root group id" +- name: "๐Ÿ” per-app mapper [{{ kc_app_id }}]: resolve groups.path root group id" ansible.builtin.script: cmd: "files/scripts/per_app_mapper/resolve_root_group_id.sh" executable: /bin/bash @@ -16,17 +16,17 @@ changed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "per-app mapper [{{ kc_app_id }}]: assert root group was resolved" +- name: "โœ… per-app mapper [{{ kc_app_id }}]: assert root group was resolved" ansible.builtin.assert: that: (per_app_root_id.stdout | default('') | trim) | length > 0 fail_msg: "could not resolve /{{ KEYCLOAK_RBAC_GROUP_NAME | trim('/') }} group id" -- name: "per-app mapper [{{ kc_app_id }}]: set root group id fact" +- name: "๐Ÿ”ง per-app mapper [{{ kc_app_id }}]: set root group id fact" ansible.builtin.set_fact: kc_root_group_id: "{{ (per_app_root_id.stdout | default('')) | trim }}" changed_when: false -- name: "per-app mapper [{{ kc_app_id }}]: ensure Keycloak group exists" +- name: "โœ… per-app mapper [{{ kc_app_id }}]: ensure Keycloak group exists" ansible.builtin.script: cmd: "files/scripts/per_app_mapper/ensure_app_group.sh" executable: /bin/bash @@ -40,12 +40,12 @@ failed_when: (per_app_group_id_out.stdout | trim) | length == 0 no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "per-app mapper [{{ kc_app_id }}]: set per-app Keycloak group id fact" +- name: "๐Ÿ”ง per-app mapper [{{ kc_app_id }}]: set per-app Keycloak group id fact" ansible.builtin.set_fact: kc_app_group_id: "{{ (per_app_group_id_out.stdout | default('')) | trim }}" changed_when: false -- name: "per-app mapper [{{ kc_app_id }}]: purge subgroups before mapper resync" +- name: "๐Ÿงน per-app mapper [{{ kc_app_id }}]: purge subgroups before mapper resync" ansible.builtin.script: cmd: "files/scripts/per_app_mapper/purge_app_subgroups.sh" executable: /bin/bash @@ -57,7 +57,7 @@ failed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "per-app mapper [{{ kc_app_id }}]: render ldap-roles-{{ kc_app_id }} mapper payload" +- name: "๐Ÿ“„ per-app mapper [{{ kc_app_id }}]: render ldap-roles-{{ kc_app_id }} mapper" # `KEYCLOAK_PER_APP_LDAP_ROLES_MAPPER` (vars/main.yml) is the single # SPOT for the per-application mapper definition. ansible.builtin.copy: @@ -67,7 +67,7 @@ changed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "per-app mapper [{{ kc_app_id }}]: upsert ldap-roles-{{ kc_app_id }} mapper" +- name: "๐Ÿ“ per-app mapper [{{ kc_app_id }}]: upsert ldap-roles-{{ kc_app_id }} mapper" ansible.builtin.script: cmd: "files/scripts/per_app_mapper/upsert_app_mapper.sh" executable: /bin/bash @@ -82,7 +82,7 @@ failed_when: (per_app_mapper_id_out.stdout | trim | length) == 0 no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "per-app mapper [{{ kc_app_id }}]: sync mapper" +- name: "๐Ÿ”„ per-app mapper [{{ kc_app_id }}]: sync mapper" ansible.builtin.script: cmd: "files/scripts/per_app_mapper/sync_app_mapper.sh" executable: /bin/bash diff --git a/roles/web-app-kix/tasks/01_core.yml b/roles/web-app-kix/tasks/01_core.yml index c1c1617d1c..c998b002ef 100644 --- a/roles/web-app-kix/tasks/01_core.yml +++ b/roles/web-app-kix/tasks/01_core.yml @@ -1,13 +1,13 @@ --- - include_tasks: utils/once/flag.yml -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: compose_handlers_flush: false -- name: "Render KIX host-side config files (local + swarm peers)" +- name: "๐Ÿ“„ Render KIX host-side config files (local + swarm peers)" ansible.builtin.include_tasks: file: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/render_replicated_templates.yml'] | path_join }}" vars: @@ -20,5 +20,5 @@ dest: "{{ KIX_PROXY_NGINX_HOST_PATH }}" mode: "0644" -- name: "flush handlers to ensure '{{ KIX_PROXY_CONTAINER }}' is up before further config" +- name: "๐Ÿ”„ Flush handlers so '{{ KIX_PROXY_CONTAINER }}' is up before further config" meta: flush_handlers diff --git a/roles/web-app-lam/tasks/01_core.yml b/roles/web-app-lam/tasks/01_core.yml index 9d6c5dd137..3e36d74c04 100644 --- a/roles/web-app-lam/tasks/01_core.yml +++ b/roles/web-app-lam/tasks/01_core.yml @@ -1,6 +1,6 @@ --- - include_tasks: utils/once/flag.yml -- name: "load docker, proxy for '{{ application_id }}'" +- name: "๐Ÿงฉ load docker, proxy for '{{ application_id }}'" include_role: name: sys-stk-full diff --git a/roles/web-app-listmonk/tasks/01_database.yml b/roles/web-app-listmonk/tasks/01_database.yml index bae7464b7c..9f19aefcbe 100644 --- a/roles/web-app-listmonk/tasks/01_database.yml +++ b/roles/web-app-listmonk/tasks/01_database.yml @@ -1,11 +1,11 @@ --- -- name: Check if listmonk schema is present (probe the 'subscribers' table) +- name: ๐Ÿ”Ž Check if listmonk schema is present (probe the 'subscribers' table) shell: '{{ LISTMONK_EXEC_DATABASE }} -c "\dt subscribers"' register: db_tables changed_when: false failed_when: false -- name: Determine Listmonk database state +- name: ๐Ÿค” Determine Listmonk database state set_fact: listmonk_db_reachable: "{{ db_tables.rc == 0 }}" listmonk_db_empty: >- @@ -16,7 +16,7 @@ ('No matching relations found' in (db_tables.stdout | default(''))) }} -- name: Abort if Listmonk database is not reachable +- name: ๐Ÿ›‘ Abort if Listmonk database is not reachable fail: msg: | Listmonk database is not reachable. @@ -27,14 +27,14 @@ Please ensure the shared PostgreSQL stack is running. when: not listmonk_db_reachable -- name: Wait for Listmonk task to converge before container exec +- name: โณ Wait for Listmonk task to converge before container exec ansible.builtin.include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/swarm/wait_converged.yml'] | path_join }}" vars: wait_service_key: "{{ LISTMONK_SERVICE }}" wait_retries: 600 wait_delay: 2 -- name: Run Listmonk initial database setup +- name: โ–ถ๏ธ Run Listmonk initial database setup shell: | container exec -i {{ LISTMONK_CONTAINER_ADDRESS }} sh -c 'set -euo pipefail; yes | ./listmonk --install' register: listmonk_install @@ -43,7 +43,7 @@ failed_when: listmonk_install.rc not in [0, 141] when: listmonk_db_empty -- name: Run Listmonk DB/schema upgrade (non-interactive) +- name: โ–ถ๏ธ Run Listmonk DB/schema upgrade (non-interactive) shell: | container exec -i {{ LISTMONK_CONTAINER_ADDRESS }} sh -c 'set -euo pipefail; echo y | ./listmonk --upgrade' register: listmonk_upgrade diff --git a/roles/web-app-listmonk/tasks/02_manager_ops.yml b/roles/web-app-listmonk/tasks/02_manager_ops.yml index cc73356a06..7a4d21ff58 100644 --- a/roles/web-app-listmonk/tasks/02_manager_ops.yml +++ b/roles/web-app-listmonk/tasks/02_manager_ops.yml @@ -1,5 +1,5 @@ --- -- name: add config.toml +- name: โž• add config.toml stack_host_template: src: "config.toml.j2" dest: "{{ LISTMONK_CONFIG_HOST }}" @@ -7,10 +7,10 @@ - meta: flush_handlers -- name: Include database setup routine for Listmonk +- name: ๐Ÿ“‚ Include database setup routine for Listmonk include_tasks: "01_database.yml" -- name: Build OIDC settings JSON +- name: ๐Ÿ”จ Build OIDC settings JSON set_fact: oidc_settings_json: >- {{ { @@ -20,7 +20,7 @@ "client_secret": OIDC.CLIENT.SECRET } | to_json }} -- name: Update administrator email and password login in Listmonk (as superuser) +- name: ๐Ÿ”„ Update administrator email and password login in Listmonk (as superuser) shell: | {{ LISTMONK_EXEC_DATABASE }} -v ON_ERROR_STOP=1 << 'EOSQL' UPDATE users @@ -31,7 +31,7 @@ args: executable: /bin/bash -- name: Apply all Listmonk settings +- name: ๐Ÿ“Œ Apply all Listmonk settings shell: | {{ LISTMONK_EXEC_DATABASE }} -v ON_ERROR_STOP=1 << 'EOSQL' UPDATE settings diff --git a/roles/web-app-listmonk/tasks/main.yml b/roles/web-app-listmonk/tasks/main.yml index fd7dddd1fa..d8213ac4b6 100644 --- a/roles/web-app-listmonk/tasks/main.yml +++ b/roles/web-app-listmonk/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: @@ -11,6 +11,6 @@ "" {% endif %} -- name: "Listmonk manager-side operations (file deploys + container exec)" +- name: "๐Ÿ‘” Listmonk manager-side operations (file deploys + container exec)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-littlejs/tasks/01_core.yml b/roles/web-app-littlejs/tasks/01_core.yml index 871d46689d..66bd6b88de 100644 --- a/roles/web-app-littlejs/tasks/01_core.yml +++ b/roles/web-app-littlejs/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: "load docker, proxy for '{{ application_id }}'" +- name: "๐Ÿงฉ load docker, proxy for '{{ application_id }}'" include_role: name: sys-stk-full vars: @@ -8,6 +8,6 @@ compose_repository_pull: true compose_repository_ref: "{{ LITTLEJS_REF }}" -- name: "LittleJS manager-side operations (file deploys + container exec)" +- name: "๐Ÿ‘” LittleJS manager-side operations (file deploys + container exec)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-littlejs/tasks/02_manager_ops.yml b/roles/web-app-littlejs/tasks/02_manager_ops.yml index cbc22517ee..d47b77ccde 100644 --- a/roles/web-app-littlejs/tasks/02_manager_ops.yml +++ b/roles/web-app-littlejs/tasks/02_manager_ops.yml @@ -1,9 +1,9 @@ --- -- name: "Load LittleJS example metadata" +- name: "๐Ÿ“„ Load LittleJS example metadata" include_vars: file: "examples.yml" -- name: "Render LittleJS index.html" +- name: "๐Ÿ“„ Render LittleJS index.html" stack_host_template: src: "html/index.html.j2" dest: "{{ LITTLEJS_INDEX_HOST_ABS }}" @@ -12,7 +12,7 @@ - compose build - compose up -- name: "Render LittleJS run.html for shorts" +- name: "๐Ÿ“„ Render LittleJS run.html for shorts" stack_host_template: src: "html/run.html.j2" dest: "{{ LITTLEJS_RUN_HOST_ABS }}" @@ -21,7 +21,7 @@ - compose build - compose up -- name: "flush compose for '{{ application_id }}'" +- name: "๐Ÿšฟ flush compose for '{{ application_id }}'" meta: flush_handlers - include_tasks: utils/once/flag.yml diff --git a/roles/web-app-magento/tasks/01_core.yml b/roles/web-app-magento/tasks/01_core.yml index a92f25b661..d144b61784 100644 --- a/roles/web-app-magento/tasks/01_core.yml +++ b/roles/web-app-magento/tasks/01_core.yml @@ -1,11 +1,11 @@ --- -- name: "load docker, db/redis/proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db/redis/proxy for {{ application_id }}" include_role: name: sys-stk-full vars: compose_handlers_flush: true -- name: "Bootstrap Magento 2.4.8 source (exact working variant)" +- name: "๐Ÿฅพ Bootstrap Magento 2.4.8 source (exact working variant)" shell: > container exec -e COMPOSER_AUTH='{"http-basic":{"repo.magento.com":{"username":"{{ MAGENTO_REPO_PUBLIC_KEY }}","password":"{{ MAGENTO_REPO_PRIVATE_KEY }}"}}}' @@ -23,7 +23,7 @@ creates: "{{ [ (MAGENTO_VOLUME | docker_volume_path), 'bin/magento' ] | path_join }}" when: IS_STACK_HOST | bool -- name: "Run Magento setup:install (in container)" +- name: "โ–ถ๏ธ Run Magento setup:install (in container)" shell: > container exec --user {{ MAGENTO_USER }} {{ MAGENTO_PHP_CONTAINER_ADDRESS }} bash -lc " cd /var/www/html && bin/magento setup:install \ diff --git a/roles/web-app-magento/tasks/02_runtime_conf.yml b/roles/web-app-magento/tasks/02_runtime_conf.yml index 358f24180f..7abf95024d 100644 --- a/roles/web-app-magento/tasks/02_runtime_conf.yml +++ b/roles/web-app-magento/tasks/02_runtime_conf.yml @@ -1,5 +1,5 @@ --- -- name: Assert required vars (no defaults anywhere) +- name: โœ… Assert required vars (no defaults anywhere) assert: that: - MAGENTO_DOMAIN is defined and MAGENTO_DOMAIN | length > 0 @@ -8,7 +8,7 @@ - MAGENTO_PHP_PORT is defined fail_msg: "Missing one of: MAGENTO_DOMAIN, MAGENTO_NGINX_PORT, MAGENTO_PHP_HOST, MAGENTO_PHP_PORT" -- name: Ensure subdirs exist (config root exists already) +- name: โœ… Ensure subdirs exist (config root exists already) file: path: "{{ item }}" state: directory @@ -17,7 +17,7 @@ - "{{ MAGENTO_NGINX_DIR }}" - "{{ MAGENTO_PHP_DIR }}" -- name: Render nginx main config (no TLS; single source of truth) +- name: ๐Ÿ“„ Render nginx main config (no TLS; single source of truth) template: # nocheck: stack-host-template (app compose dir, not project nginx tree) src: "docker.conf.j2" dest: "{{ MAGENTO_NGINX_CONF_PATH }}" @@ -25,7 +25,7 @@ force: true notify: compose up -- name: Render php-fpm pool override (TCP listen; clear_env=no) +- name: ๐Ÿ“„ Render php-fpm pool override (TCP listen; clear_env=no) template: # nocheck: stack-host-template (app compose dir, not project nginx tree) src: "php-fpm-zz-docker.conf.j2" dest: "{{ MAGENTO_PHP_ZZ_CONF_PATH }}" diff --git a/roles/web-app-magento/tasks/main.yml b/roles/web-app-magento/tasks/main.yml index 5db3a07126..7732e08958 100644 --- a/roles/web-app-magento/tasks/main.yml +++ b/roles/web-app-magento/tasks/main.yml @@ -1,4 +1,4 @@ --- -- name: "construct {{ role_name }}" +- name: "๐Ÿ—๏ธ construct {{ role_name }}" include_tasks: 01_core.yml when: run_once_web_app_magento is not defined diff --git a/roles/web-app-mailu/tasks/00_swarm_resolve_peer_vips.yml b/roles/web-app-mailu/tasks/00_swarm_resolve_peer_vips.yml index 3f1777a402..244fdff59e 100644 --- a/roles/web-app-mailu/tasks/00_swarm_resolve_peer_vips.yml +++ b/roles/web-app-mailu/tasks/00_swarm_resolve_peer_vips.yml @@ -5,7 +5,7 @@ # dials at startup (MAILU_SWARM_DB_HOST, MAILU_SWARM_REDIS_HOST). These facts # pin those names to the central services' overlay VIPs via admin `extra_hosts`, # resolved here at deploy time into literal IPs (extra_hosts rejects names). -- name: "Resolve central mariadb/redis VIPs for admin extra_hosts (swarm)" +- name: "๐Ÿ” Resolve central mariadb/redis VIPs for admin extra_hosts (swarm)" ansible.builtin.command: argv: - "{{ BIN_CONTAINER }}" @@ -24,7 +24,7 @@ loop_control: loop_var: peer -- name: "Resolve central overlay network ids (swarm)" +- name: "๐Ÿ” Resolve central overlay network ids (swarm)" ansible.builtin.command: argv: - "{{ BIN_CONTAINER }}" @@ -43,7 +43,7 @@ loop_control: loop_var: peer -- name: "Pin central mariadb/redis VIPs as admin extra_hosts facts (swarm)" +- name: "๐Ÿงฐ Pin central mariadb/redis VIPs as admin extra_hosts facts (swarm)" ansible.builtin.set_fact: MAILU_SWARM_DB_ADDR: >- {{ mailu_swarm_vip_raw.results[0].stdout | split('#') | map('trim') | select diff --git a/roles/web-app-mailu/tasks/01_core.yml b/roles/web-app-mailu/tasks/01_core.yml index 118414e2ae..361b86cd42 100644 --- a/roles/web-app-mailu/tasks/01_core.yml +++ b/roles/web-app-mailu/tasks/01_core.yml @@ -1,10 +1,10 @@ --- - include_tasks: utils/once/flag.yml -- name: "Disable SMTP to avoid port conflicts" +- name: "๐Ÿ”ด Disable SMTP to avoid port conflicts" include_tasks: "{{ [playbook_dir, 'roles/sys-svc-mail-smtp/tasks/disable.yml' ] | path_join }}" -- name: Ensure Nginx overrides directory exists (host) +- name: โœ… Ensure Nginx overrides directory exists (host) file: path: "{{ MAILU_NGINX_HOST_DIR }}" state: directory @@ -12,7 +12,7 @@ # Swarm rejects the front task if any bind source is missing at schedule time; # cert-deploy only creates this in post-bootstrap, too late for stack-up. -- name: Ensure certs bind-source directory exists (host) +- name: โœ… Ensure certs bind-source directory exists (host) file: path: "{{ MAILU_CERTS_HOST_DIR }}" state: directory @@ -22,7 +22,7 @@ # deployed post-bootstrap (sys-ctl-mtn-cert-deploy, after stack-up), and swarm's # task reschedule once it appears is too slow for the readiness waits. Seed a # self-signed placeholder so front starts healthy; cert-deploy overwrites it. -- name: Ensure a self-signed placeholder cert exists before stack-up (host) +- name: โœ… Ensure a self-signed placeholder cert exists before stack-up (host) ansible.builtin.command: cmd: >- openssl req -x509 -newkey rsa:2048 -nodes -days 365 @@ -31,23 +31,23 @@ -subj "/CN={{ MAILU_HOSTNAME }}" creates: "{{ [MAILU_CERTS_HOST_DIR, 'cert.pem'] | path_join }}" -- name: Ensure Rspamd overrides directory exists (host) +- name: โœ… Ensure Rspamd overrides directory exists (host) file: path: "{{ MAILU_RSPAMD_HOST_DIR }}" state: directory mode: "0755" -- name: Render ratelimit.conf +- name: ๐Ÿ“„ Render ratelimit.conf template: # nocheck: stack-host-template (mailu compose dir, not project nginx tree) src: ratelimit.conf.j2 dest: "{{ MAILU_RSPAMD_HOST_FILE }}" mode: "0644" -- name: "Resolve central mariadb/redis VIPs for admin extra_hosts (swarm)" +- name: "๐Ÿ” Resolve central mariadb/redis VIPs for admin extra_hosts (swarm)" include_tasks: 00_swarm_resolve_peer_vips.yml when: DEPLOYMENT_MODE == 'swarm' -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: @@ -56,6 +56,6 @@ webserver_extra_configuration: "client_max_body_size 31M;" domain: "{{ MAILU_HOSTNAME }}" -- name: "Mailu manager-side operations (file deploys + container exec)" +- name: "๐Ÿ‘” Mailu manager-side operations (file deploys + container exec)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-mailu/tasks/02_manager_ops.yml b/roles/web-app-mailu/tasks/02_manager_ops.yml index a49532eafa..fe498f1209 100644 --- a/roles/web-app-mailu/tasks/02_manager_ops.yml +++ b/roles/web-app-mailu/tasks/02_manager_ops.yml @@ -1,9 +1,9 @@ --- -- name: "Flush Docker Compose handlers" +- name: "๐Ÿšฟ Flush Docker Compose handlers" meta: flush_handlers -- name: Wait for Mailu MariaDB +- name: โณ Wait for Mailu MariaDB include_tasks: 02_wait_for_mariadb.yml -- name: "Mailu post-deploy ops" +- name: "๐Ÿš€ Mailu post-deploy ops" include_tasks: 02b_post_bootstrap_ops.yml diff --git a/roles/web-app-mailu/tasks/02_wait_for_mariadb.yml b/roles/web-app-mailu/tasks/02_wait_for_mariadb.yml index 81831ca257..4078757008 100644 --- a/roles/web-app-mailu/tasks/02_wait_for_mariadb.yml +++ b/roles/web-app-mailu/tasks/02_wait_for_mariadb.yml @@ -1,7 +1,7 @@ --- -- name: "Wait until Mailu database schema is initialized (domain table exists)" +- name: "โณ Wait until Mailu database schema is initialized (domain table exists)" block: - - name: "Check for Mailu DB domain table" + - name: "๐Ÿ”Ž Check for Mailu DB domain table" ansible.builtin.shell: > container exec -e MARIADB_PWD={{ lookup('database', application_id, 'password') | quote }} @@ -17,13 +17,13 @@ rescue: - block: - - name: "Collect Mailu admin container logs (last 300 lines)" + - name: "๐Ÿ“Š Collect Mailu admin container logs (last 300 lines)" ansible.builtin.shell: > container logs --tail=300 {{ MAILU_ADMIN_CONTAINER_ADDRESS }} register: mailu_admin_logs changed_when: false always: - - name: "Fail: Mailu database schema not initialized" + - name: "๐Ÿ›‘ Fail: Mailu database schema not initialized" ansible.builtin.fail: msg: | Mailu database schema was not initialized in time. @@ -38,9 +38,9 @@ --- Mailu admin container logs (last 300 lines) --- {{ mailu_admin_logs.stdout | default('No logs available') }} -- name: "Wait until Mailu admin Flask app is ready" +- name: "โณ Wait until Mailu admin Flask app is ready" block: - - name: "Check Mailu admin Flask routes command" + - name: "๐Ÿ”Ž Check Mailu admin Flask routes command" ansible.builtin.shell: > container exec -i {{ MAILU_ADMIN_CONTAINER_ADDRESS }} flask routes register: mailu_admin_cli_check @@ -51,13 +51,13 @@ rescue: - block: - - name: "Collect Mailu admin container logs after Flask readiness timeout" + - name: "๐Ÿ“Š Collect Mailu admin container logs after Flask readiness timeout" ansible.builtin.shell: > container logs --tail=300 {{ MAILU_ADMIN_CONTAINER_ADDRESS }} register: mailu_admin_cli_logs changed_when: false always: - - name: "Fail: Mailu admin Flask app not ready" + - name: "๐Ÿ›‘ Fail: Mailu admin Flask app not ready" ansible.builtin.fail: msg: | Mailu admin Flask app was not ready in time. diff --git a/roles/web-app-mailu/tasks/02b_post_bootstrap_ops.yml b/roles/web-app-mailu/tasks/02b_post_bootstrap_ops.yml index 8c228db325..437658e3f4 100644 --- a/roles/web-app-mailu/tasks/02b_post_bootstrap_ops.yml +++ b/roles/web-app-mailu/tasks/02b_post_bootstrap_ops.yml @@ -1,8 +1,8 @@ --- -- name: Wait for Mailu Redis +- name: โณ Wait for Mailu Redis include_tasks: 03_wait_for_redis.yml -- name: "Create Mailu accounts" +- name: "๐Ÿ“ Create Mailu accounts" include_tasks: 04_manage_user.yml vars: mailu_action: >- @@ -23,16 +23,16 @@ loop_var: user_item no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Include Cert deploy service for '{{ role_name }}'" +- name: "๐Ÿ“‚ Include Cert deploy service for '{{ role_name }}'" include_role: name: sys-ctl-mtn-cert-deploy when: lookup('tls', application_id, 'enabled') | bool -- name: Wait for Mailu antispam +- name: โณ Wait for Mailu antispam include_tasks: 07_wait_for_antispam.yml -- name: Generate DKIM public key +- name: โš™๏ธ Generate DKIM public key include_tasks: 05_generate-and-read-dkim.yml -- name: Set Mailu DNS records +- name: ๐Ÿ”ง Set Mailu DNS records include_tasks: 06_dns-records.yml diff --git a/roles/web-app-mailu/tasks/03_wait_for_redis.yml b/roles/web-app-mailu/tasks/03_wait_for_redis.yml index 12ada6607c..9e06a86b7a 100644 --- a/roles/web-app-mailu/tasks/03_wait_for_redis.yml +++ b/roles/web-app-mailu/tasks/03_wait_for_redis.yml @@ -1,7 +1,7 @@ --- -- name: "Wait until Mailu redis backend responds to PING" +- name: "โณ Wait until Mailu redis backend responds to PING" block: - - name: "Probe Mailu redis" + - name: "๐Ÿ” Probe Mailu redis" ansible.builtin.shell: > container exec -i {{ MAILU_REDIS_CONTAINER_ADDRESS }} redis-cli ping register: mailu_redis_check @@ -14,13 +14,13 @@ rescue: - block: - - name: "Collect Mailu redis container logs after readiness timeout" + - name: "๐Ÿ“Š Collect Mailu redis container logs after readiness timeout" ansible.builtin.shell: > container logs --tail=300 {{ MAILU_REDIS_CONTAINER_ADDRESS }} register: mailu_redis_logs changed_when: false always: - - name: "Fail: Mailu redis not ready" + - name: "๐Ÿ›‘ Fail: Mailu redis not ready" ansible.builtin.fail: msg: | Mailu redis did not respond to PING in time. @@ -32,9 +32,9 @@ {{ mailu_redis_logs.stdout | default('No logs available') }} when: lookup('engine', 'redis', application_id, 'local') -- name: "Wait until Mailu admin HTTP API listens on :8080" +- name: "โณ Wait until Mailu admin HTTP API listens on :8080" block: - - name: "Probe Mailu admin HTTP API" + - name: "๐Ÿ” Probe Mailu admin HTTP API" ansible.builtin.shell: > container exec -i {{ MAILU_ADMIN_CONTAINER_ADDRESS }} curl -sS -o /dev/null -w "%{http_code}" http://localhost:8080/sso/login @@ -48,13 +48,13 @@ rescue: - block: - - name: "Collect Mailu admin container logs after HTTP API readiness timeout" + - name: "๐Ÿ“Š Collect Mailu admin container logs after HTTP API readiness timeout" ansible.builtin.shell: > container logs --tail=300 {{ MAILU_ADMIN_CONTAINER_ADDRESS }} register: mailu_admin_http_logs changed_when: false always: - - name: "Fail: Mailu admin HTTP API not ready" + - name: "๐Ÿ›‘ Fail: Mailu admin HTTP API not ready" ansible.builtin.fail: msg: | Mailu admin HTTP API did not respond on :8080 in time. diff --git a/roles/web-app-mailu/tasks/04_manage_user.yml b/roles/web-app-mailu/tasks/04_manage_user.yml index e516ee1ecf..365062d09f 100644 --- a/roles/web-app-mailu/tasks/04_manage_user.yml +++ b/roles/web-app-mailu/tasks/04_manage_user.yml @@ -1,5 +1,5 @@ --- -- name: "Ensure Mailu user '{{ mailu_user_key }};{{ mailu_user_name }}@{{ MAILU_DOMAIN }}' exists" +- name: "โœ… Ensure user '{{ mailu_user_key }};{{ mailu_user_name }}@{{ MAILU_DOMAIN }}'" ansible.builtin.shell: > container exec -i {{ MAILU_ADMIN_CONTAINER_ADDRESS }} flask mailu {{ mailu_action }} @@ -26,7 +26,7 @@ when: "'mail-bot' in mailu_user_roles or 'administrator' in mailu_user_roles" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Change password for user '{{ mailu_user_key }};{{ mailu_user_name }}@{{ MAILU_DOMAIN }}'" +- name: "๐Ÿ”ง Set password '{{ mailu_user_key }};{{ mailu_user_name }}@{{ MAILU_DOMAIN }}'" ansible.builtin.shell: > container exec -i {{ MAILU_ADMIN_CONTAINER_ADDRESS }} flask mailu password @@ -43,6 +43,6 @@ when: "'mail-bot' in mailu_user_roles or 'administrator' in mailu_user_roles" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Create Mailu API Token for {{ mailu_user_name }}" +- name: "๐Ÿ“ Create Mailu API Token for {{ mailu_user_name }}" include_tasks: 04a_manage_user_token.yml when: "'mail-bot' in mailu_user_roles" diff --git a/roles/web-app-mailu/tasks/04a_manage_user_token.yml b/roles/web-app-mailu/tasks/04a_manage_user_token.yml index 87cf6e679c..26a3c0a08d 100644 --- a/roles/web-app-mailu/tasks/04a_manage_user_token.yml +++ b/roles/web-app-mailu/tasks/04a_manage_user_token.yml @@ -1,5 +1,5 @@ --- -- name: "Fetch existing API tokens via curl inside admin container" +- name: "โฌ‡๏ธ Fetch existing API tokens via curl inside admin container" ansible.builtin.shell: >- container exec -i {{ MAILU_ADMIN_CONTAINER_ADDRESS }} curl -sS --fail -X GET {{ MAILU_API_SERVICE_BASE_URL }}/token @@ -11,7 +11,7 @@ delay: 2 until: mailu_tokens_cli.rc == 0 and mailu_tokens_cli.stdout | trim | length > 0 -- name: "Extract existing token info for '{{ mailu_user_key }};{{ mailu_user_name }}'" +- name: "๐Ÿ“ค Extract existing token info for '{{ mailu_user_key }};{{ mailu_user_name }}'" set_fact: mailu_user_existing_token: >- {{ ( @@ -21,7 +21,7 @@ | list ).0 | default(None) }} -- name: "Start Mailu token procedures if token missing locally or absent in Mailu" +- name: "โ–ถ๏ธ Start Mailu token procedures if token missing locally or absent in Mailu" when: >- ( ( diff --git a/roles/web-app-mailu/tasks/04b_create_user_token.yml b/roles/web-app-mailu/tasks/04b_create_user_token.yml index b34a7e3135..e75607f69c 100644 --- a/roles/web-app-mailu/tasks/04b_create_user_token.yml +++ b/roles/web-app-mailu/tasks/04b_create_user_token.yml @@ -1,5 +1,5 @@ --- -- name: "Delete existing API token for '{{ mailu_user_key }};{{ mailu_user_name }}' if local token missing but remote exists" +- name: "๐Ÿงน Delete API token '{{ mailu_user_key }};{{ mailu_user_name }}' if local missing" ansible.builtin.shell: >- container exec -i {{ MAILU_ADMIN_CONTAINER_ADDRESS }} curl -s -X DELETE {{ MAILU_API_SERVICE_BASE_URL }}/token/{{ mailu_user_existing_token.id }} @@ -13,7 +13,7 @@ delay: 2 changed_when: mailu_token_delete.rc == 0 -- name: "Create API token for '{{ mailu_user_key }};{{ mailu_user_name }}' if no local token defined" +- name: "๐Ÿ“ Create API token '{{ mailu_user_key }};{{ mailu_user_name }}' if none local" ansible.builtin.shell: >- container exec -i {{ MAILU_ADMIN_CONTAINER_ADDRESS }} curl -sS -f -o /tmp/mailu-token-{{ mailu_user_key | quote }}.json @@ -32,7 +32,7 @@ failed_when: mailu_token_creation_request.rc != 0 changed_when: mailu_token_creation_request.rc == 0 -- name: "Read created API token response for '{{ mailu_user_key }};{{ mailu_user_name }}'" +- name: "๐Ÿ“– Read created API token response '{{ mailu_user_key }};{{ mailu_user_name }}'" ansible.builtin.shell: >- container exec -i {{ MAILU_ADMIN_CONTAINER_ADDRESS }} cat /tmp/mailu-token-{{ mailu_user_key | quote }}.json @@ -40,7 +40,7 @@ changed_when: false failed_when: mailu_token_creation_response.stdout | trim == "" -- name: "Extract created API token for '{{ mailu_user_key }};{{ mailu_user_name }}'" +- name: "๐Ÿ“ค Extract created API token for '{{ mailu_user_key }};{{ mailu_user_name }}'" ansible.builtin.set_fact: mailu_created_token: >- {{ @@ -51,7 +51,7 @@ }} failed_when: mailu_created_token | trim == "" -- name: "Persist + inject Mailu API token via sys-token-store" +- name: "๐Ÿ’พ Persist + inject Mailu API token via sys-token-store" ansible.builtin.include_role: name: sys-token-store tasks_from: write.yml diff --git a/roles/web-app-mailu/tasks/05_generate-and-read-dkim.yml b/roles/web-app-mailu/tasks/05_generate-and-read-dkim.yml index a0e981eb39..c383edd1a9 100644 --- a/roles/web-app-mailu/tasks/05_generate-and-read-dkim.yml +++ b/roles/web-app-mailu/tasks/05_generate-and-read-dkim.yml @@ -1,5 +1,5 @@ --- -- name: Check if DKIM private key file exists in the antispam container +- name: ๐Ÿ”Ž Check if DKIM private key file exists in the antispam container ansible.builtin.shell: > container exec -i {{ MAILU_ANTISPAM_CONTAINER_ADDRESS }} test -f {{ MAILU_DKIM_KEY_PATH }} @@ -12,7 +12,7 @@ args: chdir: "{{ MAILU_INSTANCE_DIR }}" -- name: Generate DKIM key +- name: โš™๏ธ Generate DKIM key ansible.builtin.shell: > container exec -i {{ MAILU_ANTISPAM_CONTAINER_ADDRESS }} rspamadm dkim_keygen -s dkim -d {{ MAILU_DOMAIN }} -k {{ MAILU_DKIM_KEY_PATH }} @@ -25,7 +25,7 @@ chdir: "{{ MAILU_INSTANCE_DIR }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Fetch DKIM private key from antispam container +- name: โฌ‡๏ธ Fetch DKIM private key from antispam container ansible.builtin.shell: > container exec -i {{ MAILU_ANTISPAM_CONTAINER_ADDRESS }} cat {{ MAILU_DKIM_KEY_PATH }} @@ -34,12 +34,12 @@ changed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Ensure openssl is installed on host +- name: โœ… Ensure openssl is installed on host include_role: name: sys-openssl when: run_once_sys_openssl is not defined -- name: Generate DKIM public key on the host +- name: โš™๏ธ Generate DKIM public key on the host command: openssl rsa -pubout args: stdin: "{{ dkim_priv_content.stdout }}" @@ -47,7 +47,7 @@ changed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Normalize and build Mailu DKIM TXT record +- name: ๐Ÿ“ Normalize and build Mailu DKIM TXT record set_fact: mailu_dkim_public_key: >- v=DKIM1; k=rsa; p={{ @@ -58,7 +58,7 @@ }} no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Debug Mailu DKIM public key +- name: ๐Ÿ› Debug Mailu DKIM public key debug: msg: "Mailu DKIM public key: {{ mailu_dkim_public_key }}" when: MODE_DEBUG | bool diff --git a/roles/web-app-mailu/tasks/06_dns-records.yml b/roles/web-app-mailu/tasks/06_dns-records.yml index 3c18d2d8fc..96b7c97326 100644 --- a/roles/web-app-mailu/tasks/06_dns-records.yml +++ b/roles/web-app-mailu/tasks/06_dns-records.yml @@ -1,5 +1,5 @@ --- -- name: "DNS (Cloudflare) for Mailu" +- name: "๐ŸŒ DNS (Cloudflare) for Mailu" include_role: name: sys-dns-cloudflare-records when: DNS_PROVIDER | lower == 'cloudflare' @@ -104,7 +104,7 @@ port: 443 value: "{{ MAILU_HOSTNAME }}" -- name: "rDNS (Hetzner Cloud) for Mailu" +- name: "๐ŸŒ rDNS (Hetzner Cloud) for Mailu" include_role: name: sys-dns-hetzner-rdns when: HOSTING_PROVIDER | lower == 'hetzner' diff --git a/roles/web-app-mailu/tasks/07_wait_for_antispam.yml b/roles/web-app-mailu/tasks/07_wait_for_antispam.yml index 6e26ebd545..6973480adf 100644 --- a/roles/web-app-mailu/tasks/07_wait_for_antispam.yml +++ b/roles/web-app-mailu/tasks/07_wait_for_antispam.yml @@ -1,7 +1,7 @@ --- -- name: "Wait until Mailu antispam container is up" +- name: "โณ Wait until Mailu antispam container is up" block: - - name: "Probe Mailu antispam" + - name: "๐Ÿ” Probe Mailu antispam" ansible.builtin.shell: > container exec -i {{ MAILU_ANTISPAM_CONTAINER_ADDRESS }} true register: mailu_antispam_check @@ -12,13 +12,13 @@ rescue: - block: - - name: "Collect Mailu antispam container logs after readiness timeout" + - name: "๐Ÿ“Š Collect Mailu antispam container logs after readiness timeout" ansible.builtin.shell: > container logs --tail=300 {{ MAILU_ANTISPAM_CONTAINER_ADDRESS }} register: mailu_antispam_logs changed_when: false always: - - name: "Fail: Mailu antispam not ready" + - name: "๐Ÿ›‘ Fail: Mailu antispam not ready" ansible.builtin.fail: msg: | Mailu antispam container did not become ready in time. diff --git a/roles/web-app-mastodon/tasks/01_core.yml b/roles/web-app-mastodon/tasks/01_core.yml index 2799c1d1b8..7b32935c1c 100644 --- a/roles/web-app-mastodon/tasks/01_core.yml +++ b/roles/web-app-mastodon/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: "Include setup for domain '{{ domain }}'" +- name: "๐Ÿ“‚ Include setup for domain '{{ domain }}'" include_role: name: sys-stk-front-proxy loop: "{{ lookup('domains', 'web-app-mastodon') }}" @@ -14,32 +14,32 @@ webserver_client_max_body_size: "80m" webserver_vhost_flavour: "ws_generic" -- name: "load docker and db for {{ application_id }}" +- name: "๐Ÿงฉ load docker and db for {{ application_id }}" include_role: name: sys-stk-backend vars: compose_handlers_flush: false -- name: "MASTODON | Apply overrides" +- name: "๐Ÿ“Œ MASTODON | Apply overrides" include_tasks: 02_overrides.yml when: MASTODON_HTTP_ONLY_ENABLED | bool -- name: Flush handlers to start Mastodon after migration +- name: ๐Ÿšฟ Flush handlers to start Mastodon after migration meta: flush_handlers -- name: "start setup procedures for mastodon" +- name: "โ–ถ๏ธ start setup procedures for mastodon" include_tasks: 03_setup.yml when: IS_STACK_HOST | bool -- name: "Wait for Mastodon" +- name: "โณ Wait for Mastodon" include_tasks: 04_wait.yml -- name: "Mastodon stack-host post-deploy" +- name: "๐Ÿ–ฅ๏ธ Mastodon stack-host post-deploy" when: IS_STACK_HOST | bool block: - - name: "Cleanup Mastodon caches when MODE_CLEANUP is true" + - name: "๐Ÿงน Cleanup Mastodon caches when MODE_CLEANUP is true" include_tasks: 05_cleanup.yml when: MODE_CLEANUP | bool - - name: "Include administrator routines for '{{ application_id }}'" + - name: "๐Ÿ“‚ Include administrator routines for '{{ application_id }}'" include_tasks: 06_administrator.yml diff --git a/roles/web-app-mastodon/tasks/02_overrides.yml b/roles/web-app-mastodon/tasks/02_overrides.yml index 967770bd85..6c631a0566 100644 --- a/roles/web-app-mastodon/tasks/02_overrides.yml +++ b/roles/web-app-mastodon/tasks/02_overrides.yml @@ -1,12 +1,12 @@ --- -- name: "MASTODON | Ensure overrides directory exists" +- name: "โœ… MASTODON | Ensure overrides directory exists" ansible.builtin.file: path: "{{ MASTODON_OVERRIDES_DIR }}" state: directory mode: "0755" when: MASTODON_HTTP_ONLY_ENABLED | bool -- name: "MASTODON | Install force_ssl override initializer (HTTP-only)" +- name: "๐Ÿ“ฆ MASTODON | Install force_ssl override initializer (HTTP-only)" ansible.builtin.copy: dest: "{{ MASTODON_FORCE_SSL_OVERRIDE_FILE }}" mode: "0644" diff --git a/roles/web-app-mastodon/tasks/03_setup.yml b/roles/web-app-mastodon/tasks/03_setup.yml index a295c155fb..6efbbdefc2 100644 --- a/roles/web-app-mastodon/tasks/03_setup.yml +++ b/roles/web-app-mastodon/tasks/03_setup.yml @@ -1,10 +1,10 @@ --- -- name: "Execute migration for '{{ application_id }}'" +- name: "โ–ถ๏ธ Execute migration for '{{ application_id }}'" ansible.builtin.shell: > container exec {{ MASTODON_CONTAINER_ADDRESS }} bundle exec rails db:migrate -- name: "MASTODON | Seed database (idempotent)" +- name: "๐ŸŒฑ MASTODON | Seed database (idempotent)" ansible.builtin.shell: > container exec {{ MASTODON_CONTAINER_ADDRESS }} bash -lc 'bin/rails db:seed' diff --git a/roles/web-app-mastodon/tasks/04_wait.yml b/roles/web-app-mastodon/tasks/04_wait.yml index 314ac5f924..ed9f2ad56e 100644 --- a/roles/web-app-mastodon/tasks/04_wait.yml +++ b/roles/web-app-mastodon/tasks/04_wait.yml @@ -1,5 +1,5 @@ --- -- name: Check health status of '{{ item }}' container +- name: ๐Ÿ”Ž Check health status of '{{ item }}' container ansible.builtin.shell: > container inspect --format '{{ "{{.State.Health.Status}}" }}' {{ lookup('container_address', application_id, item) }} diff --git a/roles/web-app-mastodon/tasks/05_cleanup.yml b/roles/web-app-mastodon/tasks/05_cleanup.yml index fdcfd107e9..caa844782c 100644 --- a/roles/web-app-mastodon/tasks/05_cleanup.yml +++ b/roles/web-app-mastodon/tasks/05_cleanup.yml @@ -1,7 +1,7 @@ --- # Cleanup routine for Mastodon # Removes cached remote media older than 14 days when MODE_CLEANUP is enabled. -- name: "Cleanup Mastodon media cache older than 14 days" +- name: "๐Ÿงน Cleanup Mastodon media cache older than 14 days" shell: cmd: "container exec -u root {{ MASTODON_CONTAINER_ADDRESS }} bin/tootctl media remove --days=14" register: mastodon_cleanup diff --git a/roles/web-app-mastodon/tasks/06_administrator.yml b/roles/web-app-mastodon/tasks/06_administrator.yml index c5ad774519..b1a0ce44b1 100644 --- a/roles/web-app-mastodon/tasks/06_administrator.yml +++ b/roles/web-app-mastodon/tasks/06_administrator.yml @@ -1,10 +1,10 @@ --- # Routines to create the administrator account -- name: Remove line containing "- administrator" from config/settings.yml to allow creating administrator account +- name: ๐Ÿงน Remove "- administrator" from config/settings.yml to enable admin creation shell: cmd: "container exec -u root {{ MASTODON_CONTAINER_ADDRESS }} sed -i '/- administrator/d' config/settings.yml" when: lookup('users', 'administrator').username == "administrator" -- name: Create admin account via tootctl +- name: ๐Ÿ“ Create admin account via tootctl shell: cmd: > container exec -u root {{ MASTODON_CONTAINER_ADDRESS }} bash -c @@ -18,7 +18,7 @@ and ("taken" not in tootctl_create.stderr | lower) no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Approve the administrator account in Mastodon +- name: ๐Ÿ‘ Approve the administrator account in Mastodon shell: cmd: > container exec -u root {{ MASTODON_CONTAINER_ADDRESS }} bash -c "bin/tootctl accounts modify {{ lookup('users', 'administrator').username }} --approve" diff --git a/roles/web-app-matomo/tasks/01_core.yml b/roles/web-app-matomo/tasks/01_core.yml index 1740999945..a3ae02745d 100644 --- a/roles/web-app-matomo/tasks/01_core.yml +++ b/roles/web-app-matomo/tasks/01_core.yml @@ -1,15 +1,15 @@ --- - include_tasks: utils/once/flag.yml -- name: "Matomo | Resolve token from store/config" +- name: "๐Ÿ” Matomo | Resolve token from store/config" include_tasks: 02_token_store.yml -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: compose_handlers_flush: false -- name: "Matomo manager-side operations (file deploys + container exec)" +- name: "๐Ÿ‘” Matomo manager-side operations (file deploys + container exec)" include_tasks: 03_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-matomo/tasks/02_token_store.yml b/roles/web-app-matomo/tasks/02_token_store.yml index e9f150349b..6861777729 100644 --- a/roles/web-app-matomo/tasks/02_token_store.yml +++ b/roles/web-app-matomo/tasks/02_token_store.yml @@ -1,5 +1,5 @@ --- -- name: "Matomo | Expose resolved token" +- name: "๐Ÿ”‘ Matomo | Expose resolved token" ansible.builtin.set_fact: matomo_token_value: "{{ lookup('users', 'administrator').tokens['web-app-matomo'] | default('') | string | trim }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" diff --git a/roles/web-app-matomo/tasks/03_manager_ops.yml b/roles/web-app-matomo/tasks/03_manager_ops.yml index 2d5ed1ceba..a1cb801e5d 100644 --- a/roles/web-app-matomo/tasks/03_manager_ops.yml +++ b/roles/web-app-matomo/tasks/03_manager_ops.yml @@ -1,5 +1,5 @@ --- -- name: "Deploy '{{ MATOMO_BOOTSTRAP_ENV_FILE }}'" +- name: "๐Ÿš€ Deploy '{{ MATOMO_BOOTSTRAP_ENV_FILE }}'" stack_host_template: src: "templates/bootstrap.env.j2" dest: "{{ MATOMO_BOOTSTRAP_ENV_FILE }}" @@ -7,11 +7,11 @@ force: true notify: compose up -- name: flush docker service +- name: ๐Ÿšฟ flush docker service meta: flush_handlers -- name: "Matomo install | Resolve hosting node + local container ID" +- name: "๐Ÿ” Matomo install | Resolve hosting node + local container ID" include_tasks: 09_resolve_host_cid.yml -- name: "Matomo install | Run downstream install path" +- name: "โ–ถ๏ธ Matomo install | Run downstream install path" include_tasks: 04_install_path.yml diff --git a/roles/web-app-matomo/tasks/04_install_path.yml b/roles/web-app-matomo/tasks/04_install_path.yml index 4cc6a20d6f..1d694e646d 100644 --- a/roles/web-app-matomo/tasks/04_install_path.yml +++ b/roles/web-app-matomo/tasks/04_install_path.yml @@ -1,5 +1,5 @@ --- -- name: "Matomo install | Check whether Matomo is already installed (config.ini.php exists)" +- name: "๐Ÿ” Matomo install | Check if already installed (config.ini.php exists)" ansible.builtin.shell: > # nocheck: container-exec-resolver MATOMO_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell container exec {{ MATOMO_LOCAL_CID | quote }} sh -lc 'test -f {{ MATOMO_CONFIG | quote }}' @@ -8,7 +8,7 @@ failed_when: false delegate_to: "{{ MATOMO_HOST_NODE }}" -- name: "Bootstrap Matomo (Initialisation and setting of API token if not defined)" +- name: "๐Ÿฅพ Bootstrap Matomo (Initialisation and setting of API token if not defined)" include_tasks: 05_bootstrap.yml when: > (matomo_config_exists.rc != 0) or @@ -16,7 +16,7 @@ # Exception: matrix-deploy round-2 uses different MariaDB creds; without rewriting # config.ini.php before the healthy-probe, matomo loops on "Database access denied". -- name: "Patch database credentials for {{ application_id }}" +- name: "๐Ÿฉน Patch database credentials for {{ application_id }}" include_tasks: file: 06_patch_database.yml apply: @@ -24,30 +24,30 @@ notify: compose up when: matomo_config_exists.rc == 0 -- name: "Patch Trusted Hosts for {{ application_id }}" +- name: "๐Ÿฉน Patch Trusted Hosts for {{ application_id }}" include_tasks: 07_patch_trusted_hosts.yml -- name: flush docker service +- name: ๐Ÿšฟ flush docker service meta: flush_handlers # Exception: in swarm the 'compose up' handler runs `docker stack deploy`, which is a # no-op when only config.ini.php on the NFS bind changed; the running container keeps # the pre-patch creds in memory and loops on "Database access denied". Force a service # restart so the patched config is re-read, then re-resolve the (possibly new) task. -- name: "Matomo install | Swarm: restart matomo so patched config is re-read" +- name: "๐Ÿ Matomo install | Swarm: restart matomo so patched config is re-read" when: DEPLOYMENT_MODE == 'swarm' block: - - name: "Matomo install | Swarm: force-restart matomo service" + - name: "๐Ÿ Matomo install | Swarm: force-restart matomo service" ansible.builtin.command: >- container service update --force {{ lookup('container_service', application_id, MATOMO_SERVICE) }} changed_when: true timeout: 600 - - name: "Matomo install | Swarm: re-resolve hosting node + container ID after restart" + - name: "๐Ÿ Matomo install | Swarm: re-resolve hosting node + container ID after restart" include_tasks: 09_resolve_host_cid.yml -- name: "Matomo install | Wait for Matomo container to be healthy" +- name: "โณ Matomo install | Wait for Matomo container to be healthy" ansible.builtin.shell: > container inspect -f '{{ "{{" }}.State.Health.Status{{ "}}" }}' {{ MATOMO_LOCAL_CID | quote }} @@ -59,14 +59,14 @@ matomo_health.rc == 0 and (matomo_health.stdout | trim) == 'healthy' delegate_to: "{{ MATOMO_HOST_NODE }}" -- name: "Matomo install | Make config writable by the web user (entrypoint re-owns it root)" +- name: "๐Ÿ” Matomo install | Make config writable by web user (entrypoint re-owns it root)" ansible.builtin.shell: > # nocheck: container-exec-resolver MATOMO_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell container exec --user root {{ MATOMO_LOCAL_CID | quote }} chown www-data:www-data {{ MATOMO_CONFIG }} changed_when: true delegate_to: "{{ MATOMO_HOST_NODE }}" -- name: "Config '{{ application_id }}' via API" +- name: "๐Ÿ”ง Config '{{ application_id }}' via API" include_tasks: file: 08_config.yml apply: diff --git a/roles/web-app-matomo/tasks/05_bootstrap.yml b/roles/web-app-matomo/tasks/05_bootstrap.yml index 7bd384adb1..90d6127141 100644 --- a/roles/web-app-matomo/tasks/05_bootstrap.yml +++ b/roles/web-app-matomo/tasks/05_bootstrap.yml @@ -1,18 +1,18 @@ --- - block: - - name: "Matomo bootstrap | Run bootstrap ({{ DEPLOYMENT_MODE }})" + - name: "โ–ถ๏ธ Matomo bootstrap | Run bootstrap ({{ DEPLOYMENT_MODE }})" ansible.builtin.include_tasks: "05_bootstrap/flavors/{{ DEPLOYMENT_MODE }}.yml" rescue: - - name: "Matomo bootstrap | Select effective bootstrap result for diagnostics" + - name: "๐ŸŽฏ Matomo bootstrap | Select effective bootstrap result for diagnostics" ansible.builtin.set_fact: matomo_bootstrap_run: "{{ matomo_bootstrap_compose if DEPLOYMENT_MODE == 'compose' else matomo_bootstrap_swarm }}" - - name: "Matomo bootstrap | Dump bootstrap diagnostics ({{ DEPLOYMENT_MODE }})" + - name: "๐Ÿ’พ Matomo bootstrap | Dump bootstrap diagnostics ({{ DEPLOYMENT_MODE }})" ansible.builtin.include_tasks: "05_bootstrap/debug/{{ DEPLOYMENT_MODE }}.yml" when: MODE_DEBUG | bool - - name: "Matomo bootstrap | Abort with bootstrap root cause" + - name: "๐Ÿ›‘ Matomo bootstrap | Abort with bootstrap root cause" ansible.builtin.fail: msg: >- Matomo bootstrap run failed after {{ matomo_bootstrap_run.attempts | default(MATOMO_BOOTSTRAP_RETRIES) }} attempt(s) @@ -22,7 +22,7 @@ stdout={{ (matomo_bootstrap_run.stdout | default('') | trim) if not (MASK_CREDENTIALS_IN_LOGS | bool) else ('') }} -- name: "Matomo bootstrap | Set effective token (prefer existing, else parse bootstrap stdout)" +- name: "๐Ÿ”ง Matomo bootstrap | Set effective token (existing, else parse bootstrap stdout)" ansible.builtin.set_fact: matomo_token_value: >- {{ @@ -36,7 +36,7 @@ ) }} -- name: "Matomo bootstrap | Assert we have a token now" +- name: "โœ… Matomo bootstrap | Assert we have a token now" ansible.builtin.assert: that: - matomo_token_value is defined @@ -47,7 +47,7 @@ stdout={{ (matomo_bootstrap_compose.stdout if DEPLOYMENT_MODE == 'compose' else matomo_bootstrap_swarm.stdout) | default('') | trim }} when: MODE_ASSERT_LOCAL | bool -- name: "Matomo | Persist + inject token via sys-token-store (store + runtime users)" +- name: "๐Ÿ’พ Matomo | Persist + inject token via sys-token-store (store + runtime users)" ansible.builtin.include_role: name: sys-token-store tasks_from: write.yml @@ -61,7 +61,7 @@ - matomo_token_value | length > 0 # web-svc-* only: re-running sys-front-inj-all for web-app consumers crashes on their unloaded role vars -- name: "Matomo | Re-render injection for early-rendered web-svc consumers" +- name: "๐Ÿ“„ Matomo | Re-render injection for early-rendered web-svc consumers" ansible.builtin.include_role: name: sys-front-inj-all vars: diff --git a/roles/web-app-matomo/tasks/05_bootstrap/debug/compose.yml b/roles/web-app-matomo/tasks/05_bootstrap/debug/compose.yml index f5475809d4..93d2d4af3f 100644 --- a/roles/web-app-matomo/tasks/05_bootstrap/debug/compose.yml +++ b/roles/web-app-matomo/tasks/05_bootstrap/debug/compose.yml @@ -1,6 +1,6 @@ --- # IMPORTANT: Avoid shell-inlining stdout/stderr because it can contain quotes and break bash parsing. -- name: "DEBUG | bootstrap result (sanitized/minimal when masked)" +- name: "๐Ÿ› DEBUG | bootstrap result (sanitized/minimal when masked)" ansible.builtin.debug: msg: - "=== compose bootstrap FAILED ===" @@ -9,7 +9,7 @@ - "stdout_len={{ (matomo_bootstrap_run.stdout | default('') | string) | length }}" - "stderr_len={{ (matomo_bootstrap_run.stderr | default('') | string) | length }}" -- name: "DEBUG | bootstrap result (full when not masked)" +- name: "๐Ÿ› DEBUG | bootstrap result (full when not masked)" ansible.builtin.debug: msg: - "=== compose bootstrap FAILED ===" @@ -20,7 +20,7 @@ - "--- stderr ---" - "{{ matomo_bootstrap_run.stderr | default('') }}" -- name: "DEBUG | compose ps -a" +- name: "๐Ÿ› DEBUG | compose ps -a" ansible.builtin.command: argv: - "{{ BIN_COMPOSE }}" @@ -35,7 +35,7 @@ changed_when: false failed_when: false -- name: "DEBUG | compose ps output (full when not masked)" +- name: "๐Ÿ› DEBUG | compose ps output (full when not masked)" ansible.builtin.debug: msg: - "--- compose ps -a stdout ---" @@ -43,7 +43,7 @@ - "--- compose ps -a stderr ---" - "{{ matomo_bootstrap_ps.stderr | default('') }}" -- name: "DEBUG | compose logs matomo (tail)" +- name: "๐Ÿ› DEBUG | compose logs matomo (tail)" ansible.builtin.command: argv: - "{{ BIN_COMPOSE }}" @@ -62,7 +62,7 @@ changed_when: false failed_when: false -- name: "DEBUG | compose logs matomo output (full when not masked)" +- name: "๐Ÿ› DEBUG | compose logs matomo output (full when not masked)" ansible.builtin.debug: msg: - "--- compose logs {{ MATOMO_SERVICE }} stdout ---" @@ -70,7 +70,7 @@ - "--- compose logs {{ MATOMO_SERVICE }} stderr ---" - "{{ matomo_bootstrap_matomo_logs.stderr | default('') }}" -- name: "DEBUG | compose logs bootstrap service (tail)" +- name: "๐Ÿ› DEBUG | compose logs bootstrap service (tail)" ansible.builtin.command: argv: - "{{ BIN_COMPOSE }}" @@ -89,7 +89,7 @@ changed_when: false failed_when: false -- name: "DEBUG | compose logs bootstrap output (full when not masked)" +- name: "๐Ÿ› DEBUG | compose logs bootstrap output (full when not masked)" ansible.builtin.debug: msg: - "--- compose logs {{ MATOMO_BOOTSTRAP_SERVICE }} stdout ---" @@ -97,7 +97,7 @@ - "--- compose logs {{ MATOMO_BOOTSTRAP_SERVICE }} stderr ---" - "{{ matomo_bootstrap_service_logs.stderr | default('') }}" -- name: "DEBUG | matomo container health (inspect json)" +- name: "๐Ÿ› DEBUG | matomo container health (inspect json)" ansible.builtin.command: argv: - container @@ -109,14 +109,14 @@ changed_when: false failed_when: false -- name: "DEBUG | matomo container health output" +- name: "๐Ÿ› DEBUG | matomo container health output" ansible.builtin.debug: msg: - "--- matomo .State.Health (json) ---" - "{{ matomo_container_health.stdout | default('') }}" - "{{ matomo_container_health.stderr | default('') }}" -- name: "DEBUG | matomo tmp permissions + write test (www-data)" +- name: "๐Ÿ› DEBUG | matomo tmp permissions + write test (www-data)" ansible.builtin.command: argv: - container @@ -139,14 +139,14 @@ changed_when: false failed_when: false -- name: "DEBUG | matomo tmp permissions + write test output" +- name: "๐Ÿ› DEBUG | matomo tmp permissions + write test output" ansible.builtin.debug: msg: - "--- filesystem + write-test diagnostics ---" - "{{ matomo_fs_permissions_check.stdout | default('') }}" - "{{ matomo_fs_permissions_check.stderr | default('') }}" -- name: "DEBUG | bootstrap artifact paths from logs" +- name: "๐Ÿ› DEBUG | bootstrap artifact paths from logs" ansible.builtin.debug: msg: - "--- bootstrap installer artifacts (paths from logs) ---" @@ -164,7 +164,7 @@ | list }} -- name: "DEBUG | show compose file" +- name: "๐Ÿ› DEBUG | show compose file" ansible.builtin.command: argv: - bash @@ -172,7 +172,7 @@ - "sed -n '1,240p' {{ lookup('container', application_id, 'files.compose') }} || true" changed_when: false -- name: "DEBUG | show env files (only when not masked)" +- name: "๐Ÿ› DEBUG | show env files (only when not masked)" ansible.builtin.command: argv: - bash @@ -186,7 +186,7 @@ cat "{{ lookup('container', application_id, 'files.env') }}" || true changed_when: false -- name: "DEBUG | compose config (effective)" +- name: "๐Ÿ› DEBUG | compose config (effective)" ansible.builtin.command: argv: - "{{ BIN_COMPOSE }}" @@ -203,13 +203,13 @@ changed_when: false failed_when: false -- name: "DEBUG | effective config output" +- name: "๐Ÿ› DEBUG | effective config output" ansible.builtin.debug: msg: - "{{ matomo_bootstrap_config.stdout | default('') }}" - "{{ matomo_bootstrap_config.stderr | default('') }}" when: not (MASK_CREDENTIALS_IN_LOGS | bool) -- name: "FAIL | abort after debug dump" +- name: "๐Ÿ›‘ FAIL | abort after debug dump" ansible.builtin.fail: msg: "Matomo bootstrap failed โ€“ see debug output above" diff --git a/roles/web-app-matomo/tasks/05_bootstrap/debug/swarm.yml b/roles/web-app-matomo/tasks/05_bootstrap/debug/swarm.yml index 08196e403f..d12e986de2 100644 --- a/roles/web-app-matomo/tasks/05_bootstrap/debug/swarm.yml +++ b/roles/web-app-matomo/tasks/05_bootstrap/debug/swarm.yml @@ -1,5 +1,5 @@ --- -- name: "Matomo bootstrap | Swarm: dump bootstrap service ps + logs" +- name: "๐Ÿ Matomo bootstrap | Swarm: dump bootstrap service ps + logs" ansible.builtin.shell: | echo "===== container service ps {{ MATOMO_BOOTSTRAP_NAME }} =====" container service ps --no-trunc {{ lookup('container_service', application_id, MATOMO_BOOTSTRAP_SERVICE) | quote }} 2>&1 || true @@ -10,7 +10,7 @@ failed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Matomo bootstrap | Swarm: show bootstrap service diagnostics" +- name: "๐Ÿ Matomo bootstrap | Swarm: show bootstrap service diagnostics" ansible.builtin.debug: msg: "{{ (matomo_bootstrap_swarm_dump.stdout | default('')).split('\n') }}" when: not (MASK_CREDENTIALS_IN_LOGS | bool) diff --git a/roles/web-app-matomo/tasks/05_bootstrap/flavors/compose.yml b/roles/web-app-matomo/tasks/05_bootstrap/flavors/compose.yml index c034b4e0f1..1618239a1d 100644 --- a/roles/web-app-matomo/tasks/05_bootstrap/flavors/compose.yml +++ b/roles/web-app-matomo/tasks/05_bootstrap/flavors/compose.yml @@ -1,5 +1,5 @@ --- -- name: "Matomo bootstrap | Compose: Run one-shot bootstrap via compose profile" +- name: "๐Ÿณ Matomo bootstrap | Compose: Run one-shot bootstrap via compose profile" ansible.builtin.command: argv: - "{{ BIN_COMPOSE }}" diff --git a/roles/web-app-matomo/tasks/05_bootstrap/flavors/swarm.yml b/roles/web-app-matomo/tasks/05_bootstrap/flavors/swarm.yml index 3113b8e19c..54e1b244af 100644 --- a/roles/web-app-matomo/tasks/05_bootstrap/flavors/swarm.yml +++ b/roles/web-app-matomo/tasks/05_bootstrap/flavors/swarm.yml @@ -1,5 +1,5 @@ --- -- name: "Matomo bootstrap | Swarm: wait for Matomo to be healthy before running the installer" +- name: "โณ Matomo bootstrap | Swarm: wait for Matomo healthy before installer" ansible.builtin.shell: > container inspect -f '{{ "{{" }}.State.Health.Status{{ "}}" }}' {{ MATOMO_LOCAL_CID | quote }} @@ -10,7 +10,7 @@ until: matomo_health_preboot.rc == 0 and (matomo_health_preboot.stdout | trim) == 'healthy' delegate_to: "{{ MATOMO_HOST_NODE }}" -- name: "Matomo bootstrap | Swarm: force a fresh installer run and wait for its token" +- name: "๐Ÿ Matomo bootstrap | Swarm: force a fresh installer run and wait for its token" ansible.builtin.script: "{{ role_path }}/files/bootstrap_swarm_poll.sh" environment: SERVICE_REF: "{{ lookup('container_service', application_id, MATOMO_BOOTSTRAP_SERVICE) }}" diff --git a/roles/web-app-matomo/tasks/06_patch_database.yml b/roles/web-app-matomo/tasks/06_patch_database.yml index c6eb4bef4f..b6978408f4 100644 --- a/roles/web-app-matomo/tasks/06_patch_database.yml +++ b/roles/web-app-matomo/tasks/06_patch_database.yml @@ -1,20 +1,20 @@ --- -- name: Update DB host +- name: ๐Ÿ”„ Update DB host ansible.builtin.shell: > # nocheck: container-exec-resolver MATOMO_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell container exec -i --user root {{ MATOMO_LOCAL_CID | quote }} sed -i "s/^host *=.*/host = {{ lookup('database', application_id, 'host') | sed_escape('/') }}/" {{ MATOMO_CONFIG }} -- name: Update DB name +- name: ๐Ÿ”„ Update DB name ansible.builtin.shell: > # nocheck: container-exec-resolver MATOMO_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell container exec -i --user root {{ MATOMO_LOCAL_CID | quote }} sed -i "s/^dbname *=.*/dbname = {{ lookup('database', application_id, 'name') | sed_escape('/') }}/" {{ MATOMO_CONFIG }} -- name: Update DB user +- name: ๐Ÿ”„ Update DB user ansible.builtin.shell: > # nocheck: container-exec-resolver MATOMO_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell container exec -i --user root {{ MATOMO_LOCAL_CID | quote }} sed -i "s/^username *=.*/username = {{ lookup('database', application_id, 'username') | sed_escape('/') }}/" {{ MATOMO_CONFIG }} -- name: Update DB password +- name: ๐Ÿ”„ Update DB password ansible.builtin.shell: > # nocheck: container-exec-resolver MATOMO_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell container exec -i --user root -e PATCH_PASSWORD={{ lookup('database', application_id, 'password') | sed_escape('/') | quote }} diff --git a/roles/web-app-matomo/tasks/07_patch_trusted_hosts.yml b/roles/web-app-matomo/tasks/07_patch_trusted_hosts.yml index e37952f4f2..8b4732e542 100644 --- a/roles/web-app-matomo/tasks/07_patch_trusted_hosts.yml +++ b/roles/web-app-matomo/tasks/07_patch_trusted_hosts.yml @@ -1,5 +1,5 @@ --- -- name: "Matomo | Set trusted hosts (domain + service + container reach host)" +- name: "๐Ÿ”ง Matomo | Set trusted hosts (domain + service + container reach host)" vars: # Exception: pin application_id and inline the domain literal; nested include_role # chains (sys-stk-front-base -> web-opt-rdr-domains / svc-prx-openresty) pollute diff --git a/roles/web-app-matomo/tasks/08_config.yml b/roles/web-app-matomo/tasks/08_config.yml index d8eb74cccb..941f214fdb 100644 --- a/roles/web-app-matomo/tasks/08_config.yml +++ b/roles/web-app-matomo/tasks/08_config.yml @@ -1,5 +1,5 @@ --- -- name: Exclude global IPs in Matomo +- name: ๐Ÿšซ Exclude global IPs in Matomo uri_retry: url: "{{ matomo_index_php_url }}" method: POST @@ -17,7 +17,7 @@ retries: 5 delay: 10 -- name: Exclude CSP-CheckerBot user agent in Matomo +- name: ๐Ÿšซ Exclude CSP-CheckerBot user agent in Matomo uri_retry: url: "{{ matomo_index_php_url }}" method: POST diff --git a/roles/web-app-matomo/tasks/09_resolve_host_cid.yml b/roles/web-app-matomo/tasks/09_resolve_host_cid.yml index b355ce5f96..66a1449db7 100644 --- a/roles/web-app-matomo/tasks/09_resolve_host_cid.yml +++ b/roles/web-app-matomo/tasks/09_resolve_host_cid.yml @@ -1,5 +1,5 @@ --- -- name: "Matomo resolve | Wait for matomo container to be running" +- name: "โณ Matomo resolve | Wait for matomo container to be running" ansible.builtin.shell: > container inspect -f '{{ "{{" }}.State.Running{{ "}}" }}' {{ lookup('container_address', application_id, MATOMO_SERVICE) }} @@ -11,7 +11,7 @@ matomo_running_compose.rc == 0 and (matomo_running_compose.stdout | trim) == 'true' when: DEPLOYMENT_MODE == 'compose' -- name: "Resolve {{ application_id }} hosting node + container id" +- name: "๐Ÿ” Resolve {{ application_id }} hosting node + container id" ansible.builtin.include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/swarm/resolve_host_cid.yml'] | path_join }}" vars: resolve_service_key: "{{ MATOMO_SERVICE }}" diff --git a/roles/web-app-matomo/tasks/main.yml b/roles/web-app-matomo/tasks/main.yml index 86a8170e62..acc3e830c1 100644 --- a/roles/web-app-matomo/tasks/main.yml +++ b/roles/web-app-matomo/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "Execute Role (once)" +- name: "โ–ถ๏ธ Execute Role (once)" include_tasks: 01_core.yml when: run_once_web_app_matomo is not defined vars: diff --git a/roles/web-app-matrix/tasks/01_core.yml b/roles/web-app-matrix/tasks/01_core.yml index 69b92fa830..2e9783dc49 100644 --- a/roles/web-app-matrix/tasks/01_core.yml +++ b/roles/web-app-matrix/tasks/01_core.yml @@ -1,21 +1,21 @@ --- - include_tasks: utils/once/flag.yml -- name: "set matrix flavor" +- name: "๐Ÿ”ง set matrix flavor" ansible.builtin.set_fact: matrix_flavor: "{{ lookup('config', application_id, 'services.matrix.flavor', 'ansible') }}" changed_when: false -- name: "assert matrix flavor is one of: ansible | compose" +- name: "โœ… assert matrix flavor is one of: ansible | compose" ansible.builtin.assert: that: - matrix_flavor in ['ansible', 'compose'] fail_msg: "services.matrix.flavor must be 'ansible' or 'compose' (got '{{ matrix_flavor }}')" -- name: "dispatch to ansible flavor (matrix-docker-ansible-deploy upstream)" +- name: "๐Ÿ“ค dispatch to ansible flavor (matrix-docker-ansible-deploy upstream)" include_tasks: flavor/ansible/main.yml when: matrix_flavor == 'ansible' -- name: "dispatch to compose flavor (deprecated; in-repo compose stack)" +- name: "๐Ÿ“ค dispatch to compose flavor (deprecated; in-repo compose stack)" include_tasks: flavor/compose/main.yml when: matrix_flavor == 'compose' diff --git a/roles/web-app-matrix/tasks/flavor/ansible/01_clone_upstream.yml b/roles/web-app-matrix/tasks/flavor/ansible/01_clone_upstream.yml index a49eb7df1e..97a113fb4f 100644 --- a/roles/web-app-matrix/tasks/flavor/ansible/01_clone_upstream.yml +++ b/roles/web-app-matrix/tasks/flavor/ansible/01_clone_upstream.yml @@ -1,11 +1,11 @@ --- -- name: "ensure MDAD checkout directory exists at {{ MATRIX_MDAD_DIR }}" +- name: "โœ… ensure MDAD checkout directory exists at {{ MATRIX_MDAD_DIR }}" ansible.builtin.file: path: "{{ MATRIX_MDAD_DIR }}" state: directory mode: "0755" -- name: "clone matrix-docker-ansible-deploy at pinned ref" +- name: "โฌ‡๏ธ clone matrix-docker-ansible-deploy at pinned ref" ansible.builtin.git: repo: "{{ lookup('config', application_id, 'services.matrix.upstream.repo') }}" dest: "{{ MATRIX_MDAD_DIR }}" diff --git a/roles/web-app-matrix/tasks/flavor/ansible/02_render_inventory.yml b/roles/web-app-matrix/tasks/flavor/ansible/02_render_inventory.yml index c4e1b5a9ff..808042ba35 100644 --- a/roles/web-app-matrix/tasks/flavor/ansible/02_render_inventory.yml +++ b/roles/web-app-matrix/tasks/flavor/ansible/02_render_inventory.yml @@ -1,17 +1,17 @@ --- -- name: "ensure MDAD inventory host_vars dir exists" +- name: "โœ… ensure MDAD inventory host_vars dir exists" ansible.builtin.file: path: "{{ MATRIX_MDAD_DIR }}/inventory/host_vars/{{ MATRIX_SYNAPSE_DOMAIN }}" state: directory mode: "0755" -- name: "render MDAD inventory hosts file" +- name: "๐Ÿ“„ render MDAD inventory hosts file" stack_host_template: src: "flavor/ansible/hosts.j2" dest: "{{ MATRIX_MDAD_DIR }}/inventory/hosts" mode: "0644" -- name: "render MDAD host_vars vars.yml" +- name: "๐Ÿ“„ render MDAD host_vars vars.yml" stack_host_template: src: "flavor/ansible/vars.yml.j2" dest: "{{ MATRIX_MDAD_DIR }}/inventory/host_vars/{{ MATRIX_SYNAPSE_DOMAIN }}/vars.yml" diff --git a/roles/web-app-matrix/tasks/flavor/ansible/03_database.yml b/roles/web-app-matrix/tasks/flavor/ansible/03_database.yml index 885653ef75..51b86e22ca 100644 --- a/roles/web-app-matrix/tasks/flavor/ansible/03_database.yml +++ b/roles/web-app-matrix/tasks/flavor/ansible/03_database.yml @@ -1,4 +1,4 @@ --- -- name: "ansible-flavor: provision Matrix database on central postgres" +- name: "๐Ÿ”ง ansible-flavor: provision Matrix database on central postgres" ansible.builtin.include_role: name: sys-svc-rdbms diff --git a/roles/web-app-matrix/tasks/flavor/ansible/04_run_playbook.yml b/roles/web-app-matrix/tasks/flavor/ansible/04_run_playbook.yml index fa4ee0e65b..ae8cc7b098 100644 --- a/roles/web-app-matrix/tasks/flavor/ansible/04_run_playbook.yml +++ b/roles/web-app-matrix/tasks/flavor/ansible/04_run_playbook.yml @@ -1,11 +1,11 @@ --- -- name: "ansible-flavor: render compose.yml + start matrix-mdad via sys-stk-backend" +- name: "๐Ÿ“„ ansible-flavor: render compose.yml + start matrix-mdad via sys-stk-backend" ansible.builtin.include_role: name: sys-stk-backend vars: compose_handlers_flush: false -- name: "ansible-flavor: ensure matrix-mdad runner build dir on STACK_HOST" +- name: "โœ… ansible-flavor: ensure matrix-mdad runner build dir on STACK_HOST" ansible.builtin.file: path: "{{ MATRIX_MDAD_RUNNER_BUILD_DIR }}" state: directory @@ -13,7 +13,7 @@ delegate_to: "{{ STACK_HOST }}" run_once: true -- name: "ansible-flavor: stage matrix-mdad runner build context on STACK_HOST" +- name: "๐ŸŽฌ ansible-flavor: stage matrix-mdad runner build context on STACK_HOST" stack_host_copy: src: "{{ item.src }}" dest: "{{ [ MATRIX_MDAD_RUNNER_BUILD_DIR, item.dest ] | path_join }}" @@ -29,5 +29,5 @@ - compose build - compose up -- name: "ansible-flavor: flush compose handlers (build runner image + start matrix-mdad)" +- name: "๐Ÿ”„ ansible-flavor: flush handlers (build runner image + start matrix-mdad)" ansible.builtin.meta: flush_handlers diff --git a/roles/web-app-matrix/tasks/flavor/ansible/05_proxy_wiring.yml b/roles/web-app-matrix/tasks/flavor/ansible/05_proxy_wiring.yml index 10c2539bed..73ecdbba79 100644 --- a/roles/web-app-matrix/tasks/flavor/ansible/05_proxy_wiring.yml +++ b/roles/web-app-matrix/tasks/flavor/ansible/05_proxy_wiring.yml @@ -1,5 +1,5 @@ --- -- name: "ansible-flavor: probe Synapse client API on host loopback (cold MDAD bootstrap ~10-15min)" +- name: "๐Ÿ” ansible-flavor: probe Synapse client API on loopback (cold MDAD ~10-15min)" uri_retry: url: "http://127.0.0.1:{{ MATRIX_SYNAPSE_PORT }}/_matrix/client/versions" status_code: 200 @@ -10,7 +10,7 @@ until: matrix_synapse_loopback_probe.status == 200 ignore_errors: true -- name: "ansible-flavor: diagnostics โ€” matrix-mdad container + systemd + bootstrap status (on probe failure)" +- name: "๐Ÿ› ansible-flavor: matrix-mdad container/systemd/bootstrap status on failure" ansible.builtin.script: cmd: "{{ role_path }}/files/flavor/ansible/diagnostics.sh" register: matrix_mdad_diagnostics @@ -20,19 +20,19 @@ - matrix_synapse_loopback_probe is failed - MODE_DEBUG | bool -- name: "ansible-flavor: dump matrix-mdad diagnostics" +- name: "๐Ÿ’พ ansible-flavor: dump matrix-mdad diagnostics" ansible.builtin.debug: var: matrix_mdad_diagnostics when: - matrix_synapse_loopback_probe is failed - MODE_DEBUG | bool -- name: "ansible-flavor: fail after diagnostics if probe never succeeded" +- name: "๐Ÿ›‘ ansible-flavor: fail after diagnostics if probe never succeeded" ansible.builtin.fail: msg: "Synapse loopback probe never reached 200 โ€” see matrix_mdad_diagnostics above." when: matrix_synapse_loopback_probe is failed -- name: "ansible-flavor: probe Element web client on host loopback" +- name: "๐Ÿ” ansible-flavor: probe Element web client on host loopback" uri_retry: url: "http://127.0.0.1:{{ MATRIX_ELEMENT_PORT }}/" status_code: 200 @@ -42,7 +42,7 @@ delay: 2 until: matrix_element_loopback_probe.status == 200 -- name: "ansible-flavor: create native admin in Synapse (DiD, idempotent via shared-secret)" +- name: "๐Ÿ“ ansible-flavor: create native Synapse admin (DiD, idempotent shared-secret)" when: IS_STACK_HOST | bool ansible.builtin.shell: cmd: >- # nocheck: raw-docker, container-exec-resolver inner docker CLI talks to the DiD daemon inside matrix-mdad; no host docker involved @@ -55,14 +55,14 @@ failed_when: matrix_admin_create.rc != 0 and 'User ID already taken' not in (matrix_admin_create.stdout + matrix_admin_create.stderr) no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "front-proxy: Element web client" +- name: "๐Ÿ”€ front-proxy: Element web client" ansible.builtin.include_role: name: sys-stk-front-proxy vars: domain: "{{ MATRIX_ELEMENT_DOMAIN }}" http_port: "{{ MATRIX_ELEMENT_PORT }}" -- name: "front-proxy: Synapse client/federation" +- name: "๐Ÿ”€ front-proxy: Synapse client/federation" ansible.builtin.include_role: name: sys-stk-front-proxy vars: diff --git a/roles/web-app-matrix/tasks/flavor/ansible/main.yml b/roles/web-app-matrix/tasks/flavor/ansible/main.yml index 560b70f66e..b7af924a13 100644 --- a/roles/web-app-matrix/tasks/flavor/ansible/main.yml +++ b/roles/web-app-matrix/tasks/flavor/ansible/main.yml @@ -1,15 +1,15 @@ --- -- name: "ansible-flavor: clone matrix-docker-ansible-deploy upstream" +- name: "โฌ‡๏ธ ansible-flavor: clone matrix-docker-ansible-deploy upstream" include_tasks: 01_clone_upstream.yml -- name: "ansible-flavor: render MDAD inventory" +- name: "๐Ÿ“„ ansible-flavor: render MDAD inventory" include_tasks: 02_render_inventory.yml -- name: "ansible-flavor: provision Matrix database on central postgres" +- name: "๐Ÿ”ง ansible-flavor: provision Matrix database on central postgres" include_tasks: 03_database.yml -- name: "ansible-flavor: launch matrix-mdad DiD container" +- name: "๐Ÿš€ ansible-flavor: launch matrix-mdad DiD container" include_tasks: 04_run_playbook.yml -- name: "ansible-flavor: wire sys-svc-proxy to matrix-mdad loopback ports" +- name: "๐Ÿ”Œ ansible-flavor: wire sys-svc-proxy to matrix-mdad loopback ports" include_tasks: 05_proxy_wiring.yml diff --git a/roles/web-app-matrix/tasks/flavor/compose/01_docker.yml b/roles/web-app-matrix/tasks/flavor/compose/01_docker.yml index abf6129910..90b8cb132c 100644 --- a/roles/web-app-matrix/tasks/flavor/compose/01_docker.yml +++ b/roles/web-app-matrix/tasks/flavor/compose/01_docker.yml @@ -1,12 +1,12 @@ --- # include-gated: when: DEPLOYMENT_MODE == "compose" -- name: "load docker and db for {{ application_id }}" +- name: "๐Ÿงฉ load docker and db for {{ application_id }}" include_role: name: sys-stk-backend vars: compose_handlers_flush: false -- name: include 02_create-and-seed-database.yml for multiple bridges +- name: ๐Ÿ“‚ include 02_create-and-seed-database.yml for multiple bridges include_tasks: 02_create-and-seed-database.yml vars: database_password: "{{ item.database_password }}" @@ -14,38 +14,38 @@ database_name: "{{ item.database_name }}" loop: "{{ MATRIX_BRIDGES }}" -- name: shut down compose project +- name: ๐Ÿณ shut down compose project command: cmd: "{{ BIN_COMPOSE }} down" chdir: "{{ lookup('container', application_id, 'directories.instance') }}" when: DEPLOYMENT_MODE == 'compose' -- name: "cleanup project folder" +- name: "๐Ÿงน cleanup project folder" file: path: "{{ lookup('container', application_id, 'directories.instance') }}mautrix/" state: absent -- name: "create bridge folders" +- name: "๐Ÿ“ create bridge folders" file: path: "{{ lookup('container', application_id, 'directories.instance') }}mautrix/{{ item.bridge_name }}" state: directory mode: "0755" loop: "{{ MATRIX_BRIDGES }}" -- name: add multiple mautrix bridge configuration +- name: โž• add multiple mautrix bridge configuration stack_host_template: src: "flavor/compose/mautrix/{{ item.bridge_name }}.config.yml.j2" dest: "{{ lookup('container', application_id, 'directories.instance') }}mautrix/{{ item.bridge_name }}/config.yaml" loop: "{{ MATRIX_BRIDGES }}" notify: compose up -- name: add element configuration +- name: โž• add element configuration stack_host_template: src: "flavor/compose/element.config.json.j2" dest: "{{ MATRIX_ELEMENT_CONFIG_PATH_HOST }}" notify: compose up -- name: "Render Synapse config files (local + swarm peers)" +- name: "๐Ÿ“„ Render Synapse config files (local + swarm peers)" ansible.builtin.include_tasks: file: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/render_replicated_templates.yml'] | path_join }}" vars: @@ -57,29 +57,29 @@ dest: "{{ MATRIX_SYNAPSE_LOG_PATH_HOST }}" mode: "{{ MATRIX_SYNAPSE_BIND_MOUNT_MODE }}" -- name: set correct folder permissions +- name: ๐Ÿ”ง set correct folder permissions command: cmd: "container run --rm --mount type=volume,src={{ MATRIX_SYNAPSE_VOLUME }},dst=/data -e SYNAPSE_SERVER_NAME={{ MATRIX_SYNAPSE_DOMAIN }} -e SYNAPSE_REPORT_STATS=no --entrypoint /bin/sh matrixdotorg/synapse:latest -c 'chown -vR 991:991 /data'" -- name: add compose.yml +- name: โž• add compose.yml stack_host_template: src: "compose.yml.j2" dest: "{{ [ lookup('container', application_id, 'directories.instance'),'compose.yml' ] | path_join }}" notify: compose up -- name: "compose-mode lifecycle (pull + up)" +- name: "๐Ÿณ compose-mode lifecycle (pull + up)" include_tasks: 03_compose_pull_and_up.yml when: DEPLOYMENT_MODE == 'compose' -- name: wait for registration files +- name: โณ wait for registration files wait_for: path: "{{ lookup('container', application_id, 'directories.instance') }}mautrix/{{ item.bridge_name }}/registration.yaml" state: present timeout: 120 loop: "{{ MATRIX_BRIDGES }}" -- name: "change file permissions" +- name: "๐Ÿ” change file permissions" file: path: "{{ lookup('container', application_id, 'directories.instance') }}mautrix/{{ item.bridge_name }}/registration.yaml" mode: "0755" @@ -87,14 +87,14 @@ async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}" poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}" -- name: "Restart synapse so it loads the freshly generated bridge appservice registrations" +- name: "๐Ÿ”„ Restart synapse to load freshly generated bridge appservice registrations" command: cmd: "{{ BIN_COMPOSE }} restart synapse" chdir: "{{ lookup('container', application_id, 'directories.instance') }}" changed_when: true when: MATRIX_BRIDGES | length > 0 -- name: wait for Synapse client/versions endpoint +- name: โณ wait for Synapse client/versions endpoint uri_retry: url: "http://127.0.0.1:{{ lookup('config', application_id, 'services.synapse.ports.local.http') }}/_matrix/client/versions" method: GET @@ -104,7 +104,7 @@ delay: 2 until: matrix_synapse_health.status == 200 -- name: create admin account +- name: ๐Ÿ“ create admin account shell: >- container exec -i {{ MATRIX_SYNAPSE_CONTAINER_ADDRESS | quote }} register_new_matrix_user @@ -120,7 +120,7 @@ no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" when: IS_STACK_HOST | bool -- name: create chatgpt bot +- name: ๐Ÿ“ create chatgpt bot shell: >- container exec -i {{ MATRIX_SYNAPSE_CONTAINER_ADDRESS | quote }} register_new_matrix_user @@ -136,5 +136,5 @@ no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" when: IS_STACK_HOST | bool -- name: Flush all handlers after docker setup so that they don't intervine with openresty +- name: "๐Ÿ”„ Flush all handlers after docker setup so they don't intervine with openresty" meta: flush_handlers diff --git a/roles/web-app-matrix/tasks/flavor/compose/02_create-and-seed-database.yml b/roles/web-app-matrix/tasks/flavor/compose/02_create-and-seed-database.yml index a91081549d..06f87d3694 100644 --- a/roles/web-app-matrix/tasks/flavor/compose/02_create-and-seed-database.yml +++ b/roles/web-app-matrix/tasks/flavor/compose/02_create-and-seed-database.yml @@ -5,13 +5,13 @@ # - database_username # - database_password -- name: "Freeze database consumer id + provider role before provider include" +- name: "๐ŸงŠ Freeze database consumer id + provider role before provider include" ansible.builtin.set_fact: _matrix_db_consumer_id: "{{ application_id }}" _matrix_db_provider_role: "{{ lookup('database', application_id, 'id') }}" changed_when: false -- name: "Create DB/user for '{{ database_name }}' in central DB" +- name: "๐Ÿ“ Create DB/user for '{{ database_name }}' in central DB" include_role: name: "{{ _matrix_db_provider_role }}" public: false @@ -22,7 +22,7 @@ database_type: "{{ lookup('database', _matrix_db_consumer_id, 'type') }}" when: lookup('database', _matrix_db_consumer_id, 'shared') | bool -- name: "Seed database entry to backup routine" +- name: "๐ŸŒฑ Seed database entry to backup routine" include_tasks: "{{ playbook_dir }}/roles/svc-bkp-container-2-local/tasks/04_seed-database-to-backup.yml" vars: database_consumer_id: "{{ _matrix_db_consumer_id }}" diff --git a/roles/web-app-matrix/tasks/flavor/compose/03_compose_pull_and_up.yml b/roles/web-app-matrix/tasks/flavor/compose/03_compose_pull_and_up.yml index 973daeefc2..2f3e0f4d3c 100644 --- a/roles/web-app-matrix/tasks/flavor/compose/03_compose_pull_and_up.yml +++ b/roles/web-app-matrix/tasks/flavor/compose/03_compose_pull_and_up.yml @@ -1,11 +1,11 @@ --- # include-gated: when: DEPLOYMENT_MODE == "compose" -- name: compose pull +- name: ๐Ÿณ compose pull command: cmd: "compose pull" chdir: "{{ lookup('container', application_id, 'directories.instance') }}" -- name: compose up +- name: ๐Ÿณ compose up command: cmd: "compose up -d --remove-orphans" chdir: "{{ lookup('container', application_id, 'directories.instance') }}" diff --git a/roles/web-app-matrix/tasks/flavor/compose/03_webserver.yml b/roles/web-app-matrix/tasks/flavor/compose/03_webserver.yml index 24d98c2731..1434775762 100644 --- a/roles/web-app-matrix/tasks/flavor/compose/03_webserver.yml +++ b/roles/web-app-matrix/tasks/flavor/compose/03_webserver.yml @@ -1,31 +1,31 @@ --- # include-gated: when: DEPLOYMENT_MODE == "compose" -- name: create {{ MATRIX_WELL_KNOWN_DIRECTORY }} +- name: ๐Ÿ“ create {{ MATRIX_WELL_KNOWN_DIRECTORY }} ansible.builtin.file: path: "{{ MATRIX_WELL_KNOWN_DIRECTORY }}" state: directory mode: "0755" -- name: create {{ MATRIX_WELL_KNOWN_FILE }} +- name: ๐Ÿ“ create {{ MATRIX_WELL_KNOWN_FILE }} stack_host_template: src: "flavor/compose/well-known.j2" dest: "{{ MATRIX_WELL_KNOWN_FILE }}" -- name: "include role sys-stk-front-proxy for {{ MATRIX_ELEMENT_DOMAIN }}" +- name: "๐Ÿ“‚ include role sys-stk-front-proxy for {{ MATRIX_ELEMENT_DOMAIN }}" ansible.builtin.include_role: name: sys-stk-front-proxy vars: domain: "{{ MATRIX_ELEMENT_DOMAIN }}" http_port: "{{ MATRIX_ELEMENT_PORT }}" -- name: "include role sys-stk-front-proxy for {{ MATRIX_SYNAPSE_DOMAIN }}" +- name: "๐Ÿ“‚ include role sys-stk-front-proxy for {{ MATRIX_SYNAPSE_DOMAIN }}" ansible.builtin.include_role: name: sys-stk-front-proxy vars: domain: "{{ MATRIX_SYNAPSE_DOMAIN }}" http_port: "{{ MATRIX_SYNAPSE_PORT }}" -- name: create {{ MATRIX_SYNAPSE_DOMAIN }}.conf +- name: ๐Ÿ“ create {{ MATRIX_SYNAPSE_DOMAIN }}.conf stack_host_template: src: "flavor/compose/synapse.conf.j2" dest: "{{ lookup('nginx', 'files.domain', MATRIX_SYNAPSE_DOMAIN) }}" diff --git a/roles/web-app-matrix/tasks/flavor/compose/main.yml b/roles/web-app-matrix/tasks/flavor/compose/main.yml index f337824803..7734e3163c 100644 --- a/roles/web-app-matrix/tasks/flavor/compose/main.yml +++ b/roles/web-app-matrix/tasks/flavor/compose/main.yml @@ -1,6 +1,6 @@ --- # include-gated: when: DEPLOYMENT_MODE == "compose" -- name: Build enabled bridge list from meta/addons/ +- name: ๐Ÿ”จ Build enabled bridge list from meta/addons/ set_fact: MATRIX_BRIDGES: >- {{ lookup('config', application_id, 'addons') @@ -11,7 +11,7 @@ | list }} changed_when: false -- name: "Drop the telegram bridge when its Telegram API credentials are absent (api_hash is required at startup)" +- name: "๐Ÿงน Drop telegram bridge when Telegram API credentials absent (api_hash needed)" set_fact: MATRIX_BRIDGES: "{{ MATRIX_BRIDGES | rejectattr('bridge_name', 'equalto', 'telegram') | list }}" when: >- @@ -19,8 +19,8 @@ or (lookup('config', application_id, 'credentials.mautrix_telgegram_bridge_api_pin', '') | default('', true) | string | trim | length == 0) changed_when: false -- name: "compose-flavor: docker stack for '{{ application_id }}'" +- name: "๐Ÿณ compose-flavor: docker stack for '{{ application_id }}'" include_tasks: 01_docker.yml -- name: "compose-flavor: webserver for '{{ application_id }}'" +- name: "๐Ÿณ compose-flavor: webserver for '{{ application_id }}'" include_tasks: 03_webserver.yml diff --git a/roles/web-app-matrix/tasks/main.yml b/roles/web-app-matrix/tasks/main.yml index 224fe4af29..4437b02c26 100644 --- a/roles/web-app-matrix/tasks/main.yml +++ b/roles/web-app-matrix/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "Execute Role (once)" +- name: "โ–ถ๏ธ Execute Role (once)" include_tasks: 01_core.yml when: run_once_web_app_matrix is not defined vars: diff --git a/roles/web-app-mattermost/tasks/01_core.yml b/roles/web-app-mattermost/tasks/01_core.yml index 195959a544..744e22a5c9 100644 --- a/roles/web-app-mattermost/tasks/01_core.yml +++ b/roles/web-app-mattermost/tasks/01_core.yml @@ -1,24 +1,24 @@ --- - include_tasks: utils/once/flag.yml -- name: "Remove stale nginx config for renamed domain chat.{{ DOMAIN_PRIMARY }}" # nocheck: domain-spot +- name: "๐Ÿ—‘๏ธ Remove stale nginx config for renamed domain chat.{{ DOMAIN_PRIMARY }}" # nocheck: domain-spot ansible.builtin.file: path: "{{ [lookup('nginx', 'directories.configuration.servers'), 'https', 'chat.' ~ DOMAIN_PRIMARY ~ '.conf'] | path_join }}" state: absent notify: restart openresty -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: compose_handlers_flush: true -- name: "Mattermost stack-host post-deploy" +- name: "๐Ÿ–ฅ๏ธ Mattermost stack-host post-deploy" when: IS_STACK_HOST | bool block: - - name: "Run Mattermost setup routines" + - name: "โ–ถ๏ธ Run Mattermost setup routines" include_tasks: 01_setup.yml - - name: "Configure Keycloak OIDC mappers for Mattermost" + - name: "๐Ÿ”ง Configure Keycloak OIDC mappers for Mattermost" include_tasks: 02_keycloak.yml when: MATTERMOST_OIDC_ENABLED | bool diff --git a/roles/web-app-mattermost/tasks/01_setup.yml b/roles/web-app-mattermost/tasks/01_setup.yml index cc0afacbf3..bcb4c0a264 100644 --- a/roles/web-app-mattermost/tasks/01_setup.yml +++ b/roles/web-app-mattermost/tasks/01_setup.yml @@ -1,5 +1,5 @@ --- -- name: "Mattermost | Wait until mmctl local mode is ready" +- name: "โณ Mattermost | Wait until mmctl local mode is ready" shell: | container exec -i {{ MATTERMOST_CONTAINER_ADDRESS }} \ /mattermost/bin/mmctl --local system status @@ -10,7 +10,7 @@ changed_when: false failed_when: mm_ready_wait.rc != 0 and mm_ready_wait.attempts == 61 -- name: "Mattermost | Create system administrator user" +- name: "๐Ÿ“ Mattermost | Create system administrator user" shell: | container exec -i {{ MATTERMOST_CONTAINER_ADDRESS }} \ /mattermost/bin/mmctl --local user create \ @@ -22,7 +22,7 @@ changed_when: mm_create_admin.rc == 0 failed_when: mm_create_admin.rc != 0 and 'already exists' not in (mm_create_admin.stdout + mm_create_admin.stderr) -- name: "Mattermost | Create default team" +- name: "๐Ÿ“ Mattermost | Create default team" shell: | container exec -i {{ MATTERMOST_CONTAINER_ADDRESS }} \ /mattermost/bin/mmctl --local team create \ @@ -33,21 +33,21 @@ failed_when: mm_create_team.rc != 0 and 'already exists' not in (mm_create_team.stdout + mm_create_team.stderr) and 'existing team' not in (mm_create_team.stdout + mm_create_team.stderr) -- name: "Mattermost | Enable open invite on default team" +- name: "๐ŸŸข Mattermost | Enable open invite on default team" database_query: config: "{{ lookup('database', application_id) }}" query_file: "{{ role_path }}/files/sql/update-default-team-open-invite.sql" mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" changed_when: false -- name: "Mattermost | Check which users are already in default team" +- name: "๐Ÿ”Ž Mattermost | Check which users are already in default team" shell: | container exec -i {{ MATTERMOST_CONTAINER_ADDRESS }} \ /mattermost/bin/mmctl --local user list --team main register: mm_team_members changed_when: false -- name: "Mattermost | Add administrator to default team" +- name: "โž• Mattermost | Add administrator to default team" shell: | container exec -i {{ MATTERMOST_CONTAINER_ADDRESS }} \ /mattermost/bin/mmctl --local team users add \ @@ -55,7 +55,7 @@ "{{ lookup('users', 'administrator').email }}" when: lookup('users', 'administrator').email not in mm_team_members.stdout -- name: "Mattermost | Check administrator auth service" +- name: "๐Ÿ”Ž Mattermost | Check administrator auth service" database_query: config: "{{ lookup('database', application_id) }}" query_file: "{{ role_path }}/files/sql/select-user-authservice.sql" @@ -67,7 +67,7 @@ changed_when: false when: MATTERMOST_OIDC_ENABLED | bool -- name: "Mattermost | Get administrator uidNumber from LDAP" +- name: "๐Ÿ—‚๏ธ Mattermost | Get administrator uidNumber from LDAP" shell: | container exec -i {{ MATTERMOST_LDAP_CONTAINER_ADDRESS }} \ ldapsearch -x -H ldap://localhost:389 \ @@ -83,7 +83,7 @@ - MATTERMOST_OIDC_ENABLED | bool - (mm_admin_authservice.rows[0][0] | default('') | trim) != 'gitlab' -- name: "Mattermost | Convert administrator to gitlab SSO auth" +- name: "๐Ÿ”„ Mattermost | Convert administrator to gitlab SSO auth" database_query: config: "{{ lookup('database', application_id) }}" query_file: "{{ role_path }}/files/sql/update-user-to-gitlab-auth.sql" diff --git a/roles/web-app-mattermost/tasks/02_keycloak.yml b/roles/web-app-mattermost/tasks/02_keycloak.yml index 64934b240a..3a93e77573 100644 --- a/roles/web-app-mattermost/tasks/02_keycloak.yml +++ b/roles/web-app-mattermost/tasks/02_keycloak.yml @@ -1,7 +1,7 @@ --- # @see https://docs.mattermost.com/deployment/sso-gitlab.html -- name: "Mattermost | Keycloak โ€” authenticate kcadm.sh" +- name: "๐Ÿ”‘ Mattermost | Keycloak โ€” authenticate kcadm.sh" shell: >- container exec -i {{ MATTERMOST_KEYCLOAK_CONTAINER_ADDRESS }} /opt/keycloak/bin/kcadm.sh config credentials @@ -13,7 +13,7 @@ chdir: "{{ lookup('container', 'web-app-keycloak', 'directories.instance') }}" changed_when: false -- name: "Mattermost | Keycloak โ€” resolve Mattermost client UUID" +- name: "๐Ÿ” Mattermost | Keycloak โ€” resolve Mattermost client UUID" shell: >- container exec -i {{ MATTERMOST_KEYCLOAK_CONTAINER_ADDRESS }} /opt/keycloak/bin/kcadm.sh get clients @@ -26,7 +26,7 @@ changed_when: false failed_when: mm_kc_client_uuid.stdout_lines | last | trim == '' -- name: "Mattermost | Keycloak โ€” list existing protocol mappers" +- name: "๐Ÿ“‹ Mattermost | Keycloak โ€” list existing protocol mappers" shell: >- container exec -i {{ MATTERMOST_KEYCLOAK_CONTAINER_ADDRESS }} /opt/keycloak/bin/kcadm.sh get @@ -38,7 +38,7 @@ register: mm_kc_existing_mappers changed_when: false -- name: "Mattermost | Keycloak โ€” list all client scopes" +- name: "๐Ÿ“‹ Mattermost | Keycloak โ€” list all client scopes" shell: >- container exec -i {{ MATTERMOST_KEYCLOAK_CONTAINER_ADDRESS }} /opt/keycloak/bin/kcadm.sh get client-scopes @@ -49,7 +49,7 @@ register: mm_kc_all_scopes changed_when: false -- name: "Mattermost | Keycloak โ€” create 'openid' client scope if missing" +- name: "๐Ÿ“ Mattermost | Keycloak โ€” create 'openid' client scope if missing" shell: >- container exec -i {{ MATTERMOST_KEYCLOAK_CONTAINER_ADDRESS }} /opt/keycloak/bin/kcadm.sh create client-scopes @@ -61,7 +61,7 @@ when: "mm_kc_all_scopes.stdout_lines | select('search', ',openid$') | list | length == 0" register: mm_kc_create_openid_scope -- name: "Mattermost | Keycloak โ€” re-read client scopes after possible creation" +- name: "๐Ÿ“– Mattermost | Keycloak โ€” re-read client scopes after possible creation" shell: >- container exec -i {{ MATTERMOST_KEYCLOAK_CONTAINER_ADDRESS }} /opt/keycloak/bin/kcadm.sh get client-scopes @@ -73,7 +73,7 @@ changed_when: false when: mm_kc_create_openid_scope is changed -- name: "Mattermost | Keycloak โ€” list existing default client scopes" +- name: "๐Ÿ“‹ Mattermost | Keycloak โ€” list existing default client scopes" shell: >- container exec -i {{ MATTERMOST_KEYCLOAK_CONTAINER_ADDRESS }} /opt/keycloak/bin/kcadm.sh get @@ -85,7 +85,7 @@ register: mm_kc_default_scopes changed_when: false -- name: "Mattermost | Keycloak โ€” add 'openid' to client default scopes" +- name: "โž• Mattermost | Keycloak โ€” add 'openid' to client default scopes" shell: >- container exec -i {{ MATTERMOST_KEYCLOAK_CONTAINER_ADDRESS }} /opt/keycloak/bin/kcadm.sh update @@ -96,7 +96,7 @@ chdir: "{{ lookup('container', 'web-app-keycloak', 'directories.instance') }}" when: "'openid' not in mm_kc_default_scopes.stdout" -- name: "Mattermost | Keycloak โ€” add 'id' mapper (integer from LDAP uidNumber)" +- name: "โž• Mattermost | Keycloak โ€” add 'id' mapper (integer from LDAP uidNumber)" shell: >- container exec -i {{ MATTERMOST_KEYCLOAK_CONTAINER_ADDRESS }} /opt/keycloak/bin/kcadm.sh create @@ -115,7 +115,7 @@ chdir: "{{ lookup('container', 'web-app-keycloak', 'directories.instance') }}" when: "'mattermost-id' not in mm_kc_existing_mappers.stdout" -- name: "Mattermost | Keycloak โ€” add 'username' mapper (from Keycloak username)" +- name: "โž• Mattermost | Keycloak โ€” add 'username' mapper (from Keycloak username)" shell: >- container exec -i {{ MATTERMOST_KEYCLOAK_CONTAINER_ADDRESS }} /opt/keycloak/bin/kcadm.sh create diff --git a/roles/web-app-mattermost/tasks/main.yml b/roles/web-app-mattermost/tasks/main.yml index 7a09e6789e..63a57769bf 100644 --- a/roles/web-app-mattermost/tasks/main.yml +++ b/roles/web-app-mattermost/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "Execute Role (once)" +- name: "โ–ถ๏ธ Execute Role (once)" include_tasks: 01_core.yml when: run_once_web_app_mattermost is not defined vars: diff --git a/roles/web-app-mediawiki/tasks/01_configuration.yml b/roles/web-app-mediawiki/tasks/01_configuration.yml index c6d54e55b5..e9ea618155 100644 --- a/roles/web-app-mediawiki/tasks/01_configuration.yml +++ b/roles/web-app-mediawiki/tasks/01_configuration.yml @@ -1,5 +1,5 @@ --- -- name: "MEDIAWIKI | Ensure required host directories exist" +- name: "โœ… MEDIAWIKI | Ensure required host directories exist" ansible.builtin.file: path: "{{ item }}" state: directory @@ -8,7 +8,7 @@ - "{{ MEDIAWIKI_LOCAL_MOUNT_DIR }}" - "{{ MEDIAWIKI_CONFIG_DIR }}" -- name: "MEDIAWIKI | Render host-side PHP config files" +- name: "๐Ÿ“„ MEDIAWIKI | Render host-side PHP config files" ansible.builtin.include_tasks: file: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/render_replicated_templates.yml'] | path_join }}" vars: diff --git a/roles/web-app-mediawiki/tasks/02_extensions.yml b/roles/web-app-mediawiki/tasks/02_extensions.yml index e49cd913e0..34e02b3bcc 100644 --- a/roles/web-app-mediawiki/tasks/02_extensions.yml +++ b/roles/web-app-mediawiki/tasks/02_extensions.yml @@ -2,13 +2,13 @@ # Install PluggableAuth + OpenIDConnect INTO the running container (idempotent) # Downloads on host (config dir), copy+extract inside container. -- name: "EXT | Ensure local download dir exists" +- name: "โœ… EXT | Ensure local download dir exists" file: path: "{{ MEDIAWIKI_EXT_CFG_BASE }}" state: directory mode: "0755" -- name: "EXT | Download extension tarballs ({{ MEDIAWIKI_EXT_BRANCH }})" +- name: "โฌ‡๏ธ EXT | Download extension tarballs ({{ MEDIAWIKI_EXT_BRANCH }})" get_url_retry: url: "{{ ext.url }}" dest: "{{ MEDIAWIKI_EXT_CFG_BASE }}/{{ ext.name }}.tar.gz" @@ -18,7 +18,7 @@ loop_var: ext label: "{{ ext.name }}" -- name: "EXT | Copy & extract into container if not installed" +- name: "๐Ÿ“‹ EXT | Copy & extract into container if not installed" script: install_extension.sh environment: EXT_NAME: "{{ ext.name }}" @@ -39,7 +39,7 @@ # Install dependencies per extension (only if vendor is missing) # Use /tmp/composer for HOME/CACHE to avoid /var/www permission issues. -- name: "EXT | composer install in each extension when needed" +- name: "๐Ÿ“ฆ EXT | composer install in each extension when needed" script: >- composer_install_extension.sh "{{ MEDIAWIKI_USER }}" "{{ MEDIAWIKI_HTML_DIR }}" @@ -58,7 +58,7 @@ changed_when: "'COMPOSER_INSTALLED:' in _vendor.stdout" # Sanity check: Jumbojett OIDC client must be loadable -- name: "EXT | Sanity check: Jumbojett OpenIDConnect client present" +- name: "โœ… EXT | Sanity check: Jumbojett OpenIDConnect client present" shell: > container exec {{ MEDIAWIKI_CONTAINER_ADDRESS }} bash -lc 'php -r "(@require \"{{ MEDIAWIKI_HTML_DIR }}/vendor/autoload.php\"); @require \"{{ MEDIAWIKI_HTML_DIR }}/extensions/OpenIDConnect/vendor/autoload.php\"; exit(class_exists(\"Jumbojett\\\\OpenIDConnectClient\")?0:1);"' diff --git a/roles/web-app-mediawiki/tasks/03_install.yml b/roles/web-app-mediawiki/tasks/03_install.yml index 8d569638c6..41c4ecf75b 100644 --- a/roles/web-app-mediawiki/tasks/03_install.yml +++ b/roles/web-app-mediawiki/tasks/03_install.yml @@ -1,5 +1,5 @@ --- -- name: "MEDIAWIKI | Bootstrap DB (install if empty) then update" +- name: "๐Ÿฅพ MEDIAWIKI | Bootstrap DB (install if empty) then update" ansible.builtin.script: >- install_or_update.sh "{{ MEDIAWIKI_NETWORK_DATABASE }}" "{{ lookup('database', application_id, 'version') | default('latest') }}" diff --git a/roles/web-app-mediawiki/tasks/04_admin.yml b/roles/web-app-mediawiki/tasks/04_admin.yml index 96090c9153..af84dc64d1 100644 --- a/roles/web-app-mediawiki/tasks/04_admin.yml +++ b/roles/web-app-mediawiki/tasks/04_admin.yml @@ -1,5 +1,5 @@ --- -- name: "Create / promote MediaWiki admin user (one-shot)" +- name: "๐Ÿ“ Create / promote MediaWiki admin user (one-shot)" ansible.builtin.command: >- container run --rm --network {{ MEDIAWIKI_NETWORK_DATABASE }} diff --git a/roles/web-app-mediawiki/tasks/main.yml b/roles/web-app-mediawiki/tasks/main.yml index a61dc19a28..371bd8a721 100644 --- a/roles/web-app-mediawiki/tasks/main.yml +++ b/roles/web-app-mediawiki/tasks/main.yml @@ -1,23 +1,23 @@ --- -- name: "load docker, db and proxy for '{{ application_id }}'" +- name: "๐Ÿงฉ load docker, db and proxy for '{{ application_id }}'" include_role: name: sys-stk-full vars: compose_handlers_flush: false -- name: "Load install procedures for '{{ application_id }}'" +- name: "๐Ÿ“‚ Load install procedures for '{{ application_id }}'" include_tasks: 01_configuration.yml -- name: "Finalize compose deploy for '{{ application_id }}'" +- name: "๐Ÿณ Finalize compose deploy for '{{ application_id }}'" include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/finalize.yml'] | path_join }}" -- name: "Load extensions procedures for '{{ application_id }}'" +- name: "๐Ÿ“‚ Load extensions procedures for '{{ application_id }}'" include_tasks: "02_extensions.yml" when: - MEDIAWIKI_OIDC_ENABLED | bool - IS_STACK_HOST | bool -- name: "Load update procedures for '{{ application_id }}'" +- name: "๐Ÿ“‚ Load update procedures for '{{ application_id }}'" include_tasks: 03_install.yml when: >- {{ @@ -27,5 +27,5 @@ (_vendor.changed | default(false)) }} -- name: "Load admin setup procedures for '{{ application_id }}'" +- name: "๐Ÿ“‚ Load admin setup procedures for '{{ application_id }}'" include_tasks: 04_admin.yml diff --git a/roles/web-app-mig/tasks/01_core.yml b/roles/web-app-mig/tasks/01_core.yml index d448a7eb33..b1c0455982 100644 --- a/roles/web-app-mig/tasks/01_core.yml +++ b/roles/web-app-mig/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: "load docker, proxy for '{{ application_id }}'" +- name: "๐Ÿงฉ load docker, proxy for '{{ application_id }}'" include_role: name: sys-stk-full vars: diff --git a/roles/web-app-mini-qr/tasks/01_core.yml b/roles/web-app-mini-qr/tasks/01_core.yml index bc4505a37c..def0255ed8 100644 --- a/roles/web-app-mini-qr/tasks/01_core.yml +++ b/roles/web-app-mini-qr/tasks/01_core.yml @@ -1,5 +1,5 @@ --- -- name: "load docker, proxy for '{{ application_id }}'" +- name: "๐Ÿงฉ load docker, proxy for '{{ application_id }}'" include_role: name: sys-stk-full vars: diff --git a/roles/web-app-minio/tasks/01_core.yml b/roles/web-app-minio/tasks/01_core.yml index 86fe2f045e..98e7e38438 100644 --- a/roles/web-app-minio/tasks/01_core.yml +++ b/roles/web-app-minio/tasks/01_core.yml @@ -1,22 +1,22 @@ --- - include_tasks: utils/once/flag.yml -- name: "load docker and db for {{ application_id }}" +- name: "๐Ÿงฉ load docker and db for {{ application_id }}" include_role: name: sys-stk-backend vars: compose_handlers_flush: false compose_repository_pull: false -- name: "Create shared object-store network for '{{ application_id }}'" +- name: "๐Ÿ“ Create shared object-store network for '{{ application_id }}'" include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/network/create.yml'] | path_join }}" vars: network_role_id: "{{ application_id }}" -- name: "Start the MinIO stack" +- name: "โ–ถ๏ธ Start the MinIO stack" ansible.builtin.meta: flush_handlers -- name: "Include role sys-stk-front-proxy for '{{ application_id }}'" +- name: "๐Ÿ“‚ Include role sys-stk-front-proxy for '{{ application_id }}'" include_role: name: sys-stk-front-proxy vars: @@ -27,14 +27,14 @@ loop_var: minio_proxy label: "{{ minio_proxy.domain }} -> {{ minio_proxy.http_port }}" -- name: "Configure MinIO OIDC (Keycloak as named IdP + policy)" +- name: "๐Ÿ”ง Configure MinIO OIDC (Keycloak as named IdP + policy)" ansible.builtin.include_tasks: file: 02_oidc.yml apply: no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" when: MINIO_OIDC_ENABLED | bool -- name: "Bind the MinIO administrator policy to the LDAP group (LDAP variant)" +- name: "๐Ÿ”— Bind the MinIO administrator policy to the LDAP group (LDAP variant)" ansible.builtin.include_tasks: file: 03_ldap.yml apply: diff --git a/roles/web-app-minio/tasks/02_oidc.yml b/roles/web-app-minio/tasks/02_oidc.yml index 905a6913ec..1a1edac3ad 100644 --- a/roles/web-app-minio/tasks/02_oidc.yml +++ b/roles/web-app-minio/tasks/02_oidc.yml @@ -14,7 +14,7 @@ # `mc admin info` returns rc=0 in a window where the very next # `mc admin policy info` still fails with `Server not initialized # yet, please try again.`. -- name: "Wait for MinIO IAM subsystem to finish initializing" +- name: "โณ Wait for MinIO IAM subsystem to finish initializing" environment: MINIO_ROOT_USER: "{{ lookup('users', 'administrator').username }}" MINIO_ROOT_PASSWORD: "{{ lookup('users', 'administrator').password }}" @@ -41,7 +41,7 @@ # legacy `MINIO_IDENTITY_OPENID_*` env-var form registers the # provider as nameless `(default)` and the SSO button never # appears, even when the server-side IdP is fully functional. -- name: "Register Keycloak as named OIDC IdP on MinIO" +- name: "๐Ÿ“ Register Keycloak as named OIDC IdP on MinIO" # All `mc idp openid add` parameters are passed to the inner sh # via env vars rather than inline-quoted args. The display name # contains parentheses (e.g. `SSO Login (INFINITO.EXAMPLE)`) and @@ -85,7 +85,7 @@ - mc_idp_add.rc != 0 - '"already exists" not in (mc_idp_add.stderr | default(""))' -- name: "Restart MinIO so the named OIDC IdP is picked up by the Console" +- name: "๐Ÿ”„ Restart MinIO so the named OIDC IdP is picked up by the Console" environment: MINIO_ROOT_USER: "{{ lookup('users', 'administrator').username }}" MINIO_ROOT_PASSWORD: "{{ lookup('users', 'administrator').password }}" @@ -103,7 +103,7 @@ changed_when: mc_admin_service_restart.rc == 0 when: mc_idp_add.changed | bool -- name: "Wait for MinIO IAM subsystem to come back after restart" +- name: "โณ Wait for MinIO IAM subsystem to come back after restart" environment: MINIO_ROOT_USER: "{{ lookup('users', 'administrator').username }}" MINIO_ROOT_PASSWORD: "{{ lookup('users', 'administrator').password }}" @@ -124,7 +124,7 @@ changed_when: false when: mc_idp_add.changed | bool -- name: "Check policy (RAW with slash) exists" +- name: "๐Ÿ”Ž Check policy (RAW with slash) exists" environment: MINIO_ROOT_USER: "{{ lookup('users', 'administrator').username }}" MINIO_ROOT_PASSWORD: "{{ lookup('users', 'administrator').password }}" @@ -142,7 +142,7 @@ failed_when: false changed_when: false -- name: "Create policy (RAW with slash) if missing" +- name: "๐Ÿ“ Create policy (RAW with slash) if missing" environment: MINIO_ROOT_USER: "{{ lookup('users', 'administrator').username }}" MINIO_ROOT_PASSWORD: "{{ lookup('users', 'administrator').password }}" diff --git a/roles/web-app-minio/tasks/03_ldap.yml b/roles/web-app-minio/tasks/03_ldap.yml index 24e7684aaa..14bb9e18e7 100644 --- a/roles/web-app-minio/tasks/03_ldap.yml +++ b/roles/web-app-minio/tasks/03_ldap.yml @@ -1,5 +1,5 @@ --- -- name: "Wait for MinIO IAM subsystem before policy attach" +- name: "โณ Wait for MinIO IAM subsystem before policy attach" environment: MINIO_ROOT_USER: "{{ lookup('users', 'administrator').username }}" MINIO_ROOT_PASSWORD: "{{ lookup('users', 'administrator').password }}" @@ -19,7 +19,7 @@ until: mc_admin_policy_ls_ldap.rc == 0 changed_when: false -- name: "Create administrator policy (LDAP variant)" +- name: "๐Ÿ“ Create administrator policy (LDAP variant)" environment: MINIO_ROOT_USER: "{{ lookup('users', 'administrator').username }}" MINIO_ROOT_PASSWORD: "{{ lookup('users', 'administrator').password }}" @@ -37,7 +37,7 @@ args: { executable: /bin/bash } changed_when: false -- name: "Attach MinIO policy to LDAP administrator group" +- name: "๐Ÿ—‚๏ธ Attach MinIO policy to LDAP administrator group" environment: MINIO_ROOT_USER: "{{ lookup('users', 'administrator').username }}" MINIO_ROOT_PASSWORD: "{{ lookup('users', 'administrator').password }}" diff --git a/roles/web-app-minio/tasks/04_init_consumer.yml b/roles/web-app-minio/tasks/04_init_consumer.yml index 88c5098c18..d9b9712f42 100644 --- a/roles/web-app-minio/tasks/04_init_consumer.yml +++ b/roles/web-app-minio/tasks/04_init_consumer.yml @@ -1,11 +1,11 @@ --- -- name: "Assert correct context" +- name: "โœ… Assert correct context" ansible.builtin.assert: that: - application_id == 'web-app-minio' - objstore_consumer_id != 'web-app-minio' -- name: "Resolve object-store facts for '{{ objstore_consumer_id }}'" +- name: "๐Ÿ” Resolve object-store facts for '{{ objstore_consumer_id }}'" ansible.builtin.set_fact: _minio_consumer_bucket: "{{ lookup('objstore', objstore_consumer_id, 'bucket') }}" _minio_consumer_access_key: "{{ lookup('objstore', objstore_consumer_id, 'access_key') }}" @@ -13,7 +13,7 @@ changed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Provision bucket + scoped service account for '{{ objstore_consumer_id }}'" +- name: "๐Ÿ”ง Provision bucket + scoped service account for '{{ objstore_consumer_id }}'" environment: MINIO_ROOT_USER: "{{ lookup('users', 'administrator').username }}" MINIO_ROOT_PASSWORD: "{{ lookup('users', 'administrator').password }}" @@ -48,7 +48,7 @@ or ('Access Key' in (minio_consumer_provision.stdout | default(''))) no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Allow anonymous downloads on the public bucket for '{{ objstore_consumer_id }}'" +- name: "๐Ÿ” Allow anonymous downloads on public bucket for '{{ objstore_consumer_id }}'" when: lookup('objstore', objstore_consumer_id, 'public') | bool environment: MINIO_ROOT_USER: "{{ lookup('users', 'administrator').username }}" diff --git a/roles/web-app-minio/tasks/main.yml b/roles/web-app-minio/tasks/main.yml index 3f85c104c6..4b8bfac0d1 100644 --- a/roles/web-app-minio/tasks/main.yml +++ b/roles/web-app-minio/tasks/main.yml @@ -1,8 +1,8 @@ --- -- name: "Deploy web-app-minio (core, once per play)" +- name: "๐Ÿš€ Deploy web-app-minio (core, once per play)" include_tasks: 01_core.yml when: run_once_web_app_minio is not defined -- name: "Provision a dedicated bucket + service account for a consumer" +- name: "๐Ÿ”ง Provision a dedicated bucket + service account for a consumer" include_tasks: 04_init_consumer.yml when: objstore_init | bool diff --git a/roles/web-app-mobilizon/tasks/main.yml b/roles/web-app-mobilizon/tasks/main.yml index 682d07e66c..4e60a57b50 100644 --- a/roles/web-app-mobilizon/tasks/main.yml +++ b/roles/web-app-mobilizon/tasks/main.yml @@ -1,11 +1,11 @@ --- -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: compose_handlers_flush: false -- name: add config.exs +- name: โž• add config.exs stack_host_template: src: "config.exs.j2" dest: "{{ mobilizon_host_conf_exs_file }}" diff --git a/roles/web-app-moodle/tasks/01_build_context.yml b/roles/web-app-moodle/tasks/01_build_context.yml index 1046d1f225..ff33fba699 100644 --- a/roles/web-app-moodle/tasks/01_build_context.yml +++ b/roles/web-app-moodle/tasks/01_build_context.yml @@ -4,17 +4,17 @@ # Filenames are read from MOODLE_BUILD_FILES (vars/main.yml) โ€” a single # spot consumed here AND referenced literally by the Dockerfile. -- name: "Set fact: moodle compose dir" +- name: "๐Ÿ”ง Set fact: moodle compose dir" ansible.builtin.set_fact: _moodle_compose_dir: >- {{ docker_compose.directories.instance | default(lookup('container', application_id, 'directories.instance')) }} -- name: "Set fact: moodle build context base" +- name: "๐Ÿ”ง Set fact: moodle build context base" ansible.builtin.set_fact: _moodle_build_dir: "{{ [_moodle_compose_dir, MOODLE_BUILD_DIR] | path_join }}" -- name: "Ensure moodle build context dirs exist" +- name: "โœ… Ensure moodle build context dirs exist" ansible.builtin.file: path: "{{ item }}" state: directory @@ -23,7 +23,7 @@ - "{{ _moodle_build_dir }}" - "{{ [_moodle_build_dir, 'php-conf'] | path_join }}" -- name: "Copy static build assets into compose context" +- name: "๐Ÿ“‹ Copy static build assets into compose context" ansible.builtin.copy: src: "{{ [MOODLE_BUILD_DIR, item.path] | path_join }}" dest: "{{ [_moodle_build_dir, item.path] | path_join }}" @@ -41,7 +41,7 @@ - compose build - compose up -- name: "Transfer msmtprc to {{ MOODLE_MSMTP_ABS }} (Mailu relay used by mail() + healthcheck)" +- name: "๐Ÿ“‹ Copy msmtprc to {{ MOODLE_MSMTP_ABS }} (Mailu relay for mail() + healthcheck)" stack_host_template: src: "{{ MOODLE_MSMTP_SRC }}" dest: "{{ MOODLE_MSMTP_ABS }}" @@ -50,7 +50,7 @@ - compose build - compose up -- name: "Render PHP runtime tuning into compose context" +- name: "๐Ÿ“„ Render PHP runtime tuning into compose context" stack_host_template: src: "{{ [MOODLE_BUILD_DIR, MOODLE_BUILD_FILES.runtime_ini ~ '.j2'] | path_join }}" dest: "{{ [_moodle_build_dir, MOODLE_BUILD_FILES.runtime_ini] | path_join }}" diff --git a/roles/web-app-moodle/tasks/01_core.yml b/roles/web-app-moodle/tasks/01_core.yml index 5776aeb195..f9faa15e21 100644 --- a/roles/web-app-moodle/tasks/01_core.yml +++ b/roles/web-app-moodle/tasks/01_core.yml @@ -1,12 +1,12 @@ --- - include_tasks: utils/once/flag.yml -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: compose_handlers_flush: false -- name: "Moodle manager-side operations (build context, file deploys, container exec)" +- name: "๐Ÿ‘” Moodle manager-side operations (build context, file deploys, container exec)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-moodle/tasks/02_manager_ops.yml b/roles/web-app-moodle/tasks/02_manager_ops.yml index b46a5439bd..f8a56655f3 100644 --- a/roles/web-app-moodle/tasks/02_manager_ops.yml +++ b/roles/web-app-moodle/tasks/02_manager_ops.yml @@ -1,26 +1,26 @@ --- -- name: "Populate Dockerfile build context (entrypoint, config.php, install scripts, php conf)" +- name: "๐Ÿ“„ Populate Dockerfile build context (entrypoint, config.php, install, php conf)" include_tasks: 01_build_context.yml -- name: "Ensure nginx vhost dir exists in compose dir" +- name: "โœ… Ensure nginx vhost dir exists in compose dir" ansible.builtin.file: path: "{{ docker_compose.directories.instance | default(lookup('container', application_id, 'directories.instance')) }}" state: directory mode: "0755" -- name: "Render nginx vhost into compose dir" +- name: "๐Ÿ“„ Render nginx vhost into compose dir" stack_host_template: src: "nginx-moodle.conf.j2" dest: "{{ docker_compose.directories.instance | default(lookup('container', application_id, 'directories.instance')) }}/nginx.conf" mode: "0640" notify: compose up -- name: flush docker service +- name: ๐Ÿšฟ flush docker service meta: flush_handlers -- name: Wait for Moodle container to become healthy +- name: โณ Wait for Moodle container to become healthy block: - - name: Wait until the Moodle container is healthy + - name: โณ Wait until the Moodle container is healthy ansible.builtin.shell: > container inspect --format '{% raw %}{{.State.Health.Status}}{% endraw %}' {{ MOODLE_CONTAINER_ADDRESS }} register: health_check @@ -29,21 +29,21 @@ delay: 5 rescue: - - name: Show Moodle container status + - name: ๐Ÿ‘๏ธ Show Moodle container status ansible.builtin.shell: > container inspect {{ MOODLE_CONTAINER_ADDRESS }} register: moodle_inspect changed_when: false failed_when: false - - name: Show Moodle container logs + - name: ๐Ÿ‘๏ธ Show Moodle container logs ansible.builtin.shell: > container logs --tail=200 {{ MOODLE_CONTAINER_ADDRESS }} register: moodle_logs changed_when: false failed_when: false - - name: Fail with diagnostic output + - name: ๐Ÿ›‘ Fail with diagnostic output ansible.builtin.fail: msg: | โŒ Moodle container did not become healthy in time. @@ -54,7 +54,7 @@ --- container logs (last 200 lines) --- {{ moodle_logs.stdout | default('no output') }} -- name: "Run Moodle install (idempotent)" +- name: "โ–ถ๏ธ Run Moodle install (idempotent)" shell: > container exec --user {{ MOODLE_RUNTIME_USER }} {{ MOODLE_CONTAINER_ADDRESS }} php {{ MOODLE_CLI_DIR }}/install_database.php @@ -73,13 +73,13 @@ - "'Database tables already present' not in moodle_install.stderr" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Include ownership settings tasks for moodle" +- name: "๐Ÿ“‚ Include ownership settings tasks for moodle" include_tasks: 02_ownership.yml -- name: "Configure OIDC login for Moodle (variant 0 only)" +- name: "๐Ÿ”ง Configure OIDC login for Moodle (variant 0 only)" include_tasks: 03_oidc.yml when: MOODLE_OIDC_ENABLED | bool -- name: "Configure auth_ldap (sync-only in variant 0, primary login in variant 1)" +- name: "๐Ÿ”ง Configure auth_ldap (sync-only in variant 0, primary login in variant 1)" include_tasks: 04_ldap_sync.yml when: MOODLE_LDAP_ENABLED | bool diff --git a/roles/web-app-moodle/tasks/02_ownership.yml b/roles/web-app-moodle/tasks/02_ownership.yml index 2b1ef57673..7dd3958eaf 100644 --- a/roles/web-app-moodle/tasks/02_ownership.yml +++ b/roles/web-app-moodle/tasks/02_ownership.yml @@ -9,30 +9,30 @@ # because only Moodle FPM (running as MOODLE_RUNTIME_USER) needs to # read/write user-uploaded content. -- name: "Ensure ownership is correct on Moodle code dir" +- name: "โœ… Ensure ownership is correct on Moodle code dir" shell: "container exec --user root {{ MOODLE_CONTAINER_ADDRESS }} chown -R {{ MOODLE_RUNTIME_USER_GROUP }} {{ MOODLE_CODE_DIR }}" changed_when: false -- name: "Ensure ownership is correct on Moodle data dir" +- name: "โœ… Ensure ownership is correct on Moodle data dir" shell: "container exec --user root {{ MOODLE_CONTAINER_ADDRESS }} chown -R {{ MOODLE_RUNTIME_USER_GROUP }} {{ MOODLE_DATA_DIR }}" changed_when: false -- name: "Code dir: 0755 dirs (nginx-readable)" +- name: "๐Ÿ“ Code dir: 0755 dirs (nginx-readable)" shell: "container exec --user root {{ MOODLE_CONTAINER_ADDRESS }} find {{ MOODLE_CODE_DIR }} -type d -exec chmod 0755 {} \\;" changed_when: false -- name: "Code dir: 0644 files (nginx-readable)" +- name: "๐Ÿ“ Code dir: 0644 files (nginx-readable)" shell: "container exec --user root {{ MOODLE_CONTAINER_ADDRESS }} find {{ MOODLE_CODE_DIR }} -type f -exec chmod 0644 {} \\;" changed_when: false -- name: "Code dir: 0640 config.php (FPM-only)" +- name: "๐Ÿ“ Code dir: 0640 config.php (FPM-only)" shell: "container exec --user root {{ MOODLE_CONTAINER_ADDRESS }} chmod 0640 {{ MOODLE_CONFIG }}" changed_when: false -- name: "Data dir: 0770 dirs (FPM-only)" +- name: "๐Ÿ“ Data dir: 0770 dirs (FPM-only)" shell: "container exec --user root {{ MOODLE_CONTAINER_ADDRESS }} find {{ MOODLE_DATA_DIR }} -type d -exec chmod 0770 {} \\;" changed_when: false -- name: "Data dir: 0660 files (FPM-only)" +- name: "๐Ÿ“ Data dir: 0660 files (FPM-only)" shell: "container exec --user root {{ MOODLE_CONTAINER_ADDRESS }} find {{ MOODLE_DATA_DIR }} -type f -exec chmod 0660 {} \\;" changed_when: false diff --git a/roles/web-app-moodle/tasks/03_oidc.yml b/roles/web-app-moodle/tasks/03_oidc.yml index 443caea8fe..0e0ac60b33 100644 --- a/roles/web-app-moodle/tasks/03_oidc.yml +++ b/roles/web-app-moodle/tasks/03_oidc.yml @@ -2,26 +2,26 @@ # Configure Moodle's auth_oidc plugin (variant 0 only). Variant 1 # disables the OIDC shared service so this file is not included. -- name: "Check OIDC plugin presence" +- name: "๐Ÿ”Ž Check OIDC plugin presence" shell: > container exec --user root {{ MOODLE_CONTAINER_ADDRESS }} test -d {{ MOODLE_OIDC_PLUGIN_DIR }} register: oidc_plugin_check changed_when: false failed_when: false -- name: "Fail if OIDC plugin is missing" +- name: "๐Ÿ›‘ Fail if OIDC plugin is missing" fail: msg: "auth_oidc plugin not found at {{ MOODLE_OIDC_PLUGIN_DIR }} โ€” image build is incomplete" when: oidc_plugin_check.rc != 0 -- name: "Run Moodle DB upgrade for OIDC plugin" +- name: "โ–ถ๏ธ Run Moodle DB upgrade for OIDC plugin" shell: > container exec --user {{ MOODLE_RUNTIME_USER }} {{ MOODLE_CONTAINER_ADDRESS }} php {{ MOODLE_CLI_DIR }}/upgrade.php --non-interactive changed_when: false failed_when: false -- name: "Set Moodle OIDC configuration via CLI" +- name: "๐Ÿ”ง Set Moodle OIDC configuration via CLI" loop: - { name: "idptype", value: 3 } - { name: "clientauthmethod", value: 1 } @@ -102,7 +102,7 @@ --name={{ item.name }} --set="{{ item.value }}" changed_when: false -- name: "Set auth = 'oidc' for all users except guest" +- name: "๐Ÿ”ง Set auth = 'oidc' for all users except guest" shell: > container exec {{ MOODLE_DB_CONTAINER_ADDRESS }} mariadb -u {{ lookup('database', application_id, 'username') }} diff --git a/roles/web-app-moodle/tasks/04_ldap_sync.yml b/roles/web-app-moodle/tasks/04_ldap_sync.yml index 634e8fbf0f..47cf7dd26a 100644 --- a/roles/web-app-moodle/tasks/04_ldap_sync.yml +++ b/roles/web-app-moodle/tasks/04_ldap_sync.yml @@ -4,14 +4,14 @@ # is the primary login plugin. Field mapping is identical between # variants. -- name: "Run Moodle DB upgrade for auth_ldap plugin" +- name: "โ–ถ๏ธ Run Moodle DB upgrade for auth_ldap plugin" shell: > container exec --user {{ MOODLE_RUNTIME_USER }} {{ MOODLE_CONTAINER_ADDRESS }} php {{ MOODLE_CLI_DIR }}/upgrade.php --non-interactive failed_when: false changed_when: false -- name: "Configure auth_ldap connection + field mapping" +- name: "๐Ÿ”ง Configure auth_ldap connection + field mapping" loop: # โ”€โ”€ connection โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ - { name: "host_url", value: "{{ LDAP.SERVER.URI }}" } @@ -98,21 +98,21 @@ no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" changed_when: false -- name: "Enable auth_ldap plugin" +- name: "๐ŸŸข Enable auth_ldap plugin" shell: > container exec --user {{ MOODLE_RUNTIME_USER }} {{ MOODLE_CONTAINER_ADDRESS }} php {{ MOODLE_CLI_DIR }}/cfg.php --name=auth --set=ldap when: not (MOODLE_OIDC_ENABLED | bool) changed_when: false -- name: "Variant 0: enable both auth_oidc + auth_ldap (oidc primary)" +- name: "๐ŸŸข Variant 0: enable both auth_oidc + auth_ldap (oidc primary)" shell: > container exec --user {{ MOODLE_RUNTIME_USER }} {{ MOODLE_CONTAINER_ADDRESS }} php {{ MOODLE_CLI_DIR }}/cfg.php --name=auth --set=oidc,ldap when: MOODLE_OIDC_ENABLED | bool changed_when: false -- name: "Hide auth_ldap from login page in variant 0 (OIDC is the only entry point)" +- name: "๐Ÿ”‘ Hide auth_ldap from login page in variant 0 (OIDC is the only entry point)" shell: > container exec --user {{ MOODLE_RUNTIME_USER }} {{ MOODLE_CONTAINER_ADDRESS }} php {{ MOODLE_CLI_DIR }}/cfg.php --component=auth_ldap @@ -120,7 +120,7 @@ when: MOODLE_OIDC_ENABLED | bool changed_when: false -- name: "Trigger auth_ldap sync to pre-provision LDAP users" +- name: "โšก Trigger auth_ldap sync to pre-provision LDAP users" shell: > container exec --user {{ MOODLE_RUNTIME_USER }} {{ MOODLE_CONTAINER_ADDRESS }} php {{ MOODLE_CLI_DIR }}/scheduled_task.php diff --git a/roles/web-app-moodle/tasks/main.yml b/roles/web-app-moodle/tasks/main.yml index 131198ab80..306b74bf67 100644 --- a/roles/web-app-moodle/tasks/main.yml +++ b/roles/web-app-moodle/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "Execute Role (once)" +- name: "โ–ถ๏ธ Execute Role (once)" include_tasks: 01_core.yml when: run_once_web_app_moodle is not defined vars: diff --git a/roles/web-app-navigator/tasks/main.yml b/roles/web-app-navigator/tasks/main.yml index 2d8eddf762..7169672a15 100644 --- a/roles/web-app-navigator/tasks/main.yml +++ b/roles/web-app-navigator/tasks/main.yml @@ -1,20 +1,20 @@ --- -- name: "pkgmgr install" +- name: "๐Ÿ“ฆ pkgmgr install" include_role: name: pkgmgr-install vars: package_name: infinito-presentation # package_notify: compose up -- name: Get path of infinito-presentation using pkgmgr +- name: โฌ‡๏ธ Get path of infinito-presentation using pkgmgr command: "{{ ansible_facts['env']['HOME'] }}/.venvs/pkgmgr/bin/pkgmgr path infinito-presentation" register: path_infinito_presentation_output -- name: Get path of infinito using pkgmgr +- name: โฌ‡๏ธ Get path of infinito using pkgmgr command: "{{ ansible_facts['env']['HOME'] }}/.venvs/pkgmgr/bin/pkgmgr path infinito" register: path_infinito_output -- name: "load docker, proxy for '{{ application_id }}'" +- name: "๐Ÿงฉ load docker, proxy for '{{ application_id }}'" include_role: name: sys-stk-full diff --git a/roles/web-app-nextcloud/tasks/01_fullstack.yml b/roles/web-app-nextcloud/tasks/01_fullstack.yml index 144f950f72..bab8b3ae74 100644 --- a/roles/web-app-nextcloud/tasks/01_fullstack.yml +++ b/roles/web-app-nextcloud/tasks/01_fullstack.yml @@ -1,5 +1,5 @@ --- -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: @@ -10,7 +10,7 @@ - when: NEXTCLOUD_WHITEBOARD_ENABLED | bool block: - - name: "Create '{{ NEXTCLOUD_WHITEBOARD_SERVICE_DIRECTORY }}' Directory" + - name: "๐Ÿ“ Create '{{ NEXTCLOUD_WHITEBOARD_SERVICE_DIRECTORY }}' Directory" file: path: "{{ NEXTCLOUD_WHITEBOARD_SERVICE_DIRECTORY }}" state: directory @@ -18,13 +18,13 @@ group: "{{ NEXTCLOUD_DOCKER_USER_ID }}" mode: "0755" - - name: "Deploy Whiteboard Dockerfile to '{{ NEXTCLOUD_WHITEBOARD_SERVICE_DOCKERFILE }}'" + - name: "๐Ÿ“„ Deploy Whiteboard Dockerfile to {{ NEXTCLOUD_WHITEBOARD_SERVICE_DOCKERFILE }}" stack_host_template: src: "Dockerfiles/Whiteboard.j2" dest: "{{ NEXTCLOUD_WHITEBOARD_SERVICE_DOCKERFILE }}" notify: compose build -- name: "create {{ NEXTCLOUD_HOST_CONF_ADD_PATH }}" +- name: "๐Ÿ“ create {{ NEXTCLOUD_HOST_CONF_ADD_PATH }}" file: path: "{{ NEXTCLOUD_HOST_CONF_ADD_PATH }}" state: directory @@ -32,7 +32,7 @@ group: "{{ NEXTCLOUD_DOCKER_USER_ID }}" mode: "0755" -- name: "Render Nextcloud config files at {{ NEXTCLOUD_HOST_CONF_ADD_PATH }} (local + swarm peers)" +- name: "๐Ÿ“„ Render Nextcloud config at {{ NEXTCLOUD_HOST_CONF_ADD_PATH }} (local + peers)" ansible.builtin.include_tasks: file: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/render_replicated_templates.yml'] | path_join }}" vars: @@ -43,7 +43,7 @@ group: "{{ NEXTCLOUD_DOCKER_USER_ID }}" mode: "0644" -- name: "NEXTCLOUD | Ensure host-mounted infinito config files ownership/permissions (recursive)" +- name: "๐Ÿ” NEXTCLOUD | Ensure host-mounted config files ownership/permissions (recursive)" ansible.builtin.file: path: "{{ NEXTCLOUD_HOST_CONF_ADD_PATH }}" state: directory @@ -52,7 +52,7 @@ group: "{{ NEXTCLOUD_DOCKER_USER_ID }}" mode: "u=rwX,g=rX,o=rX" -- name: "Render Nextcloud internal nginx config (local + swarm peers)" +- name: "๐Ÿ“„ Render Nextcloud internal nginx config (local + swarm peers)" ansible.builtin.include_tasks: file: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/render_replicated_templates.yml'] | path_join }}" vars: diff --git a/roles/web-app-nextcloud/tasks/02_config.yml b/roles/web-app-nextcloud/tasks/02_config.yml index d430b95284..bfff1c97de 100644 --- a/roles/web-app-nextcloud/tasks/02_config.yml +++ b/roles/web-app-nextcloud/tasks/02_config.yml @@ -1,7 +1,7 @@ --- # Merge all (config) files in infinito directory (container) -- name: "Render Nextcloud include.php (local + swarm peers)" +- name: "๐Ÿ“„ Render Nextcloud include.php (local + swarm peers)" ansible.builtin.include_tasks: file: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/render_replicated_templates.yml'] | path_join }}" vars: @@ -12,10 +12,10 @@ group: "{{ NEXTCLOUD_DOCKER_USER_ID }}" mode: "0644" -- name: Flush handlers so Nextcloud container is restarted and ready +- name: ๐Ÿšฟ Flush handlers so Nextcloud container is restarted and ready meta: flush_handlers -- name: "Wait until Nextcloud is reachable on port {{ lookup('config', application_id, 'services.nextcloud.ports.local.http') }}" +- name: "โณ Wait until Nextcloud is reachable on its local HTTP port" wait_for: host: "{{ DOCKER_REACH_HOST }}" port: "{{ lookup('config', application_id, 'services.nextcloud.ports.local.http') }}" @@ -23,7 +23,7 @@ delay: 2 state: started -- name: Wait until Nextcloud is installed (occ status) +- name: โณ Wait until Nextcloud is installed (occ status) shell: "{{ NEXTCLOUD_DOCKER_EXEC_OCC }} status" register: occ_status retries: 60 @@ -33,7 +33,7 @@ (occ_status.stdout | default('')) is search('installed: true') changed_when: false -- name: Ensure config.php loads {{ NEXTCLOUD_DOCKER_INCL_PATH }} (idempotent) +- name: โœ… Ensure config.php loads {{ NEXTCLOUD_DOCKER_INCL_PATH }} (idempotent) ansible.builtin.shell: | set -euo pipefail diff --git a/roles/web-app-nextcloud/tasks/03_upgrade.yml b/roles/web-app-nextcloud/tasks/03_upgrade.yml index df83e41e87..74d4a86dae 100644 --- a/roles/web-app-nextcloud/tasks/03_upgrade.yml +++ b/roles/web-app-nextcloud/tasks/03_upgrade.yml @@ -1,10 +1,10 @@ --- -- name: Nextcloud | Upgrade +- name: โฌ†๏ธ Nextcloud | Upgrade command: "{{ NEXTCLOUD_DOCKER_EXEC_OCC }} upgrade" register: occ_upgrade changed_when: "'Already up to date' not in occ_upgrade.stdout" -- name: Nextcloud | Maintenance repair +- name: ๐Ÿ”ง Nextcloud | Maintenance repair command: "{{ NEXTCLOUD_DOCKER_EXEC_OCC }} maintenance:repair --include-expensive" register: occ_repair changed_when: "'No repairs needed' not in occ_repair.stdout" @@ -12,7 +12,7 @@ delay: 10 until: occ_repair.rc == 0 -- name: Nextcloud | App update (retry once) +- name: ๐Ÿ”„ Nextcloud | App update (retry once) command: "{{ NEXTCLOUD_DOCKER_EXEC_OCC }} app:update --all" register: occ_app_update changed_when: "'No apps found for update' not in occ_app_update.stdout" @@ -20,22 +20,22 @@ delay: 3 until: occ_app_update.rc == 0 -- name: Nextcloud | Add missing columns +- name: โž• Nextcloud | Add missing columns command: "{{ NEXTCLOUD_DOCKER_EXEC_OCC }} db:add-missing-columns" register: occ_columns changed_when: "'No columns found' not in occ_columns.stdout" -- name: Nextcloud | Add missing indices +- name: โž• Nextcloud | Add missing indices command: "{{ NEXTCLOUD_DOCKER_EXEC_OCC }} db:add-missing-indices" register: occ_indices changed_when: "'No indices found' not in occ_indices.stdout" -- name: Nextcloud | Add missing primary keys +- name: โž• Nextcloud | Add missing primary keys command: "{{ NEXTCLOUD_DOCKER_EXEC_OCC }} db:add-missing-primary-keys" register: occ_pks changed_when: "'No primary keys found' not in occ_pks.stdout" -- name: Nextcloud | Disable maintenance mode +- name: ๐Ÿ”ด Nextcloud | Disable maintenance mode command: "{{ NEXTCLOUD_DOCKER_EXEC_OCC }} maintenance:mode --off" register: occ_maint_off changed_when: "'already disabled' not in occ_maint_off.stdout" diff --git a/roles/web-app-nextcloud/tasks/04_admin.yml b/roles/web-app-nextcloud/tasks/04_admin.yml index 7ebf9bac19..92e9c4f8a1 100644 --- a/roles/web-app-nextcloud/tasks/04_admin.yml +++ b/roles/web-app-nextcloud/tasks/04_admin.yml @@ -1,5 +1,5 @@ --- -- name: Ensure Nextcloud administrator is in the 'admin' group +- name: โœ… Ensure Nextcloud administrator is in the 'admin' group shell: > container exec -u {{ NEXTCLOUD_DOCKER_USER }} {{ NEXTCLOUD_CONTAINER_ADDRESS }} php occ group:adduser admin {{ NEXTCLOUD_ADMINISTRATOR_USERNAME }} diff --git a/roles/web-app-nextcloud/tasks/05_system_config.yml b/roles/web-app-nextcloud/tasks/05_system_config.yml index 6610683f15..9606b23124 100644 --- a/roles/web-app-nextcloud/tasks/05_system_config.yml +++ b/roles/web-app-nextcloud/tasks/05_system_config.yml @@ -1,9 +1,9 @@ --- -- name: Load System Nextcloud configuration variables +- name: โš™๏ธ Load System Nextcloud configuration variables include_vars: file: system.yml -- name: "Apply Nextcloud system configs (batched shell)" +- name: "๐Ÿ“Œ Apply Nextcloud system configs (batched shell)" ansible.builtin.shell: | set -euo pipefail {% for item in nextcloud_system_config %} diff --git a/roles/web-app-nextcloud/tasks/06_plugin.yml b/roles/web-app-nextcloud/tasks/06_plugin.yml index 160ba28158..eb4031a7eb 100644 --- a/roles/web-app-nextcloud/tasks/06_plugin.yml +++ b/roles/web-app-nextcloud/tasks/06_plugin.yml @@ -3,7 +3,7 @@ - include_tasks: plugin/01_install.yml when: plugin_value.enabled | bool -- name: disable {{ plugin_key }} nextcloud plugin +- name: ๐Ÿ”ด disable {{ plugin_key }} nextcloud plugin command: "{{ NEXTCLOUD_DOCKER_EXEC_OCC }} app:disable {{ plugin_key }}" register: disable_result changed_when: > diff --git a/roles/web-app-nextcloud/tasks/07_admin_identities.yml b/roles/web-app-nextcloud/tasks/07_admin_identities.yml index ae311baf08..c1df4d9c8c 100644 --- a/roles/web-app-nextcloud/tasks/07_admin_identities.yml +++ b/roles/web-app-nextcloud/tasks/07_admin_identities.yml @@ -1,5 +1,5 @@ --- -- name: Check whether Nextcloud LDAP OCC namespace is available +- name: ๐Ÿ”Ž Check whether Nextcloud LDAP OCC namespace is available command: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} list ldap register: nextcloud_admin_ldap_namespace @@ -7,7 +7,7 @@ failed_when: false when: lookup('config', application_id, 'addons.user_ldap.enabled', False) | bool -- name: Resolve LDAP-backed Nextcloud administrator identities +- name: ๐Ÿ” Resolve LDAP-backed Nextcloud administrator identities command: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} ldap:search {{ NEXTCLOUD_ADMINISTRATOR_USERNAME }} register: nextcloud_admin_ldap_search @@ -22,7 +22,7 @@ async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}" poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}" -- name: Build the list of Nextcloud administrator identities +- name: ๐Ÿ”จ Build the list of Nextcloud administrator identities set_fact: nextcloud_administrator_identities: >- {{ @@ -38,7 +38,7 @@ | unique }} -- name: Ensure all Nextcloud administrator identities are in the 'admin' group +- name: โœ… Ensure all Nextcloud administrator identities are in the 'admin' group command: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} group:adduser admin {{ item }} loop: "{{ nextcloud_administrator_identities }}" diff --git a/roles/web-app-nextcloud/tasks/08_manager_ops.yml b/roles/web-app-nextcloud/tasks/08_manager_ops.yml index bd64168a2d..c70312f370 100644 --- a/roles/web-app-nextcloud/tasks/08_manager_ops.yml +++ b/roles/web-app-nextcloud/tasks/08_manager_ops.yml @@ -1,11 +1,11 @@ --- -- name: Setup config.php +- name: ๐Ÿ”ง Setup config.php include_tasks: 02_config.yml -- name: Flush all handlers immediately so that occ can be used +- name: ๐Ÿšฟ Flush all handlers immediately so that occ can be used meta: flush_handlers -- name: Wait until Redis is ready (PONG) +- name: โณ Wait until Redis is ready (PONG) shell: "container exec {{ NEXTCLOUD_REDIS_CONTAINER_ADDRESS }} redis-cli ping" register: redis_ping retries: 60 @@ -14,10 +14,10 @@ changed_when: false when: lookup('engine', 'redis', application_id, 'local') -- name: Update\Upgrade Nextcloud +- name: ๐Ÿ”„ Update\Upgrade Nextcloud include_tasks: 03_upgrade.yml -- name: Load system configuration steps +- name: ๐Ÿ“‚ Load system configuration steps include_tasks: "{{ nextcloud_step }}" loop: - 04_admin.yml @@ -25,7 +25,7 @@ loop_control: loop_var: nextcloud_step -- name: Setup Nextcloud Plugins +- name: ๐Ÿ”ง Setup Nextcloud Plugins include_tasks: 06_plugin.yml loop: "{{ NEXTCLOUD_PLUGIN_ITEMS }}" loop_control: @@ -35,5 +35,5 @@ plugin_value: "{{ plugin_item.value }}" when: NEXTCLOUD_PLUGINS_ENABLED | bool -- name: Reconcile administrator identities after plugin setup +- name: ๐Ÿ”ง Reconcile administrator identities after plugin setup include_tasks: 07_admin_identities.yml diff --git a/roles/web-app-nextcloud/tasks/addons/integration_gitlab.yml b/roles/web-app-nextcloud/tasks/addons/integration_gitlab.yml index 62c6fc96fa..e74bb719c4 100644 --- a/roles/web-app-nextcloud/tasks/addons/integration_gitlab.yml +++ b/roles/web-app-nextcloud/tasks/addons/integration_gitlab.yml @@ -1,25 +1,25 @@ --- -- name: Resolve GitLab integration provisioning facts +- name: ๐Ÿ” Resolve GitLab integration provisioning facts set_fact: nextcloud_gl_container: "{{ lookup('config', 'web-app-gitlab', 'services.gitlab.name') }}" nextcloud_gl_nc_base_url: "{{ lookup('tls', 'web-app-nextcloud', 'url.base') | regex_replace('/$', '') }}" changed_when: false -- name: Probe whether the GitLab partner container is running +- name: ๐Ÿ” Probe whether the GitLab partner container is running command: > container inspect -f '{% raw %}{{.State.Running}}{% endraw %}' {{ nextcloud_gl_container }} register: integration_gitlab_partner_running changed_when: false failed_when: false -- name: Read persisted integration_gitlab OAuth client id +- name: ๐Ÿ“– Read persisted integration_gitlab OAuth client id command: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} config:app:get integration_gitlab client_id register: nextcloud_gl_client_id_current changed_when: false failed_when: false -- name: Read persisted integration_gitlab OAuth client secret +- name: ๐Ÿ“– Read persisted integration_gitlab OAuth client secret command: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} config:app:get integration_gitlab client_secret register: nextcloud_gl_client_secret_current @@ -27,7 +27,7 @@ failed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Provision the GitLab <-> Nextcloud OAuth coupling +- name: ๐Ÿ”ง Provision the GitLab <-> Nextcloud OAuth coupling include_tasks: "{{ [role_path, 'tasks/addons/integration_gitlab_provision.yml'] | path_join }}" when: >- (integration_gitlab_partner_running.stdout | trim) == 'true' diff --git a/roles/web-app-nextcloud/tasks/addons/integration_gitlab_provision.yml b/roles/web-app-nextcloud/tasks/addons/integration_gitlab_provision.yml index 9a806e1d8e..bc9e7e13e3 100644 --- a/roles/web-app-nextcloud/tasks/addons/integration_gitlab_provision.yml +++ b/roles/web-app-nextcloud/tasks/addons/integration_gitlab_provision.yml @@ -1,5 +1,5 @@ --- -- name: Provision the GitLab OAuth application for Nextcloud and capture credentials +- name: ๐Ÿ”ง Provision the GitLab OAuth application for Nextcloud and capture credentials ansible.builtin.command: argv: - container @@ -20,24 +20,24 @@ changed_when: "'CLIENT_ID=' in nextcloud_gl_provision.stdout" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Parse the GitLab OAuth client id +- name: ๐Ÿ”Ž Parse the GitLab OAuth client id set_fact: nextcloud_gl_client_id: "{{ nextcloud_gl_provision.stdout | regex_search('CLIENT_ID=(.+)', '\\1') | first }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Resolve the GitLab OAuth client secret (freshly emitted or persisted) +- name: ๐Ÿ” Resolve the GitLab OAuth client secret (freshly emitted or persisted) set_fact: nextcloud_gl_fresh_secret: "{{ (nextcloud_gl_provision.stdout | regex_search('CLIENT_SECRET=(.+)', '\\1') | default([], true) | first | default('', true)) | trim }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Pick the effective GitLab OAuth client secret +- name: ๐ŸŽฏ Pick the effective GitLab OAuth client secret set_fact: nextcloud_gl_client_secret: "{{ nextcloud_gl_fresh_secret if (nextcloud_gl_fresh_secret | length > 0) else (nextcloud_gl_client_secret_current.stdout | trim) }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Fail when no usable GitLab OAuth client secret is available +- name: ๐Ÿ›‘ Fail when no usable GitLab OAuth client secret is available assert: that: - (nextcloud_gl_client_id | default('') | trim) | length > 0 @@ -47,7 +47,7 @@ retrievable when the app is first created or its secret is renewed; reset the integration_gitlab client_id/client_secret app config to re-provision. -- name: Store integration_gitlab OAuth credentials Nextcloud-encrypted (ICrypto, lazy) +- name: ๐Ÿ” Store integration_gitlab OAuth credentials Nextcloud-encrypted (ICrypto, lazy) ansible.builtin.command: argv: - container diff --git a/roles/web-app-nextcloud/tasks/addons/integration_mattermost.yml b/roles/web-app-nextcloud/tasks/addons/integration_mattermost.yml index 7927232d89..d1c44b49d2 100644 --- a/roles/web-app-nextcloud/tasks/addons/integration_mattermost.yml +++ b/roles/web-app-nextcloud/tasks/addons/integration_mattermost.yml @@ -3,7 +3,7 @@ # admin keys oauth_instance_url/client_id/client_secret, which only exist once an # OAuth app is registered on Mattermost. This hook provisions that app on the # partner and wires the returned credentials into Nextcloud. -- name: Resolve Mattermost partner coupling facts +- name: ๐Ÿ” Resolve Mattermost partner coupling facts set_fact: nextcloud_mm_container: "{{ lookup('config', 'web-app-mattermost', 'services.mattermost.name') }}" nextcloud_mm_instance_dir: "{{ lookup('container', 'web-app-mattermost', 'directories.instance') }}" @@ -12,14 +12,14 @@ nextcloud_mm_redirect_path: "/apps/integration_mattermost/oauth-redirect" changed_when: false -- name: Probe whether the Mattermost partner container is running +- name: ๐Ÿ” Probe whether the Mattermost partner container is running command: > container inspect -f '{% raw %}{{.State.Running}}{% endraw %}' {{ nextcloud_mm_container }} register: nextcloud_mm_partner_running changed_when: false failed_when: false -- name: Provision the bidirectional Mattermost <-> Nextcloud OAuth coupling +- name: ๐Ÿ”ง Provision the bidirectional Mattermost <-> Nextcloud OAuth coupling include_tasks: integration_mattermost_provision.yml when: - IS_STACK_HOST | bool diff --git a/roles/web-app-nextcloud/tasks/addons/integration_mattermost_provision.yml b/roles/web-app-nextcloud/tasks/addons/integration_mattermost_provision.yml index 1675a398d7..e3f170197e 100644 --- a/roles/web-app-nextcloud/tasks/addons/integration_mattermost_provision.yml +++ b/roles/web-app-nextcloud/tasks/addons/integration_mattermost_provision.yml @@ -1,5 +1,5 @@ --- -- name: Wait until Mattermost mmctl local mode is ready +- name: โณ Wait until Mattermost mmctl local mode is ready shell: > container exec -i {{ NEXTCLOUD_MATTERMOST_CONTAINER_ADDRESS }} /mattermost/bin/mmctl --local system status @@ -12,7 +12,7 @@ changed_when: false failed_when: nextcloud_mm_ready.rc != 0 and nextcloud_mm_ready.attempts | default(0) >= 60 -- name: Enable the Mattermost OAuth 2.0 service provider (required for the connector) +- name: ๐ŸŸข Enable the Mattermost OAuth 2.0 service provider (required for the connector) shell: > container exec -i {{ NEXTCLOUD_MATTERMOST_CONTAINER_ADDRESS }} /mattermost/bin/mmctl --local config set ServiceSettings.EnableOAuthServiceProvider true @@ -21,7 +21,7 @@ register: nextcloud_mm_oauth_provider changed_when: "'true' in nextcloud_mm_oauth_provider.stdout" -- name: Generate a short-lived admin personal access token for OAuth provisioning +- name: โš™๏ธ Generate a short-lived admin personal access token for OAuth provisioning shell: > container exec -i {{ NEXTCLOUD_MATTERMOST_CONTAINER_ADDRESS }} /mattermost/bin/mmctl --local token generate {{ lookup('users', 'administrator').username }} infinito-nc-oauth-provision --json @@ -31,13 +31,13 @@ changed_when: true no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Parse the admin personal access token +- name: ๐Ÿ”Ž Parse the admin personal access token set_fact: nextcloud_mm_token: "{{ (nextcloud_mm_pat.stdout | from_json | first).token }}" nextcloud_mm_token_id: "{{ (nextcloud_mm_pat.stdout | from_json | first).id }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Provision (idempotently) the Mattermost OAuth app for Nextcloud and capture credentials +- name: ๐Ÿ”ง Provision Mattermost OAuth app for Nextcloud and capture creds (idempotent) ansible.builtin.command: argv: - bash @@ -54,13 +54,13 @@ changed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Parse Mattermost OAuth client credentials +- name: ๐Ÿ”Ž Parse Mattermost OAuth client credentials set_fact: nextcloud_mm_client_id: "{{ nextcloud_mm_provision.stdout | regex_search('CLIENT_ID=(.+)', '\\1') | first }}" nextcloud_mm_client_secret: "{{ nextcloud_mm_provision.stdout | regex_search('CLIENT_SECRET=(.+)', '\\1') | first }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Point integration_mattermost at the partner instance (admin OAuth instance URL) +- name: ๐Ÿ”ง Point integration_mattermost at partner instance (admin OAuth instance URL) command: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} config:app:set integration_mattermost oauth_instance_url @@ -68,7 +68,7 @@ register: nextcloud_mm_oauth_url_set changed_when: "' set to ' in nextcloud_mm_oauth_url_set.stdout" -- name: Store integration_mattermost OAuth credentials Nextcloud-encrypted (sensitive, lazy) +- name: ๐Ÿ” Store integration_mattermost OAuth credentials Nextcloud-encrypted (lazy) ansible.builtin.command: argv: - container @@ -89,7 +89,7 @@ changed_when: "'OK' in nextcloud_mm_enc_set.stdout" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Revoke the short-lived admin personal access token +- name: ๐Ÿšซ Revoke the short-lived admin personal access token shell: > container exec -i {{ NEXTCLOUD_MATTERMOST_CONTAINER_ADDRESS }} /mattermost/bin/mmctl --local token revoke {{ nextcloud_mm_token_id }} diff --git a/roles/web-app-nextcloud/tasks/addons/integration_openai.yml b/roles/web-app-nextcloud/tasks/addons/integration_openai.yml index 37ea8b00a1..b6f09b12bb 100644 --- a/roles/web-app-nextcloud/tasks/addons/integration_openai.yml +++ b/roles/web-app-nextcloud/tasks/addons/integration_openai.yml @@ -5,19 +5,19 @@ # (web-app-flowise credentials.llm_master_key). That partner-side credential # must be fetched and written into integration_openai api_key here; the loader # cannot derive it. -- name: Resolve Flowise/LiteLLM backend selection for integration_openai +- name: ๐Ÿ” Resolve Flowise/LiteLLM backend selection for integration_openai set_fact: nextcloud_openai_use_flowise: "{{ ('web-app-flowise' in group_names) and ('web-app-openwebui' not in group_names) }}" changed_when: false -- name: Resolve Flowise LiteLLM master key for integration_openai api_key +- name: ๐Ÿ” Resolve Flowise LiteLLM master key for integration_openai api_key set_fact: nextcloud_openai_flowise_api_key: "{{ lookup('config', 'web-app-flowise', 'credentials.llm_master_key', '') }}" changed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" when: nextcloud_openai_use_flowise | bool -- name: Provision integration_openai api_key for the Flowise/LiteLLM backend +- name: ๐Ÿ”ง Provision integration_openai api_key for the Flowise/LiteLLM backend command: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} config:app:set integration_openai api_key --value '{{ nextcloud_openai_flowise_api_key }}' diff --git a/roles/web-app-nextcloud/tasks/addons/integration_openproject.yml b/roles/web-app-nextcloud/tasks/addons/integration_openproject.yml index 37c9aa3124..05a8e62dc1 100644 --- a/roles/web-app-nextcloud/tasks/addons/integration_openproject.yml +++ b/roles/web-app-nextcloud/tasks/addons/integration_openproject.yml @@ -3,35 +3,35 @@ # An OAuth application is registered on the OpenProject side and a Nextcloud OAuth2 client is # registered back on the OpenProject storage; the partner-derived client ids/secret are linked # into integration_openproject. Re-runs only while Nextcloud is not yet coupled. -- name: Resolve expected OpenProject base URL for the integration +- name: ๐Ÿ” Resolve expected OpenProject base URL for the integration set_fact: nextcloud_op_expected_url: "{{ lookup('tls', 'web-app-openproject', 'url.base') | trim }}" nextcloud_op_web_container: "{{ lookup('config', 'web-app-openproject', 'services.web.name') }}" nextcloud_op_storage_name: "Nextcloud ({{ lookup('domain', 'web-app-nextcloud') }})" changed_when: false -- name: Probe whether the OpenProject partner container is running +- name: ๐Ÿ” Probe whether the OpenProject partner container is running command: > container inspect -f '{% raw %}{{.State.Running}}{% endraw %}' {{ nextcloud_op_web_container }} register: integration_openproject_partner_running changed_when: false failed_when: false -- name: Read persisted integration_openproject OpenProject OAuth client id +- name: ๐Ÿ“– Read persisted integration_openproject OpenProject OAuth client id command: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} config:app:get integration_openproject openproject_client_id register: nextcloud_op_client_id_current changed_when: false failed_when: false -- name: Read persisted integration_openproject Nextcloud OAuth client id +- name: ๐Ÿ“– Read persisted integration_openproject Nextcloud OAuth client id command: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} config:app:get integration_openproject nc_oauth_client_id register: nextcloud_op_nc_client_current changed_when: false failed_when: false -- name: Read persisted integration_openproject OpenProject OAuth client secret +- name: ๐Ÿ“– Read persisted integration_openproject OpenProject OAuth client secret command: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} config:app:get integration_openproject openproject_client_secret register: nextcloud_op_client_secret_current @@ -39,7 +39,7 @@ failed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Provision the bidirectional OpenProject <-> Nextcloud OAuth coupling +- name: ๐Ÿ”ง Provision the bidirectional OpenProject <-> Nextcloud OAuth coupling include_tasks: "{{ [role_path, 'tasks/addons/integration_openproject_provision.yml'] | path_join }}" when: >- (integration_openproject_partner_running.stdout | trim) == 'true' diff --git a/roles/web-app-nextcloud/tasks/addons/integration_openproject_provision.yml b/roles/web-app-nextcloud/tasks/addons/integration_openproject_provision.yml index 3d03efaa48..26092be6ae 100644 --- a/roles/web-app-nextcloud/tasks/addons/integration_openproject_provision.yml +++ b/roles/web-app-nextcloud/tasks/addons/integration_openproject_provision.yml @@ -1,12 +1,12 @@ --- -- name: Wait for the OpenProject web endpoint +- name: โณ Wait for the OpenProject web endpoint wait_for: host: "{{ lookup('domain', 'web-app-openproject') }}" port: 80 delay: 5 timeout: 600 -- name: Create the Nextcloud storage + OpenProject OAuth application +- name: ๐Ÿ“ Create the Nextcloud storage + OpenProject OAuth application ansible.builtin.command: argv: - container @@ -27,19 +27,19 @@ changed_when: "'\"oauth_application_created\":true' in nextcloud_op_storage_create.stdout" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Parse the OpenProject OAuth application credentials +- name: ๐Ÿ”Ž Parse the OpenProject OAuth application credentials set_fact: nextcloud_op_oauth: "{{ nextcloud_op_storage_create.stdout | regex_search('{.*}') | from_json }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Resolve the effective OpenProject OAuth client secret (fresh or persisted) +- name: ๐Ÿ” Resolve the effective OpenProject OAuth client secret (fresh or persisted) set_fact: nextcloud_op_client_secret: >- {{ nextcloud_op_oauth.openproject_client_secret | default((nextcloud_op_client_secret_current.stdout | trim), true) }} no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Fail when no usable OpenProject OAuth application secret is available +- name: ๐Ÿ›‘ Fail when no usable OpenProject OAuth application secret is available assert: that: - nextcloud_op_oauth.openproject_client_id | default('') | length > 0 @@ -50,7 +50,7 @@ is created; reset the integration_openproject app config (openproject_client_id, openproject_client_secret, nc_oauth_client_id) and the OpenProject storage to re-provision. -- name: Push the OpenProject OAuth application credentials into Nextcloud +- name: โฌ†๏ธ Push the OpenProject OAuth application credentials into Nextcloud command: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} config:app:set integration_openproject {{ item.key }} --value '{{ item.value }}' @@ -62,7 +62,7 @@ label: "{{ item.key }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Register a Nextcloud OAuth2 client for OpenProject +- name: ๐Ÿ“ Register a Nextcloud OAuth2 client for OpenProject command: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} oauth2:add-client "OpenProject client" @@ -73,22 +73,22 @@ failed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Wire the Nextcloud OAuth2 client into both sides when it was created +- name: ๐Ÿ”Œ Wire the Nextcloud OAuth2 client into both sides when it was created when: (nextcloud_op_ncclient_create.rc | default(1)) == 0 block: - - name: Parse the Nextcloud OAuth2 client credentials + - name: ๐Ÿ”Ž Parse the Nextcloud OAuth2 client credentials set_fact: nextcloud_op_ncclient: "{{ nextcloud_op_ncclient_create.stdout | trim | from_json }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" - - name: Push the Nextcloud OAuth2 client id into integration_openproject + - name: โฌ†๏ธ Push the Nextcloud OAuth2 client id into integration_openproject command: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} config:app:set integration_openproject nc_oauth_client_id --value '{{ nextcloud_op_ncclient.clientId }}' changed_when: true no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" - - name: Register the Nextcloud OAuth2 client back on the OpenProject storage + - name: ๐Ÿ“ Register the Nextcloud OAuth2 client back on the OpenProject storage ansible.builtin.command: argv: - container diff --git a/roles/web-app-nextcloud/tasks/addons/integration_suitecrm.yml b/roles/web-app-nextcloud/tasks/addons/integration_suitecrm.yml index d7a954b5b2..49b23b2482 100644 --- a/roles/web-app-nextcloud/tasks/addons/integration_suitecrm.yml +++ b/roles/web-app-nextcloud/tasks/addons/integration_suitecrm.yml @@ -5,7 +5,7 @@ # instance URL must then be linked into the connector's admin settings (oauth_instance_url, # client_id, client_secret), none of which the generic config block sets. The client secret is # derived deterministically so provisioning stays idempotent across re-runs on both ends. -- name: Resolve SuiteCRM partner coupling facts +- name: ๐Ÿ” Resolve SuiteCRM partner coupling facts set_fact: nextcloud_crm_container: "{{ lookup('config', 'web-app-suitecrm', 'services.suitecrm.name') }}" nextcloud_crm_instance_dir: "{{ lookup('container', 'web-app-suitecrm', 'directories.instance') }}" @@ -14,13 +14,13 @@ nextcloud_crm_client_secret: "{{ ('integration_suitecrm' ~ lookup('users', 'administrator').password) | hash('sha256') }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Probe whether the SuiteCRM partner container is running +- name: ๐Ÿ” Probe whether the SuiteCRM partner container is running command: > container inspect -f '{% raw %}{{.State.Running}}{% endraw %}' {{ nextcloud_crm_container }} register: integration_suitecrm_partner_running changed_when: false failed_when: false -- name: Provision the bidirectional SuiteCRM <-> Nextcloud OAuth coupling +- name: ๐Ÿ”ง Provision the bidirectional SuiteCRM <-> Nextcloud OAuth coupling include_tasks: "{{ [role_path, 'tasks/addons/integration_suitecrm_provision.yml'] | path_join }}" when: (integration_suitecrm_partner_running.stdout | trim) == 'true' diff --git a/roles/web-app-nextcloud/tasks/addons/integration_suitecrm_provision.yml b/roles/web-app-nextcloud/tasks/addons/integration_suitecrm_provision.yml index 78ee313dd2..1433d49a9b 100644 --- a/roles/web-app-nextcloud/tasks/addons/integration_suitecrm_provision.yml +++ b/roles/web-app-nextcloud/tasks/addons/integration_suitecrm_provision.yml @@ -1,12 +1,12 @@ --- -- name: Wait for the SuiteCRM web endpoint +- name: โณ Wait for the SuiteCRM web endpoint wait_for: host: "{{ lookup('domain', 'web-app-suitecrm') }}" port: 80 delay: 5 timeout: 600 -- name: Provision (idempotently) the SuiteCRM OAuth2 password client and capture credentials +- name: ๐Ÿ”ง Provision SuiteCRM OAuth2 password client (idempotent), capture credentials ansible.builtin.command: argv: - container @@ -27,12 +27,12 @@ changed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Parse the SuiteCRM OAuth client credentials +- name: ๐Ÿ”Ž Parse the SuiteCRM OAuth client credentials set_fact: nextcloud_crm_client_id: "{{ nextcloud_crm_provision.stdout | regex_search('CLIENT_ID=(.+)', '\\1') | first }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Link the SuiteCRM OAuth password client into integration_suitecrm +- name: ๐Ÿ”— Link the SuiteCRM OAuth password client into integration_suitecrm command: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} config:app:set integration_suitecrm {{ item.key }} --value '{{ item.value }}' diff --git a/roles/web-app-nextcloud/tasks/addons/integration_zammad.yml b/roles/web-app-nextcloud/tasks/addons/integration_zammad.yml index 7d73d1af04..4cb20c9f96 100644 --- a/roles/web-app-nextcloud/tasks/addons/integration_zammad.yml +++ b/roles/web-app-nextcloud/tasks/addons/integration_zammad.yml @@ -4,28 +4,28 @@ # application is registered on the partner Zammad. This hook provisions that application on # the partner and writes the returned credentials into Nextcloud, encrypted the same way the # integration_gitlab coupling does. -- name: Resolve Zammad integration provisioning facts +- name: ๐Ÿ” Resolve Zammad integration provisioning facts set_fact: nextcloud_zammad_container: "zammad-railsserver" nextcloud_zammad_base_url: "{{ lookup('tls', 'web-app-zammad', 'url.base') | regex_replace('/$', '') }}" nextcloud_zammad_nc_base_url: "{{ lookup('tls', 'web-app-nextcloud', 'url.base') | regex_replace('/$', '') }}" changed_when: false -- name: Probe whether the Zammad partner container is running +- name: ๐Ÿ” Probe whether the Zammad partner container is running command: > container inspect -f '{% raw %}{{.State.Running}}{% endraw %}' {{ nextcloud_zammad_container }} register: nextcloud_zammad_partner_running changed_when: false failed_when: false -- name: Read persisted integration_zammad OAuth client id +- name: ๐Ÿ“– Read persisted integration_zammad OAuth client id command: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} config:app:get integration_zammad client_id register: nextcloud_zammad_client_id_current changed_when: false failed_when: false -- name: Read persisted integration_zammad OAuth client secret +- name: ๐Ÿ“– Read persisted integration_zammad OAuth client secret command: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} config:app:get integration_zammad client_secret register: nextcloud_zammad_client_secret_current @@ -33,7 +33,7 @@ failed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Provision the Zammad <-> Nextcloud OAuth coupling +- name: ๐Ÿ”ง Provision the Zammad <-> Nextcloud OAuth coupling include_tasks: "{{ [role_path, 'tasks/addons/integration_zammad_provision.yml'] | path_join }}" when: >- (nextcloud_zammad_partner_running.stdout | trim) == 'true' diff --git a/roles/web-app-nextcloud/tasks/addons/integration_zammad_provision.yml b/roles/web-app-nextcloud/tasks/addons/integration_zammad_provision.yml index a39cd004ae..8dc73003fe 100644 --- a/roles/web-app-nextcloud/tasks/addons/integration_zammad_provision.yml +++ b/roles/web-app-nextcloud/tasks/addons/integration_zammad_provision.yml @@ -1,5 +1,5 @@ --- -- name: Provision the Zammad OAuth application for Nextcloud and capture credentials +- name: ๐Ÿ”ง Provision the Zammad OAuth application for Nextcloud and capture credentials ansible.builtin.command: argv: - container @@ -22,24 +22,24 @@ changed_when: "'CLIENT_ID=' in nextcloud_zammad_provision.stdout" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Parse the Zammad OAuth client id +- name: ๐Ÿ”Ž Parse the Zammad OAuth client id set_fact: nextcloud_zammad_client_id: "{{ nextcloud_zammad_provision.stdout | regex_search('CLIENT_ID=(.+)', '\\1') | first }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Resolve the Zammad OAuth client secret (freshly emitted or persisted) +- name: ๐Ÿ” Resolve the Zammad OAuth client secret (freshly emitted or persisted) set_fact: nextcloud_zammad_fresh_secret: "{{ (nextcloud_zammad_provision.stdout | regex_search('CLIENT_SECRET=(.+)', '\\1') | default([], true) | first | default('', true)) | trim }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Pick the effective Zammad OAuth client secret +- name: ๐ŸŽฏ Pick the effective Zammad OAuth client secret set_fact: nextcloud_zammad_client_secret: "{{ nextcloud_zammad_fresh_secret if (nextcloud_zammad_fresh_secret | length > 0) else (nextcloud_zammad_client_secret_current.stdout | trim) }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Fail when no usable Zammad OAuth client secret is available +- name: ๐Ÿ›‘ Fail when no usable Zammad OAuth client secret is available assert: that: - (nextcloud_zammad_client_id | default('') | trim) | length > 0 @@ -49,7 +49,7 @@ retrievable when the app is first created or its secret is renewed; reset the integration_zammad client_id/client_secret app config to re-provision. -- name: Point integration_zammad at the partner instance (admin OAuth instance URL) +- name: ๐Ÿ”‘ Point integration_zammad at the partner instance (admin OAuth instance URL) command: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} config:app:set integration_zammad oauth_instance_url @@ -57,7 +57,7 @@ register: nextcloud_zammad_oauth_url_set changed_when: "' set to ' in nextcloud_zammad_oauth_url_set.stdout" -- name: Store integration_zammad OAuth credentials Nextcloud-encrypted (sensitive, lazy) +- name: ๐Ÿ“ Store integration_zammad OAuth creds Nextcloud-encrypted (sensitive, lazy) ansible.builtin.command: argv: - container diff --git a/roles/web-app-nextcloud/tasks/addons/user_ldap.yml b/roles/web-app-nextcloud/tasks/addons/user_ldap.yml index 177d7fa3e4..7f30c0036b 100644 --- a/roles/web-app-nextcloud/tasks/addons/user_ldap.yml +++ b/roles/web-app-nextcloud/tasks/addons/user_ldap.yml @@ -1,16 +1,16 @@ --- # @See https://docs.nextcloud.com/server/latest/admin_manual/configuration_user/user_auth_ldap.html -- name: Resolve desired Nextcloud LDAP config ID +- name: ๐Ÿ” Resolve desired Nextcloud LDAP config ID set_fact: nextcloud_ldap_config_id: "{{ (NEXTCLOUD_LDAP_CONFIG_PREFIX | default('s01')) | string | trim }}" changed_when: false -- name: Check if desired Nextcloud LDAP config ID exists +- name: ๐Ÿ”Ž Check if desired Nextcloud LDAP config ID exists command: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} ldap:show-config {{ nextcloud_ldap_config_id }} register: nextcloud_ldap_config_probe changed_when: false failed_when: false -- name: Fail when LDAP config probe failed for unexpected reason +- name: ๐Ÿ›‘ Fail when LDAP config probe failed for unexpected reason fail: msg: >- Could not verify Nextcloud LDAP config '{{ nextcloud_ldap_config_id }}'. @@ -19,7 +19,7 @@ when: - nextcloud_ldap_config_probe.rc != 0 - "'Invalid configID' not in ((nextcloud_ldap_config_probe.stdout) ~ (nextcloud_ldap_config_probe.stderr))" -- name: Auto-create empty Nextcloud LDAP config when desired config ID is missing +- name: ๐Ÿ“ Auto-create empty Nextcloud LDAP config when desired config ID is missing command: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} ldap:create-empty-config register: nextcloud_ldap_config_create @@ -27,7 +27,7 @@ when: - nextcloud_ldap_config_probe.rc != 0 - "'Invalid configID' in ((nextcloud_ldap_config_probe.stdout) ~ (nextcloud_ldap_config_probe.stderr))" -- name: Re-check desired Nextcloud LDAP config ID after auto-create +- name: ๐Ÿ”Ž Re-check desired Nextcloud LDAP config ID after auto-create command: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} ldap:show-config {{ nextcloud_ldap_config_id }} register: nextcloud_ldap_config_reprobe @@ -36,7 +36,7 @@ when: - nextcloud_ldap_config_create is defined - nextcloud_ldap_config_create is changed -- name: Fail when desired LDAP config ID is still missing after auto-create +- name: ๐Ÿ›‘ Fail when desired LDAP config ID is still missing after auto-create assert: that: - nextcloud_ldap_config_reprobe.rc == 0 @@ -47,14 +47,14 @@ when: - nextcloud_ldap_config_create is defined - nextcloud_ldap_config_create is changed -- name: Set Nextcloud LDAP bind password +- name: ๐Ÿ”ง Set Nextcloud LDAP bind password command: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} ldap:set-config {{ nextcloud_ldap_config_id }} ldapAgentPassword "{{ LDAP.BIND_CREDENTIAL }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Activate Nextcloud LDAP configuration +- name: ๐ŸŸข Activate Nextcloud LDAP configuration command: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} ldap:set-config {{ nextcloud_ldap_config_id }} ldapConfigurationActive 1 -- name: Warm LDAP cache (to guaranty that all LDAP users are present) +- name: ๐Ÿ—‚๏ธ Warm LDAP cache (to guaranty that all LDAP users are present) command: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} ldap:search "" async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}" diff --git a/roles/web-app-nextcloud/tasks/main.yml b/roles/web-app-nextcloud/tasks/main.yml index 29501ffdce..b0e34723ef 100644 --- a/roles/web-app-nextcloud/tasks/main.yml +++ b/roles/web-app-nextcloud/tasks/main.yml @@ -1,10 +1,10 @@ --- -- name: Setup the full docker stack +- name: ๐Ÿ”ง Setup the full docker stack include_tasks: 01_fullstack.yml vars: domain: "{{ NEXTCLOUD_DOMAIN }}" http_port: "{{ NEXTCLOUD_PORT }}" -- name: "Nextcloud stack-host post-deploy (config, occ, plugins, admin)" +- name: "๐Ÿ–ฅ๏ธ Nextcloud stack-host post-deploy (config, occ, plugins, admin)" include_tasks: 08_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-nextcloud/tasks/plugin/01_install.yml b/roles/web-app-nextcloud/tasks/plugin/01_install.yml index b862c9448e..c2a9a6b5f5 100644 --- a/roles/web-app-nextcloud/tasks/plugin/01_install.yml +++ b/roles/web-app-nextcloud/tasks/plugin/01_install.yml @@ -1,12 +1,12 @@ --- # Install-behaviour flags sit at the top level for plugins entries, but under `config:` for addons entries. -- name: "Normalise install flags for {{ plugin_key }}" +- name: "๐Ÿ“ฆ Normalise install flags for {{ plugin_key }}" ansible.builtin.set_fact: plugin_incompatible: "{{ plugin_value.config.incompatible_plugins | default(plugin_value.incompatible_plugins | default([])) }}" plugin_mandatory: "{{ plugin_value.config.mandatory | default(plugin_value.mandatory | default(false)) }}" changed_when: false -- name: "Disable incompatible plugins for {{ plugin_key }} (batched shell, no async)" +- name: "๐Ÿ”ด Disable incompatible plugins for {{ plugin_key }} (batched shell, no async)" ansible.builtin.shell: | # do not set -e here; allow per-line fallbacks {% for incompatible_plugin in (plugin_incompatible | default([])) %} @@ -28,7 +28,7 @@ async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}" poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}" -- name: install {{ plugin_key }} nextcloud plugin +- name: ๐Ÿ“ฆ install {{ plugin_key }} nextcloud plugin # Clear NC appstore-fetcher cooldown (300s) before each attempt so retries # actually re-fetch the catalog instead of seeing cached empty after a first # transient failure right after container start. @@ -46,7 +46,7 @@ and not (install_result | nextcloud_install_status).unavailable changed_when: (install_result | nextcloud_install_status).changed -- name: "Fail: mandatory plugin {{ plugin_key }} is not installable on this Nextcloud version" +- name: "๐Ÿ›‘ Mandatory plugin {{ plugin_key }} not installable on this Nextcloud version" ansible.builtin.fail: msg: >- Mandatory Nextcloud plugin '{{ plugin_key }}' is @@ -57,7 +57,7 @@ - plugin_mandatory | bool - not (install_result | nextcloud_install_status).runnable -- name: "warn: {{ plugin_key }} cannot be installed on this Nextcloud version โ€” skipping" +- name: "๐Ÿ”ด Skip {{ plugin_key }}: not installable on this Nextcloud version" ansible.builtin.debug: msg: >- Plugin '{{ plugin_key }}' is {{ 'not compatible with' if (install_result | nextcloud_install_status).incompatible else 'not available on the appstore for' }} diff --git a/roles/web-app-nextcloud/tasks/plugin/02_enable.yml b/roles/web-app-nextcloud/tasks/plugin/02_enable.yml index 81548414a1..ee458ff5dd 100644 --- a/roles/web-app-nextcloud/tasks/plugin/02_enable.yml +++ b/roles/web-app-nextcloud/tasks/plugin/02_enable.yml @@ -1,5 +1,5 @@ --- -- name: enable {{ plugin_key }} nextcloud plugin +- name: ๐ŸŸข enable {{ plugin_key }} nextcloud plugin command: "{{ NEXTCLOUD_DOCKER_EXEC_OCC }} app:enable {{ plugin_key }}" register: enable_result failed_when: > @@ -9,17 +9,17 @@ enable_result.rc == 0 and ("already enabled" not in enable_result.stdout) -- name: "Classify {{ plugin_key }} enable result" +- name: "๐Ÿ”‘ Classify {{ plugin_key }} enable result" ansible.builtin.set_fact: plugin_enable_incompatible: "{{ (enable_result | nextcloud_install_status).incompatible }}" -- name: "warn: {{ plugin_key }} is incompatible with current Nextcloud version โ€” skipping enable+configure" +- name: "๐Ÿ”ด Skip {{ plugin_key }}: incompatible with Nextcloud version (enable+configure)" ansible.builtin.debug: msg: >- Plugin '{{ plugin_key }}' enable refused by occ: not compatible with the currently pinned Nextcloud server version. Skipping configure for this run. when: plugin_enable_incompatible -- name: "Configure {{ plugin_key }} (skipped when incompatible)" +- name: "๐Ÿ”ง Configure {{ plugin_key }} (skipped when incompatible)" ansible.builtin.include_tasks: 03_configure.yml when: not plugin_enable_incompatible diff --git a/roles/web-app-nextcloud/tasks/plugin/03_configure.yml b/roles/web-app-nextcloud/tasks/plugin/03_configure.yml index 11d9adf2b2..773cc89628 100644 --- a/roles/web-app-nextcloud/tasks/plugin/03_configure.yml +++ b/roles/web-app-nextcloud/tasks/plugin/03_configure.yml @@ -1,11 +1,11 @@ --- # Loaded via include_vars (not config lookup or lookup('file')) so the role-scoped vars referenced inside the payload render lazily in this task's scope. -- name: "Load {{ plugin_key }} addon spec from meta/addons/{{ plugin_key }}.yml" +- name: "๐Ÿ“„ Load {{ plugin_key }} addon spec from meta/addons/{{ plugin_key }}.yml" ansible.builtin.include_vars: file: "{{ [role_path, 'meta/addons', plugin_key ~ '.yml'] | path_join }}" name: addon_spec -- name: "Set plugin configuration (batched shell, no async)" +- name: "๐Ÿ”ง Set plugin configuration (batched shell, no async)" ansible.builtin.shell: | set -euo pipefail {% for item in (addon_spec.config.plugin_configuration | default([])) %} @@ -26,13 +26,13 @@ poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Check if {{ plugin_task_path }} exists +- name: ๐Ÿ”Ž Check if {{ plugin_task_path }} exists stat: path: "{{ plugin_task_path }}" delegate_to: localhost become: false register: plugin_tasks_file -- name: "include {{ plugin_task_path }}" +- name: "๐Ÿ“‚ include {{ plugin_task_path }}" include_tasks: "{{ plugin_task_path }}" when: plugin_tasks_file.stat.exists diff --git a/roles/web-app-odoo/tasks/01_init_database.yml b/roles/web-app-odoo/tasks/01_init_database.yml index 4cda1aed51..687fee09cf 100644 --- a/roles/web-app-odoo/tasks/01_init_database.yml +++ b/roles/web-app-odoo/tasks/01_init_database.yml @@ -2,7 +2,7 @@ # Initialize Odoo database and install core modules # Note: The PostgreSQL database is created by sys-svc-rdbms before this role runs -- name: Check if Odoo schema is initialized (ir_module_module table exists) +- name: ๐Ÿ”Ž Check if Odoo schema is initialized (ir_module_module table exists) database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -11,15 +11,15 @@ register: odoo_schema_exists ignore_errors: true -- name: Debug schema check result +- name: ๐Ÿ› Debug schema check result debug: msg: "Schema exists check: rows={{ odoo_schema_exists.rows | default('NOT DEFINED') }}, failed={{ odoo_schema_exists.failed | default(false) }}" when: MODE_DEBUG | bool -- name: Initialize Odoo database with core modules +- name: ๐ŸŽฌ Initialize Odoo database with core modules block: # Use container exec - the running container already has network access to postgres - - name: Run Odoo database initialization + - name: โ–ถ๏ธ Run Odoo database initialization ansible.builtin.shell: > container exec {{ ODOO_CONTAINER_ADDRESS }} odoo --no-http @@ -31,10 +31,10 @@ delay: 10 until: odoo_init.rc == 0 - - name: Restart Odoo container after initialization + - name: ๐Ÿ”„ Restart Odoo container after initialization ansible.builtin.command: container restart {{ ODOO_CONTAINER }} - - name: Wait for Odoo container to be healthy after init + - name: โณ Wait for Odoo container to be healthy after init ansible.builtin.command: container inspect --format {% raw %}'{{.State.Health.Status}}'{% endraw %} {{ ODOO_CONTAINER }} register: container_health until: container_health.stdout | trim == 'healthy' @@ -43,7 +43,7 @@ changed_when: false when: odoo_schema_exists.rows is not defined or odoo_schema_exists.rows | length == 0 -- name: Update existing Odoo modules (if schema exists) +- name: ๐Ÿ”„ Update existing Odoo modules (if schema exists) ansible.builtin.shell: > container exec {{ ODOO_CONTAINER_ADDRESS }} odoo --no-http diff --git a/roles/web-app-odoo/tasks/02_install_modules.yml b/roles/web-app-odoo/tasks/02_install_modules.yml index 47c376b12e..75a0e110c8 100644 --- a/roles/web-app-odoo/tasks/02_install_modules.yml +++ b/roles/web-app-odoo/tasks/02_install_modules.yml @@ -1,11 +1,11 @@ --- # Install Odoo modules -- name: "Build list of modules to install" +- name: "๐Ÿ”จ Build list of modules to install" set_fact: odoo_modules_to_install: "{{ (ODOO_MODULES_CORE + ODOO_MODULES_OPTIONAL) | join(',') }}" -- name: "Install core modules" +- name: "๐Ÿ“ฆ Install core modules" shell: > container exec {{ ODOO_CONTAINER_ADDRESS }} odoo -i {{ odoo_modules_to_install }} @@ -21,7 +21,7 @@ failed_when: false when: odoo_modules_to_install | length > 0 -- name: "Update installed modules" +- name: "๐Ÿ”„ Update installed modules" shell: > container exec {{ ODOO_CONTAINER_ADDRESS }} odoo -u all @@ -36,10 +36,10 @@ changed_when: "'loading' in module_update.stdout" failed_when: false -- name: "Install OIDC-related modules (auth_oauth + auth_signup + auth_oauth_https)" +- name: "๐Ÿ“ฆ Install OIDC-related modules (auth_oauth + auth_signup + auth_oauth_https)" when: ODOO_OIDC_ENABLED | bool block: - - name: "Install auth_oauth module for OIDC support" + - name: "๐Ÿ“ฆ Install auth_oauth module for OIDC support" shell: > container exec {{ ODOO_CONTAINER_ADDRESS }} odoo -i auth_oauth @@ -54,7 +54,7 @@ changed_when: "'loading' in auth_oauth_install.stdout" failed_when: false - - name: "Install auth_signup module for OAuth user auto-creation" + - name: "๐Ÿ“ฆ Install auth_signup module for OAuth user auto-creation" shell: > container exec {{ ODOO_CONTAINER_ADDRESS }} odoo -i auth_signup @@ -69,7 +69,7 @@ changed_when: "'loading' in auth_signup_install.stdout" failed_when: false - - name: "Install auth_oauth_https module for HTTPS redirect URI fix" + - name: "๐Ÿ“ฆ Install auth_oauth_https module for HTTPS redirect URI fix" shell: > container exec {{ ODOO_CONTAINER_ADDRESS }} odoo -i auth_oauth_https @@ -84,7 +84,7 @@ changed_when: "'loading' in auth_oauth_https_install.stdout" failed_when: false -- name: "Install auth_ldap module for LDAP support" +- name: "๐Ÿ“ฆ Install auth_ldap module for LDAP support" shell: > container exec {{ ODOO_CONTAINER_ADDRESS }} odoo -i auth_ldap diff --git a/roles/web-app-odoo/tasks/02_manager_ops.yml b/roles/web-app-odoo/tasks/02_manager_ops.yml index 59265d9043..32f70691b6 100644 --- a/roles/web-app-odoo/tasks/02_manager_ops.yml +++ b/roles/web-app-odoo/tasks/02_manager_ops.yml @@ -1,11 +1,11 @@ --- -- name: "Create Odoo addons directory" +- name: "๐Ÿ“ Create Odoo addons directory" file: path: "{{ ODOO_ADDONS_HOST }}" state: directory mode: "0755" -- name: "Deploy Odoo configuration file" +- name: "๐Ÿš€ Deploy Odoo configuration file" template: # nocheck: stack-host-template (odoo compose dir, not project nginx tree) src: "odoo.conf.j2" dest: "{{ ODOO_CONF_FILE_HOST }}" @@ -13,7 +13,7 @@ notify: - compose up -- name: "Copy custom addons" +- name: "๐Ÿ“‹ Copy custom addons" copy: src: "addons/" dest: "{{ ODOO_ADDONS_HOST }}" @@ -22,10 +22,10 @@ - compose up - compose build -- name: "Docker Compose Up for '{{ application_id }}'" +- name: "๐Ÿณ Docker Compose Up for '{{ application_id }}'" meta: flush_handlers -- name: "Wait for Odoo to be ready" +- name: "โณ Wait for Odoo to be ready" uri_retry: url: "http://127.0.0.1:{{ lookup('config', application_id, 'services.odoo.ports.local.http') }}/web/health" status_code: 200 @@ -36,19 +36,19 @@ delay: 10 ignore_errors: true -- name: "Initialize Odoo database" +- name: "๐ŸŽฌ Initialize Odoo database" include_tasks: 01_init_database.yml -- name: "Install core modules" +- name: "๐Ÿ“ฆ Install core modules" include_tasks: 02_install_modules.yml -- name: "Create administrator user" +- name: "๐Ÿ“ Create administrator user" include_tasks: 05_admin.yml -- name: "Configure OIDC provider" +- name: "๐Ÿ”ง Configure OIDC provider" include_tasks: 03_oidc.yml when: ODOO_OIDC_ENABLED | bool -- name: "Configure LDAP authentication" +- name: "๐Ÿ”ง Configure LDAP authentication" include_tasks: 04_ldap.yml when: ODOO_LDAP_ENABLED | bool diff --git a/roles/web-app-odoo/tasks/03_oidc.yml b/roles/web-app-odoo/tasks/03_oidc.yml index 766eff946e..0932d86f27 100644 --- a/roles/web-app-odoo/tasks/03_oidc.yml +++ b/roles/web-app-odoo/tasks/03_oidc.yml @@ -1,5 +1,5 @@ --- -- name: "Check if Keycloak OAuth provider exists" +- name: "๐Ÿ”Ž Check if Keycloak OAuth provider exists" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -7,7 +7,7 @@ expect_rows: true register: oauth_check -- name: "Update existing Keycloak OAuth provider" +- name: "๐Ÿ”„ Update existing Keycloak OAuth provider" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -18,7 +18,7 @@ client_id: "{{ ODOO_OIDC_CLIENT_ID }}" when: oauth_check.rows | length > 0 -- name: "Create new Keycloak OAuth provider" +- name: "๐Ÿ“ Create new Keycloak OAuth provider" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -29,7 +29,7 @@ client_id: "{{ ODOO_OIDC_CLIENT_ID }}" when: oauth_check.rows | length == 0 -- name: "Enable OAuth authentication in system parameters" +- name: "๐ŸŸข Enable OAuth authentication in system parameters" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -38,7 +38,7 @@ key: "auth_oauth.oauth_providers" value: "True" -- name: "Enable OAuth signup (allow user creation on first OAuth login)" +- name: "๐ŸŸข Enable OAuth signup (allow user creation on first OAuth login)" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -47,7 +47,7 @@ key: "auth_signup.invitation_scope" value: "b2c" -- name: "Allow uninvited OAuth signup on website" +- name: "๐Ÿ”‘ Allow uninvited OAuth signup on website" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -56,7 +56,7 @@ # Create an internal user template for OAuth signup. New users # inherit this user's groups via base.template_portal_user_id / # auth_signup.template_user_id. -- name: "Check if OAuth template user exists" +- name: "๐Ÿ”Ž Check if OAuth template user exists" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -64,7 +64,7 @@ expect_rows: true register: oauth_template_check -- name: "Create OAuth template partner" +- name: "๐Ÿ“ Create OAuth template partner" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -73,7 +73,7 @@ register: oauth_template_partner when: oauth_template_check.rows | length == 0 -- name: "Create OAuth template user" +- name: "๐Ÿ“ Create OAuth template user" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -86,19 +86,19 @@ - oauth_template_partner.rows is defined - oauth_template_partner.rows | length > 0 -- name: "Ensure OAuth template user is active" +- name: "โœ… Ensure OAuth template user is active" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" query_file: "{{ role_path }}/files/sql/oidc/update-activate-oauth-template.sql" -- name: "Grant Internal User group to OAuth template" +- name: "๐Ÿ” Grant Internal User group to OAuth template" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" query_file: "{{ role_path }}/files/sql/oidc/grant-internal-user-to-oauth-template.sql" -- name: "Grant company access to OAuth template" +- name: "๐Ÿ” Grant company access to OAuth template" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -109,7 +109,7 @@ # _create_user_from_template() during signup. # - auth_signup.template_user_id is what the Odoo UI settings page # displays; we set both for consistency. -- name: "Set OAuth template user for signup (base.template_portal_user_id)" +- name: "๐Ÿ”ง Set OAuth template user for signup (base.template_portal_user_id)" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -117,7 +117,7 @@ named_args: key: "base.template_portal_user_id" -- name: "Set OAuth template user for signup (auth_signup.template_user_id)" +- name: "๐Ÿ”ง Set OAuth template user for signup (auth_signup.template_user_id)" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -125,7 +125,7 @@ named_args: key: "auth_signup.template_user_id" -- name: "Use Authorization header for OAuth token validation" +- name: "๐Ÿ”‘ Use Authorization header for OAuth token validation" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -134,7 +134,7 @@ key: "auth_oauth.authorization_header" value: "True" -- name: "Set web.base.url for HTTPS redirects" +- name: "๐Ÿ”ง Set web.base.url for HTTPS redirects" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -143,7 +143,7 @@ key: "web.base.url" value: "{{ ODOO_URL }}" -- name: "Freeze web.base.url to prevent automatic detection" +- name: "๐ŸงŠ Freeze web.base.url to prevent automatic detection" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -155,14 +155,14 @@ # Repair fallback for users created before # base.template_portal_user_id was set correctly. New OAuth signups # inherit the group from the template, but legacy users do not. -- name: "Grant Internal User group to OAuth-created users" +- name: "๐Ÿ” Grant Internal User group to OAuth-created users" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" query_file: "{{ role_path }}/files/sql/oidc/grant-internal-user-to-oauth-users-repair.sql" # Link existing Odoo users to Keycloak for SSO. -- name: "Get Keycloak OAuth provider id in Odoo" +- name: "โฌ‡๏ธ Get Keycloak OAuth provider id in Odoo" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -170,7 +170,7 @@ expect_rows: true register: keycloak_provider -- name: "Query Keycloak DB for administrator username" +- name: "๐Ÿ” Query Keycloak DB for administrator username" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', 'web-app-keycloak') }}" @@ -182,7 +182,7 @@ register: keycloak_users when: keycloak_provider.rows | length > 0 -- name: "Link administrator user to Keycloak in Odoo" +- name: "๐Ÿ”— Link administrator user to Keycloak in Odoo" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -198,14 +198,14 @@ # Auto-created OAuth users get portal access by default. Promote # them to internal-user + default-company so they can reach the # main Odoo interface. -- name: "Grant internal user access to OAuth-created users" +- name: "๐Ÿ” Grant internal user access to OAuth-created users" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" query_file: "{{ role_path }}/files/sql/oidc/grant-internal-user-to-oauth-signup-users.sql" when: keycloak_provider.rows | length > 0 -- name: "Grant company access to OAuth-created users" +- name: "๐Ÿ” Grant company access to OAuth-created users" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" diff --git a/roles/web-app-odoo/tasks/04_ldap.yml b/roles/web-app-odoo/tasks/04_ldap.yml index b53b3cd372..4da3d520bc 100644 --- a/roles/web-app-odoo/tasks/04_ldap.yml +++ b/roles/web-app-odoo/tasks/04_ldap.yml @@ -2,7 +2,7 @@ # Configure LDAP authentication for Odoo # ODOO_LDAP_CONFIG is defined in vars/main.yml -- name: "Check if LDAP configuration exists" +- name: "๐Ÿ”Ž Check if LDAP configuration exists" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -12,7 +12,7 @@ expect_rows: true register: ldap_check -- name: "Update existing LDAP configuration" +- name: "๐Ÿ”„ Update existing LDAP configuration" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -30,7 +30,7 @@ ldap_server: "{{ ODOO_LDAP_CONFIG.ldap_server }}" when: ldap_check.rows | length > 0 -- name: "Create new LDAP configuration" +- name: "๐Ÿ“ Create new LDAP configuration" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" diff --git a/roles/web-app-odoo/tasks/05_admin.yml b/roles/web-app-odoo/tasks/05_admin.yml index 2b0681891b..ae3ab4d67b 100644 --- a/roles/web-app-odoo/tasks/05_admin.yml +++ b/roles/web-app-odoo/tasks/05_admin.yml @@ -1,7 +1,7 @@ --- # Create or update Odoo administrator user -- name: "Check if administrator user exists" +- name: "๐Ÿ”Ž Check if administrator user exists" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -11,7 +11,7 @@ expect_rows: true register: admin_check -- name: "Update administrator user password and email" +- name: "๐Ÿ”„ Update administrator user password and email" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -21,7 +21,7 @@ login: "{{ ODOO_ADMINISTRATOR_USERNAME }}" when: admin_check.rows | length > 0 -- name: "Update administrator partner email" +- name: "๐Ÿ”„ Update administrator partner email" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -31,7 +31,7 @@ login: "{{ ODOO_ADMINISTRATOR_USERNAME }}" when: admin_check.rows | length > 0 -- name: "Update default admin user credentials (user id 2)" +- name: "๐Ÿ”„ Update default admin user credentials (user id 2)" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -41,7 +41,7 @@ password: "{{ ODOO_ADMINISTRATOR_PASSWORD }}" when: admin_check.rows | length == 0 -- name: "Update default admin partner details" +- name: "๐Ÿ”„ Update default admin partner details" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" diff --git a/roles/web-app-odoo/tasks/main.yml b/roles/web-app-odoo/tasks/main.yml index 9f6c1446d1..185558b481 100644 --- a/roles/web-app-odoo/tasks/main.yml +++ b/roles/web-app-odoo/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: @@ -7,6 +7,6 @@ webserver_vhost_flavour: "ws_generic" webserver_websocket_location: "/websocket" -- name: "web-app-odoo manager-side operations (file deploys + container exec)" +- name: "๐Ÿ‘” web-app-odoo manager-side operations (file deploys + container exec)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-opencloud/tasks/main.yml b/roles/web-app-opencloud/tasks/main.yml index 22e23c1e66..f8e119cda2 100644 --- a/roles/web-app-opencloud/tasks/main.yml +++ b/roles/web-app-opencloud/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: diff --git a/roles/web-app-openproject/tasks/01_core.yml b/roles/web-app-openproject/tasks/01_core.yml index 893cc16673..ab23868ac3 100644 --- a/roles/web-app-openproject/tasks/01_core.yml +++ b/roles/web-app-openproject/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: @@ -12,6 +12,6 @@ compose_handlers_flush: false application_id: "web-app-openproject" -- name: "OpenProject manager-side operations (file deploys + container exec)" +- name: "๐Ÿ‘” OpenProject manager-side operations (file deploys + container exec)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-openproject/tasks/01_settings.yml b/roles/web-app-openproject/tasks/01_settings.yml index d0e3197abe..98857cb4ce 100644 --- a/roles/web-app-openproject/tasks/01_settings.yml +++ b/roles/web-app-openproject/tasks/01_settings.yml @@ -3,7 +3,7 @@ # It waits for the web container to be running, ensures migrations are applied, # then sets all configured settings via rails runner fed from STDIN (robust quoting). -- name: Wait until OpenProject web container is running +- name: โณ Wait until OpenProject web container is running shell: > container inspect -f '{{"{{"}}.State.Status{{"}}"}}' {{ OPENPROJECT_WEB_CONTAINER }} register: openproject_web_state @@ -12,7 +12,7 @@ until: openproject_web_state.stdout.strip() == "running" changed_when: false -- name: Run database migrations +- name: โ–ถ๏ธ Run database migrations shell: > container exec -i {{ OPENPROJECT_WEB_CONTAINER_ADDRESS | quote }} bash -lc "cd /app && bin/rails db:migrate RAILS_ENV=production" @@ -21,7 +21,7 @@ delay: 10 until: openproject_migrate.rc == 0 -- name: Wait until OpenProject web container is running (after migrations) +- name: โณ Wait until OpenProject web container is running (after migrations) shell: > container inspect -f '{{"{{"}}.State.Status{{"}}"}}' {{ OPENPROJECT_WEB_CONTAINER }} register: openproject_web_state_after_migrate @@ -30,7 +30,7 @@ until: openproject_web_state_after_migrate.stdout.strip() == "running" changed_when: false -- name: Set settings in OpenProject (rails runner via STDIN from an external script) +- name: ๐Ÿ”ง Set settings in OpenProject (rails runner via STDIN from an external script) ansible.builtin.command: argv: - container diff --git a/roles/web-app-openproject/tasks/02_ldap.yml b/roles/web-app-openproject/tasks/02_ldap.yml index a4b067655c..581e23823b 100644 --- a/roles/web-app-openproject/tasks/02_ldap.yml +++ b/roles/web-app-openproject/tasks/02_ldap.yml @@ -1,9 +1,9 @@ --- -- name: Load LDAP configuration variables +- name: โš™๏ธ Load LDAP configuration variables include_vars: file: "ldap.yml" -- name: Check if LDAP source exists +- name: ๐Ÿ”Ž Check if LDAP source exists database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -13,7 +13,7 @@ expect_rows: true register: ldap_check -- name: Update existing LDAP auth source +- name: ๐Ÿ”„ Update existing LDAP auth source database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -37,7 +37,7 @@ name: "{{ OPENPROJECT_LDAP.name }}" when: ldap_check.rows | length > 0 -- name: Create new LDAP auth source +- name: ๐Ÿ“ Create new LDAP auth source database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" diff --git a/roles/web-app-openproject/tasks/02_manager_ops.yml b/roles/web-app-openproject/tasks/02_manager_ops.yml index 2cfcfd25a9..b5f6d9c4da 100644 --- a/roles/web-app-openproject/tasks/02_manager_ops.yml +++ b/roles/web-app-openproject/tasks/02_manager_ops.yml @@ -1,11 +1,11 @@ --- -- name: "Create {{ OPENPROJECT_PLUGINS_FOLDER }}" +- name: "๐Ÿ“ Create {{ OPENPROJECT_PLUGINS_FOLDER }}" file: path: "{{ OPENPROJECT_PLUGINS_FOLDER }}" state: directory mode: "0755" -- name: "Transferring Gemfile to {{ OPENPROJECT_PLUGINS_FOLDER }} as Gemfile.plugins" +- name: "๐Ÿ“ Transferring Gemfile to {{ OPENPROJECT_PLUGINS_FOLDER }} as Gemfile.plugins" copy: src: Gemfile dest: "{{ [OPENPROJECT_PLUGINS_FOLDER,'Gemfile.plugins'] | path_join }}" @@ -13,21 +13,21 @@ - compose up - compose build -- name: "create {{ OPENPROJECT_DUMMY_DIR }}" +- name: "๐Ÿ“ create {{ OPENPROJECT_DUMMY_DIR }}" file: path: "{{ OPENPROJECT_DUMMY_DIR }}" state: directory mode: "0755" -- name: flush docker service +- name: ๐Ÿšฟ flush docker service meta: flush_handlers -- name: Deploy Settings +- name: ๐Ÿš€ Deploy Settings include_tasks: 01_settings.yml -- name: Setup LDAP +- name: ๐Ÿ”ง Setup LDAP include_tasks: 02_ldap.yml when: OPENPROJECT_LDAP_ENABLED | bool -- name: Create OpenProject Administrator +- name: ๐Ÿ“ Create OpenProject Administrator include_tasks: 03_admin.yml diff --git a/roles/web-app-openproject/tasks/03_admin.yml b/roles/web-app-openproject/tasks/03_admin.yml index 88102aff1d..8a78b284a0 100644 --- a/roles/web-app-openproject/tasks/03_admin.yml +++ b/roles/web-app-openproject/tasks/03_admin.yml @@ -1,5 +1,5 @@ --- -- name: Ensure administrator user exists and is admin +- name: โœ… Ensure administrator user exists and is admin ansible.builtin.command: argv: - container @@ -18,7 +18,7 @@ stdin: "{{ lookup('file', 'ruby/ensure_admin_user.rb') }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: Link administrator to the LDAP auth source so the trusted-header bridge can resolve it +- name: ๐Ÿ”ง Link admin to LDAP auth source so trusted-header bridge can resolve it ansible.builtin.command: argv: - container diff --git a/roles/web-app-openproject/tasks/main.yml b/roles/web-app-openproject/tasks/main.yml index 953062dd98..1241d31ac6 100644 --- a/roles/web-app-openproject/tasks/main.yml +++ b/roles/web-app-openproject/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "Execute Role (once)" +- name: "โ–ถ๏ธ Execute Role (once)" include_tasks: 01_core.yml when: run_once_web_app_openproject is not defined vars: diff --git a/roles/web-app-opentalk/tasks/02_manager_ops.yml b/roles/web-app-opentalk/tasks/02_manager_ops.yml index b5879f9dec..f382286339 100644 --- a/roles/web-app-opentalk/tasks/02_manager_ops.yml +++ b/roles/web-app-opentalk/tasks/02_manager_ops.yml @@ -1,5 +1,5 @@ --- -- name: "Render OpenTalk controller config '{{ application_id }}'" +- name: "๐Ÿ“„ Render OpenTalk controller config '{{ application_id }}'" stack_host_template: src: controller.toml.j2 dest: "{{ [lookup('container', application_id, 'directories.volumes'), 'controller.toml'] | path_join }}" @@ -7,7 +7,7 @@ notify: - compose up -- name: "Render LiveKit config '{{ application_id }}'" +- name: "๐Ÿ“„ Render LiveKit config '{{ application_id }}'" stack_host_template: src: livekit.yaml.j2 dest: "{{ [lookup('container', application_id, 'directories.volumes'), 'livekit.yaml'] | path_join }}" @@ -15,7 +15,7 @@ notify: - compose up -- name: "Render OpenTalk recorder config '{{ application_id }}'" +- name: "๐Ÿ“„ Render OpenTalk recorder config '{{ application_id }}'" stack_host_template: src: recorder.toml.j2 dest: "{{ [lookup('container', application_id, 'directories.volumes'), 'recorder.toml'] | path_join }}" @@ -23,14 +23,14 @@ notify: - compose up -- name: "Flush handlers for '{{ application_id }}' so compose up sees rendered configs" +- name: "๐Ÿšฟ Flush handlers for '{{ application_id }}' so compose up sees rendered configs" meta: flush_handlers # The shared `infinito.nexus` realm client is public, so it cannot # introspect access tokens. Provision a dedicated confidential client # (`opentalk-controller`) with a service account that can call the # Keycloak admin API and the OIDC introspection endpoint. -- name: "Authenticate kcadm against the master realm (for OpenTalk client provisioning)" +- name: "โœ… Authenticate kcadm against master realm for OpenTalk provisioning" ansible.builtin.shell: |- {{ KEYCLOAK_EXEC_CONTAINER }} sh -lc ' set -e @@ -47,7 +47,7 @@ changed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Upsert dedicated confidential Keycloak client for the OpenTalk controller" +- name: "๐Ÿ“ Upsert dedicated confidential Keycloak client for the OpenTalk controller" keycloak_kcadm_update: object_kind: "client" lookup_value: "{{ OPENTALK_CTRL_OIDC_CLIENT_ID }}" @@ -78,7 +78,7 @@ assert_mode: "{{ MODE_ASSERT | bool }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Upsert dedicated confidential Keycloak client for the OpenTalk recorder" +- name: "๐Ÿ“ Upsert dedicated confidential Keycloak client for the OpenTalk recorder" keycloak_kcadm_update: object_kind: "client" lookup_value: "{{ OPENTALK_RECORDER_OIDC_CLIENT_ID }}" @@ -109,7 +109,7 @@ assert_mode: "{{ MODE_ASSERT | bool }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Grant the OpenTalk controller's service account the realm-management `view-users` role" +- name: "๐Ÿ” Grant OpenTalk controller service account `view-users` role" ansible.builtin.shell: |- {{ KCEXEC }} sh -lc ' set -e @@ -128,13 +128,13 @@ changed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Restart the OpenTalk controller so it picks up the refreshed introspection client" +- name: "๐Ÿ”„ Restart OpenTalk controller to pick up refreshed introspection client" ansible.builtin.command: "container restart {{ OPENTALK_CTRL_CONTAINER }}" changed_when: true # The shared (shared:true) path provisions the bucket on the central provider # via sys-svc-objstore; only the embedded instance needs its bucket created here. -- name: "Wait until the embedded object store answers" +- name: "โณ Wait until the embedded object store answers" ansible.builtin.shell: > container exec {{ OPENTALK_OBJSTORE_CONTAINER_ADDRESS }} wget -q -O - http://127.0.0.1:{{ lookup('objstore', application_id, 'port') }}/status @@ -147,7 +147,7 @@ changed_when: false when: lookup('objstore', application_id, 'local') | bool -- name: "List embedded object-store buckets" +- name: "๐Ÿ“‹ List embedded object-store buckets" ansible.builtin.shell: | set -euo pipefail echo 's3.bucket.list' | container exec -i {{ OPENTALK_OBJSTORE_CONTAINER_ADDRESS }} weed shell -master=localhost:9333 @@ -157,7 +157,7 @@ changed_when: false when: lookup('objstore', application_id, 'local') | bool -- name: "Ensure the OpenTalk bucket exists (embedded)" +- name: "โœ… Ensure the OpenTalk bucket exists (embedded)" ansible.builtin.shell: | set -euo pipefail echo 's3.bucket.create -name {{ lookup('objstore', application_id, 'bucket') }}' | container exec -i {{ OPENTALK_OBJSTORE_CONTAINER_ADDRESS }} weed shell -master=localhost:9333 diff --git a/roles/web-app-opentalk/tasks/main.yml b/roles/web-app-opentalk/tasks/main.yml index 4a6b6cf750..84bd55df75 100644 --- a/roles/web-app-opentalk/tasks/main.yml +++ b/roles/web-app-opentalk/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: @@ -9,6 +9,6 @@ # controller and media server through the canonical hostname. webserver_extra_configuration: "{{ lookup('template', 'nginx/extra.conf.j2') }}" -- name: "OpenTalk manager-side operations (file deploys + container exec)" +- name: "๐Ÿ‘” OpenTalk manager-side operations (file deploys + container exec)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-openwebui/tasks/01_core.yml b/roles/web-app-openwebui/tasks/01_core.yml index ce627e6f06..be0509b805 100644 --- a/roles/web-app-openwebui/tasks/01_core.yml +++ b/roles/web-app-openwebui/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: "load docker, proxy for '{{ application_id }}'" +- name: "๐Ÿงฉ load docker, proxy for '{{ application_id }}'" include_role: name: sys-stk-full vars: diff --git a/roles/web-app-openwebui/tasks/main.yml b/roles/web-app-openwebui/tasks/main.yml index dd0faf4e12..6da8caa9ef 100644 --- a/roles/web-app-openwebui/tasks/main.yml +++ b/roles/web-app-openwebui/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "Execute Role (once)" +- name: "โ–ถ๏ธ Execute Role (once)" include_tasks: 01_core.yml when: run_once_web_app_openwebui is not defined vars: diff --git a/roles/web-app-peertube/tasks/01_core.yml b/roles/web-app-peertube/tasks/01_core.yml index 3811210b0c..c17ddd0dec 100644 --- a/roles/web-app-peertube/tasks/01_core.yml +++ b/roles/web-app-peertube/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: "include 01_create-domains.yml for peertube" +- name: "๐Ÿ“‚ include 01_create-domains.yml for peertube" include_tasks: 01_create-domains.yml loop: "{{ lookup('domains', application_id) }}" loop_control: @@ -10,12 +10,12 @@ http_port: "{{ lookup('config', application_id, 'services.peertube.ports.local.http') }}" websocket_port: "{{ lookup('config', application_id, 'services.peertube.ports.local.http') }}" -- name: "load docker and db for {{ application_id }}" +- name: "๐Ÿงฉ load docker and db for {{ application_id }}" include_role: name: sys-stk-backend vars: compose_handlers_flush: true -- name: "Execute stack host routines" +- name: "โ–ถ๏ธ Execute stack host routines" include_tasks: 02_stack_host.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-peertube/tasks/01_create-domains.yml b/roles/web-app-peertube/tasks/01_create-domains.yml index a24371b406..ac031b5ebf 100644 --- a/roles/web-app-peertube/tasks/01_create-domains.yml +++ b/roles/web-app-peertube/tasks/01_create-domains.yml @@ -1,9 +1,9 @@ --- -- name: "CSP/INJ | Apply global injections for {{ domain }}" +- name: "๐Ÿ“Œ CSP/INJ | Apply global injections for {{ domain }}" ansible.builtin.include_role: name: sys-front-inj-all -- name: configure {{ domain }}.conf +- name: ๐Ÿ”ง configure {{ domain }}.conf stack_host_template: src: "templates/peertube.conf.j2" dest: "{{ lookup('nginx', 'files.domain', domain) }}" diff --git a/roles/web-app-peertube/tasks/02_stack_host.yml b/roles/web-app-peertube/tasks/02_stack_host.yml index c3ba74e655..4f09f81f49 100644 --- a/roles/web-app-peertube/tasks/02_stack_host.yml +++ b/roles/web-app-peertube/tasks/02_stack_host.yml @@ -1,11 +1,11 @@ --- -- name: "PEERTUBE | Patch the `application` table so the bootstrap INSERT survives fresh installs" +- name: "๐Ÿ”ง PEERTUBE | Patch `application` table so bootstrap INSERT survives installs" include_tasks: 03_fix-application-schema.yml -- name: "Install and activate auth-openid-connect plugin if OIDC is enabled" +- name: "๐Ÿ“ฆ Install and activate auth-openid-connect plugin if OIDC is enabled" include_tasks: oidc/enable.yml when: PEERTUBE_OIDC_ENABLED | bool -- name: "Deinstall and disable auth-openid-connect plugin if OIDC is disabled" +- name: "๐Ÿ”ด Deinstall and disable auth-openid-connect plugin if OIDC is disabled" include_tasks: oidc/disable.yml when: not PEERTUBE_OIDC_ENABLED | bool diff --git a/roles/web-app-peertube/tasks/03_fix-application-schema.yml b/roles/web-app-peertube/tasks/03_fix-application-schema.yml index 85af26e0a6..3016933a2c 100644 --- a/roles/web-app-peertube/tasks/03_fix-application-schema.yml +++ b/roles/web-app-peertube/tasks/03_fix-application-schema.yml @@ -27,7 +27,7 @@ # in non-shared mode). Running inside the container side-steps the # controller-side TCP reachability gap that affects non-shared deploys. -- name: "PEERTUBE | Wait for peertube to create the `application` table" +- name: "โณ PEERTUBE | Wait for peertube to create the `application` table" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -42,7 +42,7 @@ and (_peertube_app_table_check.rows[0][0] | default('')) == 'application' changed_when: false -- name: "PEERTUBE | Back-fill column defaults so the bootstrap INSERT does not violate NOT NULL" +- name: "๐Ÿ”ง PEERTUBE | Back-fill column defaults so bootstrap INSERT keeps NOT NULL" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -50,7 +50,7 @@ register: _peertube_app_defaults notify: compose up -- name: "PEERTUBE | Wait for peertube container to become healthy after schema back-fill" +- name: "โณ PEERTUBE | Wait for peertube container healthy after schema back-fill" ansible.builtin.command: argv: - container diff --git a/roles/web-app-peertube/tasks/main.yml b/roles/web-app-peertube/tasks/main.yml index 0149e71522..e054a7c0b2 100644 --- a/roles/web-app-peertube/tasks/main.yml +++ b/roles/web-app-peertube/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "Execute Role (once)" +- name: "โ–ถ๏ธ Execute Role (once)" include_tasks: 01_core.yml when: run_once_web_app_peertube is not defined vars: diff --git a/roles/web-app-peertube/tasks/oidc/disable.yml b/roles/web-app-peertube/tasks/oidc/disable.yml index 3297b0a3c9..270a7b9d24 100644 --- a/roles/web-app-peertube/tasks/oidc/disable.yml +++ b/roles/web-app-peertube/tasks/oidc/disable.yml @@ -1,5 +1,5 @@ --- -- name: "Uninstall auth-openid-connect plugin for Peertube" +- name: "๐Ÿ—‘๏ธ Uninstall auth-openid-connect plugin for Peertube" shell: > container exec {{ PEERTUBE_CONTAINER_ADDRESS }} \ npm run plugin:uninstall -- --npm-name {{ PEERTUBE_OIDC_PLUGIN }} diff --git a/roles/web-app-peertube/tasks/oidc/enable.yml b/roles/web-app-peertube/tasks/oidc/enable.yml index b22a7c5110..a7db78b606 100644 --- a/roles/web-app-peertube/tasks/oidc/enable.yml +++ b/roles/web-app-peertube/tasks/oidc/enable.yml @@ -1,16 +1,16 @@ --- -- name: "Load OIDC Settings for Peertube" +- name: "โš™๏ธ Load OIDC Settings for Peertube" include_vars: vars/oidc-settings.yml changed_when: false -- name: Check if OIDC plugin is already installed +- name: ๐Ÿ”Ž Check if OIDC plugin is already installed shell: > container exec {{ PEERTUBE_CONTAINER_ADDRESS }} test -d /data/plugins/data/peertube-plugin-auth-openid-connect register: peertube_oidc_plugin_check failed_when: false changed_when: false -- name: "Install auth-openid-connect plugin for Peertube (with temp mem_limit bump + diagnostics on failure)" +- name: "๐Ÿ“ฆ Install auth-openid-connect plugin for Peertube (mem_limit bump + diagnostics)" when: peertube_oidc_plugin_check.rc != 0 block: # Raise the container cgroup ceiling for the duration of the install. @@ -21,7 +21,7 @@ # as "Container is restarting" on subsequent exec attempts. # --memory-swap -1 allows unlimited swap for the install window (host # has a 16G swapfile from issue #162). - - name: "PEERTUBE | Raise mem_limit for plugin install" + - name: "๐Ÿ“ฆ PEERTUBE | Raise mem_limit for plugin install" ansible.builtin.command: >- container update --memory {{ PEERTUBE_OIDC_PLUGIN_INSTALL_MEM_LIMIT }} @@ -29,7 +29,7 @@ {{ PEERTUBE_CONTAINER }} changed_when: true - - name: "Install auth-openid-connect plugin for Peertube" + - name: "๐Ÿ“ฆ Install auth-openid-connect plugin for Peertube" # V8 heap is still capped tight โ€” the cgroup bump above covers native # memory and spawned workers, while --max-old-space-size keeps the # install's V8 old-generation predictable. @@ -51,7 +51,7 @@ # bumped limits in place so diagnostics reflect real install-time # state; the next `compose up` recreates the container and reinstates # docker's default memory-swap behavior from compose.yml. - - name: "PEERTUBE | Restore compose-defined mem_limit" + - name: "โ™ป๏ธ PEERTUBE | Restore compose-defined mem_limit" ansible.builtin.command: >- container update --memory {{ PEERTUBE_MEM_LIMIT }} @@ -60,7 +60,7 @@ changed_when: true rescue: - - name: "PEERTUBE | Dump diagnostics after install failure" + - name: "๐Ÿ’พ PEERTUBE | Dump diagnostics after install failure" ansible.builtin.script: "{{ role_path }}/files/diagnostics.sh {{ PEERTUBE_CONTAINER }}" environment: PEERTUBE_OIDC_PLUGIN_INSTALL_MAX_OLD_SPACE_MB: "{{ PEERTUBE_OIDC_PLUGIN_INSTALL_MAX_OLD_SPACE_MB }}" @@ -68,14 +68,14 @@ changed_when: false failed_when: false - - name: "PEERTUBE | Fail explicitly after diagnostics" + - name: "๐Ÿ›‘ PEERTUBE | Fail explicitly after diagnostics" ansible.builtin.fail: msg: >- Installing peertube-plugin-auth-openid-connect failed. See PEERTUBE DIAGNOSTICS block above for state, OOMKilled, exit code, logs, stats, host memory, and dmesg OOM-killer evidence. -- name: "Update the settings column of the auth-openid-connect plugin" +- name: "๐Ÿ”„ Update the settings column of the auth-openid-connect plugin" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: "{{ lookup('database', application_id) }}" @@ -88,7 +88,7 @@ until: _peertube_oidc_update is succeeded notify: compose up -- name: "Ensure plugin is enabled in PeerTube (CLI)" +- name: "โœ… Ensure plugin is enabled in PeerTube (CLI)" shell: > container exec {{ PEERTUBE_CONTAINER_ADDRESS }} npm run plugin:enable -- --npm-name {{ PEERTUBE_OIDC_PLUGIN }} register: _peertube_enable diff --git a/roles/web-app-penpot/tasks/main.yml b/roles/web-app-penpot/tasks/main.yml index 10698acb70..852aef0dcb 100644 --- a/roles/web-app-penpot/tasks/main.yml +++ b/roles/web-app-penpot/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "For '{{ application_id }}': load docker, db and proxy" +- name: "๐Ÿงฉ For '{{ application_id }}': load docker, db and proxy" include_role: name: sys-stk-full vars: @@ -8,10 +8,10 @@ webserver_client_max_body_size: "100m" compose_handlers_flush: true -- name: "Bootstrap the Penpot administrator's local account" +- name: "๐Ÿฅพ Bootstrap the Penpot administrator's local account" when: IS_STACK_HOST | bool block: - - name: "Bootstrap the Penpot administrator's local account (idempotent)" + - name: "๐Ÿฅพ Bootstrap the Penpot administrator's local account (idempotent)" when: PENPOT_NATIVE_LOGIN_ENABLED | bool ansible.builtin.shell: > container exec -i {{ PENPOT_BACKEND_CONTAINER_ADDRESS | quote }} @@ -31,7 +31,7 @@ - "'already exists' not in (penpot_admin_create.stdout | default('') ~ penpot_admin_create.stderr | default(''))" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" - - name: "Set the Penpot administrator's local password when the profile already exists" + - name: "๐Ÿ”ง Set the Penpot administrator's local password when the profile already exists" ansible.builtin.shell: > container exec -i {{ PENPOT_BACKEND_CONTAINER_ADDRESS | quote }} python3 manage.py update-profile diff --git a/roles/web-app-pgadmin/tasks/configuration.yml b/roles/web-app-pgadmin/tasks/configuration.yml index f4d866398c..2ed2ca29f3 100644 --- a/roles/web-app-pgadmin/tasks/configuration.yml +++ b/roles/web-app-pgadmin/tasks/configuration.yml @@ -1,16 +1,16 @@ --- -- name: "loading database configuration variables" +- name: "โš™๏ธ loading database configuration variables" include_vars: file: "{{ role_path }}/vars/db_config.yml" -- name: "Render servers.json file" +- name: "๐Ÿ“„ Render servers.json file" stack_host_template: src: servers.json.j2 dest: "{{ pgadmin_host_server_file }}" mode: "0644" notify: compose up -- name: "Render .pgpass file" +- name: "๐Ÿ“„ Render .pgpass file" stack_host_template: src: pgpass.j2 dest: "{{ pgadmin_host_password_file }}" diff --git a/roles/web-app-pgadmin/tasks/main.yml b/roles/web-app-pgadmin/tasks/main.yml index f8423dcc5c..cc06748c55 100644 --- a/roles/web-app-pgadmin/tasks/main.yml +++ b/roles/web-app-pgadmin/tasks/main.yml @@ -1,8 +1,8 @@ --- -- name: "load docker, proxy for '{{ application_id }}'" +- name: "๐Ÿงฉ load docker, proxy for '{{ application_id }}'" include_role: name: sys-stk-full -- name: "configure pgadmin servers" +- name: "๐Ÿ”ง configure pgadmin servers" include_tasks: configuration.yml when: PGADMIN_SERVER_MODE | bool diff --git a/roles/web-app-phpldapadmin/tasks/main.yml b/roles/web-app-phpldapadmin/tasks/main.yml index 77dfe4a3aa..465de494dd 100644 --- a/roles/web-app-phpldapadmin/tasks/main.yml +++ b/roles/web-app-phpldapadmin/tasks/main.yml @@ -1,4 +1,4 @@ --- -- name: "load docker, proxy for '{{ application_id }}'" +- name: "๐Ÿงฉ load docker, proxy for '{{ application_id }}'" include_role: name: sys-stk-full diff --git a/roles/web-app-phpmyadmin/tasks/main.yml b/roles/web-app-phpmyadmin/tasks/main.yml index 77dfe4a3aa..465de494dd 100644 --- a/roles/web-app-phpmyadmin/tasks/main.yml +++ b/roles/web-app-phpmyadmin/tasks/main.yml @@ -1,4 +1,4 @@ --- -- name: "load docker, proxy for '{{ application_id }}'" +- name: "๐Ÿงฉ load docker, proxy for '{{ application_id }}'" include_role: name: sys-stk-full diff --git a/roles/web-app-pihole/tasks/01_core.yml b/roles/web-app-pihole/tasks/01_core.yml index acf21cf107..e55e87f90f 100644 --- a/roles/web-app-pihole/tasks/01_core.yml +++ b/roles/web-app-pihole/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: "Load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ Load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: @@ -32,7 +32,7 @@ # affect every `flavor: oauth2` role platform-wide and was out of scope per # review feedback. This task is a no-op on production (TLS_MODE=letsencrypt), # where a real CA is trusted and this isn't needed. -- name: "Pi-hole | Trust self-signed platform CA for sso-proxy OIDC discovery" +- name: "๐Ÿค Pi-hole | Trust self-signed platform CA for sso-proxy OIDC discovery" ansible.builtin.lineinfile: path: >- {{ (application_id | get_docker_paths(DIR_COMPOSITIONS)).directories.volumes @@ -44,10 +44,10 @@ - lookup('sso', application_id, 'is_proxy_gated') - (TLS_MODE | lower) == 'self_signed' -- name: "flush compose and SSO proxy" +- name: "๐Ÿšฟ flush compose and SSO proxy" meta: flush_handlers -- name: "Wait for Pi-hole HTTP endpoint" +- name: "โณ Wait for Pi-hole HTTP endpoint" wait_for: host: "{{ DOCKER_REACH_HOST }}" port: "{{ lookup('config', application_id, 'services.pihole.ports.local.http') }}" diff --git a/roles/web-app-pixelfed/tasks/01_core.yml b/roles/web-app-pixelfed/tasks/01_core.yml index 99fb7eeeaa..bb68bbe2ea 100644 --- a/roles/web-app-pixelfed/tasks/01_core.yml +++ b/roles/web-app-pixelfed/tasks/01_core.yml @@ -1,13 +1,13 @@ --- - include_tasks: utils/once/flag.yml -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: compose_handlers_flush: false webserver_extra_configuration: "client_max_body_size 512M;" -- name: "Pixelfed manager-side operations (file deploys + container exec)" +- name: "๐Ÿ‘” Pixelfed manager-side operations (file deploys + container exec)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-pixelfed/tasks/02_bootstrap.yml b/roles/web-app-pixelfed/tasks/02_bootstrap.yml index eddbc1e9ee..9dd83303ee 100644 --- a/roles/web-app-pixelfed/tasks/02_bootstrap.yml +++ b/roles/web-app-pixelfed/tasks/02_bootstrap.yml @@ -5,7 +5,7 @@ # Keep this wait at the top of the bootstrap flow. The later artisan commands # assume the repo-managed entrypoint has already brought Apache up. -- name: "Wait until the Pixelfed application container finished its entrypoint bootstrap" +- name: "โณ Wait until Pixelfed application container finished entrypoint bootstrap" ansible.builtin.command: argv: - container @@ -21,7 +21,7 @@ until: pixelfed_entrypoint_bootstrap.rc == 0 delegate_to: "{{ PIXELFED_HOST_NODE }}" -- name: "Check whether the Pixelfed bootstrap marker exists" +- name: "๐Ÿ”Ž Check whether the Pixelfed bootstrap marker exists" ansible.builtin.command: argv: - container @@ -35,7 +35,7 @@ failed_when: false delegate_to: "{{ PIXELFED_HOST_NODE }}" -- name: "Check whether the Pixelfed users table exists" +- name: "๐Ÿ”Ž Check whether the Pixelfed users table exists" database_query: config: "{{ lookup('database', application_id) }}" query_file: "{{ role_path }}/files/sql/select-users-table.sql" @@ -50,7 +50,7 @@ until: pixelfed_bootstrap_users_table is success no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Count existing Pixelfed users when the users table already exists" +- name: "๐Ÿ‘ฅ Count existing Pixelfed users when the users table already exists" database_query: config: "{{ lookup('database', application_id) }}" query_file: "{{ role_path }}/files/sql/count-users.sql" @@ -64,7 +64,7 @@ until: pixelfed_bootstrap_user_count is success no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Choose Pixelfed migration strategy" +- name: "๐Ÿšš Choose Pixelfed migration strategy" ansible.builtin.set_fact: # Preserve the "no marker + no users" reset path. It is the safety net for # broken first boots where Pixelfed partially initialized and would @@ -87,7 +87,7 @@ ) }} -- name: "Run Pixelfed migrations" +- name: "โ–ถ๏ธ Run Pixelfed migrations" ansible.builtin.command: argv: "{{ pixelfed_migrate_argv }}" register: pixelfed_migrate @@ -97,7 +97,7 @@ until: pixelfed_migrate.rc == 0 delegate_to: "{{ PIXELFED_HOST_NODE }}" -- name: "Ensure Pixelfed Passport keys exist" +- name: "โœ… Ensure Pixelfed Passport keys exist" ansible.builtin.command: argv: - container @@ -118,7 +118,7 @@ until: pixelfed_passport_keys.rc == 0 delegate_to: "{{ PIXELFED_HOST_NODE }}" -- name: "Ensure the Pixelfed public storage symlink exists" +- name: "โœ… Ensure the Pixelfed public storage symlink exists" ansible.builtin.command: argv: - container @@ -139,7 +139,7 @@ until: pixelfed_storage_link.rc == 0 delegate_to: "{{ PIXELFED_HOST_NODE }}" -- name: "Initialize the Pixelfed instance actor" +- name: "๐ŸŽฌ Initialize the Pixelfed instance actor" ansible.builtin.command: argv: - container @@ -159,7 +159,7 @@ # The worker uses this marker to skip its own init path. Do not move this above # the actor/storage setup or the worker can start against an incomplete app. -- name: "Mark Pixelfed bootstrap as complete for the worker container" +- name: "๐Ÿท๏ธ Mark Pixelfed bootstrap as complete for the worker container" ansible.builtin.command: argv: - container diff --git a/roles/web-app-pixelfed/tasks/02_manager_ops.yml b/roles/web-app-pixelfed/tasks/02_manager_ops.yml index 7bc86858e8..f9a3d24394 100644 --- a/roles/web-app-pixelfed/tasks/02_manager_ops.yml +++ b/roles/web-app-pixelfed/tasks/02_manager_ops.yml @@ -2,14 +2,14 @@ # Keep the custom entrypoint on disk before the first compose up. If this is # moved below the flush, Pixelfed can boot once with the upstream entrypoint and # get stuck in the half-initialized state this role is meant to recover from. -- name: "Deploy '{{ PIXELFED_ENTRYPOINT_HOST_ABS }}'" +- name: "๐Ÿš€ Deploy '{{ PIXELFED_ENTRYPOINT_HOST_ABS }}'" ansible.builtin.copy: src: "{{ PIXELFED_ENTRYPOINT_FILE }}" dest: "{{ PIXELFED_ENTRYPOINT_HOST_ABS }}" mode: "0755" notify: compose up -- name: "Ensure Pixelfed .env ownership and permissions for www-data" +- name: "โœ… Ensure Pixelfed .env ownership and permissions for www-data" ansible.builtin.file: path: "{{ PIXELFED_ENV_FILE }}" owner: "{{ PIXELFED_APP_USER }}" @@ -18,22 +18,22 @@ # Flush here on purpose: the application container must start with the # repo-managed entrypoint before 02_bootstrap.yml runs any artisan bootstrap. -- name: "Start Pixelfed containers with the repo-managed entrypoint" +- name: "โ–ถ๏ธ Start Pixelfed containers with the repo-managed entrypoint" ansible.builtin.meta: flush_handlers -- name: "Pixelfed | Resolve hosting node + local container id" +- name: "๐Ÿ” Pixelfed | Resolve hosting node + local container id" ansible.builtin.include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/swarm/resolve_host_cid.yml'] | path_join }}" vars: resolve_service_key: pixelfed resolve_output_prefix: PIXELFED resolve_compose_cid: "{{ PIXELFED_CONTAINER }}" -- name: "Bootstrap the Pixelfed application" +- name: "๐Ÿฅพ Bootstrap the Pixelfed application" ansible.builtin.import_tasks: 02_bootstrap.yml -- name: "Bootstrap the Pixelfed administrator" +- name: "๐Ÿฅพ Bootstrap the Pixelfed administrator" ansible.builtin.import_tasks: 03_administrator.yml -- name: "Bootstrap the Pixelfed administrator OIDC mapping" +- name: "๐Ÿฅพ Bootstrap the Pixelfed administrator OIDC mapping" ansible.builtin.import_tasks: 04_oidc_mapping.yml when: PIXELFED_OIDC_ENABLED | bool diff --git a/roles/web-app-pixelfed/tasks/03_administrator.yml b/roles/web-app-pixelfed/tasks/03_administrator.yml index c247f9644a..9b4cb553c9 100644 --- a/roles/web-app-pixelfed/tasks/03_administrator.yml +++ b/roles/web-app-pixelfed/tasks/03_administrator.yml @@ -1,5 +1,5 @@ --- -- name: "Wait until the Pixelfed users table exists" +- name: "โณ Wait until the Pixelfed users table exists" database_query: config: "{{ lookup('database', application_id) }}" query_file: "{{ role_path }}/files/sql/select-users-table.sql" @@ -14,7 +14,7 @@ until: pixelfed_users_table.rows | length > 0 no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Check whether the Pixelfed administrator already exists" +- name: "๐Ÿ”Ž Check whether the Pixelfed administrator already exists" database_query: config: "{{ lookup('database', application_id) }}" query_file: "{{ role_path }}/files/sql/select-admin-id.sql" @@ -26,7 +26,7 @@ changed_when: false no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Create the Pixelfed administrator via artisan" +- name: "๐Ÿ“ Create the Pixelfed administrator via artisan" ansible.builtin.command: argv: - container @@ -49,7 +49,7 @@ no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" delegate_to: "{{ PIXELFED_HOST_NODE }}" -- name: "Resolve the Pixelfed administrator id" +- name: "๐Ÿ” Resolve the Pixelfed administrator id" database_query: config: "{{ lookup('database', application_id) }}" query_file: "{{ role_path }}/files/sql/select-admin-id.sql" diff --git a/roles/web-app-pixelfed/tasks/04_oidc_mapping.yml b/roles/web-app-pixelfed/tasks/04_oidc_mapping.yml index 617cd871d6..4b22a53cca 100644 --- a/roles/web-app-pixelfed/tasks/04_oidc_mapping.yml +++ b/roles/web-app-pixelfed/tasks/04_oidc_mapping.yml @@ -6,7 +6,7 @@ # `-database` container โ€” the database_query module hands the # query off to whichever the `database` lookup resolves to. -- name: "Wait until the Pixelfed OIDC mapping table exists" +- name: "โณ Wait until the Pixelfed OIDC mapping table exists" database_query: config: "{{ lookup('database', application_id) }}" query_file: "{{ role_path }}/files/sql/oidc-mapping/select-table.sql" @@ -21,7 +21,7 @@ until: pixelfed_admin_oidc_table.rows | length > 0 no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Verify the Pixelfed OIDC mapping table contains the expected columns" +- name: "โœ… Verify the Pixelfed OIDC mapping table contains the expected columns" database_query: config: "{{ lookup('database', application_id) }}" query_file: "{{ role_path }}/files/sql/oidc-mapping/count-columns.sql" @@ -34,7 +34,7 @@ failed_when: (pixelfed_admin_oidc_columns.rows[0][0] | int) != 4 no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Ensure the Pixelfed administrator OIDC mapping exists" +- name: "โœ… Ensure the Pixelfed administrator OIDC mapping exists" database_query: config: "{{ lookup('database', application_id) }}" query_file: "{{ role_path }}/files/sql/oidc-mapping/upsert.sql" diff --git a/roles/web-app-postmarks/tasks/01_core.yml b/roles/web-app-postmarks/tasks/01_core.yml index 84fb62447b..ea75bf205a 100644 --- a/roles/web-app-postmarks/tasks/01_core.yml +++ b/roles/web-app-postmarks/tasks/01_core.yml @@ -1,12 +1,12 @@ --- -- name: "Load docker and front proxy for {{ application_id }}" +- name: "๐Ÿงฉ Load docker and front proxy for {{ application_id }}" include_role: name: sys-stk-full vars: domain: "{{ lookup('domain', application_id) }}" http_port: "{{ lookup('config', application_id, 'services.postmarks.ports.local.http') }}" -- name: "Stage trusted-header SSO build-context files for {{ application_id }}" +- name: "๐ŸŽฌ Stage trusted-header SSO build-context files for {{ application_id }}" stack_host_copy: src: "{{ item.src }}" dest: "{{ [ lookup('container', application_id, 'directories.instance'), item.dest ] | path_join }}" diff --git a/roles/web-app-pretix/tasks/main.yml b/roles/web-app-pretix/tasks/main.yml index f8c54629e8..a9f040727e 100644 --- a/roles/web-app-pretix/tasks/main.yml +++ b/roles/web-app-pretix/tasks/main.yml @@ -1,6 +1,6 @@ --- - block: - - name: "load docker, db and proxy for {{ application_id }}" + - name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: diff --git a/roles/web-app-prometheus/tasks/01_core.yml b/roles/web-app-prometheus/tasks/01_core.yml index c102dadfcb..2fef9577b7 100644 --- a/roles/web-app-prometheus/tasks/01_core.yml +++ b/roles/web-app-prometheus/tasks/01_core.yml @@ -1,19 +1,19 @@ --- - include_tasks: utils/once/flag.yml -- name: "load docker and proxy for '{{ application_id }}'" +- name: "๐Ÿงฉ load docker and proxy for '{{ application_id }}'" include_role: name: sys-stk-backend vars: compose_handlers_flush: false -- name: "Deploy prometheus nginx http-block config to {{ lookup('nginx','directories.configuration.global') }}prometheus.conf" +- name: "๐Ÿš€ Deploy prometheus nginx http-block config" stack_host_template: src: "roles/web-app-prometheus/templates/nginx/prometheus.conf.j2" dest: "{{ [ lookup('nginx','directories.configuration.global'), 'prometheus.conf' ] | path_join }}" notify: restart openresty -- name: "Render Prometheus config files (local + swarm peers)" +- name: "๐Ÿ“„ Render Prometheus config files (local + swarm peers)" ansible.builtin.include_tasks: file: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/render_replicated_templates.yml'] | path_join }}" vars: @@ -31,16 +31,16 @@ dest: "{{ ALERT_RULES_CONFIG_HOST }}" mode: "0644" -- name: "Pre-create native-metrics docker networks (idempotent)" +- name: "๐Ÿ“ Pre-create native-metrics docker networks (idempotent)" include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/network/create.yml' ] | path_join }}" vars: network_role_id: "{{ item }}" loop: "{{ lookup('native_metrics_apps') }}" -- name: "flush handlers for '{{ application_id }}'" +- name: "๐Ÿšฟ flush handlers for '{{ application_id }}'" meta: flush_handlers -- name: "Include role sys-stk-front-proxy for '{{ application_id }}'" +- name: "๐Ÿ“‚ Include role sys-stk-front-proxy for '{{ application_id }}'" include_role: name: sys-stk-front-proxy vars: diff --git a/roles/web-app-roulette-wheel/tasks/main.yml b/roles/web-app-roulette-wheel/tasks/main.yml index 5c61beb598..12d78aaf7f 100644 --- a/roles/web-app-roulette-wheel/tasks/main.yml +++ b/roles/web-app-roulette-wheel/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "load docker, proxy for '{{ application_id }}'" +- name: "๐Ÿงฉ load docker, proxy for '{{ application_id }}'" include_role: name: sys-stk-full vars: diff --git a/roles/web-app-seaweedfs/tasks/01_core.yml b/roles/web-app-seaweedfs/tasks/01_core.yml index d76e5dedd5..90965d4873 100644 --- a/roles/web-app-seaweedfs/tasks/01_core.yml +++ b/roles/web-app-seaweedfs/tasks/01_core.yml @@ -1,40 +1,40 @@ --- - include_tasks: utils/once/flag.yml -- name: "For '{{ application_id }}': load docker and compose" +- name: "๐Ÿงฉ For '{{ application_id }}': load docker and compose" include_role: name: sys-stk-backend vars: compose_handlers_flush: false -- name: "Ensure volumes directory exists" +- name: "โœ… Ensure volumes directory exists" ansible.builtin.file: path: "{{ lookup('container', application_id, 'directories.volumes') }}" state: directory mode: "0755" -- name: "Create shared object-store network for '{{ application_id }}'" +- name: "๐Ÿ“ Create shared object-store network for '{{ application_id }}'" include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/network/create.yml'] | path_join }}" vars: network_role_id: "{{ application_id }}" -- name: "Render SeaweedFS S3 identities config" +- name: "๐Ÿ“„ Render SeaweedFS S3 identities config" stack_host_template: src: s3.json.j2 dest: "{{ SEAWEEDFS_S3_CONFIG_PATH }}" notify: compose up no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Render role proxy nginx config" +- name: "๐Ÿ“„ Render role proxy nginx config" stack_host_template: src: nginx.conf.j2 dest: "{{ [lookup('container', application_id, 'directories.volumes'), 'nginx.conf'] | path_join }}" notify: compose up -- name: "Start the SeaweedFS stack" +- name: "โ–ถ๏ธ Start the SeaweedFS stack" ansible.builtin.meta: flush_handlers -- name: "Include role sys-stk-front-proxy for '{{ application_id }}'" +- name: "๐Ÿ“‚ Include role sys-stk-front-proxy for '{{ application_id }}'" include_role: name: sys-stk-front-proxy vars: @@ -45,7 +45,7 @@ loop_var: seaweedfs_proxy label: "{{ seaweedfs_proxy.domain }} -> {{ seaweedfs_proxy.http_port }}" -- name: "Wait until the SeaweedFS S3 gateway answers" +- name: "โณ Wait until the SeaweedFS S3 gateway answers" ansible.builtin.shell: > container exec {{ SEAWEEDFS_CONTAINER_ADDRESS }} wget -q -O - http://127.0.0.1:{{ SEAWEEDFS_S3_PORT_INTERNAL }}/status diff --git a/roles/web-app-seaweedfs/tasks/02_init_consumer.yml b/roles/web-app-seaweedfs/tasks/02_init_consumer.yml index 726fbc9679..398ca2cbde 100644 --- a/roles/web-app-seaweedfs/tasks/02_init_consumer.yml +++ b/roles/web-app-seaweedfs/tasks/02_init_consumer.yml @@ -1,14 +1,14 @@ --- -- name: "Assert correct context" +- name: "โœ… Assert correct context" ansible.builtin.assert: that: - application_id == 'web-app-seaweedfs' - objstore_consumer_id != 'web-app-seaweedfs' -- name: "Provision the SeaweedFS bucket on the stack host" +- name: "๐Ÿ”ง Provision the SeaweedFS bucket on the stack host" when: IS_STACK_HOST | bool block: - - name: "List SeaweedFS buckets" + - name: "๐Ÿ“‹ List SeaweedFS buckets" ansible.builtin.shell: | set -euo pipefail echo 's3.bucket.list' | container exec -i {{ SEAWEEDFS_CONTAINER_ADDRESS }} weed shell -master=localhost:{{ SEAWEEDFS_MASTER_PORT_INTERNAL }} @@ -21,7 +21,7 @@ delay: 10 until: _seaweedfs_buckets is succeeded - - name: "Create the SeaweedFS bucket for '{{ objstore_consumer_id }}'" + - name: "๐Ÿ“ Create the SeaweedFS bucket for '{{ objstore_consumer_id }}'" ansible.builtin.shell: | set -euo pipefail echo 's3.bucket.create -name {{ lookup('objstore', objstore_consumer_id, 'bucket') }}' | container exec -i {{ SEAWEEDFS_CONTAINER_ADDRESS }} weed shell -master=localhost:{{ SEAWEEDFS_MASTER_PORT_INTERNAL }} diff --git a/roles/web-app-seaweedfs/tasks/main.yml b/roles/web-app-seaweedfs/tasks/main.yml index edc0e6dc84..9b4c4c83b4 100644 --- a/roles/web-app-seaweedfs/tasks/main.yml +++ b/roles/web-app-seaweedfs/tasks/main.yml @@ -1,8 +1,8 @@ --- -- name: "Deploy web-app-seaweedfs (core, once per play)" +- name: "๐Ÿš€ Deploy web-app-seaweedfs (core, once per play)" include_tasks: 01_core.yml when: run_once_web_app_seaweedfs is not defined -- name: "Provision a dedicated bucket for a consumer" +- name: "๐Ÿ”ง Provision a dedicated bucket for a consumer" include_tasks: 02_init_consumer.yml when: objstore_init | bool diff --git a/roles/web-app-shopware/tasks/01_admin.yml b/roles/web-app-shopware/tasks/01_admin.yml index d4f999eeba..7fb8e65664 100644 --- a/roles/web-app-shopware/tasks/01_admin.yml +++ b/roles/web-app-shopware/tasks/01_admin.yml @@ -1,5 +1,5 @@ --- -- name: "Rename default Shopware admin user to {{ lookup('users', 'administrator').username }}" +- name: "๐Ÿ”ง Rename Shopware admin to {{ lookup('users', 'administrator').username }}" ansible.builtin.shell: >- container exec -i --user {{ SHOPWARE_USER }} -e SHOPWARE_ROOT={{ SHOPWARE_ROOT | quote }} @@ -8,7 +8,7 @@ sh < {{ role_path }}/files/rename_admin_user.sh changed_when: false -- name: "Ensure Shopware admin exists and has the desired password" +- name: "โœ… Ensure Shopware admin exists and has the desired password" shell: >- container exec -i --user {{ SHOPWARE_USER }} -e SHOPWARE_ROOT={{ SHOPWARE_ROOT | quote }} diff --git a/roles/web-app-shopware/tasks/02_manager_ops.yml b/roles/web-app-shopware/tasks/02_manager_ops.yml index ed7f8cd21c..4fb2f25491 100644 --- a/roles/web-app-shopware/tasks/02_manager_ops.yml +++ b/roles/web-app-shopware/tasks/02_manager_ops.yml @@ -1,5 +1,5 @@ --- -- name: "Deploy {{ SHOPWARE_INIT_HOST }}" +- name: "๐Ÿš€ Deploy {{ SHOPWARE_INIT_HOST }}" copy: src: init.sh dest: "{{ SHOPWARE_INIT_HOST }}" @@ -8,7 +8,7 @@ - compose up - compose build -- name: "Render framework.yaml (trusted proxies/headers/hosts)" +- name: "๐Ÿ“„ Render framework.yaml (trusted proxies/headers/hosts)" copy: src: "framework.yaml" dest: "{{ SHOPWARE_FRAMEWORK_HOST }}" @@ -16,7 +16,7 @@ notify: - compose up -- name: "Render shopware.yaml (SeaweedFS S3 filesystem)" +- name: "๐Ÿ“„ Render shopware.yaml (SeaweedFS S3 filesystem)" stack_host_template: src: "shopware.yaml.j2" dest: "{{ SHOPWARE_FILESYSTEM_HOST }}" @@ -26,17 +26,17 @@ - compose up - compose build -- name: "Flush compose handlers" +- name: "๐Ÿšฟ Flush compose handlers" meta: flush_handlers -- name: Wait for Shopware HTTP endpoint +- name: โณ Wait for Shopware HTTP endpoint wait_for: host: "{{ DOCKER_REACH_HOST }}" port: "{{ lookup('config', application_id, 'services.shopware.ports.local.http') }}" delay: 5 timeout: 300 -- name: "Ensure admin user exists with correct password" +- name: "โœ… Ensure admin user exists with correct password" ansible.builtin.include_tasks: file: 01_admin.yml apply: diff --git a/roles/web-app-shopware/tasks/02_setup.yml b/roles/web-app-shopware/tasks/02_setup.yml index 38a7baa68b..ca0a08c8dd 100644 --- a/roles/web-app-shopware/tasks/02_setup.yml +++ b/roles/web-app-shopware/tasks/02_setup.yml @@ -1,11 +1,11 @@ --- -- name: "Shopware setup plugins (manager-only)" +- name: "๐Ÿ”ง Shopware setup plugins (manager-only)" when: IS_STACK_HOST | bool block: - - name: Install & configure OIDC plugin (if enabled) + - name: ๐Ÿ“ฆ Install & configure OIDC plugin (if enabled) include_tasks: setup/oidc.yml when: SHOPWARE_OIDC_ENABLED | bool - - name: Install & configure LDAP plugin (if enabled) + - name: ๐Ÿ“ฆ Install & configure LDAP plugin (if enabled) include_tasks: setup/ldap.yml when: SHOPWARE_LDAP_ENABLED | bool diff --git a/roles/web-app-shopware/tasks/03_cleanup.yml b/roles/web-app-shopware/tasks/03_cleanup.yml index ae7e3c3ca2..0a035970bf 100644 --- a/roles/web-app-shopware/tasks/03_cleanup.yml +++ b/roles/web-app-shopware/tasks/03_cleanup.yml @@ -1,11 +1,11 @@ --- -- name: "Shopware cleanup plugins (manager-only)" +- name: "๐Ÿงน Shopware cleanup plugins (manager-only)" when: IS_STACK_HOST | bool block: - - name: Remove OIDC plugin if disabled + - name: ๐Ÿ—‘๏ธ Remove OIDC plugin if disabled include_tasks: cleanup/oidc.yml when: not (SHOPWARE_OIDC_ENABLED | bool) - - name: Remove LDAP plugin if disabled + - name: ๐Ÿ—‘๏ธ Remove LDAP plugin if disabled include_tasks: cleanup/ldap.yml when: not (SHOPWARE_LDAP_ENABLED | bool) diff --git a/roles/web-app-shopware/tasks/cleanup/ldap.yml b/roles/web-app-shopware/tasks/cleanup/ldap.yml index c92e751ff8..ea416fff0f 100644 --- a/roles/web-app-shopware/tasks/cleanup/ldap.yml +++ b/roles/web-app-shopware/tasks/cleanup/ldap.yml @@ -1,5 +1,5 @@ --- -- name: "Deactivate/uninstall LDAP plugin if present" +- name: "๐Ÿ”ด Deactivate/uninstall LDAP plugin if present" shell: | container exec -i --user {{ SHOPWARE_USER }} {{ SHOPWARE_WEB_CONTAINER_ADDRESS }} sh -lc ' cd {{ SHOPWARE_ROOT }} diff --git a/roles/web-app-shopware/tasks/cleanup/oidc.yml b/roles/web-app-shopware/tasks/cleanup/oidc.yml index 04a0a86fca..23867187ec 100644 --- a/roles/web-app-shopware/tasks/cleanup/oidc.yml +++ b/roles/web-app-shopware/tasks/cleanup/oidc.yml @@ -1,5 +1,5 @@ --- -- name: "Deactivate/uninstall OIDC plugin if present" +- name: "๐Ÿ”ด Deactivate/uninstall OIDC plugin if present" shell: | container exec -i --user {{ SHOPWARE_USER }} {{ SHOPWARE_WEB_CONTAINER_ADDRESS }} sh -lc ' cd {{ SHOPWARE_ROOT }} diff --git a/roles/web-app-shopware/tasks/main.yml b/roles/web-app-shopware/tasks/main.yml index dbebab2c49..093cb45770 100644 --- a/roles/web-app-shopware/tasks/main.yml +++ b/roles/web-app-shopware/tasks/main.yml @@ -1,10 +1,10 @@ --- -- name: "Load docker, DB and proxy for {{ application_id }}" +- name: "๐Ÿงฉ Load docker, DB and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: compose_handlers_flush: false -- name: "Shopware manager-side operations (file deploys + container exec)" +- name: "๐Ÿ‘” Shopware manager-side operations (file deploys + container exec)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-shopware/tasks/setup/ldap.yml b/roles/web-app-shopware/tasks/setup/ldap.yml index b5cdbeea29..6ebfa4cad1 100644 --- a/roles/web-app-shopware/tasks/setup/ldap.yml +++ b/roles/web-app-shopware/tasks/setup/ldap.yml @@ -1,6 +1,6 @@ --- # Replace INFX_LDAP_PLUGIN with the actual plugin name you use -- name: "Install LDAP admin plugin & activate" +- name: "๐Ÿ“ฆ Install LDAP admin plugin & activate" shell: | container exec -i --user {{ SHOPWARE_USER }} {{ SHOPWARE_WEB_CONTAINER_ADDRESS }} sh -lc ' set -e @@ -10,7 +10,7 @@ php bin/console cache:clear ' -- name: "Configure LDAP connection" +- name: "๐Ÿ”ง Configure LDAP connection" shell: | container exec -i --user {{ SHOPWARE_USER }} {{ SHOPWARE_WEB_CONTAINER_ADDRESS }} sh -lc ' set -e diff --git a/roles/web-app-shopware/tasks/setup/oidc.yml b/roles/web-app-shopware/tasks/setup/oidc.yml index 1ffc500286..8f9a809a49 100644 --- a/roles/web-app-shopware/tasks/setup/oidc.yml +++ b/roles/web-app-shopware/tasks/setup/oidc.yml @@ -1,6 +1,6 @@ --- # Replace INFX_OIDC_PLUGIN with the actual plugin name (Composer or local) -- name: "Install OIDC plugin & activate" +- name: "๐Ÿ“ฆ Install OIDC plugin & activate" shell: | container exec -i --user {{ SHOPWARE_USER }} {{ SHOPWARE_WEB_CONTAINER_ADDRESS }} sh -lc ' set -e @@ -10,7 +10,7 @@ php bin/console cache:clear ' -- name: "Configure OIDC via system:config" +- name: "๐Ÿ”ง Configure OIDC via system:config" shell: | container exec -i --user {{ SHOPWARE_USER }} {{ SHOPWARE_WEB_CONTAINER_ADDRESS }} sh -lc ' set -e diff --git a/roles/web-app-snipe-it/tasks/01_install.yml b/roles/web-app-snipe-it/tasks/01_install.yml index a038c80511..a855f84ab8 100644 --- a/roles/web-app-snipe-it/tasks/01_install.yml +++ b/roles/web-app-snipe-it/tasks/01_install.yml @@ -1,5 +1,5 @@ --- -- name: Wait until application container is up +- name: โณ Wait until application container is up ansible.builtin.shell: >- container ps --filter label=com.docker.swarm.service.name={{ lookup('container_service', application_id, SNIPE_IT_SERVICE) }} @@ -10,7 +10,7 @@ until: snipeit_app_id.stdout | length > 0 changed_when: false -- name: "Wait until the Snipe-IT Service is available" +- name: "โณ Wait until the Snipe-IT Service is available" uri_retry: url: "{{ SNIPE_IT_URL }}" method: GET @@ -21,7 +21,7 @@ delay: 5 until: snipeit_admin_check.status == 200 -- name: Run Snipe-IT migrations (idempotent) +- name: โ–ถ๏ธ Run Snipe-IT migrations (idempotent) ansible.builtin.shell: >- container exec -i -e APP_KEY="{{ SNIPE_IT_APP_KEY }}" @@ -34,7 +34,7 @@ or ('Migrated:' in snipeit_migrate.stdout) failed_when: snipeit_migrate.rc != 0 -- name: Seed Snipe-IT database (optional, safe to rerun if seeder is idempotent) +- name: ๐ŸŒฑ Seed Snipe-IT database (optional, safe to rerun if seeder is idempotent) ansible.builtin.shell: >- container exec -i -e APP_KEY="{{ SNIPE_IT_APP_KEY }}" diff --git a/roles/web-app-snipe-it/tasks/01a_manager_ops.yml b/roles/web-app-snipe-it/tasks/01a_manager_ops.yml index fc4e6427c2..8cbde71b32 100644 --- a/roles/web-app-snipe-it/tasks/01a_manager_ops.yml +++ b/roles/web-app-snipe-it/tasks/01a_manager_ops.yml @@ -1,14 +1,14 @@ --- -- name: "Installation Procedures" +- name: "๐Ÿ“‹ Installation Procedures" include_tasks: 01_install.yml -- name: "Configure Snipe-IT LDAP settings" +- name: "๐Ÿ”ง Configure Snipe-IT LDAP settings" include_tasks: 02_ldap.yml when: SNIPE_IT_LDAP_ENABLED | bool -- name: "Create bootstrap Snipe-IT administrator" +- name: "๐Ÿ“ Create bootstrap Snipe-IT administrator" include_tasks: 03_admin.yml -- name: "Configure Snipe-IT trusted-header SSO bridge" +- name: "๐Ÿ”ง Configure Snipe-IT trusted-header SSO bridge" include_tasks: 04_sso.yml when: SNIPE_IT_SSO_ENABLED | bool diff --git a/roles/web-app-snipe-it/tasks/02_ldap.yml b/roles/web-app-snipe-it/tasks/02_ldap.yml index 2ce3525ef3..e09a072907 100644 --- a/roles/web-app-snipe-it/tasks/02_ldap.yml +++ b/roles/web-app-snipe-it/tasks/02_ldap.yml @@ -1,6 +1,6 @@ # @See https://raw.githubusercontent.com/snipe/snipe-it/master/app/Models/Setting.php --- -- name: "snipe-it: wait until settings table is seeded" +- name: "โณ snipe-it: wait until settings table is seeded" ansible.builtin.shell: cmd: "container exec -i {{ SNIPE_IT_CONTAINER_ADDRESS | quote }} php" stdin: "{{ lookup('file', 'wait_settings.php') }}" @@ -11,7 +11,7 @@ changed_when: false failed_when: snipe_settings_ready.rc != 0 -- name: "snipe-it: apply LDAP configuration via Setting model" +- name: "๐Ÿ“Œ snipe-it: apply LDAP configuration via Setting model" ansible.builtin.shell: cmd: >- container exec -i @@ -33,7 +33,7 @@ changed_when: true no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "snipe-it: clear Laravel caches" +- name: "๐Ÿงน snipe-it: clear Laravel caches" ansible.builtin.shell: cmd: "container exec -i {{ SNIPE_IT_CONTAINER_ADDRESS | quote }} php artisan optimize:clear" changed_when: true diff --git a/roles/web-app-snipe-it/tasks/03_admin.yml b/roles/web-app-snipe-it/tasks/03_admin.yml index 2f5749749d..dd20ef95f6 100644 --- a/roles/web-app-snipe-it/tasks/03_admin.yml +++ b/roles/web-app-snipe-it/tasks/03_admin.yml @@ -1,5 +1,5 @@ --- -- name: "Check if Snipe-IT admin user already exists (by username)" +- name: "๐Ÿ”Ž Check if Snipe-IT admin user already exists (by username)" ansible.builtin.shell: | container exec -i \ -e APP_KEY="{{ SNIPE_IT_APP_KEY }}" \ @@ -17,7 +17,7 @@ changed_when: false failed_when: false -- name: "Create Snipe-IT administrator account" +- name: "๐Ÿ“ Create Snipe-IT administrator account" ansible.builtin.shell: > container exec -i -e APP_KEY="{{ SNIPE_IT_APP_KEY }}" diff --git a/roles/web-app-snipe-it/tasks/04_sso.yml b/roles/web-app-snipe-it/tasks/04_sso.yml index a95e1a2325..1639510e2a 100644 --- a/roles/web-app-snipe-it/tasks/04_sso.yml +++ b/roles/web-app-snipe-it/tasks/04_sso.yml @@ -1,6 +1,6 @@ # @See https://raw.githubusercontent.com/snipe/snipe-it/master/app/Http/Controllers/Auth/LoginController.php --- -- name: "snipe-it: wait until settings table is seeded" +- name: "โณ snipe-it: wait until settings table is seeded" ansible.builtin.shell: cmd: "container exec -i {{ SNIPE_IT_CONTAINER_ADDRESS }} php" stdin: "{{ lookup('file', 'wait_settings.php') }}" @@ -11,7 +11,7 @@ changed_when: false failed_when: snipe_sso_settings_ready.rc != 0 -- name: "snipe-it: apply trusted-header SSO configuration via Setting model" +- name: "๐Ÿ“Œ snipe-it: apply trusted-header SSO configuration via Setting model" ansible.builtin.shell: cmd: >- container exec -i @@ -22,7 +22,7 @@ stdin: "{{ lookup('file', 'apply_sso_config.php') }}" changed_when: true -- name: "snipe-it: clear Laravel caches" +- name: "๐Ÿงน snipe-it: clear Laravel caches" ansible.builtin.shell: cmd: "container exec {{ SNIPE_IT_CONTAINER_ADDRESS }} php artisan optimize:clear" changed_when: true diff --git a/roles/web-app-snipe-it/tasks/main.yml b/roles/web-app-snipe-it/tasks/main.yml index 8eb9ea1141..7d5d49bf0a 100644 --- a/roles/web-app-snipe-it/tasks/main.yml +++ b/roles/web-app-snipe-it/tasks/main.yml @@ -1,10 +1,10 @@ --- -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: compose_handlers_flush: true -- name: "Snipe-IT manager-side operations (container exec)" +- name: "๐Ÿ‘” Snipe-IT manager-side operations (container exec)" include_tasks: 01a_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-sphinx/tasks/main.yml b/roles/web-app-sphinx/tasks/main.yml index 36623046ff..ebd8c3a4a7 100644 --- a/roles/web-app-sphinx/tasks/main.yml +++ b/roles/web-app-sphinx/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "load docker, proxy for '{{ application_id }}'" +- name: "๐Ÿงฉ load docker, proxy for '{{ application_id }}'" include_role: name: sys-stk-full vars: diff --git a/roles/web-app-suitecrm/tasks/01_core.yml b/roles/web-app-suitecrm/tasks/01_core.yml index 229018d983..85a84b8eee 100644 --- a/roles/web-app-suitecrm/tasks/01_core.yml +++ b/roles/web-app-suitecrm/tasks/01_core.yml @@ -1,12 +1,12 @@ --- - include_tasks: utils/once/flag.yml -- name: "Load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ Load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: compose_handlers_flush: false -- name: "SuiteCRM manager-side operations (file deploys + container exec)" +- name: "๐Ÿ‘” SuiteCRM manager-side operations (file deploys + container exec)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-suitecrm/tasks/02_manager_ops.yml b/roles/web-app-suitecrm/tasks/02_manager_ops.yml index 4f7dc9e4ab..83859b821b 100644 --- a/roles/web-app-suitecrm/tasks/02_manager_ops.yml +++ b/roles/web-app-suitecrm/tasks/02_manager_ops.yml @@ -1,12 +1,12 @@ --- -- name: "Deploy PHP error configuration (env aware)" +- name: "๐Ÿš€ Deploy PHP error configuration (env aware)" stack_host_template: src: "php.ini.j2" dest: "{{ SUITECRM_PHP_CONFIG_HOST }}" notify: - compose up -- name: "Render SuiteCRM LDAP mapping (local + swarm peers)" +- name: "๐Ÿ“„ Render SuiteCRM LDAP mapping (local + swarm peers)" ansible.builtin.include_tasks: file: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/render_replicated_templates.yml'] | path_join }}" vars: @@ -15,7 +15,7 @@ dest: "{{ SUITECRM_LDAP_CONFIG_HOST }}" when: "{{ SUITECRM_LDAP_ENABLED | bool }}" -- name: "Deploy '{{ SUITECRM_ENTRYPOINT_SCRIPT_HOST_ABS }}'" +- name: "๐Ÿš€ Deploy '{{ SUITECRM_ENTRYPOINT_SCRIPT_HOST_ABS }}'" copy: src: "{{ SUITECRM_ENTRYPOINT_SCRIPT_FILE }}" dest: "{{ SUITECRM_ENTRYPOINT_SCRIPT_HOST_ABS }}" @@ -23,5 +23,5 @@ - compose up - compose build -- name: "Docker Compose Up for '{{ application_id }}'" +- name: "๐Ÿณ Docker Compose Up for '{{ application_id }}'" meta: flush_handlers diff --git a/roles/web-app-suitecrm/tasks/main.yml b/roles/web-app-suitecrm/tasks/main.yml index 80d5bb9ad5..f734c246d5 100644 --- a/roles/web-app-suitecrm/tasks/main.yml +++ b/roles/web-app-suitecrm/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "Execute Role (once)" +- name: "โ–ถ๏ธ Execute Role (once)" include_tasks: 01_core.yml when: run_once_web_app_suitecrm is not defined vars: diff --git a/roles/web-app-taiga/tasks/01_administrator.yml b/roles/web-app-taiga/tasks/01_administrator.yml index bc079a9699..3a0d27fe49 100644 --- a/roles/web-app-taiga/tasks/01_administrator.yml +++ b/roles/web-app-taiga/tasks/01_administrator.yml @@ -1,5 +1,5 @@ --- -- name: "Run Taiga migrations (required before admin creation)" +- name: "โ–ถ๏ธ Run Taiga migrations (required before admin creation)" ansible.builtin.shell: > container exec -i {{ TAIGA_MANAGER_CONTAINER_ADDRESS }} @@ -7,7 +7,7 @@ register: taiga_migrate changed_when: taiga_migrate.rc == 0 -- name: "Create Taiga admin user (idempotent)" +- name: "๐Ÿ“ Create Taiga admin user (idempotent)" ansible.builtin.shell: > container exec -i -e DJANGO_SUPERUSER_PASSWORD={{ TAIGA_SUPERUSER_PASSWORD | quote }} @@ -24,7 +24,7 @@ ('integrityerror' not in (taiga_create_admin.stdout + taiga_create_admin.stderr) | lower) no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Upsert Taiga admin via manage.py shell" +- name: "๐Ÿ“ Upsert Taiga admin via manage.py shell" ansible.builtin.shell: > container exec -i -e DJANGO_SUPERUSER_PASSWORD={{ TAIGA_SUPERUSER_PASSWORD | quote }} diff --git a/roles/web-app-taiga/tasks/02_manager_ops.yml b/roles/web-app-taiga/tasks/02_manager_ops.yml index a2e8069ce1..3afb1769e5 100644 --- a/roles/web-app-taiga/tasks/02_manager_ops.yml +++ b/roles/web-app-taiga/tasks/02_manager_ops.yml @@ -1,54 +1,54 @@ --- -- name: "copy taiga gateway config with OIDC route" +- name: "๐Ÿ“‹ copy taiga gateway config with OIDC route" template: # nocheck: stack-host-template (taiga compose dir, not project nginx tree) src: "taiga-gateway/taiga.conf.j2" dest: "{{ [compose_repository_path, 'taiga-gateway', 'taiga.conf'] | path_join }}" when: TAIGA_OIDC_ENABLED | bool notify: compose up -- name: "render Dockerfile.taiga-back for custom auth-enabled backend image" +- name: "๐Ÿ“„ render Dockerfile.taiga-back for custom auth-enabled backend image" stack_host_template: src: "Dockerfile.backend.j2" dest: "{{ [compose_repository_path, 'Dockerfile.taiga-back'] | path_join }}" when: TAIGA_PLUGINS_ENABLED | bool notify: compose up -- name: "render Dockerfile.taiga-front for custom OIDC frontend image" +- name: "๐Ÿ“„ render Dockerfile.taiga-front for custom OIDC frontend image" stack_host_template: src: "Dockerfile.frontend.j2" dest: "{{ [compose_repository_path, 'Dockerfile.taiga-front'] | path_join }}" when: TAIGA_OIDC_ENABLED | bool notify: compose up -- name: "copy taiga config.append.py (OIDC and/or LDAP settings appended to config.py at runtime)" +- name: "๐Ÿ“‹ Copy taiga config.append.py (OIDC/LDAP settings appended at runtime)" stack_host_template: src: "settings/config.append.py.j2" dest: "{{ TAIGA_CONFIG_APPEND_PATH }}" when: TAIGA_PLUGINS_ENABLED | bool notify: compose up -- name: "copy taiga urls.py (OIDC URL routing)" +- name: "๐Ÿ“‹ copy taiga urls.py (OIDC URL routing)" stack_host_template: src: "settings/urls.py.j2" dest: "{{ TAIGA_URLS_PATH }}" when: TAIGA_OIDC_ENABLED | bool notify: compose up -- name: "copy taiga frontend conf.json (loginFormType / contribPlugins)" +- name: "๐Ÿ“‹ copy taiga frontend conf.json (loginFormType / contribPlugins)" stack_host_template: src: "settings/conf.json.j2" dest: "{{ TAIGA_FRONTEND_CONF_PATH }}" when: TAIGA_PLUGINS_ENABLED | bool notify: compose up -- name: "create {{ TAIGA_COMPOSE_INIT_PATH }}" +- name: "๐Ÿ“ create {{ TAIGA_COMPOSE_INIT_PATH }}" stack_host_template: src: "compose-inits.yml.j2" dest: "{{ TAIGA_COMPOSE_INIT_PATH }}" notify: compose up -- name: "Flush Taiga handlers" +- name: "๐Ÿšฟ Flush Taiga handlers" meta: flush_handlers -- name: "Include Taiga administrator routines" +- name: "๐Ÿ“‚ Include Taiga administrator routines" include_tasks: 01_administrator.yml diff --git a/roles/web-app-taiga/tasks/main.yml b/roles/web-app-taiga/tasks/main.yml index a50f6991f7..c9a0254d8a 100644 --- a/roles/web-app-taiga/tasks/main.yml +++ b/roles/web-app-taiga/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: @@ -8,6 +8,6 @@ compose_repository_ref: "{{ TAIGA_REF }}" compose_repository_pull: true -- name: "Taiga manager-side operations (file deploys + container exec)" +- name: "๐Ÿ‘” Taiga manager-side operations (file deploys + container exec)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-wordpress/tasks/01_patch_config.yml b/roles/web-app-wordpress/tasks/01_patch_config.yml index 1a639a0058..1316f8ad49 100644 --- a/roles/web-app-wordpress/tasks/01_patch_config.yml +++ b/roles/web-app-wordpress/tasks/01_patch_config.yml @@ -1,7 +1,7 @@ --- # The seeds need to be executed as root, because www-data isn't allowed to create files in the wordpress directory -- name: "Strip stale Multisite bareword constants from {{ WORDPRESS_CONFIG_FILE }} (defensive, runs before any wp-cli call)" +- name: "๐Ÿงน Strip stale Multisite bareword constants from {{ WORDPRESS_CONFIG_FILE }}" # Pre-fix runs of 06_multisite.yml wrote DOMAIN_CURRENT_SITE / # PATH_CURRENT_SITE with `wp config set --raw`, but Ansible's # `command:` module pipes through shlex, which strips the surrounding @@ -21,28 +21,28 @@ {{ WORDPRESS_DOCKER_CONF_PATH }} changed_when: true -- name: Update DB host in {{ WORDPRESS_CONFIG_FILE }} +- name: ๐Ÿ”„ Update DB host in {{ WORDPRESS_CONFIG_FILE }} shell: > container exec --user root {{ WORDPRESS_CONTAINER_ADDRESS }} sed -i "s/define(\s*'DB_HOST'\s*,\s*'[^']*'\s*);/define( 'DB_HOST', '{{ lookup('database', application_id, 'host') | sed_escape('/') }}:{{ lookup('database', application_id, 'port') | sed_escape('/') }}' );/i" {{ WORDPRESS_DOCKER_CONF_PATH }} notify: compose up -- name: Update DB name in {{ WORDPRESS_CONFIG_FILE }} +- name: ๐Ÿ”„ Update DB name in {{ WORDPRESS_CONFIG_FILE }} shell: > container exec --user root {{ WORDPRESS_CONTAINER_ADDRESS }} sed -i "s/define(\s*'DB_NAME'\s*,\s*'[^']*'\s*);/define( 'DB_NAME', '{{ lookup('database', application_id, 'name') | sed_escape('/') }}' );/i" {{ WORDPRESS_DOCKER_CONF_PATH }} notify: compose up -- name: Update DB user in {{ WORDPRESS_CONFIG_FILE }} +- name: ๐Ÿ”„ Update DB user in {{ WORDPRESS_CONFIG_FILE }} shell: > container exec --user root {{ WORDPRESS_CONTAINER_ADDRESS }} sed -i "s/define(\s*'DB_USER'\s*,\s*'[^']*'\s*);/define( 'DB_USER', '{{ lookup('database', application_id, 'username') | sed_escape('/') }}' );/i" {{ WORDPRESS_DOCKER_CONF_PATH }} notify: compose up -- name: Update DB password in {{ WORDPRESS_CONFIG_FILE }} +- name: ๐Ÿ”„ Update DB password in {{ WORDPRESS_CONFIG_FILE }} shell: > container exec --user root -e PATCH_PASSWORD={{ lookup('database', application_id, 'password') | sed_escape('/') | quote }} @@ -51,5 +51,5 @@ notify: compose up no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" -- name: "Flush handlers to reinitialize new database credentials" +- name: "๐Ÿšฟ Flush handlers to reinitialize new database credentials" meta: flush_handlers diff --git a/roles/web-app-wordpress/tasks/02_install.yml b/roles/web-app-wordpress/tasks/02_install.yml index 8b6d6b8371..4a17481d0a 100644 --- a/roles/web-app-wordpress/tasks/02_install.yml +++ b/roles/web-app-wordpress/tasks/02_install.yml @@ -1,5 +1,5 @@ --- -- name: "Wait until WordPress core files exist in {{ WORDPRESS_DOCKER_HTML_PATH }}" +- name: "โณ Wait until WordPress core files exist in {{ WORDPRESS_DOCKER_HTML_PATH }}" shell: > container exec {{ WORDPRESS_CONTAINER_ADDRESS }} test -f {{ WORDPRESS_DOCKER_HTML_PATH }}/wp-includes/version.php @@ -10,7 +10,7 @@ until: wp_core_present.rc == 0 failed_when: false -- name: "Seed WordPress core into volume if missing" +- name: "๐ŸŒฑ Seed WordPress core into volume if missing" when: wp_core_present.rc != 0 shell: > container exec -u root {{ WORDPRESS_CONTAINER_ADDRESS }} sh -lc @@ -20,7 +20,7 @@ chown -R {{ WORDPRESS_USER }}:{{ WORDPRESS_USER }} {{ WORDPRESS_DOCKER_HTML_PATH }}' changed_when: true -- name: "Run WordPress core install via WP CLI" +- name: "โ–ถ๏ธ Run WordPress core install via WP CLI" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" shell: > container exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER_ADDRESS }} diff --git a/roles/web-app-wordpress/tasks/03_enable_plugin.yml b/roles/web-app-wordpress/tasks/03_enable_plugin.yml index 5f899e37de..71557b899a 100644 --- a/roles/web-app-wordpress/tasks/03_enable_plugin.yml +++ b/roles/web-app-wordpress/tasks/03_enable_plugin.yml @@ -1,16 +1,16 @@ --- -- name: "Check if plugin has a dedicated install task under '{{ plugin_task_path }}'" +- name: "๐Ÿ”Ž Check if plugin has a dedicated install task under '{{ plugin_task_path }}'" stat: path: "{{ plugin_task_path }}" register: plugin_task_file delegate_to: localhost become: false -- name: "Include plugin-specific install task if it exists" +- name: "๐Ÿ“‚ Include plugin-specific install task if it exists" include_tasks: "{{ plugin_task_path }}" when: plugin_task_file.stat.exists -- name: "Install and activate WordPress plugin via WP CLI" +- name: "๐Ÿ“ฆ Install and activate WordPress plugin via WP CLI" ansible.builtin.shell: > container exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER_ADDRESS }} wp plugin install {{ plugin_name }} --activate diff --git a/roles/web-app-wordpress/tasks/04_update_domain.yml b/roles/web-app-wordpress/tasks/04_update_domain.yml index 508d5b5cd8..dfc5334869 100644 --- a/roles/web-app-wordpress/tasks/04_update_domain.yml +++ b/roles/web-app-wordpress/tasks/04_update_domain.yml @@ -2,7 +2,7 @@ # Updates WordPress single-site URLs and normalizes DB references. # Expects: wp_new_url (passed from main.yml), WORDPRESS_USER/container/docker_html_path. -- name: Get current 'home' URL +- name: โฌ‡๏ธ Get current 'home' URL shell: > container exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER_ADDRESS }} wp option get home --path={{ WORDPRESS_DOCKER_HTML_PATH }} @@ -10,7 +10,7 @@ changed_when: false failed_when: false -- name: Get current 'siteurl' +- name: โฌ‡๏ธ Get current 'siteurl' shell: > container exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER_ADDRESS }} wp option get siteurl --path={{ WORDPRESS_DOCKER_HTML_PATH }} @@ -18,7 +18,7 @@ changed_when: false failed_when: false -- name: Update 'home' (if needed) +- name: ๐Ÿ”„ Update 'home' (if needed) vars: wp_new_url_norm: "{{ wp_new_url | regex_replace('/+$','') }}" wp_home_norm: "{{ wp_home.stdout | regex_replace('/+$','') }}" @@ -27,7 +27,7 @@ wp option update home "{{ wp_new_url_norm }}" --path={{ WORDPRESS_DOCKER_HTML_PATH }} when: wp_home_norm != wp_new_url_norm -- name: Update 'siteurl' (if needed) +- name: ๐Ÿ”„ Update 'siteurl' (if needed) vars: wp_new_url_norm: "{{ wp_new_url | regex_replace('/+$','') }}" wp_siteurl_norm: "{{ wp_siteurl.stdout | regex_replace('/+$','') }}" @@ -36,7 +36,7 @@ wp option update siteurl "{{ wp_new_url_norm }}" --path={{ WORDPRESS_DOCKER_HTML_PATH }} when: wp_siteurl_norm != wp_new_url_norm -- name: Search-replace old โ†’ new URLs in DB (single site) +- name: ๐Ÿ” Search-replace old โ†’ new URLs in DB (single site) vars: wp_old_url_norm: "{{ wp_home.stdout | regex_replace('/+$','') }}" wp_new_url_norm: "{{ wp_new_url | regex_replace('/+$','') }}" @@ -48,7 +48,7 @@ register: wp_sr_domain changed_when: "{{ ('Success: Made 0 replacements.' not in wp_sr_domain.stdout) | bool }}" -- name: Normalize scheme to https if needed (http โ†’ https) +- name: ๐Ÿ“ Normalize scheme to https if needed (http โ†’ https) vars: domain_only: "{{ (wp_new_url | regex_replace('^https?://','')) | regex_replace('/+$','') }}" http_url: "http://{{ domain_only }}" @@ -62,7 +62,7 @@ changed_when: "{{ ('Success: Made 0 replacements.' not in wp_sr_scheme.stdout) | bool }}" when: lookup('tls', application_id, 'enabled') | bool -- name: Flush caches and rewrite rules +- name: ๐Ÿšฟ Flush caches and rewrite rules shell: > container exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER_ADDRESS }} bash -lc "wp cache flush --path={{ WORDPRESS_DOCKER_HTML_PATH }} && diff --git a/roles/web-app-wordpress/tasks/05_mu_plugins.yml b/roles/web-app-wordpress/tasks/05_mu_plugins.yml index addf4d77d4..945d33d662 100644 --- a/roles/web-app-wordpress/tasks/05_mu_plugins.yml +++ b/roles/web-app-wordpress/tasks/05_mu_plugins.yml @@ -3,13 +3,13 @@ # always active (mu-plugins cannot be deactivated from the admin UI). # Currently installs the OIDCโ†’RBAC role mapper. -- name: "Ensure mu-plugins directory exists inside the container" +- name: "โœ… Ensure mu-plugins directory exists inside the container" shell: > container exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER_ADDRESS }} mkdir -p {{ WORDPRESS_DOCKER_HTML_PATH }}/wp-content/mu-plugins changed_when: false -- name: "Copy infinito-oidc-rbac-mapper.php into the container" +- name: "๐Ÿ“‹ Copy infinito-oidc-rbac-mapper.php into the container" shell: > container cp {{ [role_path, 'files/mu-plugins/infinito-oidc-rbac-mapper.php'] | path_join }} @@ -18,14 +18,14 @@ changed_when: cp_mu_plugin.rc == 0 failed_when: cp_mu_plugin.rc != 0 -- name: "Ensure WordPress user owns the mu-plugin file" +- name: "โœ… Ensure WordPress user owns the mu-plugin file" shell: > container exec {{ WORDPRESS_CONTAINER_ADDRESS }} chown {{ WORDPRESS_USER }}:{{ WORDPRESS_USER }} {{ WORDPRESS_DOCKER_HTML_PATH }}/wp-content/mu-plugins/infinito-oidc-rbac-mapper.php changed_when: false -- name: "Copy infinito-http-ca-trust.php into the container" +- name: "๐Ÿ“‹ Copy infinito-http-ca-trust.php into the container" shell: > container cp {{ [role_path, 'files/mu-plugins/infinito-http-ca-trust.php'] | path_join }} @@ -34,7 +34,7 @@ changed_when: cp_ca_trust_mu_plugin.rc == 0 failed_when: cp_ca_trust_mu_plugin.rc != 0 -- name: "Ensure WordPress user owns the CA-trust mu-plugin file" +- name: "โœ… Ensure WordPress user owns the CA-trust mu-plugin file" shell: > container exec {{ WORDPRESS_CONTAINER_ADDRESS }} chown {{ WORDPRESS_USER }}:{{ WORDPRESS_USER }} diff --git a/roles/web-app-wordpress/tasks/06_multisite.yml b/roles/web-app-wordpress/tasks/06_multisite.yml index bba60c8d9b..f2dbc5561f 100644 --- a/roles/web-app-wordpress/tasks/06_multisite.yml +++ b/roles/web-app-wordpress/tasks/06_multisite.yml @@ -11,7 +11,7 @@ # stay green. Sites that already exist are detected via `wp site list` # before `wp site create` runs. -- name: "Multisite: convert Single-Site to Multisite network (subdomain install)" +- name: "๐ŸŒ Multisite: convert Single-Site to Multisite network (subdomain install)" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" shell: > container exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER_ADDRESS }} @@ -26,7 +26,7 @@ and ('already' not in (wp_ms_convert.stderr | lower)) and ('multisite' not in (wp_ms_convert.stderr | lower)) -- name: "Multisite: patch wp-config.php with PHP-literal constants (booleans, ints) - requires --raw" +- name: "๐Ÿ”ง Multisite: patch wp-config.php with PHP-literal constants (--raw)" # `--raw` writes the value verbatim into the file, so MULTISITE/ # SUBDOMAIN_INSTALL must arrive at wp-cli as bareword PHP literals # (true, false, 123, ...). For these the value contains no characters @@ -44,7 +44,7 @@ - { key: "BLOG_ID_CURRENT_SITE", value: "1" } changed_when: true -- name: "Multisite: patch wp-config.php with PHP-string constants (domain, path) without --raw" +- name: "๐Ÿ”ง Multisite: patch wp-config.php with PHP-string constants (no --raw)" # WHY split this loop: when `--raw` is set, wp-cli writes the value # verbatim. We previously tried to inject `'blog.infinito.example'` # WITH literal single-quotes so the verbatim write would land as a @@ -65,14 +65,14 @@ - { key: "PATH_CURRENT_SITE", value: "/" } changed_when: true -- name: "Multisite: list the existing sites in the network" +- name: "๐ŸŒ Multisite: list the existing sites in the network" shell: > container exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER_ADDRESS }} wp site list --field=url --path={{ WORDPRESS_DOCKER_HTML_PATH }} register: wp_ms_sites changed_when: false -- name: "Multisite: create any missing per-canonical-domain site" +- name: "๐ŸŒ Multisite: create any missing per-canonical-domain site" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" shell: > container exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER_ADDRESS }} diff --git a/roles/web-app-wordpress/tasks/07_manager_ops.yml b/roles/web-app-wordpress/tasks/07_manager_ops.yml index 85c642574d..0da9025e87 100644 --- a/roles/web-app-wordpress/tasks/07_manager_ops.yml +++ b/roles/web-app-wordpress/tasks/07_manager_ops.yml @@ -1,30 +1,30 @@ --- -- name: Check if {{ WORDPRESS_CONFIG_FILE }} exists in WordPress +- name: ๐Ÿ”Ž Check if {{ WORDPRESS_CONFIG_FILE }} exists in WordPress shell: > container exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER_ADDRESS }} test -f {{ WORDPRESS_CONFIG_PATH }} register: wp_config_file_exists changed_when: false failed_when: false -- name: Patch WordPress {{ WORDPRESS_CONFIG_FILE }} with updated DB credentials +- name: ๐Ÿฉน Patch WordPress {{ WORDPRESS_CONFIG_FILE }} with updated DB credentials include_tasks: 01_patch_config.yml when: wp_config_file_exists.rc == 0 -- name: "Install wordpress" +- name: "๐Ÿ“ฆ Install wordpress" include_tasks: 02_install.yml -- name: "Convert to Multisite when opted in" +- name: "๐Ÿ”„ Convert to Multisite when opted in" include_tasks: 06_multisite.yml when: >- (lookup('config', application_id, 'services.wordpress.multisite.enabled') | default(false) | bool) -- name: "Install mu-plugins (OIDCโ†’RBAC role mapper)" +- name: "๐Ÿ“ฆ Install mu-plugins (OIDCโ†’RBAC role mapper)" include_tasks: 05_mu_plugins.yml -- name: "Install and activate WordPress plugins" +- name: "๐Ÿ“ฆ Install and activate WordPress plugins" block: - - name: "Iterate through WordPress plugins" + - name: "๐Ÿ” Iterate through WordPress plugins" include_tasks: 03_enable_plugin.yml loop: "{{ WORDPRESS_PLUGINS }}" loop_control: @@ -36,14 +36,14 @@ plugin_task_path: "{{ [role_path, 'tasks/addons', plugin_name ~ '.yml' ] | path_join }}" when: plugin_enabled | bool -- name: Detect if WordPress is Multisite +- name: ๐Ÿ” Detect if WordPress is Multisite shell: > container exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER_ADDRESS }} wp eval 'echo (int) is_multisite();' --path={{ WORDPRESS_DOCKER_HTML_PATH }} register: wp_is_multisite changed_when: false -- name: "Update Single Side WordPress domain" +- name: "๐Ÿ”„ Update Single Side WordPress domain" include_tasks: 04_update_domain.yml when: (wp_is_multisite.stdout | trim) == '0' vars: diff --git a/roles/web-app-wordpress/tasks/addons/daggerhart-openid-connect-generic.yml b/roles/web-app-wordpress/tasks/addons/daggerhart-openid-connect-generic.yml index 48c86f50ac..f0dcb9fb85 100644 --- a/roles/web-app-wordpress/tasks/addons/daggerhart-openid-connect-generic.yml +++ b/roles/web-app-wordpress/tasks/addons/daggerhart-openid-connect-generic.yml @@ -1,15 +1,15 @@ --- -- name: "WP OIDC: stack-host container ops" +- name: "๐Ÿ–ฅ๏ธ WP OIDC: stack-host container ops" when: IS_STACK_HOST | bool block: - - name: "Ensure the OIDC settings option exists as a PHP-serialized empty array" + - name: "โœ… Ensure the OIDC settings option exists as a PHP-serialized empty array" ansible.builtin.shell: > container exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER_ADDRESS }} bash -lc "serialized_empty_array=$(wp eval 'echo serialize(array());' --path={{ WORDPRESS_DOCKER_HTML_PATH }}); \ wp option add openid_connect_generic_settings \"$serialized_empty_array\" --path={{ WORDPRESS_DOCKER_HTML_PATH }} \ || wp option update openid_connect_generic_settings \"$serialized_empty_array\" --path={{ WORDPRESS_DOCKER_HTML_PATH }};" - - name: "Apply all OIDC settings via WP-CLI eval (safe via base64)" + - name: "๐Ÿ“Œ Apply all OIDC settings via WP-CLI eval (safe via base64)" # base64-encoded JSON to avoid shell-escape issues in the eval payload. vars: oidc_settings_json_b64: "{{ lookup('config', application_id, 'addons.daggerhart-openid-connect-generic.config.oidc_settings') | to_json | b64encode }}" diff --git a/roles/web-app-wordpress/tasks/addons/wp-discourse-stack-host.yml b/roles/web-app-wordpress/tasks/addons/wp-discourse-stack-host.yml index 5395e04fc0..8e33eed936 100644 --- a/roles/web-app-wordpress/tasks/addons/wp-discourse-stack-host.yml +++ b/roles/web-app-wordpress/tasks/addons/wp-discourse-stack-host.yml @@ -1,11 +1,11 @@ --- -- name: Add /var/www/discourse to Git safe.directory +- name: โž• Add /var/www/discourse to Git safe.directory ansible.builtin.shell: > container exec {{ WORDPRESS_DISCOURSE_CONTAINER_ADDRESS }} git config --global --add safe.directory /var/www/discourse changed_when: false -- name: Revoke old WP Discourse API keys via Rails +- name: ๐Ÿšซ Revoke old WP Discourse API keys via Rails ansible.builtin.command: argv: - container @@ -19,12 +19,12 @@ changed_when: false failed_when: false -- name: Generate new WP Discourse API key via Rake task +- name: โš™๏ธ Generate new WP Discourse API key via Rake task ansible.builtin.shell: > container exec {{ WORDPRESS_DISCOURSE_CONTAINER_ADDRESS }} bash -lc "cd /var/www/discourse && bin/rake api_key:create_master['WP Discourse Integration']" register: discourse_generated_api_key -- name: Store the new WP Discourse API key in a fact +- name: ๐Ÿ’พ Store the new WP Discourse API key in a fact set_fact: vault_discourse_api_key: "{{ discourse_generated_api_key.stdout | trim }}" diff --git a/roles/web-app-wordpress/tasks/addons/wp-discourse.yml b/roles/web-app-wordpress/tasks/addons/wp-discourse.yml index f9e870468b..f6489412f9 100644 --- a/roles/web-app-wordpress/tasks/addons/wp-discourse.yml +++ b/roles/web-app-wordpress/tasks/addons/wp-discourse.yml @@ -1,33 +1,33 @@ --- -- name: Wait for Discourse API +- name: โณ Wait for Discourse API wait_for: host: "{{ lookup('domain','web-app-discourse') }}" port: 80 delay: 5 timeout: 600 -- name: "WP Discourse: stack-host container ops against Discourse" +- name: "๐Ÿ–ฅ๏ธ WP Discourse: stack-host container ops against Discourse" include_tasks: wp-discourse-stack-host.yml when: IS_STACK_HOST | bool # Use include_vars (not lookup('file')|from_yaml) so values lazy-render and the deploy-time vault_discourse_api_key resolves in this scope. -- name: "Load WP Discourse addon spec from meta/addons/wp-discourse.yml" +- name: "๐Ÿ“„ Load WP Discourse addon spec from meta/addons/wp-discourse.yml" ansible.builtin.include_vars: file: "{{ [role_path, 'meta/addons', 'wp-discourse.yml'] | path_join }}" name: wp_discourse_addon -- name: "Resolve WP Discourse settings" +- name: "๐Ÿ” Resolve WP Discourse settings" set_fact: discourse_settings: "{{ wp_discourse_addon.config.discourse_settings | default([]) }}" changed_when: false -- name: "Install WP Discourse plugin" +- name: "๐Ÿ“ฆ Install WP Discourse plugin" ansible.builtin.shell: > container exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER_ADDRESS }} wp plugin install wp-discourse --activate --path={{ WORDPRESS_DOCKER_HTML_PATH }} when: IS_STACK_HOST | bool -- name: "Configure WP Discourse settings" +- name: "๐Ÿ”ง Configure WP Discourse settings" loop: "{{ discourse_settings | map(attribute='name') | unique | list }}" loop_control: label: "{{ item }}" diff --git a/roles/web-app-wordpress/tasks/main.yml b/roles/web-app-wordpress/tasks/main.yml index 36c13dfacc..14f08b72fa 100644 --- a/roles/web-app-wordpress/tasks/main.yml +++ b/roles/web-app-wordpress/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "Include role sys-stk-front-proxy for {{ application_id }}" +- name: "๐Ÿ“‚ Include role sys-stk-front-proxy for {{ application_id }}" include_role: name: sys-stk-front-proxy loop: "{{ WORDPRESS_DOMAINS }}" @@ -9,13 +9,13 @@ webserver_extra_configuration: "client_max_body_size {{ WORDPRESS_MAX_UPLOAD_SIZE }};" http_port: "{{ lookup('config', application_id, 'services.wordpress.ports.local.http') }}" -- name: "load docker and db for {{ application_id }}" +- name: "๐Ÿงฉ load docker and db for {{ application_id }}" include_role: name: sys-stk-backend vars: compose_handlers_flush: false -- name: "Transfering upload.ini to {{ WORDPRESS_CONFIG_UPLD_ABS }}" +- name: "โฌ†๏ธ Transfering upload.ini to {{ WORDPRESS_CONFIG_UPLD_ABS }}" stack_host_template: src: upload.ini.j2 dest: "{{ WORDPRESS_CONFIG_UPLD_ABS }}" @@ -23,15 +23,15 @@ - compose up - compose build -- name: "Transfering msmtprc to {{ WORDPRESS_MSMTP_ABS }}" +- name: "๐Ÿ“ง Transfering msmtprc to {{ WORDPRESS_MSMTP_ABS }}" stack_host_template: src: "{{ WORDPRESS_MSMTP_SRC }}" dest: "{{ WORDPRESS_MSMTP_ABS }}" notify: compose up -- name: Flush handlers to make {{ WORDPRESS_CONFIG_FILE }} available before patch +- name: ๐Ÿšฟ Flush handlers to make {{ WORDPRESS_CONFIG_FILE }} available before patch meta: flush_handlers -- name: "WordPress stack-host post-deploy (container exec, plugin install, domain ops)" +- name: "๐Ÿ–ฅ๏ธ WordPress stack-host post-deploy (container exec, plugin install, domain ops)" include_tasks: 07_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-xwiki/tasks/01_core.yml b/roles/web-app-xwiki/tasks/01_core.yml index 53f8a7325d..7737756b6b 100644 --- a/roles/web-app-xwiki/tasks/01_core.yml +++ b/roles/web-app-xwiki/tasks/01_core.yml @@ -1,24 +1,24 @@ --- - include_tasks: utils/once/flag.yml -- name: Validate XWiki variables +- name: โœ… Validate XWiki variables include_tasks: 02_validation.yml - block: - - name: "load docker, db and proxy for {{ application_id }}" + - name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: compose_handlers_flush: false - - name: Deploy Bootstrap Config + - name: ๐Ÿš€ Deploy Bootstrap Config include_tasks: _flush_config.yml when: IS_STACK_HOST | bool vars: xwiki_oidc_enabled_switch: false xwiki_ldap_enabled_switch: false -- name: "XWiki manager-side operations (file deploys + container exec)" +- name: "๐Ÿ‘” XWiki manager-side operations (file deploys + container exec)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-xwiki/tasks/02_manager_ops.yml b/roles/web-app-xwiki/tasks/02_manager_ops.yml index b9c8a71eee..8febe4ef2b 100644 --- a/roles/web-app-xwiki/tasks/02_manager_ops.yml +++ b/roles/web-app-xwiki/tasks/02_manager_ops.yml @@ -1,5 +1,5 @@ --- -- name: "ASSERT | superadmin can authenticate (needed for installer)" +- name: "โœ… ASSERT | superadmin can authenticate (needed for installer)" uri_retry: url: "{{ [XWIKI_REST_XWIKI, 'spaces'] | url_join }}" method: GET @@ -13,7 +13,7 @@ failed_when: false - block: - - name: "DEBUG | superadmin check + pw hash compare (condensed)" + - name: "๐Ÿ› DEBUG | superadmin check + pw hash compare (condensed)" script: >- debug_superadmin.sh "{{ _super_check_ext.status }}" @@ -28,7 +28,7 @@ changed_when: false failed_when: false - - name: "FAIL | superadmin authentication failed (extensions phase)" + - name: "๐Ÿ›‘ FAIL | superadmin authentication failed (extensions phase)" fail: msg: | superadmin authentication failed (extensions phase) @@ -45,24 +45,24 @@ hint: check xwiki.cfg in image / password / Dockerfile build when: _super_check_ext.status != 200 -- name: Load setup procedures for admin +- name: ๐Ÿ“‚ Load setup procedures for admin include_tasks: 03_administrator.yml when: not (XWIKI_SSO_ENABLED | bool) -- name: Load setup procedures for extensions +- name: ๐Ÿ“‚ Load setup procedures for extensions include_tasks: 04_extensions.yml -- name: "XWIKI | Ensure Main.WebHome exists" +- name: "โœ… XWIKI | Ensure Main.WebHome exists" include_tasks: 05_main_webhome.yml - block: - - name: "Create Final Docker Compose File" + - name: "๐Ÿ“ Create Final Docker Compose File" stack_host_template: src: "compose.yml.j2" dest: "{{ lookup('container', application_id, 'files.compose') }}" notify: compose up - - name: Deploy Final Config + - name: ๐Ÿš€ Deploy Final Config include_tasks: _flush_config.yml vars: xwiki_oidc_enabled_switch: "{{ XWIKI_OIDC_ENABLED | bool }}" diff --git a/roles/web-app-xwiki/tasks/02_validation.yml b/roles/web-app-xwiki/tasks/02_validation.yml index 7f8fb08ab0..5698be4a47 100644 --- a/roles/web-app-xwiki/tasks/02_validation.yml +++ b/roles/web-app-xwiki/tasks/02_validation.yml @@ -1,5 +1,5 @@ --- -- name: "ASSERT | Only one auth backend (OIDC or LDAP) may be enabled" +- name: "โœ… ASSERT | Only one auth backend (OIDC or LDAP) may be enabled" assert: that: - not ((XWIKI_OIDC_ENABLED | bool) and (XWIKI_LDAP_ENABLED | bool)) diff --git a/roles/web-app-xwiki/tasks/03_administrator.yml b/roles/web-app-xwiki/tasks/03_administrator.yml index 1623f14aa4..c172fd984a 100644 --- a/roles/web-app-xwiki/tasks/03_administrator.yml +++ b/roles/web-app-xwiki/tasks/03_administrator.yml @@ -1,11 +1,11 @@ --- # Ensure an admin user exists (when SSO is disabled) and can administer XWiki. -- name: "XWIKI | Fetch REST session + form token (admin write ops)" +- name: "โฌ‡๏ธ XWIKI | Fetch REST session + form token (admin write ops)" include_tasks: _rest_session.yml # 1) Create page XWiki. (PUT is idempotent) -- name: "XWIKI | Ensure user page exists: XWiki.{{ XWIKI_ADMIN_USER }}" +- name: "โœ… XWIKI | Ensure user page exists: XWiki.{{ XWIKI_ADMIN_USER }}" uri_retry: url: "{{ [XWIKI_REST_XWIKI_PAGES, XWIKI_ADMIN_USER | urlencode] | url_join }}" method: PUT @@ -18,7 +18,7 @@ register: _user_page # 2) Add XWiki.XWikiUsers object (only if it does not already exist) -- name: "XWIKI | Check if XWikiUsers object exists" +- name: "๐Ÿ”Ž XWIKI | Check if XWikiUsers object exists" uri_retry: url: "{{ [XWIKI_REST_XWIKI_PAGES, XWIKI_ADMIN_USER | urlencode, 'objects'] | url_join }}?classname=XWiki.XWikiUsers" method: GET @@ -28,7 +28,7 @@ status_code: [200, 404] register: _users_obj_list -- name: "XWIKI | Add XWiki.XWikiUsers object" +- name: "โž• XWIKI | Add XWiki.XWikiUsers object" uri_retry: url: "{{ [XWIKI_REST_XWIKI_PAGES, XWIKI_ADMIN_USER | urlencode, 'objects'] | url_join }}" method: POST @@ -42,7 +42,7 @@ register: _user_obj_created - block: - - name: "XWIKI | Ensure {{ XWIKI_ADMIN_GROUP_PAGE }} page exists" + - name: "โœ… XWIKI | Ensure {{ XWIKI_ADMIN_GROUP_PAGE }} page exists" uri_retry: url: "{{ [XWIKI_REST_XWIKI_PAGES, XWIKI_ADMIN_GROUP_PAGE] | url_join }}" method: PUT @@ -52,7 +52,7 @@ status_code: [201, 202, 204, 200] headers: "{{ xwiki_rest_headers_write }}" body: "{{ lookup('template', 'xml/xwiki_admin_group_page.xml.j2') }}" - - name: "XWIKI | Ensure user is in {{ XWIKI_ADMIN_GROUP_PAGE }}" + - name: "โœ… XWIKI | Ensure user is in {{ XWIKI_ADMIN_GROUP_PAGE }}" uri_retry: url: "{{ [XWIKI_REST_XWIKI_PAGES, XWIKI_ADMIN_GROUP_PAGE, 'objects'] | url_join }}" method: POST diff --git a/roles/web-app-xwiki/tasks/04_extensions.yml b/roles/web-app-xwiki/tasks/04_extensions.yml index 04c56f0a4f..905c799be2 100644 --- a/roles/web-app-xwiki/tasks/04_extensions.yml +++ b/roles/web-app-xwiki/tasks/04_extensions.yml @@ -11,7 +11,7 @@ # Notes: # - We print machine-readable markers so Ansible can assert deterministically. -- name: "XWIKI | Build Groovy installer code from static file (base64 payload)" +- name: "๐Ÿ”จ XWIKI | Build Groovy installer code from static file (base64 payload)" vars: _wanted_b64: "{{ XWIKI_PLUGINS | to_json | b64encode }}" set_fact: @@ -19,10 +19,10 @@ {{ lookup('file', 'roles/web-app-xwiki/files/extension_installer_b64.groovy') | regex_replace('__WANTED_B64__', _wanted_b64) }} -- name: "XWIKI | Fetch REST session + form token (extensions write ops)" +- name: "โฌ‡๏ธ XWIKI | Fetch REST session + form token (extensions write ops)" include_tasks: _rest_session.yml -- name: "XWIKI | PUT installer page Main.InstallExtensions" +- name: "โฌ†๏ธ XWIKI | PUT installer page Main.InstallExtensions" uri_retry: url: "{{ [XWIKI_REST_XWIKI_PAGES, 'InstallExtensions'] | url_join }}" method: PUT @@ -35,15 +35,15 @@ register: _put_page - block: - - name: "XWIKI | Load installer-page execution + assertion routines" + - name: "๐Ÿ“‚ XWIKI | Load installer-page execution + assertion routines" include_tasks: 04b_extensions_execute.yml rescue: - - name: "XWIKI | Load extension-install rescue/debug routines" + - name: "๐Ÿ“‚ XWIKI | Load extension-install rescue/debug routines" include_tasks: 04a_extensions_rescue.yml always: - - name: "XWIKI | Delete installer page (best effort)" + - name: "๐Ÿ—‘๏ธ XWIKI | Delete installer page (best effort)" uri_retry: url: "{{ [XWIKI_REST_XWIKI_PAGES, 'InstallExtensions'] | url_join }}" method: DELETE @@ -56,7 +56,7 @@ changed_when: _delete_page_best_effort.status != 404 failed_when: false -- name: "XWIKI | Verify requested extensions via Groovy checker" +- name: "โœ… XWIKI | Verify requested extensions via Groovy checker" include_tasks: _check_extension_via_groovy.yml loop: "{{ XWIKI_PLUGINS }}" loop_control: @@ -66,7 +66,7 @@ ext_id: "{{ plugin.id }}" result_var: "probe_{{ plugin.id | regex_replace('[^A-Za-z0-9_]', '_') }}" -- name: "XWIKI | Collect probe results" +- name: "๐Ÿ“Š XWIKI | Collect probe results" set_fact: _xwiki_probe_results: "{{ _xwiki_probe_results | default([]) + [ { 'id': plugin.id, 'status': ( (hostvars[inventory_hostname]['probe_' ~ (plugin.id | regex_replace('[^A-Za-z0-9_]', '_'))] | default({})).status | default(404) | int ) } ] }}" @@ -75,14 +75,14 @@ loop_var: plugin changed_when: false -- name: "XWIKI | Assert all requested extensions are installed" +- name: "โœ… XWIKI | Assert all requested extensions are installed" vars: missing: "{{ (_xwiki_probe_results | default([])) | selectattr('status','equalto',404) | map(attribute='id') | list }}" fail: msg: "Missing extensions: {{ missing | join(', ') }}" when: missing | length > 0 -- name: "XWIKI | Delete installer page" +- name: "๐Ÿ—‘๏ธ XWIKI | Delete installer page" uri_retry: url: "{{ [XWIKI_REST_XWIKI_PAGES, 'InstallExtensions'] | url_join }}" method: DELETE diff --git a/roles/web-app-xwiki/tasks/04a_extensions_rescue.yml b/roles/web-app-xwiki/tasks/04a_extensions_rescue.yml index 049c5a899c..77524b6752 100644 --- a/roles/web-app-xwiki/tasks/04a_extensions_rescue.yml +++ b/roles/web-app-xwiki/tasks/04a_extensions_rescue.yml @@ -1,9 +1,9 @@ --- -- name: "XWIKI | DEBUG | Show installer page output" +- name: "๐Ÿ‘๏ธ XWIKI | DEBUG | Show installer page output" debug: var: _exec_page.content -- name: "XWIKI | DEBUG | Repo reachability from container (nexus + maven central)" +- name: "๐ŸŒฟ XWIKI | DEBUG | Repo reachability from container (nexus + maven central)" ansible.builtin.shell: | set -euo pipefail container exec "{{ XWIKI_CONTAINER_ADDRESS }}" sh -lc ' @@ -18,7 +18,7 @@ changed_when: false failed_when: false -- name: "XWIKI | DEBUG | Dump mounted xwiki.properties (first 200 lines)" +- name: "๐Ÿ’พ XWIKI | DEBUG | Dump mounted xwiki.properties (first 200 lines)" ansible.builtin.shell: | set -euo pipefail container exec "{{ XWIKI_CONTAINER_ADDRESS }}" sh -lc ' @@ -32,7 +32,7 @@ changed_when: false failed_when: false -- name: "XWIKI | DEBUG | Tail container logs" +- name: "๐Ÿ“ฆ XWIKI | DEBUG | Tail container logs" ansible.builtin.shell: | set -euo pipefail container logs --tail 300 "{{ XWIKI_CONTAINER }}" || true @@ -40,7 +40,7 @@ changed_when: false failed_when: false -- name: "XWIKI | DEBUG | Print debug outputs" +- name: "๐Ÿ’ฌ XWIKI | DEBUG | Print debug outputs" debug: msg: | ===== XWIKI DEBUG NET ===== @@ -55,7 +55,7 @@ {{ _dbg_logs.stdout | default('') }} {{ _dbg_logs.stderr | default('') }} -- name: "XWIKI | FAIL | Extension installation failed (see debug above)" +- name: "๐Ÿ› XWIKI | FAIL | Extension installation failed (see debug above)" fail: msg: | Extension installation failed. diff --git a/roles/web-app-xwiki/tasks/04b_extensions_execute.yml b/roles/web-app-xwiki/tasks/04b_extensions_execute.yml index df749e4e69..13d42e3b10 100644 --- a/roles/web-app-xwiki/tasks/04b_extensions_execute.yml +++ b/roles/web-app-xwiki/tasks/04b_extensions_execute.yml @@ -1,5 +1,5 @@ --- -- name: "XWIKI | Execute installer page" +- name: "โ–ถ๏ธ XWIKI | Execute installer page" uri_retry: url: "{{ XWIKI_DOCKER_REACH_URL }}/bin/view/XWiki/InstallExtensions?xpage=plain" method: GET @@ -17,7 +17,7 @@ - (_exec_page.content | default('')) is not search('WARN::') changed_when: false -- name: "XWIKI | Assert installer output has no errors" +- name: "โœ… XWIKI | Assert installer output has no errors" assert: that: - (_exec_page.content | default('')) is not search('ERROR::') diff --git a/roles/web-app-xwiki/tasks/05_main_webhome.yml b/roles/web-app-xwiki/tasks/05_main_webhome.yml index b270b9524d..d106b50ac4 100644 --- a/roles/web-app-xwiki/tasks/05_main_webhome.yml +++ b/roles/web-app-xwiki/tasks/05_main_webhome.yml @@ -1,5 +1,5 @@ --- -- name: "XWIKI | Check if Main.WebHome exists" +- name: "๐Ÿ”Ž XWIKI | Check if Main.WebHome exists" uri_retry: url: "{{ [XWIKI_REST_BASE, 'wikis/xwiki/spaces/Main/pages/WebHome'] | url_join }}" method: GET @@ -11,11 +11,11 @@ register: _main_webhome_check changed_when: false -- name: "XWIKI | Fetch REST session + form token (Main.WebHome write ops)" +- name: "โฌ‡๏ธ XWIKI | Fetch REST session + form token (Main.WebHome write ops)" include_tasks: _rest_session.yml when: _main_webhome_check.status == 404 -- name: "XWIKI | Create Main.WebHome if missing" +- name: "๐Ÿ“ XWIKI | Create Main.WebHome if missing" uri_retry: url: "{{ [XWIKI_REST_BASE, 'wikis/xwiki/spaces/Main/pages/WebHome'] | url_join }}" method: PUT diff --git a/roles/web-app-xwiki/tasks/_check_extension_via_groovy.yml b/roles/web-app-xwiki/tasks/_check_extension_via_groovy.yml index 155e8a9b75..2cc32347d2 100644 --- a/roles/web-app-xwiki/tasks/_check_extension_via_groovy.yml +++ b/roles/web-app-xwiki/tasks/_check_extension_via_groovy.yml @@ -1,11 +1,11 @@ --- # PUT a temporary Groovy page that checks installed extensions, call it, then delete it. -- name: "XWIKI | Fetch REST session + form token (extension check write ops)" +- name: "โฌ‡๏ธ XWIKI | Fetch REST session + form token (extension check write ops)" include_tasks: _rest_session.yml # PUT a temporary Groovy page that checks installed extensions -- name: "XWIKI | PUT checker page XWiki.CheckExtension" +- name: "โฌ†๏ธ XWIKI | PUT checker page XWiki.CheckExtension" uri_retry: url: "{{ [XWIKI_REST_XWIKI_PAGES, 'CheckExtension'] | url_join }}" method: PUT @@ -19,7 +19,7 @@ changed_when: false # Call the page to check a single extension -- name: "XWIKI | Check installed via Groovy for {{ ext_id }}" +- name: "๐Ÿ”Ž XWIKI | Check installed via Groovy for {{ ext_id }}" uri_retry: url: "{{ XWIKI_DOCKER_REACH_URL }}/bin/view/XWiki/CheckExtension?xpage=plain&id={{ ext_id | urlencode }}" method: GET @@ -31,14 +31,14 @@ register: _check_output changed_when: false -- name: "XWIKI | Save Groovy check result for {{ ext_id }}" +- name: "๐Ÿ’พ XWIKI | Save Groovy check result for {{ ext_id }}" set_fact: "{{ result_var }}": status: "{{ _check_output.content | xwiki_extension_status }}" raw: "{{ _check_output.content }}" # Cleanup (optional; you can leave the page, but we remove it to keep things tidy) -- name: "XWIKI | Delete checker page" +- name: "๐Ÿ—‘๏ธ XWIKI | Delete checker page" uri_retry: url: "{{ [XWIKI_REST_XWIKI_PAGES, 'CheckExtension'] | url_join }}" method: DELETE diff --git a/roles/web-app-xwiki/tasks/_flush_config.yml b/roles/web-app-xwiki/tasks/_flush_config.yml index 332885391b..d9761eb2e3 100644 --- a/roles/web-app-xwiki/tasks/_flush_config.yml +++ b/roles/web-app-xwiki/tasks/_flush_config.yml @@ -1,14 +1,14 @@ --- -- name: "Deploy xwiki.properties" +- name: "๐Ÿš€ Deploy xwiki.properties" stack_host_template: src: "xwiki.properties.j2" dest: "{{ XWIKI_HOST_PROPERTIES_PATH }}" notify: compose up -- name: "flush compose for '{{ application_id }}'" +- name: "๐Ÿšฟ flush compose for '{{ application_id }}'" meta: flush_handlers -- name: "Wait until XWiki REST is ready (no DW redirect)" +- name: "โณ Wait until XWiki REST is ready (no DW redirect)" uri_retry: url: "{{ XWIKI_REST_BASE }}" status_code: [200, 401] diff --git a/roles/web-app-xwiki/tasks/_rest_session.yml b/roles/web-app-xwiki/tasks/_rest_session.yml index f205af919d..bf514e55c4 100644 --- a/roles/web-app-xwiki/tasks/_rest_session.yml +++ b/roles/web-app-xwiki/tasks/_rest_session.yml @@ -6,7 +6,7 @@ # # This task file sets a fact `xwiki_rest_headers_write` that you can reuse. -- name: "XWIKI | Fetch REST session + form token (write ops)" +- name: "โฌ‡๏ธ XWIKI | Fetch REST session + form token (write ops)" uri_retry: url: "{{ [XWIKI_REST_XWIKI, 'spaces'] | url_join }}" method: GET @@ -18,7 +18,7 @@ register: _xwiki_rest_session changed_when: false -- name: "XWIKI | Set REST write headers" +- name: "๐Ÿ”ง XWIKI | Set REST write headers" set_fact: xwiki_rest_headers_write: Content-Type: "application/xml" diff --git a/roles/web-app-yourls/tasks/install.yml b/roles/web-app-yourls/tasks/install.yml index 5d7f0dfcef..b895e43aac 100644 --- a/roles/web-app-yourls/tasks/install.yml +++ b/roles/web-app-yourls/tasks/install.yml @@ -1,8 +1,8 @@ --- -- name: "Provision YOURLS on the stack host" +- name: "๐Ÿ”ง Provision YOURLS on the stack host" when: IS_STACK_HOST | bool block: - - name: "Wait until YOURLS is reachable inside {{ YOURLS_CONTAINER }}" + - name: "โณ Wait until YOURLS is reachable inside {{ YOURLS_CONTAINER }}" ansible.builtin.shell: cmd: >- container exec {{ YOURLS_CONTAINER_ADDRESS }} @@ -13,7 +13,7 @@ until: yourls_install_probe.rc == 0 changed_when: false - - name: "Create the YOURLS database schema via the installer (idempotent)" + - name: "๐Ÿ“ Create the YOURLS database schema via the installer (idempotent)" ansible.builtin.shell: cmd: >- container exec {{ YOURLS_CONTAINER_ADDRESS }} diff --git a/roles/web-app-yourls/tasks/main.yml b/roles/web-app-yourls/tasks/main.yml index 05c96b0466..19d7f76cf9 100644 --- a/roles/web-app-yourls/tasks/main.yml +++ b/roles/web-app-yourls/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: @@ -7,7 +7,7 @@ compose_handlers_flush: false webserver_extra_configuration: "{{ lookup('template', 'redirect.conf.j2') }}" -- name: "Stage trusted-header SSO build-context files for {{ application_id }}" +- name: "๐ŸŽฌ Stage trusted-header SSO build-context files for {{ application_id }}" stack_host_copy: src: "{{ item.src }}" dest: "{{ [ lookup('container', application_id, 'directories.instance'), item.dest ] | path_join }}" @@ -16,9 +16,9 @@ - { src: "Dockerfile", dest: "Dockerfile" } - { src: "sso/infinito_sso.php", dest: "infinito_sso.php" } -- name: "Flush compose handlers for {{ application_id }}" +- name: "๐Ÿšฟ Flush compose handlers for {{ application_id }}" ansible.builtin.meta: flush_handlers -- name: "Install the YOURLS database schema for {{ application_id }}" +- name: "๐Ÿ“ฆ Install the YOURLS database schema for {{ application_id }}" ansible.builtin.include_tasks: install.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-zammad/tasks/01_core.yml b/roles/web-app-zammad/tasks/01_core.yml index 29a8fb0ecc..f6c2b1304d 100644 --- a/roles/web-app-zammad/tasks/01_core.yml +++ b/roles/web-app-zammad/tasks/01_core.yml @@ -1,12 +1,12 @@ --- - include_tasks: utils/once/flag.yml -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: compose_handlers_flush: false -- name: "Zammad manager-side operations (file deploys + container exec)" +- name: "๐Ÿ‘” Zammad manager-side operations (file deploys + container exec)" include_tasks: 02_manager_ops.yml when: IS_STACK_HOST | bool diff --git a/roles/web-app-zammad/tasks/02_manager_ops.yml b/roles/web-app-zammad/tasks/02_manager_ops.yml index ff3edc78a1..19ffd472a0 100644 --- a/roles/web-app-zammad/tasks/02_manager_ops.yml +++ b/roles/web-app-zammad/tasks/02_manager_ops.yml @@ -1,5 +1,5 @@ --- -- name: "Stage Zammad host-side init files (local + swarm peers)" +- name: "๐ŸŽฌ Stage Zammad host-side init files (local + swarm peers)" ansible.builtin.include_tasks: file: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/render_replicated_templates.yml'] | path_join }}" vars: @@ -18,7 +18,7 @@ mode: "0644" when: "{{ ZAMMAD_OIDC_ENABLED }}" -- name: "grant CREATEDB to the Zammad PostgreSQL role (Zammad's init runs rake db:create even when the DB exists)" +- name: "๐Ÿ” grant CREATEDB to Zammad PostgreSQL role (init runs rake db:create)" database_query: mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" config: >- @@ -31,10 +31,10 @@ query: "{{ lookup('template', role_path ~ '/templates/sql/grant_createdb.sql.j2') }}" when: lookup('config', application_id, 'services.postgres.shared') | bool -- name: "flush handlers so the Zammad init container starts with auto_wizard.json bind-mounted" +- name: "๐Ÿ”„ flush handlers so Zammad init starts with auto_wizard.json bind-mounted" meta: flush_handlers -- name: "wait for the Zammad Rails server to answer" +- name: "โณ wait for the Zammad Rails server to answer" ansible.builtin.shell: | set -eo pipefail container exec {{ ZAMMAD_RAILS_CONTAINER_ADDRESS }} \ @@ -45,7 +45,7 @@ delay: 5 until: zammad_rails_ready.rc == 0 -- name: "process auto_wizard.json if Zammad's setup wizard hasn't completed yet (idempotent)" +- name: "โ–ถ๏ธ process auto_wizard.json if Zammad setup wizard incomplete (idempotent)" ansible.builtin.shell: | set -euo pipefail container exec -i {{ ZAMMAD_RAILS_CONTAINER_ADDRESS }} bundle exec rails r ' @@ -57,7 +57,7 @@ register: zammad_auto_wizard_setup changed_when: false -- name: "ensure API-bot user in Zammad (Basic-auth REST API; runs in EVERY variant including no-auth)" +- name: "โœ… ensure API-bot user in Zammad (Basic-auth REST API; all variants, no-auth too)" ansible.builtin.shell: | set -euo pipefail container exec -i \ @@ -73,7 +73,7 @@ register: zammad_api_bot_apply changed_when: false -- name: "apply OIDC settings in Zammad (post-bootstrap; idempotent)" +- name: "๐Ÿ“Œ apply OIDC settings in Zammad (post-bootstrap; idempotent)" ansible.builtin.shell: | set -euo pipefail container exec -i \ @@ -92,7 +92,7 @@ changed_when: false when: ZAMMAD_OIDC_ENABLED -- name: "configure Zammad's LdapSource against svc-db-openldap (post-bootstrap; idempotent)" +- name: "๐Ÿ”ง configure Zammad LdapSource vs svc-db-openldap (post-bootstrap; idempotent)" ansible.builtin.shell: | set -euo pipefail container exec -i \ @@ -112,7 +112,7 @@ changed_when: false when: ZAMMAD_LDAP_ENABLED -- name: "configure Zammad's Email channel (inbound IMAP + outbound SMTP) against Mailu" +- name: "๐Ÿ”ง configure Zammad's Email channel (inbound IMAP + outbound SMTP) against Mailu" ansible.builtin.shell: | set -euo pipefail container exec -i \ diff --git a/roles/web-opt-rdr-domains/tasks/main.yml b/roles/web-opt-rdr-domains/tasks/main.yml index f09ba64217..28e34d81a5 100644 --- a/roles/web-opt-rdr-domains/tasks/main.yml +++ b/roles/web-opt-rdr-domains/tasks/main.yml @@ -1,13 +1,13 @@ --- # nocheck: run-once -- name: Include dependency 'sys-svc-webserver-https' +- name: ๐Ÿ“‚ Include dependency 'sys-svc-webserver-https' include_role: name: sys-svc-webserver-https vars: compose_handlers_flush: true -- name: "Include domains redirects" +- name: "๐Ÿ“‚ Include domains redirects" include_tasks: redirect-domain.yml vars: domain: "{{ item.source }}" diff --git a/roles/web-opt-rdr-domains/tasks/redirect-domain.yml b/roles/web-opt-rdr-domains/tasks/redirect-domain.yml index 0f9cfa6362..e004cc0d67 100644 --- a/roles/web-opt-rdr-domains/tasks/redirect-domain.yml +++ b/roles/web-opt-rdr-domains/tasks/redirect-domain.yml @@ -1,12 +1,12 @@ --- -- name: "TLS | Apply tls layer" +- name: "๐Ÿ“Œ TLS | Apply tls layer" include_role: name: sys-front-tls when: lookup('tls', domain, 'enabled') | bool vars: application_id: "{{ domain }}" -- name: "Deploying NGINX redirect configuration for '{{ domain }}'" +- name: "๐ŸŒ Deploying NGINX redirect configuration for '{{ domain }}'" stack_host_template: src: redirect-domain.conf.j2 dest: "{{ lookup('nginx', 'files.domain', domain) }}" diff --git a/roles/web-opt-rdr-www/tasks/_01_cloudflare_edge_redirect.yml b/roles/web-opt-rdr-www/tasks/_01_cloudflare_edge_redirect.yml index 875fc66d60..18752567f4 100644 --- a/roles/web-opt-rdr-www/tasks/_01_cloudflare_edge_redirect.yml +++ b/roles/web-opt-rdr-www/tasks/_01_cloudflare_edge_redirect.yml @@ -1,5 +1,5 @@ --- -- name: Include Cloudflare redirect rule to enforce www โ†’ apex +- name: ๐Ÿ“‚ Include Cloudflare redirect rule to enforce www โ†’ apex include_tasks: _02_cloudflare_redirect_rule.yml vars: domain: "{{ item.target }}" diff --git a/roles/web-opt-rdr-www/tasks/_02_cloudflare_redirect_rule.yml b/roles/web-opt-rdr-www/tasks/_02_cloudflare_redirect_rule.yml index b35095a4f7..c10c3a7754 100644 --- a/roles/web-opt-rdr-www/tasks/_02_cloudflare_redirect_rule.yml +++ b/roles/web-opt-rdr-www/tasks/_02_cloudflare_redirect_rule.yml @@ -7,12 +7,12 @@ # apex_url: "https://example.com" # API.cloudflare.api_token (via lookup('api', 'cloudflare.api_token')) -- name: "Derive zone from www_fqdn; apex comes from caller" +- name: "๐Ÿงฎ Derive zone from www_fqdn; apex comes from caller" set_fact: cf_zone_name: "{{ www_fqdn | to_zone }}" domain_apex: "{{ domain }}" -- name: "Cloudflare: Lookup zone id for {{ cf_zone_name }}" +- name: "๐Ÿ” Cloudflare: Lookup zone id for {{ cf_zone_name }}" uri_retry: url: "https://api.cloudflare.com/client/v4/zones?name={{ cf_zone_name }}" method: GET @@ -25,11 +25,11 @@ (cf_zone_lookup.status != 200) or (cf_zone_lookup.json.result | length) == 0 -- name: "Set fact: zone_id" +- name: "๐Ÿ”ง Set fact: zone_id" set_fact: cf_zone_id: "{{ (cf_zone_lookup.json.result | first).id }}" -- name: "Remove conflicting A/AAAA record for {{ www_fqdn }}" +- name: "๐Ÿ—‘๏ธ Remove conflicting A/AAAA record for {{ www_fqdn }}" community.general.cloudflare_dns: api_token: "{{ lookup('api', 'cloudflare.api_token') }}" zone: "{{ cf_zone_name }}" @@ -38,7 +38,7 @@ state: absent ignore_errors: true -- name: "Cloudflare DNS: ensure {{ www_fqdn }} is proxied (CNAME)" +- name: "๐ŸŒ Cloudflare DNS: ensure {{ www_fqdn }} is proxied (CNAME)" community.general.cloudflare_dns: api_token: "{{ lookup('api', 'cloudflare.api_token') }}" zone: "{{ cf_zone_name }}" @@ -50,7 +50,7 @@ state: present # 1) Fetch existing redirect rulesets -- name: "Cloudflare Rulesets: list dynamic redirect rulesets" +- name: "๐Ÿ“‹ Cloudflare Rulesets: list dynamic redirect rulesets" uri_retry: url: "https://api.cloudflare.com/client/v4/zones/{{ cf_zone_id }}/rulesets?phase=http_request_dynamic_redirect" method: GET @@ -60,7 +60,7 @@ return_content: true register: cf_rulesets -- name: "Pick existing custom ruleset (if any)" +- name: "๐ŸŽฏ Pick existing custom ruleset (if any)" set_fact: cf_redirect_ruleset: >- {{ @@ -72,7 +72,7 @@ cf_redirect_ruleset_id: "{{ (cf_redirect_ruleset.id | default('')) }}" # Desired redirect rule object -- name: "Build desired redirect rule object" +- name: "๐Ÿ”จ Build desired redirect rule object" set_fact: desired_redirect_rule: ref: "redirect_www_to_apex" @@ -87,7 +87,7 @@ preserve_query_string: true # 2) Update existing ruleset (PUT) -- name: "Update existing dynamic redirect ruleset (PUT)" +- name: "๐Ÿ”„ Update existing dynamic redirect ruleset (PUT)" when: cf_redirect_ruleset_id | length > 0 vars: existing_rules: "{{ cf_redirect_ruleset.rules | default([]) }}" @@ -115,7 +115,7 @@ changed_when: cf_ruleset_update.status in [200] # 3) Create new ruleset (POST) -- name: "Create dynamic redirect ruleset (POST)" +- name: "๐Ÿ“ Create dynamic redirect ruleset (POST)" when: cf_redirect_ruleset_id | length == 0 uri_retry: url: "https://api.cloudflare.com/client/v4/zones/{{ cf_zone_id }}/rulesets" diff --git a/roles/web-opt-rdr-www/tasks/main.yml b/roles/web-opt-rdr-www/tasks/main.yml index b82ac984cb..20a4d6100e 100644 --- a/roles/web-opt-rdr-www/tasks/main.yml +++ b/roles/web-opt-rdr-www/tasks/main.yml @@ -1,12 +1,12 @@ --- -- name: Include web-opt-rdr-domains role for www-to-bare redirects +- name: ๐Ÿ“‚ Include web-opt-rdr-domains role for www-to-bare redirects include_tasks: "utils/load_app.yml" vars: load_app_id: web-opt-rdr-domains redirect_domain_mappings: "{{ REDIRECT_WWW_DOMAINS }}" when: REDIRECT_WWW_FLAVOR == 'origin' -- name: Include Cloudflare edge redirect +- name: ๐Ÿ“‚ Include Cloudflare edge redirect include_tasks: _01_cloudflare_edge_redirect.yml when: - DNS_PROVIDER == 'cloudflare' diff --git a/roles/web-svc-asset/tasks/01_core.yml b/roles/web-svc-asset/tasks/01_core.yml index 82e07f2496..74ba458194 100644 --- a/roles/web-svc-asset/tasks/01_core.yml +++ b/roles/web-svc-asset/tasks/01_core.yml @@ -1,12 +1,12 @@ --- - include_tasks: utils/once/flag.yml -- name: "Recursively copy files from local '{{ source_directory }}' to '{{ target_directory }}'" +- name: "๐Ÿ“‹ copy files from local '{{ source_directory }}' to '{{ target_directory }}'" ansible.builtin.copy: src: "{{ source_directory }}" dest: "{{ target_directory }}" -- name: "Redirect {{ lookup('domain', 'web-svc-asset') }} to web-svc-file" +- name: "๐Ÿ” Redirect {{ lookup('domain', 'web-svc-asset') }} to web-svc-file" include_role: name: web-opt-rdr-domains vars: diff --git a/roles/web-svc-cdn/tasks/01_core.yml b/roles/web-svc-cdn/tasks/01_core.yml index 94074847a3..1922cccc22 100644 --- a/roles/web-svc-cdn/tasks/01_core.yml +++ b/roles/web-svc-cdn/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: Include dependencies +- name: ๐Ÿ“‚ Include dependencies include_role: name: "{{ item }}" loop: diff --git a/roles/web-svc-cdn/tasks/main.yml b/roles/web-svc-cdn/tasks/main.yml index 0bbfa7ac87..12711b873b 100644 --- a/roles/web-svc-cdn/tasks/main.yml +++ b/roles/web-svc-cdn/tasks/main.yml @@ -5,7 +5,7 @@ application_id: "web-svc-cdn" webserver_vhost_flavour: "basic" -- name: "Reset compose Handler for CDN" +- name: "โ™ป๏ธ Reset compose Handler for CDN" include_tasks: utils/load_handlers.yml vars: handler_role_name: "sys-svc-compose" diff --git a/roles/web-svc-collabora/tasks/01_core.yml b/roles/web-svc-collabora/tasks/01_core.yml index 010d7c25b1..5ce05d989e 100644 --- a/roles/web-svc-collabora/tasks/01_core.yml +++ b/roles/web-svc-collabora/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: "load docker, proxy for '{{ application_id }}'" +- name: "๐Ÿงฉ load docker, proxy for '{{ application_id }}'" include_role: name: sys-stk-full public: true @@ -11,17 +11,17 @@ webserver_vhost_flavour: "basic" application_id: "web-svc-collabora" -- name: "Collabora stack-host-only coolconfig setup" +- name: "๐Ÿ–ฅ๏ธ Collabora stack-host-only coolconfig setup" when: IS_STACK_HOST | bool block: - - name: "Collabora resolve | Wait for collabora task to converge" + - name: "โณ Collabora resolve | Wait for collabora task to converge" ansible.builtin.include_tasks: "{{ [playbook_dir, 'roles/sys-svc-compose/tasks/utils/swarm/wait_converged.yml'] | path_join }}" vars: wait_service_key: "{{ entity_name }}" wait_retries: 600 wait_delay: 2 - - name: Update Collabora systemplate to include new fonts + - name: ๐Ÿ”„ Update Collabora systemplate to include new fonts shell: "{{ COLLABORA_DOCKER_CONF_EXEC }} update-system-template" register: collabora_fonts changed_when: > @@ -31,7 +31,7 @@ async: "{{ ASYNC_TIME if (ASYNC_ENABLED | bool) else omit }}" poll: "{{ ASYNC_POLL if (ASYNC_ENABLED | bool) else omit }}" - - name: Allow Nextcloud host IP for Collabora preview conversion + - name: ๐Ÿ–ฅ๏ธ Allow Nextcloud host IP for Collabora preview conversion shell: "{{ COLLABORA_DOCKER_CONF_EXEC }} set net.post_allow.host {{ networks.internet.ip4 }}" register: collabora_preview changed_when: > diff --git a/roles/web-svc-collabora/tasks/main.yml b/roles/web-svc-collabora/tasks/main.yml index 439bc207f1..d3e5277dc7 100644 --- a/roles/web-svc-collabora/tasks/main.yml +++ b/roles/web-svc-collabora/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "Load core functions for '{{ application_id }}'" +- name: "๐Ÿ“‚ Load core functions for '{{ application_id }}'" include_tasks: 01_core.yml when: run_once_web_svc_collabora is not defined vars: diff --git a/roles/web-svc-coturn/tasks/01_core.yml b/roles/web-svc-coturn/tasks/01_core.yml index b5b5f67ae8..4963bdcc67 100644 --- a/roles/web-svc-coturn/tasks/01_core.yml +++ b/roles/web-svc-coturn/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: "Load 'sys-stk-full' for '{{ application_id }}'" +- name: "๐Ÿงฉ Load 'sys-stk-full' for '{{ application_id }}'" include_role: name: sys-stk-full vars: diff --git a/roles/web-svc-css/tasks/01_core.yml b/roles/web-svc-css/tasks/01_core.yml index b2fa4e973e..0afd81d4c1 100644 --- a/roles/web-svc-css/tasks/01_core.yml +++ b/roles/web-svc-css/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: "Redirect {{ lookup('domain', 'web-svc-css') }} to web-svc-cdn" +- name: "๐Ÿ” Redirect {{ lookup('domain', 'web-svc-css') }} to web-svc-cdn" include_role: name: web-opt-rdr-domains vars: diff --git a/roles/web-svc-file/tasks/01_core.yml b/roles/web-svc-file/tasks/01_core.yml index 94074847a3..1922cccc22 100644 --- a/roles/web-svc-file/tasks/01_core.yml +++ b/roles/web-svc-file/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: Include dependencies +- name: ๐Ÿ“‚ Include dependencies include_role: name: "{{ item }}" loop: diff --git a/roles/web-svc-html/tasks/01_core.yml b/roles/web-svc-html/tasks/01_core.yml index 0528838b02..f4e8052876 100644 --- a/roles/web-svc-html/tasks/01_core.yml +++ b/roles/web-svc-html/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: "load front-proxy + dev-git for {{ application_id }}" +- name: "๐Ÿงฉ load front-proxy + dev-git for {{ application_id }}" include_role: name: "{{ item }}" loop: diff --git a/roles/web-svc-legal/tasks/01_core.yml b/roles/web-svc-legal/tasks/01_core.yml index 55661a12bb..e796422d1d 100644 --- a/roles/web-svc-legal/tasks/01_core.yml +++ b/roles/web-svc-legal/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: Copy imprint.html +- name: ๐Ÿ“‹ Copy imprint.html stack_host_template: src: imprint.html.j2 dest: "{{ [ lookup('nginx', 'directories.data.html'), 'imprint.html' ] | path_join }}" diff --git a/roles/web-svc-libretranslate/tasks/01_core.yml b/roles/web-svc-libretranslate/tasks/01_core.yml index 6ddfd26222..79b8024ec4 100644 --- a/roles/web-svc-libretranslate/tasks/01_core.yml +++ b/roles/web-svc-libretranslate/tasks/01_core.yml @@ -1,6 +1,6 @@ --- - include_tasks: utils/once/flag.yml -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full diff --git a/roles/web-svc-logout/tasks/01_core.yml b/roles/web-svc-logout/tasks/01_core.yml index 389f84b1f9..77b3af2a08 100644 --- a/roles/web-svc-logout/tasks/01_core.yml +++ b/roles/web-svc-logout/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: "Add logout domains to CSP connect-src" +- name: "โž• Add logout domains to CSP connect-src" set_fact: webserver_csp_whitelist_extra_by_app: >- {{ @@ -22,7 +22,7 @@ ) }} -- name: "load docker, proxy for '{{ application_id }}'" +- name: "๐Ÿงฉ load docker, proxy for '{{ application_id }}'" include_role: name: sys-stk-full vars: diff --git a/roles/web-svc-onlyoffice/tasks/01_core.yml b/roles/web-svc-onlyoffice/tasks/01_core.yml index 699799ef9f..6d00a4bca0 100644 --- a/roles/web-svc-onlyoffice/tasks/01_core.yml +++ b/roles/web-svc-onlyoffice/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full vars: diff --git a/roles/web-svc-onlyoffice/tasks/main.yml b/roles/web-svc-onlyoffice/tasks/main.yml index 282caf607e..cfdd7336ee 100644 --- a/roles/web-svc-onlyoffice/tasks/main.yml +++ b/roles/web-svc-onlyoffice/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "Load core functions for '{{ application_id }}'" +- name: "๐Ÿ“‚ Load core functions for '{{ application_id }}'" include_tasks: 01_core.yml when: run_once_web_svc_onlyoffice is not defined vars: diff --git a/roles/web-svc-simpleicons/tasks/01_core.yml b/roles/web-svc-simpleicons/tasks/01_core.yml index 6c0d764e2c..987de57d65 100644 --- a/roles/web-svc-simpleicons/tasks/01_core.yml +++ b/roles/web-svc-simpleicons/tasks/01_core.yml @@ -1,7 +1,7 @@ --- - include_tasks: utils/once/flag.yml -- name: "load docker, proxy for '{{ application_id }}'" +- name: "๐Ÿงฉ load docker, proxy for '{{ application_id }}'" include_role: name: sys-stk-full vars: @@ -10,7 +10,7 @@ aca_headers: '"Origin, X-Requested-With, Content-Type, Accept, Authorization" always' webserver_vhost_flavour: "basic" -- name: "Copy '{{ application_id }}' files" +- name: "๐Ÿ“‹ Copy '{{ application_id }}' files" stack_host_template: src: "{{ item.source }}" dest: "{{ item.target }}" diff --git a/roles/web-svc-simpleicons/tasks/main.yml b/roles/web-svc-simpleicons/tasks/main.yml index 6ecbf973db..4d5b7efb98 100644 --- a/roles/web-svc-simpleicons/tasks/main.yml +++ b/roles/web-svc-simpleicons/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "Load core functions for '{{ application_id }}'" +- name: "๐Ÿ“‚ Load core functions for '{{ application_id }}'" include_tasks: 01_core.yml when: run_once_web_svc_simpleicons is not defined vars: diff --git a/roles/web-svc-xmpp/tasks/main.yml b/roles/web-svc-xmpp/tasks/main.yml index 627387d7a0..d10affc96d 100644 --- a/roles/web-svc-xmpp/tasks/main.yml +++ b/roles/web-svc-xmpp/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: "load docker, db and proxy for {{ application_id }}" +- name: "๐Ÿงฉ load docker, db and proxy for {{ application_id }}" include_role: name: sys-stk-full @@ -7,7 +7,7 @@ # instance directory (sys-svc-compose creates `/opt/compose/xmpp/`). # Rendering before that fails with `Destination directory # /opt/compose/xmpp does not exist`. -- name: "Render ejabberd configuration" +- name: "๐Ÿ“„ Render ejabberd configuration" stack_host_template: src: configuration.yml.j2 dest: "{{ XMPP_CONFIG_FILE }}" diff --git a/tasks/stages/01_constructor.yml b/tasks/stages/01_constructor.yml index 6fbb871a5e..ed95446fa3 100644 --- a/tasks/stages/01_constructor.yml +++ b/tasks/stages/01_constructor.yml @@ -1,28 +1,28 @@ --- -- name: Detect container environment (systemd-detect-virt) +- name: ๐Ÿ” Detect container environment (systemd-detect-virt) ansible.builtin.command: systemd-detect-virt --container register: systemd_detect_virt_container changed_when: false failed_when: false -- name: Normalize DOCKER_IN_CONTAINER from runtime detection +- name: ๐Ÿ“ Normalize DOCKER_IN_CONTAINER from runtime detection ansible.builtin.set_fact: DOCKER_IN_CONTAINER: "{{ (systemd_detect_virt_container.rc | default(1) | int) == 0 }}" -- name: Check DNS resolution for test domain +- name: ๐Ÿ”Ž Check DNS resolution for test domain ansible.builtin.command: "getent hosts {{ DOMAIN_TEST }}" register: dns_check changed_when: false failed_when: dns_check.rc != 0 when: MODE_ASSERT | bool -- name: Merge variables +- name: ๐Ÿ”€ Merge variables block: - - name: Merge networks definitions + - name: ๐Ÿ”€ Merge networks definitions ansible.builtin.set_fact: networks: "{{ defaults_networks | combine(networks | default({}, true), recursive=True) }}" - - name: "Sanity check: all group_names must exist in applications" + - name: "โœ… Sanity check: all group_names must exist in applications" ansible.builtin.assert: that: - group_name in lookup('applications') @@ -33,12 +33,12 @@ loop_var: group_name when: MODE_ASSERT | bool - - name: Merge current play applications + - name: ๐Ÿ”€ Merge current play applications ansible.builtin.set_fact: CURRENT_PLAY_APPLICATIONS: "{{ lookup('applications_current_play') }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" - - name: Merge current play domain definitions + - name: ๐Ÿ”€ Merge current play domain definitions ansible.builtin.set_fact: CURRENT_PLAY_DOMAINS: >- {{ @@ -51,11 +51,11 @@ ) }} - - name: Set CURRENT_PLAY_REDIRECT_DOMAINS + - name: ๐Ÿ”ง Set CURRENT_PLAY_REDIRECT_DOMAINS ansible.builtin.set_fact: CURRENT_PLAY_REDIRECT_DOMAINS: "{{ lookup('current_play_redirect_domains') }}" - - name: Set current play all domains incl. www redirect if enabled + - name: ๐Ÿ”ง Set current play all domains incl. www redirect if enabled ansible.builtin.set_fact: CURRENT_PLAY_DOMAINS_ALL: >- {{ @@ -70,44 +70,44 @@ | generate_all_domains(WWW_REDIRECT_ENABLED | bool) }} - - name: Merge OIDC configuration + - name: ๐Ÿ”€ Merge OIDC configuration ansible.builtin.set_fact: OIDC: "{{ defaults_oidc | combine(OIDC | default({}, true), recursive=True) }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" - - name: Merge design configuration + - name: ๐Ÿ”€ Merge design configuration ansible.builtin.set_fact: design: "{{ defaults_design | combine(design | default({}, true), recursive=True) }}" - - name: Merge service_provider configuration + - name: ๐Ÿ”€ Merge service_provider configuration ansible.builtin.set_fact: service_provider: "{{ defaults_service_provider | combine(service_provider | default({}, true), recursive=True) }}" -- name: "Persist {{ SOFTWARE_NAME }} version" +- name: "๐Ÿ’พ Persist {{ SOFTWARE_NAME }} version" ansible.builtin.include_role: name: sys-version -- name: init root user +- name: ๐ŸŽฌ init root user ansible.builtin.include_role: name: user-root -- name: update device +- name: ๐Ÿ”„ update device ansible.builtin.include_role: name: update -- name: "Ensure correct timezone is '{{ HOST_TIMEZONE }}'" +- name: "โœ… Ensure correct timezone is '{{ HOST_TIMEZONE }}'" community.general.timezone: name: "{{ HOST_TIMEZONE }}" when: not DOCKER_IN_CONTAINER | bool -- name: System Cleanup +- name: ๐Ÿงน System Cleanup ansible.builtin.include_role: name: sys-cleanup when: - MODE_CLEANUP | bool - DOCKER_IN_CONTAINER | bool -- name: "Auto-place single-host shared services on first manager (swarm mode)" +- name: "๐Ÿ–ฅ๏ธ Auto-place single-host shared services on first manager (swarm mode)" ansible.builtin.add_host: name: "{{ (groups['svc-swarm-manager'] | default([]))[0] }}" groups: "{{ role_id }}" @@ -123,7 +123,7 @@ run_once: true changed_when: false -- name: "Auto-place svc-prx-openresty (manager in swarm, first play host in compose) so web apps get a vhost" +- name: "๐Ÿ”ง auto-place svc-prx-openresty (swarm manager, first compose host) for vhosts" ansible.builtin.add_host: name: "{{ (groups['svc-swarm-manager'] | default([]))[0] | default(ansible_play_hosts | first) }}" groups: svc-prx-openresty @@ -142,18 +142,18 @@ run_once: true changed_when: false -- name: "Bootstrap svc-swarm-node" +- name: "๐Ÿฅพ Bootstrap svc-swarm-node" ansible.builtin.include_role: name: svc-swarm-node when: "'svc-swarm-node' | application_allowed(group_names, lookup('deployment').whitelist)" -- name: "Open service-loader preload context BEFORE Bootstrap" +- name: "๐Ÿ“‚ Open service-loader preload context BEFORE Bootstrap" ansible.builtin.set_fact: service_loader_post_run: [] service_loader_preloading: true changed_when: false -- name: "Bootstrap NFS clients + registry (MUST precede Preload)" +- name: "๐Ÿฅพ Bootstrap NFS clients + registry (MUST precede Preload)" ansible.builtin.include_tasks: "./tasks/groups/{{ role_group }}-roles.yml" loop: - svc-storage @@ -162,16 +162,16 @@ loop_var: role_group label: "{{ role_group }}-roles.yml" -- name: Include Token Store +- name: ๐Ÿ“‚ Include Token Store ansible.builtin.include_role: name: sys-token-store when: run_once_sys_token_store is not defined -- name: Preload shared services +- name: ๐Ÿ› ๏ธ Preload shared services ansible.builtin.include_role: name: sys-service-loader -- name: "Load base roles" +- name: "๐Ÿงฉ Load base roles" ansible.builtin.include_tasks: "./tasks/groups/{{ role_group }}-roles.yml" loop: - update # 1. Update system @@ -187,20 +187,20 @@ loop_var: role_group label: "{{ role_group }}-roles.yml" -- name: Install inventory-defined system packages +- name: ๐Ÿ“ฆ Install inventory-defined system packages ansible.builtin.include_role: name: sys-package when: - SYS_PACKAGES | default([]) | length > 0 -- name: Ensure AUR helper for inventory-defined AUR packages +- name: โœ… Ensure AUR helper for inventory-defined AUR packages ansible.builtin.include_role: name: sys-aur when: - SYS_AUR_PACKAGES | default([]) | length > 0 - run_once_sys_aur is not defined -- name: Install inventory-defined AUR packages +- name: ๐Ÿ“ฆ Install inventory-defined AUR packages ansible.builtin.include_role: name: sys-aur-install vars: diff --git a/tasks/stages/02_server.yml b/tasks/stages/02_server.yml index da42b5e8bc..cacd4b167f 100644 --- a/tasks/stages/02_server.yml +++ b/tasks/stages/02_server.yml @@ -1,5 +1,5 @@ --- -- name: Setup server base +- name: ๐Ÿ”ง Setup server base include_role: name: "{{ server_role }}" loop: @@ -14,7 +14,7 @@ loop_control: loop_var: server_role -- name: "Bootstrap swarm cluster + NFS clients (must precede web-app render)" +- name: "๐Ÿฅพ Bootstrap swarm cluster + NFS clients (must precede web-app render)" ansible.builtin.include_role: name: "{{ item }}" loop: @@ -22,7 +22,7 @@ - svc-storage-nfs-client when: "'svc-swarm-node' in group_names" -- name: "Include server roles" +- name: "๐Ÿ“‚ Include server roles" include_tasks: "./tasks/groups/{{ server_group }}-roles.yml" loop: - web-svc # 1. Load web server services @@ -32,7 +32,7 @@ loop_var: server_group label: "{{ server_group }}-roles.yml" -- name: Run E2E Playwright tests +- name: โ–ถ๏ธ Run E2E Playwright tests include_role: name: "test-e2e-playwright" # E2E fires in every controlled runtime: local dev (`make compose-deploy` diff --git a/tasks/stages/02_universal.yml b/tasks/stages/02_universal.yml index d5b040c8be..bf0b0ac6a9 100644 --- a/tasks/stages/02_universal.yml +++ b/tasks/stages/02_universal.yml @@ -1,5 +1,5 @@ --- -- name: Universal roles lifecycle notice +- name: ๐Ÿ”„ Universal roles lifecycle notice ansible.builtin.debug: msg: "Universal roles are covered by constructor and destructor." when: MODE_DEBUG | bool diff --git a/tasks/stages/02_workstation.yml b/tasks/stages/02_workstation.yml index c879b11900..b38fe7bb53 100644 --- a/tasks/stages/02_workstation.yml +++ b/tasks/stages/02_workstation.yml @@ -1,11 +1,11 @@ --- -- name: setup workstation user +- name: ๐Ÿ”ง setup workstation user include_role: name: "user-workstation" -- name: "setup docker role includes for workstations" +- name: "๐Ÿ”ง setup docker role includes for workstations" include_tasks: "./tasks/groups/desk-roles.yml" -- name: general host setup +- name: ๐Ÿ–ฅ๏ธ general host setup include_role: name: drv-non-free diff --git a/tasks/stages/03_destructor.yml b/tasks/stages/03_destructor.yml index c9c2cd22cc..5c86573365 100644 --- a/tasks/stages/03_destructor.yml +++ b/tasks/stages/03_destructor.yml @@ -1,5 +1,5 @@ --- -- name: "Load destruction roles" +- name: "๐Ÿงฉ Load destruction roles" include_tasks: "./tasks/groups/{{ destruction_group }}-roles.yml" loop: - svc-opt # Load optimation services @@ -7,6 +7,6 @@ loop_var: destruction_group label: "{{ destruction_group }}-roles.yml" -- name: "Finalize services" +- name: "๐Ÿ› ๏ธ Finalize services" include_role: name: sys-service-terminator diff --git a/tasks/utils/load_app.yml b/tasks/utils/load_app.yml index 3b62859409..abf1e21cb4 100644 --- a/tasks/utils/load_app.yml +++ b/tasks/utils/load_app.yml @@ -1,12 +1,12 @@ --- -- name: "DEBUG | Loading parameters" +- name: "๐Ÿ› DEBUG | Loading parameters" ansible.builtin.debug: msg: application_id: "{{ application_id | default('undefined') }}" load_app_id: "{{ load_app_id }}" when: MODE_DEBUG | bool -- name: "Loading {{ load_app_id }}'" +- name: "๐Ÿ“ฅ Loading {{ load_app_id }}'" include_role: name: "{{ load_app_id }}" public: false diff --git a/tasks/utils/load_handlers.yml b/tasks/utils/load_handlers.yml index 5a64afb029..de1642b32d 100644 --- a/tasks/utils/load_handlers.yml +++ b/tasks/utils/load_handlers.yml @@ -1,5 +1,5 @@ --- -- name: "Load pure handlers from '{{ handler_role_name }}' without 'when' to guaranty that they are executed" +- name: "๐Ÿ“‚ load pure handlers from '{{ handler_role_name }}' (no 'when') to force run" import_role: name: "{{ handler_role_name }}" tasks_from: "none.yml" diff --git a/tasks/utils/once/flag.yml b/tasks/utils/once/flag.yml index 0bbf5102bd..541ca849f2 100644 --- a/tasks/utils/once/flag.yml +++ b/tasks/utils/once/flag.yml @@ -1,4 +1,4 @@ --- -- name: Set โ€œrun-onceโ€ fact for role {{ role_name }} +- name: ๐Ÿ”ง Set โ€œrun-onceโ€ fact for role {{ role_name }} set_fact: "{{ 'run_once_' + (role_name | lower | replace('-', '_')) }}": true diff --git a/tests/lint/repository/test_name_emoji_and_length.py b/tests/lint/repository/test_name_emoji_and_length.py new file mode 100644 index 0000000000..e4aa8d98d4 --- /dev/null +++ b/tests/lint/repository/test_name_emoji_and_length.py @@ -0,0 +1,134 @@ +"""Lint: every task / job / step / workflow name starts with an emoji (a +non-alphanumeric character) and is at most 80 characters long. + +Scope +===== +* Ansible **task** names: every `name:` in a task list inside `roles/*/tasks/**` + or top-level `tasks/**` YAML (recursing block / rescue / always / handlers / + pre_tasks / post_tasks). Module-argument `name:` keys are NOT walked. +* GitHub Actions: the workflow `name`, every job `name` (the "runner"), and + every step `name` in `.github/workflows/*.yml`. + +Why +=== +* Names must begin with an emoji (NOT `0-9` / `a-z` / `A-Z`) so a human scanning + `ansible-playbook` output or a CI step list spots each line instantly. +* Names must stay <= 80 chars so they fit one terminal / CI log line without + wrapping. +""" + +from __future__ import annotations + +import string +import unittest +from pathlib import Path + +from ruamel.yaml import YAML + +from utils.cache.files import iter_project_files + +from . import PROJECT_ROOT + +_MAX_LEN = 80 +_ALNUM = frozenset(string.ascii_letters + string.digits) +_TASK_LIST_KEYS = ( + "block", + "rescue", + "always", + "tasks", + "pre_tasks", + "post_tasks", + "handlers", +) + +_yaml = YAML(typ="safe") +_yaml.allow_duplicate_keys = True + + +def _load(path: str): + try: + with Path(path).open(encoding="utf-8") as handle: + return _yaml.load(handle) + except Exception: + # Files whose Jinja/tags defeat a safe parse are policed by the yaml + # lint elsewhere; skip them here rather than fail on unrelated noise. + return None + + +def _iter_task_names(node): + """Yield task/play/block names, descending ONLY task-list keys so a + module-argument `name:` (e.g. `apt: {name: nginx}`) is never collected.""" + if isinstance(node, list): + for item in node: + yield from _iter_task_names(item) + elif isinstance(node, dict): + if isinstance(node.get("name"), str): + yield node["name"] + for key in _TASK_LIST_KEYS: + if key in node: + yield from _iter_task_names(node[key]) + + +def _iter_gha_names(data): + if not isinstance(data, dict): + return + if isinstance(data.get("name"), str): + yield data["name"] + jobs = data.get("jobs") + if isinstance(jobs, dict): + for job in jobs.values(): + if not isinstance(job, dict): + continue + if isinstance(job.get("name"), str): + yield job["name"] + steps = job.get("steps") + if isinstance(steps, list): + for step in steps: + if isinstance(step, dict) and isinstance(step.get("name"), str): + yield step["name"] + + +def _issues(name: str) -> list[str]: + found: list[str] = [] + if len(name) > _MAX_LEN: + found.append(f"{len(name)}>{_MAX_LEN} chars") + if not name or name[0] in _ALNUM: + found.append("no emoji prefix") + return found + + +def _in_scope(rel: str): + if rel.startswith(".github/workflows/"): + return _iter_gha_names + if rel.startswith("tasks/") or (rel.startswith("roles/") and "/tasks/" in rel): + return _iter_task_names + return None + + +class TestNameEmojiAndLength(unittest.TestCase): + def test_names_start_with_emoji_and_fit_one_line(self) -> None: + offenders: list[str] = [] + for path_str in iter_project_files(extensions=(".yml", ".yaml")): + rel = Path(path_str).relative_to(PROJECT_ROOT).as_posix() + extractor = _in_scope(rel) + if extractor is None: + continue + for name in extractor(_load(path_str)): + issues = _issues(name) + if issues: + offenders.append(f"{rel}: [{', '.join(issues)}] {name[:60]!r}") + + if offenders: + shown = sorted(offenders) + more = f"\n... and {len(shown) - 60} more" if len(shown) > 60 else "" + self.fail( + f"{len(offenders)} task / step / job / workflow name(s) break the " + "convention. Each name MUST start with an emoji (not 0-9/a-z/A-Z) " + "and be <= 80 chars. Fix: shorten the wording and pick a fitting " + "emoji prefix (e.g. '๐Ÿ”ง Configure ...', '๐Ÿงน Clean ...', " + "'โœ… Assert ...'):\n" + "\n".join(shown[:60]) + more + ) + + +if __name__ == "__main__": + unittest.main()