update
This commit is contained in:
@@ -107,6 +107,20 @@ replacing `/bin/gzip`. APT remains dual-stack by default; its conditional IPv4
|
||||
compatibility check is optional. Global vzdump bandwidth and I/O-priority
|
||||
changes are available through a separate explicit menu.
|
||||
|
||||
Pulse can also be deployed without installing TA-ProxMenu. Run the standalone
|
||||
bootstrap as root on a Proxmox VE host:
|
||||
|
||||
```bash
|
||||
bash <(curl -fsSL https://git.schroedercity.com/TAI/TA-ProxMenu/raw/branch/V2/install-pulse.sh)
|
||||
```
|
||||
|
||||
The bootstrap downloads the Pulse deployment module and its LXC storage helper
|
||||
from the same branch into a protected temporary directory, validates their Bash
|
||||
syntax and expected entry points, runs the normal interactive Pulse workflow,
|
||||
and removes the temporary files afterward. It does not clone or install
|
||||
TA-ProxMenu. Set `TAPM_PULSE_SOURCE_BRANCH` before running it to use another
|
||||
branch.
|
||||
|
||||
VirtIO downloads are managed from a dedicated submenu. The stable release is
|
||||
checked only when that submenu is opened, and curated compatibility ISOs are
|
||||
available for Windows Server 2008, 2008 R2, 2012/R2, and 2016. Downloads are
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
action="${1:-}"
|
||||
FOLDER='/opt/idssys/ta-proxmenu'
|
||||
VERS='2026.7.26-9'
|
||||
VERS='2026.7.28-1'
|
||||
|
||||
noupdate=' '
|
||||
|
||||
|
||||
Executable
+255
@@ -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
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env bash
|
||||
set -u -o pipefail
|
||||
|
||||
TEST_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
source "${TEST_ROOT}/tests/testlib.sh"
|
||||
TAPM_PULSE_STANDALONE_NO_MAIN=1
|
||||
source "${TEST_ROOT}/install-pulse.sh"
|
||||
|
||||
assert_success "default V2 source branch accepted" \
|
||||
TAPM_PULSE_VALID_SOURCE_BRANCH V2
|
||||
assert_success "nested release branch accepted" \
|
||||
TAPM_PULSE_VALID_SOURCE_BRANCH releases/pulse-6
|
||||
assert_failure "empty source branch rejected" \
|
||||
TAPM_PULSE_VALID_SOURCE_BRANCH ''
|
||||
assert_failure "source branch traversal rejected" \
|
||||
TAPM_PULSE_VALID_SOURCE_BRANCH '../main'
|
||||
assert_success "HTTPS source base accepted" \
|
||||
TAPM_PULSE_VALID_SOURCE_BASE \
|
||||
https://git.schroedercity.com/TAI/TA-ProxMenu/raw/branch/V2
|
||||
assert_failure "HTTP source base rejected" \
|
||||
TAPM_PULSE_VALID_SOURCE_BASE \
|
||||
http://git.schroedercity.com/TAI/TA-ProxMenu/raw/branch/V2
|
||||
|
||||
finish_tests
|
||||
Reference in New Issue
Block a user