Files
computer-playbook/roles/web-app-xwiki/files/shell/xwiki-entrypoint.sh
kevinveenbirkenbachandClaude Opus 5 c7727a5996 fix(xwiki): let a rotated superadmin password reach the worker
The credential was baked into the image: files/Dockerfile appended xwiki.superadminpassword to WEB-INF/xwiki.cfg from a build arg. The swarm matrix rotates it between passes, so the manager rebuilds the image with the new value, but 'docker stack deploy --resolve-image never' leaves the mutable tag untouched and a worker that already holds it never re-pulls. The task keeps serving the pre-rotation password and answers 401 to every authenticated call the deploy makes next, which is where both XWiki jobs of run 33445831564 died: 03_administrator.yml:7 and 04_extensions.yml:25, after 31 attempts each.

The entrypoint writes it at start instead, from the environment the role already renders into templates/env.j2 and that sys-svc-container/templates/base.yml.j2 attaches as env_file. Both copies of xwiki.cfg are written, because the stock entrypoint restores the data volume over WEB-INF on every start but the first; writing only WEB-INF would survive one boot and be reverted by the next. The keys are deleted and re-appended rather than substituted, so a generated password never reaches a sed replacement.

Read from xwiki/xwiki-docker at master to settle three assumptions: other_starts() does restore xwiki.cfg, the stock entrypoint never touches the superadmin keys, and CONTEXT_PATH defaults to ROOT. The delete pattern was exercised against all four key spellings xwiki_replace accepts, and a password carrying sed metacharacters was verified to arrive byte for byte.

Dropping the build arg also keeps the credential out of the image history.

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

43 lines
1.8 KiB
Bash

#!/bin/sh
#
# The stock entrypoint restores WEB-INF/xwiki.properties from the data volume and
# then rewrites it in place; a read-only mount over WEB-INF (the swarm config
# object) makes that writeback fail. Feed our config through the data volume and
# let the stock entrypoint own WEB-INF.
#
# The superadmin credential is written here rather than baked by the Dockerfile:
# a rotation rebuilds the image on the manager, but `docker stack deploy
# --resolve-image never` leaves the mutable tag alone, so a worker that already
# holds it keeps serving the pre-rotation password and answers 401 to every
# authenticated call the deploy makes afterwards.
#
# Both copies are written because the stock entrypoint's other_starts() runs
# `restoreConfigurationFile 'xwiki.cfg'`, which copies the data volume over
# WEB-INF on every start but the first. Writing only WEB-INF would survive the
# first boot and be reverted by the second.
#
# The keys are deleted and re-appended rather than substituted: the stock
# xwiki_replace matches `#? ?key ?=`, so a commented or spaced default has to go
# too, and a generated password must never reach a sed replacement, where its
# delimiter or backreference characters would be read as syntax.
set -e
if [ -f /etc/infinito/xwiki.properties ]; then
mkdir -p /usr/local/xwiki/data
cp /etc/infinito/xwiki.properties /usr/local/xwiki/data/xwiki.properties
fi
if [ -n "${XWIKI_SUPERADMIN_PASSWORD:-}" ]; then
for cfg in /usr/local/xwiki/data/xwiki.cfg \
"/usr/local/tomcat/webapps/${CONTEXT_PATH:-ROOT}/WEB-INF/xwiki.cfg"; do
[ -f "${cfg}" ] || continue
sed -i -E '/^#? ?xwiki\.superadmin(password)? ?=/d' "${cfg}"
printf '%s\n' \
'xwiki.superadmin=1' \
"xwiki.superadminpassword=${XWIKI_SUPERADMIN_PASSWORD}" \
>>"${cfg}"
done
fi
exec docker-entrypoint.sh "$@"