Files
TA-ProxMenu/run.sh
T
2026-07-26 15:45:45 -05:00

315 lines
9.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# TA-ProxMenu preloader
DEFAULTS_REPOSITORY='/opt/idssys/defaults'
DEFAULTS_CACHE_DIR='/var/cache/ta-proxmenu'
DEFAULTS_CHECK_FILE="${DEFAULTS_CACHE_DIR}/defaults-last-check"
DEFAULTS_CHECK_SECONDS=14400
TAPM_CONFIG_FILE='/etc/ta-proxmenu/config.env'
if [[ -z "${GITEA_DOMAIN:-}" && -r "$TAPM_CONFIG_FILE" ]]; then
GITEA_DOMAIN="$(
sed -n 's/^[[:space:]]*GITEA_DOMAIN[[:space:]]*=[[:space:]]*//p' \
"$TAPM_CONFIG_FILE" |
tail -n 1
)"
GITEA_DOMAIN="${GITEA_DOMAIN#\"}"
GITEA_DOMAIN="${GITEA_DOMAIN%\"}"
GITEA_DOMAIN="${GITEA_DOMAIN#\'}"
GITEA_DOMAIN="${GITEA_DOMAIN%\'}"
fi
if [[ "${GITEA_DOMAIN:-}" =~ ^[A-Za-z0-9.-]+(:[0-9]+)?$ ]]; then
GITEA_URL="https://${GITEA_DOMAIN}"
DEFAULTS_REPOSITORY_URL="${GITEA_URL}/voltron/iDS-Defaults.git"
else
GITEA_URL=''
DEFAULTS_REPOSITORY_URL=''
fi
source /opt/idssys/ta-proxmenu/inc/git-update.inc
AUTO_UPDATE_DEFAULTS() {
local checked_at=0
local current_branch
local now
local state
mkdir -p "$DEFAULTS_CACHE_DIR" 2>/dev/null || true
now="$(date +%s)"
[[ -r "$DEFAULTS_CHECK_FILE" ]] && read -r checked_at <"$DEFAULTS_CHECK_FILE"
if [[ "$checked_at" =~ ^[0-9]+$ ]] &&
(( now - checked_at < DEFAULTS_CHECK_SECONDS )); then
return
fi
exec 9>"${DEFAULTS_CACHE_DIR}/defaults-update.lock" || return
flock -n 9 || return
# Another process may have completed the update while this one waited.
checked_at=0
[[ -r "$DEFAULTS_CHECK_FILE" ]] && read -r checked_at <"$DEFAULTS_CHECK_FILE"
if [[ "$checked_at" =~ ^[0-9]+$ ]] &&
(( now - checked_at < DEFAULTS_CHECK_SECONDS )); then
return
fi
if [[ ! -d "${DEFAULTS_REPOSITORY}/.git" ]]; then
echo "iDSSYS Defaults is missing; restoring it from origin..."
if [[ -z "$DEFAULTS_REPOSITORY_URL" ]]; then
echo "WARNING: GITEA_DOMAIN is not configured; unable to restore iDSSYS Defaults." >&2
return
fi
mkdir -p /opt/idssys
if ! timeout 60 git clone \
"$DEFAULTS_REPOSITORY_URL" "$DEFAULTS_REPOSITORY"; then
echo "WARNING: Unable to restore iDSSYS Defaults." >&2
return
fi
else
current_branch="$(git -C "$DEFAULTS_REPOSITORY" branch --show-current 2>/dev/null)"
if [[ "$current_branch" != "master" ]]; then
echo "WARNING: iDSSYS Defaults is not on master; automatic update skipped." >&2
date +%s >"$DEFAULTS_CHECK_FILE"
return
fi
if TAPM_GIT_WORKTREE_DIRTY "$DEFAULTS_REPOSITORY"; then
echo "WARNING: iDSSYS Defaults has local changes; automatic update skipped." >&2
date +%s >"$DEFAULTS_CHECK_FILE"
return
fi
if ! TAPM_GIT_FETCH_BRANCH "$DEFAULTS_REPOSITORY" master 20 \
>/dev/null 2>&1; then
echo "WARNING: Unable to check iDSSYS Defaults; using the installed copy." >&2
return
fi
state="$(TAPM_GIT_BRANCH_STATE "$DEFAULTS_REPOSITORY" master)"
case "$state" in
behind)
echo "Updating required iDSSYS Defaults..."
if ! TAPM_GIT_FAST_FORWARD "$DEFAULTS_REPOSITORY" master \
>/dev/null 2>&1; then
echo "WARNING: Unable to update iDSSYS Defaults; using the installed copy." >&2
return
fi
;;
current)
;;
ahead)
echo "WARNING: iDSSYS Defaults has local commits not on origin; automatic update skipped." >&2
;;
diverged)
echo "WARNING: iDSSYS Defaults has diverged from origin; automatic update skipped." >&2
;;
*)
echo "WARNING: Unable to update iDSSYS Defaults; using the installed copy." >&2
return
;;
esac
fi
date +%s >"$DEFAULTS_CHECK_FILE"
}
AUTO_UPDATE_DEFAULTS
[ "${2:-}" != "q" ] && source /opt/idssys/defaults/colors.inc
source /opt/idssys/defaults/default.inc
source /opt/idssys/ta-proxmenu/defaults.inc
UPDATE_REPOSITORY() {
local repository="$1"
local branch="$2"
local label="$3"
local current_branch
local state
if [[ ! -d "${repository}/.git" ]]; then
echo -e "${idsCL[Red]}${label} is not a Git repository.${idsCL[Default]}"
return 1
fi
current_branch="$(git -C "$repository" branch --show-current 2>/dev/null)"
if [[ -z "$current_branch" ]]; then
echo -e "${idsCL[Red]}${label} is in a detached HEAD state; update skipped.${idsCL[Default]}"
return 1
fi
if [[ "$current_branch" != "$branch" ]]; then
echo -e "${idsCL[Red]}${label} is on '${current_branch}', not '${branch}'; update skipped.${idsCL[Default]}"
return 1
fi
if TAPM_GIT_WORKTREE_DIRTY "$repository"; then
echo -e "${idsCL[LightYellow]}${label} has local changes; update skipped to preserve them.${idsCL[Default]}"
git -C "$repository" status --short
return 1
fi
if ! TAPM_GIT_FETCH_BRANCH "$repository" "$branch" 30 >/dev/null 2>&1; then
echo -e "${idsCL[Red]}Could not fetch branch '${branch}' for ${label}.${idsCL[Default]}"
return 1
fi
state="$(TAPM_GIT_BRANCH_STATE "$repository" "$branch")"
case "$state" in
current)
echo -e "${idsCL[Green]}${label} is current (${branch}).${idsCL[Default]}"
return 0
;;
behind)
echo -en "${idsCL[LightCyan]}Updating ${label} (${branch})...${idsCL[Default]}"
if TAPM_GIT_FAST_FORWARD "$repository" "$branch" >/dev/null 2>&1; then
echo -e " ${idsCL[Green]}Done${idsCL[Default]}"
return 0
fi
echo -e " ${idsCL[Red]}Failed; local files were preserved.${idsCL[Default]}"
return 1
;;
ahead)
echo -e "${idsCL[LightYellow]}${label} is ahead of origin; its local commits were preserved.${idsCL[Default]}"
return 1
;;
diverged)
echo -e "${idsCL[LightYellow]}${label} has diverged from origin; automatic update was refused.${idsCL[Default]}"
return 1
;;
*)
echo -e "${idsCL[Red]}Could not determine the update state for ${label}.${idsCL[Default]}"
return 1
;;
esac
}
SWITCH_TAPM_BRANCH() {
local target_branch="$1"
local repository='/opt/idssys/ta-proxmenu'
local current_branch
local target_state=''
if ! git check-ref-format --branch "$target_branch" >/dev/null 2>&1; then
echo -e "${idsCL[Red]}'${target_branch}' is not a valid Git branch name.${idsCL[Default]}"
return 1
fi
if [[ ! -d "${repository}/.git" ]]; then
echo -e "${idsCL[Red]}TA-ProxMenu is not a Git repository.${idsCL[Default]}"
return 1
fi
current_branch="$(git -C "$repository" branch --show-current 2>/dev/null)"
if [[ -z "$current_branch" ]]; then
echo -e "${idsCL[Red]}TA-ProxMenu is in a detached HEAD state; branch switching was refused.${idsCL[Default]}"
return 1
fi
if [[ "$target_branch" == "$current_branch" ]]; then
echo -e "${idsCL[Green]}TA-ProxMenu is already using '${target_branch}'.${idsCL[Default]}"
return 0
fi
if TAPM_GIT_WORKTREE_DIRTY "$repository"; then
echo -e "${idsCL[LightYellow]}TA-ProxMenu has local changes; branch switching was refused to preserve them.${idsCL[Default]}"
git -C "$repository" status --short
return 1
fi
echo -e "${idsCL[LightCyan]}Fetching TA-ProxMenu branch '${target_branch}'...${idsCL[Default]}"
if ! TAPM_GIT_FETCH_BRANCH "$repository" "$target_branch" 30 >/dev/null 2>&1; then
echo -e "${idsCL[Red]}Could not fetch branch '${target_branch}' from origin.${idsCL[Default]}"
return 1
fi
if git -C "$repository" show-ref --verify --quiet "refs/heads/${target_branch}"; then
target_state="$(
TAPM_GIT_RELATION "$repository" "refs/heads/${target_branch}" \
"refs/remotes/origin/${target_branch}"
)" || {
echo -e "${idsCL[Red]}Could not compare local and remote '${target_branch}'.${idsCL[Default]}"
return 1
}
case "$target_state" in
ahead)
echo -e "${idsCL[LightYellow]}Local branch '${target_branch}' has commits not on origin; switching was refused.${idsCL[Default]}"
return 1
;;
diverged)
echo -e "${idsCL[LightYellow]}Local branch '${target_branch}' has diverged from origin; switching was refused.${idsCL[Default]}"
return 1
;;
esac
git -C "$repository" switch "$target_branch" >/dev/null || return 1
else
git -C "$repository" switch --create "$target_branch" \
--track "origin/${target_branch}" >/dev/null || return 1
fi
if [[ "$target_state" == "behind" ]] &&
! TAPM_GIT_FAST_FORWARD "$repository" "$target_branch" >/dev/null; then
echo -e "${idsCL[Red]}Could not fast-forward '${target_branch}'; no commits were discarded.${idsCL[Default]}"
return 1
fi
rm -f /var/cache/ta-proxmenu/update-status 2>/dev/null || true
echo -e "${idsCL[Green]}TA-ProxMenu is now using branch '${target_branch}'. Loading its menu...${idsCL[Default]}"
exec /opt/idssys/ta-proxmenu/run.sh
}
INSTALL_UPDATES() {
local current_branch
local defaults_warning=0
local update_failed=0
echo -e "${idsCL[LightCyan]}Checking for updates...${idsCL[Default]}"
if [[ -z "$GITEA_URL" ]]; then
echo -e "${idsCL[Red]}GITEA_DOMAIN is not configured in ${TAPM_CONFIG_FILE}.${idsCL[Default]}"
return 1
fi
if ! curl --fail --silent --show-error --head \
--connect-timeout 3 --max-time 10 "$GITEA_URL" >/dev/null; then
echo -e "${idsCL[Red]}Could not connect to ${GITEA_DOMAIN}${idsCL[Default]}"
return 1
fi
UPDATE_REPOSITORY /opt/idssys/defaults master "iDSSYS Defaults" ||
defaults_warning=1
current_branch="$(git -C /opt/idssys/ta-proxmenu branch --show-current)"
if [ -z "$current_branch" ]; then
echo -e "${idsCL[Red]}TA-ProxMenu is in a detached HEAD state; update skipped${idsCL[Default]}"
update_failed=1
else
UPDATE_REPOSITORY /opt/idssys/ta-proxmenu "$current_branch" "TA-ProxMenu" ||
update_failed=1
fi
rm -f /var/cache/ta-proxmenu/update-status 2>/dev/null || true
if (( update_failed == 0 )); then
source /opt/idssys/ta-proxmenu/defaults.inc
echo -e "\n${idsCL[Green]}Update check complete. Installed version: ${VERS}${idsCL[Default]}"
if (( defaults_warning == 1 )); then
echo -e "${idsCL[LightYellow]}TA-ProxMenu was processed, but iDSSYS Defaults requires attention.${idsCL[Default]}"
fi
return 0
fi
return 1
}
case "${1:-}" in
update|u)
INSTALL_UPDATES
exit $?
;;
main)
SWITCH_TAPM_BRANCH "$1"
exit $?
;;
tapm)
exit 0
;;
esac
/opt/idssys/ta-proxmenu/proxmenu-scripts.sh \
"${1:-}" "${2:-}" "${3:-}" "${4:-}"
exit $?