This commit is contained in:
2026-07-28 08:49:38 -05:00
parent 8c73cb7a53
commit 3ea33a17d8
4 changed files with 294 additions and 1 deletions
+255
View File
@@ -0,0 +1,255 @@
#!/usr/bin/env bash
# Standalone TA-managed Pulse LXC deployment bootstrap for Proxmox VE.
set -u -o pipefail
TAPM_PULSE_SOURCE_BRANCH="${TAPM_PULSE_SOURCE_BRANCH:-V2}"
TAPM_PULSE_SOURCE_BASE="${TAPM_PULSE_SOURCE_BASE:-https://git.schroedercity.com/TAI/TA-ProxMenu/raw/branch/${TAPM_PULSE_SOURCE_BRANCH}}"
TAPM_PULSE_BOOTSTRAP_DIR=''
TAPM_TEMP_DIR=''
declare -a TAPM_TEMP_DIRS=()
declare -A idsCL=()
TAPM_PULSE_VALID_SOURCE_BRANCH() {
local branch="${1:-}"
[[ -n "$branch" &&
"$branch" =~ ^[A-Za-z0-9._/-]+$ &&
"$branch" != /* &&
"$branch" != */ &&
"$branch" != *..* ]]
}
TAPM_PULSE_VALID_SOURCE_BASE() {
local url="${1:-}"
[[ "$url" == https://* &&
"$url" != *$'\n'* &&
"$url" != *$'\r'* &&
"$url" != *'"'* &&
"$url" != *\\* &&
"$url" != *[[:space:]]* ]]
}
TAPM_PULSE_DEFINE_COLORS() {
if [[ -t 1 && -z "${NO_COLOR:-}" ]]; then
idsCL[Default]=$'\e[0m'
idsCL[Red]=$'\e[31m'
idsCL[Green]=$'\e[32m'
idsCL[White]=$'\e[97m'
idsCL[LightRed]=$'\e[91m'
idsCL[LightGreen]=$'\e[92m'
idsCL[LightYellow]=$'\e[93m'
idsCL[LightCyan]=$'\e[96m'
else
idsCL[Default]=''
idsCL[Red]=''
idsCL[Green]=''
idsCL[White]=''
idsCL[LightRed]=''
idsCL[LightGreen]=''
idsCL[LightYellow]=''
idsCL[LightCyan]=''
fi
}
TAPM_CLEAN_TEMP_DIR() {
local temp_dir="${1:-}"
if [[ "$temp_dir" == /tmp/ta-proxmenu-* && -d "$temp_dir" ]]; then
rm -rf -- "$temp_dir"
fi
}
TAPM_CLEAN_ALL_TEMP_DIRS() {
local temp_dir
for temp_dir in "${TAPM_TEMP_DIRS[@]}"; do
TAPM_CLEAN_TEMP_DIR "$temp_dir"
done
TAPM_CLEAN_TEMP_DIR "$TAPM_PULSE_BOOTSTRAP_DIR"
}
TAPM_CREATE_TEMP_DIR() {
local label="${1:-installer}"
TAPM_TEMP_DIR="$(mktemp -d "/tmp/ta-proxmenu-${label}.XXXXXX")" || {
echo -e "${idsCL[LightRed]}Unable to create a temporary installer directory.${idsCL[Default]}"
return 1
}
if ! chmod 0700 "$TAPM_TEMP_DIR"; then
TAPM_CLEAN_TEMP_DIR "$TAPM_TEMP_DIR"
echo -e "${idsCL[LightRed]}Unable to secure the temporary installer directory.${idsCL[Default]}"
return 1
fi
TAPM_TEMP_DIRS+=("$TAPM_TEMP_DIR")
}
TAPM_DOWNLOAD_HTTPS() {
local url="$1"
local destination="$2"
local label="${3:-Installer}"
if ! TAPM_PULSE_VALID_SOURCE_BASE "$url"; then
echo -e "${idsCL[LightRed]}${label} requires a valid HTTPS URL.${idsCL[Default]}"
return 1
fi
if ! printf 'url = "%s"\n' "$url" |
curl --fail --location --silent --show-error \
--proto '=https' --proto-redir '=https' \
--output "$destination" --config -; then
echo -e "${idsCL[LightRed]}${label} download failed.${idsCL[Default]}"
return 1
fi
if [[ ! -s "$destination" ]]; then
echo -e "${idsCL[LightRed]}${label} download was empty.${idsCL[Default]}"
return 1
fi
}
EXIT1() {
stty echo 2>/dev/null || true
printf '%s' "${idsCL[Default]}"
}
SELECT_MENU() {
local title="$1"
local labels_name="$2"
local values_name="$3"
local allow_back="${4:-1}"
local -n labels_ref="$labels_name"
local -n values_ref="$values_name"
local selected=0
local key sequence index
while true; do
if [[ -t 1 ]]; then
clear 2>/dev/null || printf '\e[H\e[2J'
fi
echo
echo -e " ${idsCL[LightCyan]}${title}${idsCL[Default]}"
echo
for index in "${!labels_ref[@]}"; do
if (( index == selected )); then
printf '\e[7m %d %-64s\e[0m\n' \
"$((index + 1))" "${labels_ref[$index]}"
else
printf ' %d %s\n' "$((index + 1))" "${labels_ref[$index]}"
fi
done
echo
if (( allow_back == 1 )); then
echo " ↑/↓ Navigate Enter Select Number Quick Select ←/Esc/B Back Q Quit"
else
echo " ↑/↓ Navigate Enter Select Number Quick Select Q Quit"
fi
IFS= read -rsn1 key
case "$key" in
"")
MENU_SELECTION="${values_ref[$selected]}"
return 0
;;
[1-9])
index=$((10#$key - 1))
if (( index < ${#values_ref[@]} )); then
MENU_SELECTION="${values_ref[$index]}"
return 0
fi
;;
[Qq])
MENU_SELECTION=quit
return 0
;;
[Bb])
if (( allow_back == 1 )); then
MENU_SELECTION=back
return 0
fi
;;
$'\e')
sequence=''
IFS= read -rsn2 -t 0.1 sequence || true
case "$sequence" in
"[A"|"OA")
((selected = (selected - 1 + ${#labels_ref[@]}) % ${#labels_ref[@]}))
;;
"[B"|"OB")
((selected = (selected + 1) % ${#labels_ref[@]}))
;;
"[C"|"OC")
MENU_SELECTION="${values_ref[$selected]}"
return 0
;;
"[D"|"OD"|"")
if (( allow_back == 1 )); then
MENU_SELECTION=back
return 0
fi
;;
esac
;;
esac
done
}
TAPM_PULSE_STANDALONE_MAIN() {
local iso_helpers pulse_module
TAPM_PULSE_DEFINE_COLORS
if (( BASH_VERSINFO[0] < 4 ||
(BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] < 3) )); then
echo "Pulse deployment requires Bash 4.3 or newer." >&2
return 1
fi
if (( EUID != 0 )); then
echo "Run this installer as root on a Proxmox VE host." >&2
return 1
fi
for command in curl pct pvesh; do
if ! command -v "$command" >/dev/null 2>&1; then
echo "Required command '${command}' was not found." >&2
return 1
fi
done
if ! TAPM_PULSE_VALID_SOURCE_BRANCH "$TAPM_PULSE_SOURCE_BRANCH" ||
! TAPM_PULSE_VALID_SOURCE_BASE "$TAPM_PULSE_SOURCE_BASE"; then
echo "The configured TA-ProxMenu source branch or URL is invalid." >&2
return 1
fi
TAPM_PULSE_BOOTSTRAP_DIR="$(
mktemp -d /tmp/ta-proxmenu-pulse-bootstrap.XXXXXX
)" || return 1
chmod 0700 "$TAPM_PULSE_BOOTSTRAP_DIR" || return 1
iso_helpers="${TAPM_PULSE_BOOTSTRAP_DIR}/deploy-iso-nfs-lxc.sh"
pulse_module="${TAPM_PULSE_BOOTSTRAP_DIR}/deploy-pulse-lxc.sh"
echo "Downloading the TA-managed Pulse deployment components..."
TAPM_DOWNLOAD_HTTPS \
"${TAPM_PULSE_SOURCE_BASE}/inc/deploy-iso-nfs-lxc.sh" \
"$iso_helpers" "LXC storage helper" || return 1
TAPM_DOWNLOAD_HTTPS \
"${TAPM_PULSE_SOURCE_BASE}/inc/deploy-pulse-lxc.sh" \
"$pulse_module" "Pulse deployment module" || return 1
bash -n "$iso_helpers" "$pulse_module" || {
echo "A downloaded Pulse deployment component failed validation." >&2
return 1
}
grep -q '^TAPM_ISO_NFS_SELECT_STORAGE()' "$iso_helpers" &&
grep -q '^TAPM_DEPLOY_PULSE_LXC()' "$pulse_module" || {
echo "The downloaded files were not recognized as TAPM deployment components." >&2
return 1
}
# shellcheck disable=SC1090
source "$iso_helpers"
# shellcheck disable=SC1090
source "$pulse_module"
TAPM_DEPLOY_PULSE_LXC
}
if [[ "${TAPM_PULSE_STANDALONE_NO_MAIN:-0}" != 1 ]]; then
trap TAPM_CLEAN_ALL_TEMP_DIRS EXIT
TAPM_PULSE_STANDALONE_MAIN "$@"
fi