diff --git a/roles/web-app-espocrm/tasks/01_patch_config.yml b/roles/web-app-espocrm/tasks/01_patch_config.yml index ab3004b0..53974ba1 100644 --- a/roles/web-app-espocrm/tasks/01_patch_config.yml +++ b/roles/web-app-espocrm/tasks/01_patch_config.yml @@ -1,25 +1,37 @@ -- name: Update DB host +- name: Update DB host (idempotent) command: > - docker exec --user root {{ ESPOCRM_NAME }} - sed -i "s/'host' => .*/'host' => '{{ database_host }}',/" {{ ESPOCRM_CONFIG_FILE_PRIVATE }} + docker exec --user root {{ ESPOCRM_CONTAINER }} sh -lc + "grep -q \"'host' *=> *'{{ database_host }}',\" {{ ESPOCRM_CONFIG_FILE_PRIVATE }} || + { sed -i \"s/'host'\\s*=>\\s*[^,]*,/'host' => '{{ database_host }}',/\" {{ ESPOCRM_CONFIG_FILE_PRIVATE }} && echo CHANGED; }" + register: db_host_set + changed_when: "'CHANGED' in db_host_set.stdout" notify: docker compose restart -- name: Update DB name +- name: Update DB name (idempotent) command: > - docker exec --user root {{ ESPOCRM_NAME }} - sed -i "s/'dbname' => .*/'dbname' => '{{ database_name }}',/" {{ ESPOCRM_CONFIG_FILE_PRIVATE }} + docker exec --user root {{ ESPOCRM_CONTAINER }} sh -lc + "grep -q \"'dbname' *=> *'{{ database_name }}',\" {{ ESPOCRM_CONFIG_FILE_PRIVATE }} || + { sed -i \"s/'dbname'\\s*=>\\s*[^,]*,/'dbname' => '{{ database_name }}',/\" {{ ESPOCRM_CONFIG_FILE_PRIVATE }} && echo CHANGED; }" + register: db_name_set + changed_when: "'CHANGED' in db_name_set.stdout" notify: docker compose restart -- name: Update DB user +- name: Update DB user (idempotent) command: > - docker exec --user root {{ ESPOCRM_NAME }} - sed -i "s/'user' => .*/'user' => '{{ database_username }}',/" {{ ESPOCRM_CONFIG_FILE_PRIVATE }} + docker exec --user root {{ ESPOCRM_CONTAINER }} sh -lc + "grep -q \"'user' *=> *'{{ database_username }}',\" {{ ESPOCRM_CONFIG_FILE_PRIVATE }} || + { sed -i \"s/'user'\\s*=>\\s*[^,]*,/'user' => '{{ database_username }}',/\" {{ ESPOCRM_CONFIG_FILE_PRIVATE }} && echo CHANGED; }" + register: db_user_set + changed_when: "'CHANGED' in db_user_set.stdout" notify: docker compose restart -- name: Update DB password +- name: Update DB password (idempotent) command: > - docker exec --user root {{ ESPOCRM_NAME }} - sed -i "s/'password' => .*/'password' => '{{ database_password }}',/" {{ ESPOCRM_CONFIG_FILE_PRIVATE }} + docker exec --user root {{ ESPOCRM_CONTAINER }} sh -lc + "grep -q \"'password' *=> *'{{ database_password }}',\" {{ ESPOCRM_CONFIG_FILE_PRIVATE }} || + { sed -i \"s/'password'\\s*=>\\s*[^,]*,/'password' => '{{ database_password }}',/\" {{ ESPOCRM_CONFIG_FILE_PRIVATE }} && echo CHANGED; }" + register: db_pass_set + changed_when: "'CHANGED' in db_pass_set.stdout" notify: docker compose restart no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" @@ -43,26 +55,56 @@ register: siteurl_set changed_when: "'CHANGED' in siteurl_set.stdout" -- name: Disable EspoCRM maintenance mode - ansible.builtin.shell: | - docker exec -u root {{ ESPOCRM_NAME }} \ - sed -i "s/'maintenanceMode' => true/'maintenanceMode' => false/" {{ ESPOCRM_CONFIG_FILE_PUBLIC }} - register: disable_maintenance - changed_when: disable_maintenance.rc == 0 - failed_when: disable_maintenance.rc != 0 +- name: Ensure maintenance off, cron on, cache on (idempotent via ConfigWriter) + block: + - name: Apply config via ConfigWriter as app user + command: > + docker exec --user {{ ESPOCRM_USER }} {{ ESPOCRM_CONTAINER }} + php -r ' + require "/var/www/html/bootstrap.php"; + $app = new \Espo\Core\Application(); + $c = $app->getContainer(); + $cfg = $c->get("config"); + $w = $c->get("injectableFactory")->create("\Espo\Core\Utils\Config\ConfigWriter"); + $pairs = [ + "maintenanceMode" => false, + "cronDisabled" => false, + "useCache" => true + ]; + $changed = false; + foreach ($pairs as $k => $v) { + if ($cfg->get($k) !== $v) { $w->set($k, $v); $changed = true; } + } + if ($changed) { $w->save(); echo "CHANGED"; } + ' + register: cfg_set + changed_when: "'CHANGED' in cfg_set.stdout" -- name: Enable EspoCRM cache - ansible.builtin.shell: | - docker exec -u root {{ ESPOCRM_NAME }} \ - sed -i "s/'useCache' => false/'useCache' => true/" {{ ESPOCRM_CONFIG_FILE_PUBLIC }} - register: enable_cache - changed_when: enable_cache.rc == 0 - failed_when: enable_cache.rc != 0 + rescue: + - name: Apply config via ConfigWriter as root (fallback) + command: > + docker exec --user root {{ ESPOCRM_CONTAINER }} + php -r ' + require "/var/www/html/bootstrap.php"; + $app = new \Espo\Core\Application(); + $c = $app->getContainer(); + $cfg = $c->get("config"); + $w = $c->get("injectableFactory")->create("\Espo\Core\Utils\Config\ConfigWriter"); + $pairs = [ + "maintenanceMode" => false, + "cronDisabled" => false, + "useCache" => true + ]; + $changed = false; + foreach ($pairs as $k => $v) { + if ($cfg->get($k) !== $v) { $w->set($k, $v); $changed = true; } + } + if ($changed) { $w->save(); echo "CHANGED"; } + ' + register: cfg_set + changed_when: "'CHANGED' in cfg_set.stdout" -- name: Enable EspoCRM cron - ansible.builtin.shell: | - docker exec -u root {{ ESPOCRM_NAME }} \ - sed -i "s/'cronDisabled' => true/'cronDisabled' => false/" {{ ESPOCRM_CONFIG_FILE_PUBLIC }} - register: enable_cron - changed_when: enable_cron.rc == 0 - failed_when: enable_cron.rc != 0 +- name: Clear EspoCRM cache (only when config changed and we are updating) + command: > + docker exec --user {{ ESPOCRM_USER }} {{ ESPOCRM_CONTAINER }} php clear_cache.php + when: "'CHANGED' in cfg_set.stdout and MODE_UPDATE | bool" diff --git a/roles/web-app-espocrm/tasks/main.yml b/roles/web-app-espocrm/tasks/main.yml index b4054c01..f228341b 100644 --- a/roles/web-app-espocrm/tasks/main.yml +++ b/roles/web-app-espocrm/tasks/main.yml @@ -6,29 +6,14 @@ docker_compose_flush_handlers: true - name: Check if config.php exists in EspoCRM - command: docker exec --user root {{ ESPOCRM_NAME }} test -f {{ ESPOCRM_CONFIG_FILE_PRIVATE }} + command: docker exec --user root {{ ESPOCRM_CONTAINER }} test -f {{ ESPOCRM_CONFIG_FILE_PRIVATE }} register: config_file_exists changed_when: false failed_when: false -- name: Patch EspoCRM config.php with updated DB credentials +- name: Patch EspoCRM config.php include_tasks: 01_patch_config.yml when: config_file_exists.rc == 0 - name: Flush handlers to make DB available before password reset meta: flush_handlers - -- name: Set OIDC scopes in EspoCRM config (inside web container) - ansible.builtin.shell: | - docker compose exec -T web php -r ' - require "/var/www/html/bootstrap.php"; - $writer = (new \Espo\Core\Application()) - ->getContainer() - ->get("injectableFactory") - ->create("\Espo\Core\Utils\Config\ConfigWriter"); - $writer->set("oidcScopes", ["openid", "profile", "email"]); - $writer->save(); - ' - args: - chdir: "{{ docker_compose.directories.instance }}" - when: ESPOCRM_OIDC_ENABLED | bool \ No newline at end of file diff --git a/roles/web-app-espocrm/templates/docker-compose.yml.j2 b/roles/web-app-espocrm/templates/docker-compose.yml.j2 index dac0b96b..8e8ccbbb 100644 --- a/roles/web-app-espocrm/templates/docker-compose.yml.j2 +++ b/roles/web-app-espocrm/templates/docker-compose.yml.j2 @@ -1,6 +1,6 @@ {% include 'roles/docker-compose/templates/base.yml.j2' %} web: - container_name: {{ ESPOCRM_NAME }} + container_name: {{ ESPOCRM_CONTAINER }} image: "{{ ESPOCRM_IMAGE }}:{{ ESPOCRM_VERSION }}" {% include 'roles/docker-container/templates/base.yml.j2' %} {% include 'roles/docker-container/templates/healthcheck/curl.yml.j2' %} diff --git a/roles/web-app-espocrm/vars/main.yml b/roles/web-app-espocrm/vars/main.yml index f1c7882a..56f72168 100644 --- a/roles/web-app-espocrm/vars/main.yml +++ b/roles/web-app-espocrm/vars/main.yml @@ -13,9 +13,9 @@ vhost_flavour: "ws_generic" # Espocrm ESPOCRM_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.espocrm.version', True) }}" ESPOCRM_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.espocrm.image', True) }}" -ESPOCRM_NAME: "{{ applications | get_app_conf(application_id, 'docker.services.espocrm.name', True) }}" +ESPOCRM_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.espocrm.name', True) }}" ESPOCRM_VOLUME: "{{ applications | get_app_conf(application_id, 'docker.volumes.data', True) }}" ESPOCRM_CONFIG_FILE_PRIVATE: "/var/www/html/data/config-internal.php" -ESPOCRM_CONFIG_FILE_PUBLIC: "/var/www/html/data/config.php" ESPOCRM_URL: "{{ domains | get_url(application_id, WEB_PROTOCOL) }}" -ESPOCRM_OIDC_ENABLED: "{{ applications | get_app_conf(application_id, 'features.central_database', False) }}" +ESPOCRM_OIDC_ENABLED: "{{ applications | get_app_conf(application_id, 'features.oidc', False) }}" +ESPOCRM_USER: "www-data"