LibrePortal/scripts/function/checks/check_success.sh
librelad 5b6ed924d2 fix(chat tools): wire list_users into the WebUI user-list modal
The Tools tab has an interactive modal: when a list_users task completes it
parses the task log for EZ_USER lines and renders one row per account with
reset / promote / delete buttons. All four new apps failed its contract in every
respect, so running List Users produced log text and nothing else.

- The marker is EZ_USER, tab-separated as email, username, roles. Matrix and
  Stoat emitted LP_USER in a different field order; Mattermost and Rocket.Chat
  emitted no marker at all.
- Matrix and Stoat then consumed their own marker lines in the formatting loop
  and printed only the pretty version, so nothing reached the log to parse.
- The row buttons look up tools by id: reset_password, set_admin, delete_user.
  The deactivate tools were named deactivate_user / disable_user, so no delete
  button rendered.
- Prefill only fills a field named email or username. Rocket.Chat's and Stoat's
  identifier field was called user, so a row action would have opened with an
  empty box.
- '-' placeholders are truthy, so the modal's `email || username` fallback
  picked '-' over the real username for accounts without an email (rocket.cat).
  The EZ_USER line now carries an empty string; '-' stays in the readable line.

Mattermost's listing is rebuilt on `mmctl --json`, which carries roles and
delete_at. The text listing has neither, and there is no --system-admin filter
on user list, so every account was reported as a plain user. Two parsing notes
that cost time: mmctl prints status lines both before and after the JSON, so it
needs raw_decode rather than json.loads; and --per-page above 200 makes it emit
a warning line ahead of the payload.

The modal's delete button also stops asserting "Delete user" over whatever the
tool actually does — it takes its label and icon from the tool, because most of
these deactivate and Matrix cannot delete at all.

Verified by replaying the modal's own parser over real tool output: 2 rows for
Matrix, 4 for Mattermost, 3 for Rocket.Chat, with admin and deactivated states
resolving correctly.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 23:23:12 +01:00

69 lines
2.9 KiB
Bash
Executable File

#!/bin/bash
# checkSuccess "message" — report on the exit status of the PRECEDING command.
#
# IMPORTANT for callers: $? must still be the command's exit when this is called.
# `local VAR=$(cmd); checkSuccess ...` is a BUG — the `local`/`declare` builtin
# resets $? to 0, masking the command's real failure. Use `local VAR; VAR=$(cmd)`
# (split declaration from assignment) so $? survives.
#
# On failure this ALWAYS records the failure to a greppable error report
# ($logs_dir/error_report.log) with the caller's script:line + exit code, so a
# failure can never hide behind a green check again. Then it either continues
# (CFG_REQUIREMENT_CONTINUE_ON_ERROR=true, the default — surface every issue in a
# single pass) or falls back to the strict abort/prompt behaviour when that's off.
function checkSuccess()
{
local rc=$?
local msg="$1"
if [ "$rc" -eq 0 ]; then
isSuccessful "$msg"
if [ -f "$logs_dir/$docker_log_file" ]; then
echo "✓ Success $msg" | runInstallWrite -a "$logs_dir/$docker_log_file" >/dev/null
fi
return 0
fi
# ---- failure ----
isError "$msg"
# Record EVERY failure to a dedicated, greppable report (manager-owned logs),
# tagged with the caller's script:line + exit code. Best-effort; never aborts.
local _where="${BASH_SOURCE[1]##*/}:${BASH_LINENO[0]}"
local _stamp; _stamp="$(date '+%F %T' 2>/dev/null || echo now)"
printf '%s\t[exit %s]\t%s\t(%s)\n' "$_stamp" "$rc" "$msg" "$_where" \
| runInstallWrite -a "${logs_dir%/}/error_report.log" 2>/dev/null || true
if [ -f "$logs_dir/$docker_log_file" ]; then
isError " $msg (exit $rc, $_where)" | runInstallWrite -a "$logs_dir/$docker_log_file" >/dev/null 2>&1 || true
fi
# Continue-on-error (default true): log and carry on so a single failure
# doesn't abort the whole run and we surface EVERY issue in one pass. Turn
# CFG_REQUIREMENT_CONTINUE_ON_ERROR off for strict abort once things are clean.
if [[ "${CFG_REQUIREMENT_CONTINUE_ON_ERROR:-true}" == "true" ]]; then
isNotice "continue-on-error: logged to ${logs_dir%/}/error_report.log — continuing."
return 0
fi
# ---- strict mode (continue-on-error off) ----
# Non-interactive (task processor / cron / piped): bail instead of blocking.
if [[ "$LIBREPORTAL_NONINTERACTIVE" == "1" ]] || [ ! -t 0 ]; then
isNotice "Non-interactive mode: aborting on error."
exit 1
fi
while true; do
isQuestion "An error has occurred. Do you want to continue, exit or go to back to the Menu? (c/x/m) "
read -rp "" error_occurred
[[ -n "$error_occurred" ]] && break
isNotice "Please provide a valid input."
done
[[ "$error_occurred" == [cC] ]] && isNotice "Continuing after error has occurred."
[[ "$error_occurred" == [xX] ]] && exit 1
if [[ "$error_occurred" == [mM] && "$initial_command2" == "terminal" ]]; then
resetToMenu
fi
}