256 lines
6.4 KiB
Bash
Executable File
256 lines
6.4 KiB
Bash
Executable File
#!/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
|