Files
ProxMenux/scripts/post_install/update_post_install_function.sh
T
2026-05-09 18:59:59 +02:00

176 lines
5.7 KiB
Bash

#!/bin/bash
# ==========================================================
# ProxMenux - Sprint 12B: re-run a single post-install function
# ==========================================================
# Invoked by the Monitor's "Update" buttons (Settings → ProxMenux
# Optimizations) and by the bash menu's update flow. Sources the
# appropriate post_install script and invokes one specific function so
# the user can update a single tool without re-running the whole flow.
#
# Two invocation modes:
#
# SINGLE — set SOURCE_TYPE + FUNCTION_NAME (+ optionally TOOL_KEY):
# SOURCE_TYPE=auto FUNCTION_NAME=install_log2ram_auto
#
# BATCH — set FUNCTIONS_BATCH to a newline-separated list of
# "source:function:tool_key" triples (tool_key optional):
# FUNCTIONS_BATCH="auto:install_log2ram_auto:log2ram
# custom:install_ceph:ceph"
#
# In batch mode the wrapper iterates the list, sourcing each flow once
# and re-using its function definitions. Tools coming from the same
# flow share a single source step so the terminal output stays clean.
# ==========================================================
set -e
LOCAL_SCRIPTS="/usr/local/share/proxmenux/scripts"
BASE_DIR="/usr/local/share/proxmenux"
UTILS_FILE="$BASE_DIR/utils.sh"
if [[ -f "$UTILS_FILE" ]]; then
# shellcheck disable=SC1090
source "$UTILS_FILE"
fi
if command -v load_language >/dev/null 2>&1; then
load_language
fi
if command -v initialize_cache >/dev/null 2>&1; then
initialize_cache
fi
if command -v show_proxmenux_logo >/dev/null 2>&1; then
show_proxmenux_logo
fi
SOURCE_TYPE="${SOURCE_TYPE:-}"
FUNCTION_NAME="${FUNCTION_NAME:-}"
TOOL_KEY="${TOOL_KEY:-${FUNCTION_NAME}}"
FUNCTIONS_BATCH="${FUNCTIONS_BATCH:-}"
# Build the list of (source, function, tool_key) tuples from either the
# single-mode env vars or the batch payload.
declare -a BATCH=()
if [[ -n "$FUNCTIONS_BATCH" ]]; then
while IFS= read -r line; do
[[ -z "$line" ]] && continue
BATCH+=("$line")
done <<< "$FUNCTIONS_BATCH"
elif [[ -n "$SOURCE_TYPE" && -n "$FUNCTION_NAME" ]]; then
BATCH+=("${SOURCE_TYPE}:${FUNCTION_NAME}:${TOOL_KEY}")
else
echo "ERROR: provide either SOURCE_TYPE+FUNCTION_NAME (single mode) or FUNCTIONS_BATCH (batch mode)."
exit 2
fi
# ----------------------------------------------------------------------
# Source the flow scripts on first use. Both auto and customizable
# guard their entry point with `if [[ "${BASH_SOURCE[0]}" == "${0}" ]]`,
# so sourcing loads function definitions without triggering the
# interactive menu or the extremeshok dialog.
# ----------------------------------------------------------------------
SOURCED_AUTO=0
SOURCED_CUSTOM=0
ensure_flow_loaded() {
local source_type="$1"
case "$source_type" in
auto)
if [[ $SOURCED_AUTO -eq 0 ]]; then
# shellcheck disable=SC1091
source "$LOCAL_SCRIPTS/post_install/auto_post_install.sh"
SOURCED_AUTO=1
fi
;;
custom)
if [[ $SOURCED_CUSTOM -eq 0 ]]; then
# shellcheck disable=SC1091
source "$LOCAL_SCRIPTS/post_install/customizable_post_install.sh"
SOURCED_CUSTOM=1
fi
;;
*)
echo "ERROR: invalid source '$source_type' (must be 'auto' or 'custom')"
return 2
;;
esac
}
# ----------------------------------------------------------------------
# Run each tool. We don't bail on the first failure — the user marked a
# multi-select, they expect every chosen tool to be attempted. RCs are
# collected and the wrapper exits non-zero if any failed.
# ----------------------------------------------------------------------
TOTAL=${#BATCH[@]}
FAILED=0
INDEX=0
for entry in "${BATCH[@]}"; do
INDEX=$((INDEX + 1))
IFS=':' read -r src fn tkey <<< "$entry"
[[ -z "$tkey" ]] && tkey="$fn"
if command -v msg_info2 >/dev/null 2>&1; then
msg_info2 "[$INDEX/$TOTAL] Updating ${tkey} (running ${fn} from ${src} flow)..."
else
echo "[ProxMenux] [$INDEX/$TOTAL] Updating ${tkey} (running ${fn} from ${src} flow)..."
fi
if ! ensure_flow_loaded "$src"; then
FAILED=$((FAILED + 1))
continue
fi
if ! declare -F "$fn" >/dev/null 2>&1; then
if command -v msg_error >/dev/null 2>&1; then
msg_error "Function '$fn' is not defined in the ${src} flow."
else
echo "ERROR: function '$fn' is not defined in the ${src} flow."
fi
FAILED=$((FAILED + 1))
continue
fi
set +e
"$fn"
RC=$?
set -e
if [[ $RC -eq 0 ]]; then
if command -v msg_ok >/dev/null 2>&1; then
msg_ok "Update for ${tkey} completed."
else
echo "[ProxMenux] Update for ${tkey} completed."
fi
else
if command -v msg_error >/dev/null 2>&1; then
msg_error "Update for ${tkey} exited with status $RC."
else
echo "ERROR: update for ${tkey} exited with status $RC."
fi
FAILED=$((FAILED + 1))
fi
done
if [[ $FAILED -eq 0 ]]; then
if command -v msg_success >/dev/null 2>&1; then
msg_success "All $TOTAL update(s) completed successfully."
else
echo "[ProxMenux] All $TOTAL update(s) completed successfully."
fi
else
if command -v msg_warn >/dev/null 2>&1; then
msg_warn "$FAILED of $TOTAL updates failed — see the messages above."
else
echo "WARNING: $FAILED of $TOTAL updates failed."
fi
fi
if command -v msg_success >/dev/null 2>&1; then
msg_success "Press Enter to close this terminal..."
else
echo "Press Enter to close this terminal..."
fi
read -r 2>/dev/null || true
[[ $FAILED -eq 0 ]] && exit 0 || exit 1