mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-08-30 07:18:09 +02:00
feat(mediawiki): Refactor OIDC + debug; install Composer deps in-container; modularize role
Discussion: https://chatgpt.com/share/68b10c0a-c308-800f-93ac-2ffb386cf58b - Split tasks into 01_install, 02_debug, 03_admin, 04_extensions, 05_oidc. - Ensure unzip+git+composer on demand in the container; run Composer as www-data with COMPOSER_HOME=/tmp/composer. - Idempotently unpack/install PluggableAuth & OpenIDConnect; run composer install only if vendor/ is missing. - Add sanity check for Jumbojett\OpenIDConnectClient. - Copy oidc.php only when changed and append a single require_once to LocalSettings.php. - Use REL1_44-compatible numeric array for $wgPluggableAuth_Config; set $wgPluggableAuth_ButtonLabelMessage. - Debug: add debug.php that logs to STDERR (visible via docker logs); toggle cleanly with MODE_DEBUG. - Enable OIDC feature in config; add paths/OIDC/extension vars in vars/main.yml. fix(services): include SYS_SERVICE_GROUP_CLEANUP in StartPre lock (ssd-hdd, docker-hard). fix(desktop/joomla): simplify MODE_DEBUG templating. chore: minor cleanups and renames.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
- include_role:
|
- include_role:
|
||||||
name: sys-service
|
name: sys-service
|
||||||
vars:
|
vars:
|
||||||
system_service_tpl_exec_start_pre: '/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(" ") }} --ignore {{ SYS_SERVICE_OPTIMIZE_DRIVE }} {{ SYS_SERVICE_BACKUP_RMT_2_LOC }} --timeout "{{ SYS_TIMEOUT_STORAGE_OPTIMIZER }}"'
|
system_service_tpl_exec_start_pre: '/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(" ") }} --ignore {{ SYS_SERVICE_OPTIMIZE_DRIVE }} {{ SYS_SERVICE_BACKUP_RMT_2_LOC }} {{ SYS_SERVICE_GROUP_CLEANUP | join(" ") }} --timeout "{{ SYS_TIMEOUT_STORAGE_OPTIMIZER }}"'
|
||||||
system_service_tpl_exec_start: '{{ system_service_script_exec }} --mass-storage-path {{ OPT_DRIVE_MASS_STORAGE_PATH }} --rapid-storage-path {{ OPT_DRIVE_RAPID_STORAGE_PATH }}'
|
system_service_tpl_exec_start: '{{ system_service_script_exec }} --mass-storage-path {{ OPT_DRIVE_MASS_STORAGE_PATH }} --rapid-storage-path {{ OPT_DRIVE_RAPID_STORAGE_PATH }}'
|
@@ -8,7 +8,7 @@
|
|||||||
vars:
|
vars:
|
||||||
system_service_on_calendar: "{{ SYS_SCHEDULE_REPAIR_DOCKER_HARD }}"
|
system_service_on_calendar: "{{ SYS_SCHEDULE_REPAIR_DOCKER_HARD }}"
|
||||||
system_service_timer_enabled: true
|
system_service_timer_enabled: true
|
||||||
system_service_tpl_exec_start_pre: '/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(" ") }} --ignore {{ SYS_SERVICE_REPAIR_DOCKER_HARD }} --timeout "{{ SYS_TIMEOUT_RESTART_DOCKER }}"'
|
system_service_tpl_exec_start_pre: '/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(" ") }} --ignore {{ SYS_SERVICE_REPAIR_DOCKER_HARD }} {{ SYS_SERVICE_GROUP_CLEANUP | join(" ") }} --timeout "{{ SYS_TIMEOUT_RESTART_DOCKER }}"'
|
||||||
system_service_tpl_exec_start: '{{ system_service_script_exec }} {{ PATH_DOCKER_COMPOSE_INSTANCES }}'
|
system_service_tpl_exec_start: '{{ system_service_script_exec }} {{ PATH_DOCKER_COMPOSE_INSTANCES }}'
|
||||||
system_service_tpl_exec_start_post: "/usr/bin/systemctl start {{ SYS_SERVICE_CLEANUP_ANONYMOUS_VOLUMES }}"
|
system_service_tpl_exec_start_post: "/usr/bin/systemctl start {{ SYS_SERVICE_CLEANUP_ANONYMOUS_VOLUMES }}"
|
||||||
system_service_tpl_on_failure: "{{ SYS_SERVICE_ON_FAILURE_COMPOSE }}"
|
system_service_tpl_on_failure: "{{ SYS_SERVICE_ON_FAILURE_COMPOSE }}"
|
||||||
|
@@ -12,4 +12,3 @@
|
|||||||
system_service_tpl_exec_start_pre: "/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(' ') }} --ignore {{ SYS_SERVICE_GROUP_CLEANUP| join(' ') }} {{ SYS_SERVICE_REPAIR_DOCKER_SOFT }} --timeout '{{ SYS_TIMEOUT_HEAL_DOCKER }}'"
|
system_service_tpl_exec_start_pre: "/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(' ') }} --ignore {{ SYS_SERVICE_GROUP_CLEANUP| join(' ') }} {{ SYS_SERVICE_REPAIR_DOCKER_SOFT }} --timeout '{{ SYS_TIMEOUT_HEAL_DOCKER }}'"
|
||||||
system_service_tpl_exec_start: >
|
system_service_tpl_exec_start: >
|
||||||
/bin/sh -c '{{ system_service_script_exec }} --manipulation-string "{{ SYS_SERVICE_GROUP_MANIPULATION | join(" ") }}" {{ PATH_DOCKER_COMPOSE_INSTANCES }}'
|
/bin/sh -c '{{ system_service_script_exec }} --manipulation-string "{{ SYS_SERVICE_GROUP_MANIPULATION | join(" ") }}" {{ PATH_DOCKER_COMPOSE_INSTANCES }}'
|
||||||
|
|
||||||
|
@@ -16,7 +16,7 @@ const KC_CONFIG = {
|
|||||||
silentCheckSsoRedirectUri: window.location.origin + "{{ DESKTOP_LOCATION_SILENT_CHECK }}"
|
silentCheckSsoRedirectUri: window.location.origin + "{{ DESKTOP_LOCATION_SILENT_CHECK }}"
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEBUG = {{ 'true' if MODE_DEBUG | default(false) else 'false' }};
|
const DEBUG = {{ 'true' if MODE_DEBUG else 'false' }};
|
||||||
|
|
||||||
/* ==============================================
|
/* ==============================================
|
||||||
2) Helpers for menu manipulation
|
2) Helpers for menu manipulation
|
||||||
|
@@ -4,9 +4,9 @@
|
|||||||
- docker
|
- docker
|
||||||
- exec
|
- exec
|
||||||
- -e
|
- -e
|
||||||
- "J_MODE_DEBUG={{ MODE_DEBUG | default(false) | bool | ternary('1','0') }}"
|
- "J_MODE_DEBUG={{ MODE_DEBUG | bool | ternary('1','0') }}"
|
||||||
- -e
|
- -e
|
||||||
- "J_ERR_LEVEL={{ MODE_DEBUG | default(false) | bool | ternary('maximum','default') }}"
|
- "J_ERR_LEVEL={{ MODE_DEBUG | bool | ternary('maximum','default') }}"
|
||||||
- "{{ JOOMLA_CONTAINER }}"
|
- "{{ JOOMLA_CONTAINER }}"
|
||||||
- php
|
- php
|
||||||
- -r
|
- -r
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
sitename: "Wiki on {{ PRIMARY_DOMAIN | upper }}"
|
sitename: "Wiki on {{ PRIMARY_DOMAIN | upper }}"
|
||||||
meta_namespace: "Meta"
|
|
||||||
server:
|
server:
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
@@ -21,3 +20,4 @@ features:
|
|||||||
central_database: true
|
central_database: true
|
||||||
css: true
|
css: true
|
||||||
desktop: true
|
desktop: true
|
||||||
|
oidc: true
|
||||||
|
44
roles/web-app-mediawiki/tasks/01_install.yml
Normal file
44
roles/web-app-mediawiki/tasks/01_install.yml
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
- name: "Wait for DB to be reachable"
|
||||||
|
command: >
|
||||||
|
docker exec {{ MEDIAWIKI_CONTAINER }}
|
||||||
|
php /var/www/html/maintenance/sql.php --query "SELECT 1;"
|
||||||
|
register: mw_db_ready
|
||||||
|
retries: 15
|
||||||
|
delay: 2
|
||||||
|
until: mw_db_ready.rc == 0
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: "Install MediaWiki if no schema exists"
|
||||||
|
command: >
|
||||||
|
docker exec -u {{ MEDIAWIKI_USER }} {{ MEDIAWIKI_CONTAINER }}
|
||||||
|
php /var/www/html/maintenance/install.php
|
||||||
|
--dbname="{{ database_name }}"
|
||||||
|
--dbuser="{{ database_username }}"
|
||||||
|
--dbpass="{{ database_password }}"
|
||||||
|
--dbserver="{{ database_host }}:{{ database_port }}"
|
||||||
|
--installdbuser="{{ database_username }}"
|
||||||
|
--installdbpass="{{ database_password }}"
|
||||||
|
--server="{{ MEDIAWIKI_URL }}"
|
||||||
|
--scriptpath=""
|
||||||
|
--lang={{ HOST_LL }}
|
||||||
|
--pass="{{ MEDIAWIKI_ADMINISTRATOR_PASSWORD }}"
|
||||||
|
"{{ MEDIAWIKI_SITENAME }}"
|
||||||
|
"{{ MEDIAWIKI_ADMINISTRATOR_NAME }}"
|
||||||
|
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
||||||
|
register: mw_install
|
||||||
|
changed_when: mw_install.rc == 0
|
||||||
|
failed_when: >
|
||||||
|
mw_install.rc != 0 and
|
||||||
|
('LocalSettings.php file has been detected' not in (((mw_install.stdout | default('')) ~ (mw_install.stderr | default(''))))) and
|
||||||
|
('run update.php instead' not in (((mw_install.stdout | default('')) ~ (mw_install.stderr | default('')))))
|
||||||
|
|
||||||
|
- name: "Initialize / migrate MediaWiki database schema"
|
||||||
|
command: >
|
||||||
|
docker exec
|
||||||
|
-u {{ MEDIAWIKI_USER }}
|
||||||
|
{{ MEDIAWIKI_CONTAINER }}
|
||||||
|
php /var/www/html/maintenance/update.php --quick
|
||||||
|
register: mw_update
|
||||||
|
changed_when: "'...done.' in (mw_update.stdout | default(''))"
|
||||||
|
failed_when: mw_update.rc != 0
|
37
roles/web-app-mediawiki/tasks/02_debug.yml
Normal file
37
roles/web-app-mediawiki/tasks/02_debug.yml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
# Aktiviert Debug, wenn MODE_DEBUG=true; entfernt es sauber, wenn false.
|
||||||
|
|
||||||
|
- name: "DEBUG | Enable block when MODE_DEBUG=true"
|
||||||
|
when: MODE_DEBUG | bool
|
||||||
|
include_tasks: _enable_debug.yml
|
||||||
|
|
||||||
|
- name: "DEBUG | Disable block when MODE_DEBUG=false"
|
||||||
|
when: not (MODE_DEBUG | bool)
|
||||||
|
block:
|
||||||
|
- name: "Remove require_once line from LocalSettings.php (if present)"
|
||||||
|
shell: |
|
||||||
|
docker exec -u {{ MEDIAWIKI_USER }} {{ MEDIAWIKI_CONTAINER }} bash -lc '
|
||||||
|
LSP={{ MEDIAWIKI_HTML_DIR }}/LocalSettings.php
|
||||||
|
if [ -f "$LSP" ]; then
|
||||||
|
if grep -Fqx -- "require_once __DIR__ . '\''/debug.php'\'';" "$LSP"; then
|
||||||
|
sed -i "\#require_once __DIR__ . '/debug.php';#d" "$LSP"
|
||||||
|
echo REMOVED_REQUIRE
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
'
|
||||||
|
args: { executable: /bin/bash }
|
||||||
|
register: _dbg_rm_req
|
||||||
|
changed_when: "'REMOVED_REQUIRE' in (_dbg_rm_req.stdout | default(''))"
|
||||||
|
|
||||||
|
- name: "Remove debug.php from container (if present)"
|
||||||
|
shell: >
|
||||||
|
docker exec {{ MEDIAWIKI_CONTAINER }} bash -lc
|
||||||
|
"if [ -f {{ MEDIAWIKI_HTML_DIR }}/debug.php ]; then rm -f {{ MEDIAWIKI_HTML_DIR }}/debug.php; echo REMOVED_FILE; fi"
|
||||||
|
args: { executable: /bin/bash }
|
||||||
|
register: _dbg_rm_file
|
||||||
|
changed_when: "'REMOVED_FILE' in (_dbg_rm_file.stdout | default(''))"
|
||||||
|
|
||||||
|
- name: "Remove local debug.php (if present)"
|
||||||
|
file:
|
||||||
|
path: "{{ MEDIAWIKI_CONFIG_DIR }}/debug.php"
|
||||||
|
state: absent
|
19
roles/web-app-mediawiki/tasks/03_admin.yml
Normal file
19
roles/web-app-mediawiki/tasks/03_admin.yml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
- name: "Create MediaWiki admin user"
|
||||||
|
command: >
|
||||||
|
docker exec
|
||||||
|
-u {{ MEDIAWIKI_USER }}
|
||||||
|
{{ MEDIAWIKI_CONTAINER }}
|
||||||
|
php /var/www/html/maintenance/createAndPromote.php
|
||||||
|
--bureaucrat --sysop
|
||||||
|
{{ MEDIAWIKI_ADMINISTRATOR_NAME }}
|
||||||
|
{{ MEDIAWIKI_ADMINISTRATOR_PASSWORD }}
|
||||||
|
{{ MEDIAWIKI_ADMINISTRATOR_EMAIL }}
|
||||||
|
register: create_admin
|
||||||
|
changed_when: >
|
||||||
|
('created' in ((create_admin.stdout | default('')) ~ (create_admin.stderr | default('')))) or
|
||||||
|
('Created' in ((create_admin.stdout | default('')) ~ (create_admin.stderr | default(''))))
|
||||||
|
failed_when: >
|
||||||
|
create_admin.rc != 0 and
|
||||||
|
('already exists' not in ((create_admin.stdout | default('')) ~ (create_admin.stderr | default('')))) and
|
||||||
|
('Account exists' not in ((create_admin.stdout | default('')) ~ (create_admin.stderr | default(''))))
|
||||||
|
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
147
roles/web-app-mediawiki/tasks/04_extensions.yml
Normal file
147
roles/web-app-mediawiki/tasks/04_extensions.yml
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
---
|
||||||
|
# Install PluggableAuth + OpenIDConnect INTO the running container (idempotent)
|
||||||
|
# Downloads on host (config dir), copy+extract inside container.
|
||||||
|
|
||||||
|
- name: "EXT | Ensure local download dir exists"
|
||||||
|
file:
|
||||||
|
path: "{{ MEDIAWIKI_EXT_CFG_BASE }}"
|
||||||
|
state: directory
|
||||||
|
mode: "0755"
|
||||||
|
|
||||||
|
- name: "EXT | Download extension tarballs ({{ MEDIAWIKI_EXT_BRANCH }})"
|
||||||
|
get_url:
|
||||||
|
url: "{{ ext.url }}"
|
||||||
|
dest: "{{ MEDIAWIKI_EXT_CFG_BASE }}/{{ ext.name }}.tar.gz"
|
||||||
|
mode: "0644"
|
||||||
|
loop: "{{ MEDIAWIKI_EXT_LIST }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: ext
|
||||||
|
label: "{{ ext.name }}"
|
||||||
|
|
||||||
|
- name: "EXT | Copy & extract into container if not installed"
|
||||||
|
shell: >
|
||||||
|
docker exec {{ MEDIAWIKI_CONTAINER }} bash -lc '
|
||||||
|
set -e
|
||||||
|
dst="{{ MEDIAWIKI_HTML_DIR }}/extensions/{{ ext.name }}"
|
||||||
|
if [ ! -f "$dst/extension.json" ]; then
|
||||||
|
rm -rf "$dst" && mkdir -p "$dst"
|
||||||
|
fi
|
||||||
|
'
|
||||||
|
&& docker cp "{{ MEDIAWIKI_EXT_CFG_BASE }}/{{ ext.name }}.tar.gz" "{{ MEDIAWIKI_CONTAINER }}:/tmp/{{ ext.name }}.tar.gz"
|
||||||
|
&& docker exec {{ MEDIAWIKI_CONTAINER }} bash -lc '
|
||||||
|
set -e
|
||||||
|
dst="{{ MEDIAWIKI_HTML_DIR }}/extensions/{{ ext.name }}"
|
||||||
|
if [ ! -f "$dst/extension.json" ]; then
|
||||||
|
tar -xzf /tmp/{{ ext.name }}.tar.gz -C "$dst" --strip-components=1
|
||||||
|
chown -R {{ MEDIAWIKI_USER }}:{{ MEDIAWIKI_USER }} "$dst"
|
||||||
|
rm -f /tmp/{{ ext.name }}.tar.gz
|
||||||
|
echo INSTALLED:{{ ext.name }}
|
||||||
|
else
|
||||||
|
rm -f /tmp/{{ ext.name }}.tar.gz
|
||||||
|
echo PRESENT:{{ ext.name }}
|
||||||
|
fi
|
||||||
|
'
|
||||||
|
args:
|
||||||
|
executable: /bin/bash
|
||||||
|
loop: "{{ MEDIAWIKI_EXT_LIST }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: ext
|
||||||
|
label: "{{ ext.name }}"
|
||||||
|
register: _install_results
|
||||||
|
changed_when: "'INSTALLED:' in (stdout | default(''))"
|
||||||
|
|
||||||
|
- name: "EXT | Determine if any extension was installed"
|
||||||
|
set_fact:
|
||||||
|
_any_installed: >-
|
||||||
|
{{ _install_results.results
|
||||||
|
| map(attribute='stdout')
|
||||||
|
| select('search', 'INSTALLED:')
|
||||||
|
| list | length > 0 }}
|
||||||
|
|
||||||
|
# Ensure unzip + git are available in the container (idempotent)
|
||||||
|
- name: "EXT | Ensure unzip+git available in container"
|
||||||
|
shell: |
|
||||||
|
docker exec {{ MEDIAWIKI_CONTAINER }} bash -lc '
|
||||||
|
set -e
|
||||||
|
need=0
|
||||||
|
command -v unzip >/dev/null 2>&1 || need=1
|
||||||
|
command -v git >/dev/null 2>&1 || need=1
|
||||||
|
if [ "$need" -eq 1 ]; then
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
apt-get update -y
|
||||||
|
apt-get install -y --no-install-recommends unzip git ca-certificates
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
echo INSTALLED_TOOLS
|
||||||
|
fi
|
||||||
|
'
|
||||||
|
args:
|
||||||
|
executable: /bin/bash
|
||||||
|
register: _tools
|
||||||
|
changed_when: "'INSTALLED_TOOLS' in (_tools.stdout | default(''))"
|
||||||
|
|
||||||
|
# Ensure Composer is available inside the container (idempotent)
|
||||||
|
- name: "EXT | Ensure Composer available in container"
|
||||||
|
shell: |
|
||||||
|
docker exec {{ MEDIAWIKI_CONTAINER }} bash -lc '
|
||||||
|
if ! command -v composer >/dev/null 2>&1; then
|
||||||
|
php -r "copy(\"https://getcomposer.org/installer\", \"composer-setup.php\");"
|
||||||
|
php composer-setup.php --install-dir=/usr/local/bin --filename=composer
|
||||||
|
rm -f composer-setup.php
|
||||||
|
echo INSTALLED_COMPOSER
|
||||||
|
fi
|
||||||
|
'
|
||||||
|
args:
|
||||||
|
executable: /bin/bash
|
||||||
|
register: _composer
|
||||||
|
changed_when: "'INSTALLED_COMPOSER' in (_composer.stdout | default(''))"
|
||||||
|
|
||||||
|
# Install dependencies per extension (only if vendor is missing)
|
||||||
|
# Use /tmp/composer for HOME/CACHE to avoid /var/www permission issues.
|
||||||
|
- name: "EXT | composer install in each extension when needed"
|
||||||
|
shell: |
|
||||||
|
docker exec -u {{ MEDIAWIKI_USER }} {{ MEDIAWIKI_CONTAINER }} bash -lc '
|
||||||
|
set -e
|
||||||
|
d="{{ MEDIAWIKI_HTML_DIR }}/extensions/{{ ext.name }}"
|
||||||
|
if [ -f "$d/composer.json" ] && [ ! -f "$d/vendor/autoload.php" ]; then
|
||||||
|
install -d -m 0775 /tmp/composer/cache
|
||||||
|
export COMPOSER_HOME=/tmp/composer
|
||||||
|
export COMPOSER_CACHE_DIR=/tmp/composer/cache
|
||||||
|
cd "$d"
|
||||||
|
composer install --no-dev -n --prefer-dist
|
||||||
|
echo COMPOSER_INSTALLED:{{ ext.name }}
|
||||||
|
fi
|
||||||
|
'
|
||||||
|
args:
|
||||||
|
executable: /bin/bash
|
||||||
|
loop: "{{ MEDIAWIKI_EXT_LIST }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: ext
|
||||||
|
label: "{{ ext.name }}"
|
||||||
|
register: _ext_composer
|
||||||
|
changed_when: "'COMPOSER_INSTALLED:' in (stdout | default(''))"
|
||||||
|
|
||||||
|
# Sanity check: Jumbojett OIDC client must be loadable
|
||||||
|
- name: "EXT | Sanity check: Jumbojett OpenIDConnect client present"
|
||||||
|
shell: >
|
||||||
|
docker exec {{ MEDIAWIKI_CONTAINER }} bash -lc
|
||||||
|
'php -r "(@require \"{{ MEDIAWIKI_HTML_DIR }}/vendor/autoload.php\"); @require \"{{ MEDIAWIKI_HTML_DIR }}/extensions/OpenIDConnect/vendor/autoload.php\"; exit(class_exists(\"Jumbojett\\\\OpenIDConnectClient\")?0:1);"'
|
||||||
|
args:
|
||||||
|
executable: /bin/bash
|
||||||
|
register: _oidc_class
|
||||||
|
changed_when: false
|
||||||
|
failed_when: _oidc_class.rc != 0
|
||||||
|
|
||||||
|
# Run MediaWiki updates (changed if something installed)
|
||||||
|
- name: "EXT | Run update.php (safe to run repeatedly)"
|
||||||
|
shell: >
|
||||||
|
docker exec -u {{ MEDIAWIKI_USER }} {{ MEDIAWIKI_CONTAINER }}
|
||||||
|
php {{ MEDIAWIKI_HTML_DIR }}/maintenance/update.php --quick
|
||||||
|
args:
|
||||||
|
executable: /bin/bash
|
||||||
|
register: _mw_upd
|
||||||
|
changed_when: >
|
||||||
|
(_any_installed) or
|
||||||
|
(_ext_composer is defined and
|
||||||
|
(_ext_composer.results | map(attribute='stdout')
|
||||||
|
| select('search','COMPOSER_INSTALLED:')
|
||||||
|
| list | length > 0))
|
61
roles/web-app-mediawiki/tasks/05_oidc.yml
Normal file
61
roles/web-app-mediawiki/tasks/05_oidc.yml
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
---
|
||||||
|
# All operations remain INSIDE the running container.
|
||||||
|
# Template is rendered into docker_compose.directories.config on the host.
|
||||||
|
# Change detection is based on checksum comparison vs. container file.
|
||||||
|
|
||||||
|
- name: "OIDC | Ensure local config directory exists"
|
||||||
|
file:
|
||||||
|
path: "{{ MEDIAWIKI_CONFIG_DIR }}"
|
||||||
|
state: directory
|
||||||
|
mode: "0755"
|
||||||
|
|
||||||
|
- name: "OIDC | Render oidc.php locally (template into config dir)"
|
||||||
|
template:
|
||||||
|
src: "oidc.php.j2"
|
||||||
|
dest: "{{ MEDIAWIKI_OIDC_FILE }}"
|
||||||
|
mode: "0644"
|
||||||
|
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
||||||
|
|
||||||
|
- name: "OIDC | Compute local checksum"
|
||||||
|
stat:
|
||||||
|
path: "{{ MEDIAWIKI_OIDC_FILE }}"
|
||||||
|
checksum_algorithm: sha256
|
||||||
|
register: _local_oidc
|
||||||
|
|
||||||
|
- name: "OIDC | Compute container checksum (if exists)"
|
||||||
|
shell: >
|
||||||
|
docker exec {{ MEDIAWIKI_CONTAINER }} bash -lc
|
||||||
|
"test -f {{ MEDIAWIKI_HTML_DIR }}/oidc.php &&
|
||||||
|
sha256sum {{ MEDIAWIKI_HTML_DIR }}/oidc.php | awk '{print $1}' || echo MISSING"
|
||||||
|
args:
|
||||||
|
executable: /bin/bash
|
||||||
|
register: _remote_oidc
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: "OIDC | Copy oidc.php into container docroot only if different"
|
||||||
|
shell: >
|
||||||
|
if [ "{{ (_remote_oidc.stdout | default('') | trim) }}" != "{{ _local_oidc.stat.checksum }}" ]; then
|
||||||
|
docker cp "{{ MEDIAWIKI_OIDC_FILE }}" "{{ MEDIAWIKI_CONTAINER }}:{{ MEDIAWIKI_HTML_DIR }}/oidc.php" &&
|
||||||
|
docker exec {{ MEDIAWIKI_CONTAINER }} bash -lc "chown {{ MEDIAWIKI_USER }}:{{ MEDIAWIKI_USER }} {{ MEDIAWIKI_HTML_DIR }}/oidc.php && chmod 0644 {{ MEDIAWIKI_HTML_DIR }}/oidc.php" &&
|
||||||
|
echo COPIED;
|
||||||
|
fi
|
||||||
|
args:
|
||||||
|
executable: /bin/bash
|
||||||
|
register: _cp_oidc
|
||||||
|
changed_when: "'COPIED' in (_cp_oidc.stdout | default(''))"
|
||||||
|
|
||||||
|
- name: "OIDC | Require oidc.php once inside LocalSettings.php"
|
||||||
|
shell: |
|
||||||
|
docker exec -u {{ MEDIAWIKI_USER }} {{ MEDIAWIKI_CONTAINER }} bash -lc '
|
||||||
|
LSP={{ MEDIAWIKI_HTML_DIR }}/LocalSettings.php
|
||||||
|
LINE="require_once __DIR__ . '\''/oidc.php'\'';"
|
||||||
|
if ! grep -Fqx -- "$LINE" "$LSP"; then
|
||||||
|
printf "%s\n" "$LINE" >> "$LSP"
|
||||||
|
echo ADDED_REQUIRE
|
||||||
|
fi
|
||||||
|
'
|
||||||
|
args:
|
||||||
|
executable: /bin/bash
|
||||||
|
register: _mw_oidc_req
|
||||||
|
changed_when: "'ADDED_REQUIRE' in (_mw_oidc_req.stdout | default(''))"
|
||||||
|
|
45
roles/web-app-mediawiki/tasks/_enable_debug.yml
Normal file
45
roles/web-app-mediawiki/tasks/_enable_debug.yml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
- name: "Render debug.php locally"
|
||||||
|
template:
|
||||||
|
src: "debug.php.j2"
|
||||||
|
dest: "{{ MEDIAWIKI_CONFIG_DIR }}/debug.php"
|
||||||
|
mode: "0644"
|
||||||
|
|
||||||
|
- name: "Compute local checksum"
|
||||||
|
stat:
|
||||||
|
path: "{{ MEDIAWIKI_CONFIG_DIR }}/debug.php"
|
||||||
|
checksum_algorithm: sha256
|
||||||
|
register: _dbg_local
|
||||||
|
|
||||||
|
- name: "Compute container checksum (if exists)"
|
||||||
|
shell: >
|
||||||
|
docker exec {{ MEDIAWIKI_CONTAINER }} bash -lc
|
||||||
|
"test -f {{ MEDIAWIKI_HTML_DIR }}/debug.php &&
|
||||||
|
sha256sum {{ MEDIAWIKI_HTML_DIR }}/debug.php | awk '{print $1}' || echo MISSING"
|
||||||
|
args: { executable: /bin/bash }
|
||||||
|
register: _dbg_remote
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: "Copy debug.php into container only if different"
|
||||||
|
shell: >
|
||||||
|
if [ "{{ (_dbg_remote.stdout | default('') | trim) }}" != "{{ _dbg_local.stat.checksum }}" ]; then
|
||||||
|
docker cp "{{ MEDIAWIKI_CONFIG_DIR }}/debug.php" "{{ MEDIAWIKI_CONTAINER }}:{{ MEDIAWIKI_HTML_DIR }}/debug.php" &&
|
||||||
|
docker exec {{ MEDIAWIKI_CONTAINER }} bash -lc "chown {{ MEDIAWIKI_USER }}:{{ MEDIAWIKI_USER }} {{ MEDIAWIKI_HTML_DIR }}/debug.php && chmod 0644 {{ MEDIAWIKI_HTML_DIR }}/debug.php" &&
|
||||||
|
echo COPIED;
|
||||||
|
fi
|
||||||
|
args: { executable: /bin/bash }
|
||||||
|
register: _dbg_cp
|
||||||
|
changed_when: "'COPIED' in (_dbg_cp.stdout | default(''))"
|
||||||
|
|
||||||
|
- name: "require_once debug.php in LocalSettings.php"
|
||||||
|
shell: |
|
||||||
|
docker exec -u {{ MEDIAWIKI_USER }} {{ MEDIAWIKI_CONTAINER }} bash -lc '
|
||||||
|
LSP={{ MEDIAWIKI_HTML_DIR }}/LocalSettings.php
|
||||||
|
LINE="require_once __DIR__ . '\''/debug.php'\'';"
|
||||||
|
if ! grep -Fqx -- "$LINE" "$LSP"; then
|
||||||
|
printf "%s\n" "$LINE" >> "$LSP"
|
||||||
|
echo ADDED_DEBUG_REQUIRE
|
||||||
|
fi
|
||||||
|
'
|
||||||
|
args: { executable: /bin/bash }
|
||||||
|
register: _dbg_req
|
||||||
|
changed_when: "'ADDED_DEBUG_REQUIRE' in (_dbg_req.stdout | default(''))"
|
@@ -1,73 +1,22 @@
|
|||||||
---
|
---
|
||||||
- name: "load docker, db and proxy for {{ application_id }}"
|
- name: "load docker, db and proxy for '{{ application_id }}'"
|
||||||
include_role:
|
include_role:
|
||||||
name: sys-stk-full-stateful
|
name: sys-stk-full-stateful
|
||||||
vars:
|
vars:
|
||||||
docker_compose_flush_handlers: true
|
docker_compose_flush_handlers: true
|
||||||
|
|
||||||
- name: "Wait for DB to be reachable"
|
- name: "Load install procedures for '{{ application_id }}''"
|
||||||
command: >
|
include_tasks: 01_install.yml
|
||||||
docker exec {{ MEDIAWIKI_CONTAINER }}
|
|
||||||
php /var/www/html/maintenance/sql.php --query "SELECT 1;"
|
|
||||||
register: mw_db_ready
|
|
||||||
retries: 15
|
|
||||||
delay: 2
|
|
||||||
until: mw_db_ready.rc == 0
|
|
||||||
changed_when: false
|
|
||||||
failed_when: false
|
|
||||||
|
|
||||||
- name: "Install MediaWiki if no schema exists"
|
- name: "Load debug procedures for '{{ application_id }}''"
|
||||||
command: >
|
include_tasks: 02_debug.yml
|
||||||
docker exec -u {{ MEDIAWIKI_USER }} {{ MEDIAWIKI_CONTAINER }}
|
|
||||||
php /var/www/html/maintenance/install.php
|
|
||||||
--dbname="{{ database_name }}"
|
|
||||||
--dbuser="{{ database_username }}"
|
|
||||||
--dbpass="{{ database_password }}"
|
|
||||||
--dbserver="{{ database_host }}:{{ database_port }}"
|
|
||||||
--installdbuser="{{ database_username }}"
|
|
||||||
--installdbpass="{{ database_password }}"
|
|
||||||
--server="{{ MEDIAWIKI_URL }}"
|
|
||||||
--scriptpath=""
|
|
||||||
--lang={{ HOST_LL }}
|
|
||||||
--pass="{{ MEDIAWIKI_ADMINISTRATOR_PASSWORD }}"
|
|
||||||
"{{ MEDIAWIKI_SITENAME }}"
|
|
||||||
"{{ MEDIAWIKI_ADMINISTRATOR_NAME }}"
|
|
||||||
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
|
||||||
register: mw_install
|
|
||||||
changed_when: mw_install.rc == 0
|
|
||||||
failed_when: >
|
|
||||||
mw_install.rc != 0 and
|
|
||||||
('LocalSettings.php file has been detected' not in (((mw_install.stdout | default('')) ~ (mw_install.stderr | default(''))))) and
|
|
||||||
('run update.php instead' not in (((mw_install.stdout | default('')) ~ (mw_install.stderr | default('')))))
|
|
||||||
|
|
||||||
- name: "Initialize / migrate MediaWiki database schema"
|
- name: "Load admin setup procedures for '{{ application_id }}''"
|
||||||
command: >
|
include_tasks: 03_admin.yml
|
||||||
docker exec
|
|
||||||
-u {{ MEDIAWIKI_USER }}
|
|
||||||
{{ MEDIAWIKI_CONTAINER }}
|
|
||||||
php /var/www/html/maintenance/update.php --quick
|
|
||||||
register: mw_update
|
|
||||||
changed_when: "'...done.' in (mw_update.stdout | default(''))"
|
|
||||||
failed_when: mw_update.rc != 0
|
|
||||||
|
|
||||||
- name: "Create MediaWiki admin user"
|
- name: "Load OIDC procedures for '{{ application_id }}''"
|
||||||
command: >
|
include_tasks: "{{ item }}"
|
||||||
docker exec
|
loop:
|
||||||
-u {{ MEDIAWIKI_USER }}
|
- 04_extensions.yml
|
||||||
{{ MEDIAWIKI_CONTAINER }}
|
- 05_oidc.yml
|
||||||
php /var/www/html/maintenance/createAndPromote.php
|
when: MEDIAWIKI_OIDC_ENABLED | bool
|
||||||
--bureaucrat --sysop
|
|
||||||
{{ MEDIAWIKI_ADMINISTRATOR_NAME }}
|
|
||||||
{{ MEDIAWIKI_ADMINISTRATOR_PASSWORD }}
|
|
||||||
{{ MEDIAWIKI_ADMINISTRATOR_EMAIL }}
|
|
||||||
register: create_admin
|
|
||||||
changed_when: >
|
|
||||||
('created' in ((create_admin.stdout | default('')) ~ (create_admin.stderr | default('')))) or
|
|
||||||
('Created' in ((create_admin.stdout | default('')) ~ (create_admin.stderr | default(''))))
|
|
||||||
failed_when: >
|
|
||||||
create_admin.rc != 0 and
|
|
||||||
('already exists' not in ((create_admin.stdout | default('')) ~ (create_admin.stderr | default('')))) and
|
|
||||||
('Account exists' not in ((create_admin.stdout | default('')) ~ (create_admin.stderr | default(''))))
|
|
||||||
async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}"
|
|
||||||
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"
|
|
||||||
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
|
21
roles/web-app-mediawiki/templates/debug.php.j2
Normal file
21
roles/web-app-mediawiki/templates/debug.php.j2
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$wgShowExceptionDetails = true;
|
||||||
|
$wgShowDBErrorBacktrace = true;
|
||||||
|
$wgShowSQLErrors = true;
|
||||||
|
$wgDevelopmentWarnings = true;
|
||||||
|
|
||||||
|
@ini_set('display_errors', '1');
|
||||||
|
@ini_set('display_startup_errors', '1');
|
||||||
|
@ini_set('log_errors', '1');
|
||||||
|
@ini_set('error_log', '/proc/self/fd/2');
|
||||||
|
|
||||||
|
$wgDebugLogGroups = array_merge($wgDebugLogGroups ?? [], [
|
||||||
|
'exception' => 'php://stderr',
|
||||||
|
'error' => 'php://stderr',
|
||||||
|
'authentication' => 'php://stderr',
|
||||||
|
'session' => 'php://stderr',
|
||||||
|
'resourceloader' => 'php://stderr',
|
||||||
|
'PluggableAuth' => 'php://stderr',
|
||||||
|
'OpenIDConnect' => 'php://stderr',
|
||||||
|
]);
|
27
roles/web-app-mediawiki/templates/oidc.php.j2
Normal file
27
roles/web-app-mediawiki/templates/oidc.php.j2
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
// ### OIDC (PluggableAuth) – BEGIN (managed by Ansible)
|
||||||
|
wfLoadExtension( 'PluggableAuth' );
|
||||||
|
wfLoadExtension( 'OpenIDConnect' );
|
||||||
|
|
||||||
|
$wgPluggableAuth_EnableAutoLogin = false; // don’t auto-redirect to IdP
|
||||||
|
$wgPluggableAuth_EnableLocalLogin = true; // keep local user/pass login
|
||||||
|
$wgPluggableAuth_ButtonLabelMessage = '{{ MEDIAWIKI_OIDC_BUTTON_TEXT }}';
|
||||||
|
|
||||||
|
// PluggableAuth expects a list of providers (numeric array) on REL1_44
|
||||||
|
$wgPluggableAuth_Config = [
|
||||||
|
[
|
||||||
|
'plugin' => 'OpenIDConnect',
|
||||||
|
'data' => [
|
||||||
|
// For Keycloak, use the REALM URL, e.g. https://auth.example/realms/<realm>
|
||||||
|
'providerURL' => '{{ MEDIAWIKI_OIDC_ISSUER }}',
|
||||||
|
'clientID' => '{{ MEDIAWIKI_OIDC_CLIENT_ID }}',
|
||||||
|
'clientsecret' => '{{ MEDIAWIKI_OIDC_CLIENT_SECRET }}',
|
||||||
|
'scope' => [ 'openid', 'profile', 'email' ],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
// Helpful defaults
|
||||||
|
$wgOpenIDConnect_UseEmailNameAsUserName = true;
|
||||||
|
$wgOpenIDConnect_MigrateUsers = true;
|
||||||
|
// ### OIDC (PluggableAuth) – END
|
@@ -7,6 +7,11 @@ container_port: 80
|
|||||||
MEDIAWIKI_SITENAME: "{{ applications | get_app_conf(application_id, 'sitename') }}"
|
MEDIAWIKI_SITENAME: "{{ applications | get_app_conf(application_id, 'sitename') }}"
|
||||||
MEDIAWIKI_URL: "{{ domains | get_url(application_id, WEB_PROTOCOL) }}"
|
MEDIAWIKI_URL: "{{ domains | get_url(application_id, WEB_PROTOCOL) }}"
|
||||||
|
|
||||||
|
## Folders
|
||||||
|
MEDIAWIKI_HTML_DIR: "/var/www/html"
|
||||||
|
MEDIAWIKI_CONFIG_DIR: "{{ docker_compose.directories.config }}"
|
||||||
|
MEDIAWIKI_OIDC_FILE: "{{ docker_compose.directories.config }}/oidc.php"
|
||||||
|
|
||||||
## Docker
|
## Docker
|
||||||
MEDIAWIKI_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.mediawiki.version') }}"
|
MEDIAWIKI_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.mediawiki.version') }}"
|
||||||
MEDIAWIKI_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.mediawiki.image') }}"
|
MEDIAWIKI_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.mediawiki.image') }}"
|
||||||
@@ -18,3 +23,19 @@ MEDIAWIKI_USER: "www-data"
|
|||||||
MEDIAWIKI_ADMINISTRATOR_NAME: "{{ users.administrator.username }}"
|
MEDIAWIKI_ADMINISTRATOR_NAME: "{{ users.administrator.username }}"
|
||||||
MEDIAWIKI_ADMINISTRATOR_PASSWORD: "{{ users.administrator.password }}"
|
MEDIAWIKI_ADMINISTRATOR_PASSWORD: "{{ users.administrator.password }}"
|
||||||
MEDIAWIKI_ADMINISTRATOR_EMAIL: "{{ users.administrator.email }}"
|
MEDIAWIKI_ADMINISTRATOR_EMAIL: "{{ users.administrator.email }}"
|
||||||
|
|
||||||
|
# OIDC
|
||||||
|
MEDIAWIKI_OIDC_ENABLED: "{{ applications | get_app_conf(application_id, 'features.oidc') }}"
|
||||||
|
MEDIAWIKI_OIDC_CLIENT_ID: "{{ OIDC.CLIENT.ID }}"
|
||||||
|
MEDIAWIKI_OIDC_CLIENT_SECRET: "{{ OIDC.CLIENT.SECRET }}"
|
||||||
|
MEDIAWIKI_OIDC_ISSUER: "{{ OIDC.CLIENT.ISSUER_URL }}"
|
||||||
|
MEDIAWIKI_OIDC_BUTTON_TEXT: "{{ OIDC.BUTTON_TEXT }}"
|
||||||
|
|
||||||
|
# Extensions
|
||||||
|
MEDIAWIKI_EXT_BRANCH: "REL1_44" # passend zu MediaWiki 1.44
|
||||||
|
MEDIAWIKI_EXT_CFG_BASE: "{{ MEDIAWIKI_CONFIG_DIR }}/mwext/{{ MEDIAWIKI_EXT_BRANCH }}"
|
||||||
|
MEDIAWIKI_EXT_LIST:
|
||||||
|
- name: "PluggableAuth"
|
||||||
|
url: "https://codeload.github.com/wikimedia/mediawiki-extensions-PluggableAuth/tar.gz/refs/heads/{{ MEDIAWIKI_EXT_BRANCH }}"
|
||||||
|
- name: "OpenIDConnect"
|
||||||
|
url: "https://codeload.github.com/wikimedia/mediawiki-extensions-OpenIDConnect/tar.gz/refs/heads/{{ MEDIAWIKI_EXT_BRANCH }}"
|
Reference in New Issue
Block a user