mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
The extension installer returned as soon as an add-on was installed, in whatever version. A new pin in meta/addons/ therefore reached a fresh wiki only, and an existing wiki kept the version it was first deployed with. The installer now skips an add-on only when the installed version equals the pin. Otherwise it calls install(id, version, namespace), which the Extension Manager resolves as an upgrade, and it reports an error when the add-on is not on the pin afterwards. The check that follows the installer compared presence only. It takes the pin as well, so a deploy fails when an add-on is installed in another version. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
105 lines
4.4 KiB
YAML
105 lines
4.4 KiB
YAML
---
|
|
# Installs OIDC / LDAP using a temporary Groovy page that calls the
|
|
# Extension Script Service (services.extension.install).
|
|
# Avoids REST job API and any Namespace class import for portability.
|
|
#
|
|
# Flow:
|
|
# - Bootstrap config renders with both auth backends OFF (already in your role).
|
|
# - This file installs required extensions on the current wiki.
|
|
# - Final config later turns auth ON (already in your role).
|
|
#
|
|
# Notes:
|
|
# - We print machine-readable markers so Ansible can assert deterministically.
|
|
|
|
- name: "🔨 XWIKI | Build Groovy installer code from static file (base64 payload)"
|
|
vars:
|
|
_wanted_b64: "{{ XWIKI_PLUGINS | to_json | b64encode }}"
|
|
set_fact:
|
|
_install_code: >-
|
|
{{ 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)"
|
|
include_tasks: utils/rest_session.yml
|
|
|
|
- name: "⬆️ XWIKI | PUT installer page Main.InstallExtensions"
|
|
uri_retry:
|
|
url: "{{ [XWIKI_REST_XWIKI_PAGES, 'InstallExtensions'] | url_join }}"
|
|
method: PUT
|
|
url_username: "{{ XWIKI_SUPERADMIN_USERNAME }}"
|
|
url_password: "{{ XWIKI_SUPERADMIN_PASSWORD }}"
|
|
force_basic_auth: true
|
|
status_code: [200, 201, 202, 204]
|
|
headers: "{{ xwiki_rest_headers_write }}"
|
|
body: "{{ lookup('template', 'xml/install_extensions_page.xml.j2') }}"
|
|
register: _put_page
|
|
|
|
- block:
|
|
- name: "📂 XWIKI | Load installer-page execution + assertion routines"
|
|
include_tasks: 04_extensions/extensions_execute.yml
|
|
|
|
rescue:
|
|
- name: "🌿 XWiki | Probe extension repos + dump xwiki.properties" # nocheck: rescue-extra-diagnostics extension-repo reachability and xwiki.properties are xwiki-specific and not in any log the generic rescue script captures
|
|
ansible.builtin.script: "{{ lookup('path_absolute', 'roles/web-app-xwiki/files/shell/rescue_extensions.sh') }}"
|
|
environment:
|
|
XWIKI_CONTAINER_ADDRESS: "{{ XWIKI_CONTAINER_ADDRESS }}"
|
|
changed_when: false
|
|
failed_when: false
|
|
- name: "🛑 XWiki | fail after extension diagnostics"
|
|
ansible.builtin.fail:
|
|
msg: "Extension install failed; repo reachability + xwiki.properties were dumped into the diagnostics folder (the workflow-level rescue capture collects the
|
|
full snapshot)"
|
|
|
|
always:
|
|
- name: "🗑️ XWIKI | Delete installer page (best effort)"
|
|
uri_retry:
|
|
url: "{{ [XWIKI_REST_XWIKI_PAGES, 'InstallExtensions'] | url_join }}"
|
|
method: DELETE
|
|
url_username: "{{ XWIKI_SUPERADMIN_USERNAME }}"
|
|
url_password: "{{ XWIKI_SUPERADMIN_PASSWORD }}"
|
|
force_basic_auth: true
|
|
status_code: [204, 200, 202, 404]
|
|
headers: "{{ xwiki_rest_headers_write | default({}) }}"
|
|
register: _delete_page_best_effort
|
|
changed_when: _delete_page_best_effort.status != 404
|
|
failed_when: false
|
|
|
|
- name: "✅ XWIKI | Verify requested extensions via Groovy checker"
|
|
include_tasks: _check_extension_via_groovy.yml
|
|
loop: "{{ XWIKI_PLUGINS }}"
|
|
loop_control:
|
|
loop_var: plugin
|
|
label: "{{ plugin.id }}"
|
|
vars:
|
|
ext_id: "{{ plugin.id }}"
|
|
ext_version: "{{ plugin.version }}"
|
|
result_var: "probe_{{ plugin.id | regex_replace('[^A-Za-z0-9_]', '_') }}"
|
|
|
|
- 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 ) } ] }}"
|
|
loop: "{{ XWIKI_PLUGINS }}"
|
|
loop_control:
|
|
loop_var: plugin
|
|
changed_when: false
|
|
|
|
- name: "✅ XWIKI | Assert all requested extensions are on their pinned version"
|
|
vars:
|
|
missing: "{{ (_xwiki_probe_results | default([])) | selectattr('status','equalto',404) | map(attribute='id') | list }}"
|
|
fail:
|
|
msg: "Extensions missing or not on their pinned version: {{ missing | join(', ') }}"
|
|
when: missing | length > 0
|
|
|
|
- name: "🗑️ XWIKI | Delete installer page"
|
|
uri_retry:
|
|
url: "{{ [XWIKI_REST_XWIKI_PAGES, 'InstallExtensions'] | url_join }}"
|
|
method: DELETE
|
|
url_username: "{{ XWIKI_SUPERADMIN_USERNAME }}"
|
|
url_password: "{{ XWIKI_SUPERADMIN_PASSWORD }}"
|
|
force_basic_auth: true
|
|
status_code: [204, 200, 202, 404]
|
|
headers: "{{ xwiki_rest_headers_write }}"
|
|
register: _delete_page
|
|
changed_when: _delete_page.status != 404
|