03_install_modules.ymlΒΆ

---
- name: "πŸ”¨ Build list of modules to install"
  set_fact:
    odoo_modules_to_install: "{{ (ODOO_MODULES_CORE + ODOO_MODULES_OPTIONAL) | join(',') }}"

- name: "⏸️ Pause Odoo crons for the module install/update window"
  database_query:
    mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
    config: "{{ lookup('database', application_id) }}"
    query_file: "{{ role_path }}/files/sql/update/ir-cron/pause.sql"
  changed_when: true

- name: "πŸ“¦ Run module install/update with crons paused"
  block:
    - name: "πŸ“¦ Load module operations"
      include_tasks: 03_install_modules/module_ops.yml
  always:
    - name: "▢️ Resume Odoo crons after the module window"
      database_query:
        mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
        config: "{{ lookup('database', application_id) }}"
        query_file: "{{ role_path }}/files/sql/update/ir-cron/resume.sql"
      changed_when: true

- name: "πŸͺ£ Configure the object store as attachment storage before the `-u all` boot"
  include_tasks: 07_objstore.yml
  when: ODOO_OBJSTORE_ENABLED | bool

- name: "πŸ“ Flag Odoo for an offline `-u all` on the next boot"
  ansible.builtin.shell: > # nocheck: container-exec-resolver  runtime-resolved CID, delegated to the hosting node
    container exec {{ ODOO_LOCAL_CID | quote }} touch {{ ODOO_UPDATE_MARKER | quote }}
  delegate_to: "{{ ODOO_HOST_NODE }}"
  changed_when: true

- name: "♻️ Restart Odoo so the entrypoint runs `-u all` as the sole DB actor (compose)"
  ansible.builtin.command: container restart {{ ODOO_CONTAINER }}
  changed_when: true
  when: IS_COMPOSE_MODE

- name: "♻️ Restart Odoo so the entrypoint runs `-u all` as the sole DB actor (swarm)"
  ansible.builtin.include_tasks: 03_install_modules/swarm_drain_restart.yml
  when: IS_SWARM_MODE

- name: "πŸ” Re-resolve Odoo hosting node + container id after the update restart"
  ansible.builtin.include_tasks: "{{ lookup('path_absolute', 'roles/sys-svc-compose/tasks/utils/swarm/resolve_host_cid.yml') }}"
  vars:
    resolve_service_key: "{{ ODOO_SERVICE }}"
    resolve_output_prefix: ODOO
    resolve_compose_cid: "{{ ODOO_CONTAINER }}"

- name: "⏳ Wait for Odoo to serve /web/health after the `-u all` update restart"
  ansible.builtin.shell: |
    set -eu
    # nocheck: container-exec-resolver  runtime-resolved CID, delegated to the hosting node
    container exec {{ ODOO_LOCAL_CID | quote }} timeout 10 bash -c 'exec 3<>/dev/tcp/localhost/{{ container_port }} && printf "GET /web/health HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n" >&3 && IFS= read -r _status <&3 && case "$_status" in *" 200 "*) exit 0 ;; *) exit 1 ;; esac'
  delegate_to: "{{ ODOO_HOST_NODE }}"
  register: odoo_health_after_update
  changed_when: false
  retries: 60
  delay: 10
  until: odoo_health_after_update.rc == 0