Files
computer-playbook/roles/web-app-espocrm/tasks/02_manager_ops.yml
kevinveenbirkenbachandClaude Opus 5 73814a9d42 fix(espocrm): realign the administrator password the installer wrote once
The task above this one is named 'Flush handlers to make DB available before password reset' and was the last line in the file: the reset it flushed for did not exist. The upstream entrypoint sets the password, but inside its install branch next to create-admin-user, so it only ever runs when the app is first installed. The swarm matrix rotates credentials between the sync and the async pass, and the async pass then typed a password EspoCRM had never been told about; in run 33923190220 espocrm#1 re-rendered the login form with the credential still filled in.

The invocation mirrors the entrypoint's own: bin/command is literally 'include __DIR__ . "/../command.php"', so php command.php set-password is the same program, and SetPassword reads through IO::readSecretLine, which is fopen('php://stdin') plus fgets and needs no terminal. Executed against the image: the stty -echo call complains on stderr without a tty and fgets still returns the piped value. The image's working directory is /var/www/html, so the relative path resolves.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 00:07:13 +02:00

84 lines
3.1 KiB
YAML

---
- name: "🚀 Deploy '{{ ESPOCRM_ENTRYPOINT_SCRIPT_HOST_ABS }}'"
copy:
src: "shell/{{ ESPOCRM_ENTRYPOINT_SCRIPT_FILE }}"
dest: "{{ ESPOCRM_ENTRYPOINT_SCRIPT_HOST_ABS }}"
notify:
- compose-up
- compose-build
- name: "🚀 Deploy '{{ ESPOCRM_SCRIPT_SEED_HOST_ABS }}'"
copy:
src: "php/{{ ESPOCRM_SCRIPT_SEED_FILE }}"
dest: "{{ ESPOCRM_SCRIPT_SEED_HOST_ABS }}"
notify:
- compose-up
- compose-build
- name: "🚀 Deploy '{{ ESPOCRM_SCRIPT_SIDECAR_HOST_ABS }}'"
copy:
src: "shell/{{ ESPOCRM_SCRIPT_SIDECAR_FILE }}"
dest: "{{ ESPOCRM_SCRIPT_SIDECAR_HOST_ABS }}"
notify:
- compose-up
- compose-build
- name: "🐳 Docker Compose Up for '{{ application_id }}'"
meta: flush_handlers
- name: "🧭 Resolve EspoCRM host node + local container id"
ansible.builtin.include_tasks: "{{ lookup('path_absolute', 'roles/sys-svc-compose/tasks/utils/swarm/resolve_host_cid.yml') }}"
vars:
resolve_service_key: "{{ entity_name }}"
resolve_output_prefix: ESPOCRM
resolve_compose_cid: "{{ ESPOCRM_CONTAINER }}"
- name: 🔎 Check if config.php exists in EspoCRM
shell: |
# nocheck: container-exec-resolver runtime-resolved CID, delegated to the hosting node
container exec --user root {{ ESPOCRM_LOCAL_CID | quote }} test -f {{ ESPOCRM_CONFIG_FILE_PRIVATE }}
register: config_file_exists
changed_when: false
failed_when: false
delegate_to: "{{ ESPOCRM_HOST_NODE }}"
- name: 🩹 Patch EspoCRM config.php
include_tasks:
file: 01_patch_config.yml
apply:
delegate_to: "{{ ESPOCRM_HOST_NODE }}"
when: config_file_exists.rc == 0
- name: ▶️ Run EspoCRM upgrade
shell: |
# nocheck: container-exec-resolver runtime-resolved CID, delegated to the hosting node
container exec --user {{ ESPOCRM_USER }} {{ ESPOCRM_LOCAL_CID | quote }} \
php command.php upgrade -y
register: espocrm_upgrade
changed_when: "'Upgrading' in espocrm_upgrade.stdout or 'successfully' in espocrm_upgrade.stdout"
failed_when: false
delegate_to: "{{ ESPOCRM_HOST_NODE }}"
- name: ▶️ Run flag setter as root (fallback)
shell: |
# nocheck: container-exec-resolver runtime-resolved CID, delegated to the hosting node
container exec --user root {{ ESPOCRM_LOCAL_CID | quote }} \
php {{ ESPOCRM_SCRIPT_SEED_DOCKER }}
register: flags_result_root
changed_when: "'CHANGED' in flags_result_root.stdout"
delegate_to: "{{ ESPOCRM_HOST_NODE }}"
- name: 🚿 Flush handlers to make DB available before password reset
meta: flush_handlers
- name: 🔑 Realign the administrator password EspoCRM persisted at install
ansible.builtin.shell: |
# nocheck: container-exec-resolver runtime-resolved CID, delegated to the hosting node
container exec -i {{ ESPOCRM_LOCAL_CID | quote }} \
php command.php set-password {{ lookup('config', application_id, 'users.administrator.username') | quote }}
args:
stdin: "{{ lookup('config', application_id, 'secrets.credentials.administrator_password') }}"
register: espocrm_admin_password
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
changed_when: espocrm_admin_password.rc == 0
delegate_to: "{{ ESPOCRM_HOST_NODE }}"