Files
computer-playbook/roles/sys-token-store/tasks/write.yml
kevinveenbirkenbachandClaude Opus 5.5 67f6c8d7e8 fix(cache): keep the applications carrier valid across token store writes
Since 778c18fb23 the carrier key holds the tokens file's mtime and size.
sys-token-store changed that stat on every inclusion (00_core.yml
touched the file) and on every persisted token, and nothing re-parked a
carrier afterwards. Every later task's fresh worker then rendered the
applications SPOT cold, 30 to 80 s each. On main fea6f31d9f (run
38812964308) seven heavy jobs logged 194 to 287 such tasks and ran out
of the 20400 s budget; the same jobs before 778c18fb23 logged 65 to 83,
all of them real waits.

- 00_core.yml touches the store with modification_time and access_time
  preserved, so it only creates a missing file. In swarm the controller
  sees the store over NFS with attribute caching, and the touch alone
  made the second pass go cold without any write.
- write.yml re-parks the carrier when the persist or the controller
  mirror changed the store. Both run once, so every host that ran the
  include gets the same verdict.
- tasks/utils/setup/role.yml re-parks after every role on every host,
  so hosts that did not run the writing role recover too. Where the
  key still matches this serves the carried payload; measured 0.1 s per
  role in a local compose deploy.
- The tokens file enters the key as the SHA-256 of its content,
  memoised per inode, mtime and size, so a touch no longer changes the
  key. A stat that still matches serves the memo (1.67 us against
  1.41 us for the old stat signature), and a stale stat keeps key and
  YAML cache on the same old content instead of pairing new content
  with an old key.
- applications_carrier opens the tokens file before it computes the
  key, so on the NFS-mounted controller the parked key reflects the
  revalidated attributes rather than a cached stat that changes a
  minute later.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 11:11:47 +02:00

72 lines
2.5 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
# REQUIRED:
# sys_token_store_user_key
# sys_token_store_app
# sys_token_store_token # must be non-empty
- name: "✅ Ensure store exists"
ansible.builtin.import_tasks: 00_core.yml
- 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)"
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"
ansible.builtin.set_fact:
sys_token_store_users_merged: >-
{{
sys_token_store_users
| combine({
sys_token_store_user_key: (
sys_token_store_users.get(sys_token_store_user_key, {})
| combine({
'tokens': (
sys_token_store_users.get(sys_token_store_user_key, {}).get('tokens', {})
| combine({ sys_token_store_app: sys_token_store_token_effective })
)
}, recursive=True
)
)
}, recursive=True
)
}}
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
- name: "💾 Persist store (idempotent, single-writer via STACK_HOST)"
ansible.builtin.copy:
dest: "{{ FILE_TOKENS }}"
owner: "{{ SYS_TOKEN_STORE_OWNER }}"
group: "{{ SYS_TOKEN_STORE_GROUP }}"
mode: "{{ SYS_TOKEN_STORE_FILE_MODE }}"
content: "{{ {'users': sys_token_store_users_merged} | to_nice_yaml(indent=2, width=9999) }}"
when: sys_token_store_users_merged != sys_token_store_users
delegate_to: "{{ STACK_HOST }}"
run_once: true
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
become: true
register: sys_token_store_persisted
- name: "🪞 Mirror the store onto the controller, where every users lookup reads"
ansible.builtin.copy:
dest: "{{ FILE_TOKENS }}"
mode: "{{ SYS_TOKEN_STORE_FILE_MODE }}"
content: "{{ {'users': sys_token_store_users_merged} | to_nice_yaml(indent=2, width=9999) }}"
when:
- sys_token_store_users_merged != sys_token_store_users
- DEPLOYMENT_MODE == 'swarm'
delegate_to: localhost
run_once: true
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
register: sys_token_store_mirrored
- name: 🧊 Re-render the applications SPOT the new token invalidated
applications_carrier: {}
when: sys_token_store_persisted is changed or sys_token_store_mirrored is changed