fix(nexus-db): address codex review — early encoding guard, robust helpers
CI / Shell-Lint (bash -n, source-check, Validierungs-Tests) (pull_request) Successful in 2s

- assert encoding BEFORE role/password mutation on re-run, so an old
  SQL_ASCII DB aborts with no side effects (codex finding 1)
- ensure_utf8_locale_active honours its locale argument consistently in
  match, locale.gen line and export (codex finding 2)
- assert_db_encoding_utf8 uses argv-clean runuser psql with :'db' literal
  binding instead of nested su -c shell; docs keep su - postgres -c
  (codex finding 3)
This commit is contained in:
2026-06-13 14:34:35 +02:00
parent bd4293f53e
commit 6543fd77d8
2 changed files with 26 additions and 11 deletions
+16 -6
View File
@@ -63,14 +63,21 @@ apt_cleanup() {
# for THIS process before the server package runs its automatic initdb, then
# fail loudly if it is not actually available (generating alone is not enough
# — the locale must be active when initdb runs).
# Generates+activates a UTF-8 locale (default en_US.UTF-8); the argument
# honours other UTF-8 locales consistently (match, locale.gen line and the
# exported value all derive from it). Matching normalises case and dashes so
# the canonical `en_US.UTF-8` matches `locale -a`'s `en_US.utf8`.
ensure_utf8_locale_active() {
local loc="${1:-en_US.UTF-8}"
local norm; norm="$(printf '%s' "$loc" | tr 'A-Z' 'a-z' | tr -d '-')"
_locale_present() { locale -a 2>/dev/null | tr 'A-Z' 'a-z' | tr -d '-' | grep -qx "$norm"; }
msg_info "Ensuring $loc is generated and active (DB encoding is frozen at initdb)..."
if ! locale -a 2>/dev/null | tr 'A-Z' 'a-z' | grep -q '^en_us\.utf-\?8$'; then
sed -i 's/^# *en_US\.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen
if ! _locale_present; then
# Uncomment the matching `# <loc> UTF-8` line, then generate.
sed -i "s/^# *${loc} UTF-8/${loc} UTF-8/" /etc/locale.gen
locale-gen >/dev/null
fi
if ! locale -a 2>/dev/null | tr 'A-Z' 'a-z' | grep -q '^en_us\.utf-\?8$'; then
if ! _locale_present; then
msg_err "Locale $loc not available after locale-gen — refusing to continue (initdb would create a SQL_ASCII cluster)"
return 1
fi
@@ -82,11 +89,14 @@ ensure_utf8_locale_active() {
# Post-install guard: a database MUST be UTF8. Encoding is irreversible, so a
# wrong value is database damage — abort with a clear, actionable message
# instead of shipping a broken cluster. Reads via `su - postgres -c` (minimal
# LXCs have no sudo).
# instead of shipping a broken cluster. Uses argv-clean `runuser ... psql`
# with a quoted :'db' literal binding (robust regardless of caller); the
# credentials/README docs use `su - postgres -c` for hand maintenance (these
# minimal LXCs have no sudo).
assert_db_encoding_utf8() {
local db="$1" enc
enc="$(su - postgres -c "psql -X -qAt -c \"SELECT pg_encoding_to_char(encoding) FROM pg_database WHERE datname='$db'\"")"
enc="$(runuser -u postgres -- psql -X -qAt -v db="$db" \
-c "SELECT pg_encoding_to_char(encoding) FROM pg_database WHERE datname = :'db'")"
if [[ "$enc" != "UTF8" ]]; then
msg_err "Database '$db' has encoding '${enc:-<not found>}', expected UTF8."
msg_err "Encoding is frozen at creation time — this is DB damage, not cosmetic."