update
This commit is contained in:
+552
-95
@@ -18,6 +18,7 @@ FINISH_ACTION() {
|
||||
FINISH_FAILED_ACTION() {
|
||||
(( ACTION_REQUESTED == 1 )) && exit 1
|
||||
ENTER2CONTINUE
|
||||
return 1
|
||||
}
|
||||
|
||||
declare -a TAPM_TEMP_DIRS=()
|
||||
@@ -89,6 +90,22 @@ TAPM_DOWNLOAD_HTTPS() {
|
||||
fi
|
||||
}
|
||||
|
||||
TAPM_DOWNLOAD_SHA256() {
|
||||
local url="$1"
|
||||
local destination="$2"
|
||||
local expected_sha256="${3,,}"
|
||||
local label="${4:-Installer}"
|
||||
local actual_sha256
|
||||
|
||||
TAPM_DOWNLOAD_HTTPS "$url" "$destination" "$label" || return 1
|
||||
actual_sha256="$(sha256sum "$destination" | cut -d' ' -f1)"
|
||||
if [[ "$actual_sha256" != "$expected_sha256" ]]; then
|
||||
rm -f -- "$destination"
|
||||
echo -e "${idsCL[LightRed]}${label} checksum did not match; the file was removed.${idsCL[Default]}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
TAPM_PACKAGE_INSTALLED() {
|
||||
dpkg-query -W -f='${Status}' "$1" 2>/dev/null |
|
||||
grep -q '^install ok installed$'
|
||||
@@ -108,6 +125,23 @@ TAPM_WAIT_FOR_SERVICE() {
|
||||
return 1
|
||||
}
|
||||
|
||||
TAPM_WAIT_FOR_TCP_PORT() {
|
||||
local port="$1"
|
||||
local attempts="${2:-30}"
|
||||
local attempt=0
|
||||
|
||||
while (( attempt < attempts )); do
|
||||
if ss -H -lnt 2>/dev/null |
|
||||
awk -v port="$port" '$4 ~ (":" port "$") { found=1 } END { exit !found }'; then
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
((attempt++))
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
trap TAPM_CLEAN_ALL_TEMP_DIRS EXIT
|
||||
|
||||
TAPM_CLEAR_AUTHORIZATION() {
|
||||
@@ -286,13 +320,68 @@ INSTALL_PROXMENUX() {
|
||||
}
|
||||
|
||||
PROXMENUX_POST_INSTALL() {
|
||||
PMFLDR='/usr/local/share/proxmenux/scripts/post_install'
|
||||
[ ! -f "${PMFLDR}/customizable_post_install.sh" ] && INSTALL_PROXMENUX
|
||||
bash "${PMFLDR}/customizable_post_install.sh"
|
||||
|
||||
touch /opt/.PROXMENUX_POST_INSTALL
|
||||
[ -s /etc/apt/sources.list ] && cat /dev/null > /etc/apt/sources.list
|
||||
|
||||
local backup_dir='/var/backups/ta-proxmenu'
|
||||
local backup_file=''
|
||||
local post_install_dir='/usr/local/share/proxmenux/scripts/post_install'
|
||||
local post_install_script="${post_install_dir}/customizable_post_install.sh"
|
||||
local timestamp
|
||||
|
||||
if [[ ! -f "$post_install_script" ]]; then
|
||||
INSTALL_PROXMENUX
|
||||
[[ -f "$post_install_script" ]] || return 1
|
||||
fi
|
||||
|
||||
if ! bash "$post_install_script"; then
|
||||
echo -e "${idsCL[LightRed]}The ProxMenux post-install script failed. A completion marker was not created.${idsCL[Default]}"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ -e /etc/apt/sources.list && ! -f /etc/apt/sources.list ]]; then
|
||||
echo -e "${idsCL[LightRed]}/etc/apt/sources.list is not a regular file and was not changed.${idsCL[Default]}"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ -s /etc/apt/sources.list ]]; then
|
||||
timestamp="$(date +%Y%m%d-%H%M%S)"
|
||||
if ! install -d -m 0700 "$backup_dir" ||
|
||||
! backup_file="$(mktemp "${backup_dir}/sources.list.proxmenux.${timestamp}.XXXXXX")" ||
|
||||
! install -m 0600 /etc/apt/sources.list "$backup_file"; then
|
||||
[[ -n "$backup_file" ]] && rm -f -- "$backup_file"
|
||||
echo -e "${idsCL[LightRed]}Could not back up /etc/apt/sources.list; it was not cleared.${idsCL[Default]}"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! : >/etc/apt/sources.list ||
|
||||
! chmod 0644 /etc/apt/sources.list; then
|
||||
echo -e "${idsCL[LightRed]}Could not enforce an empty /etc/apt/sources.list.${idsCL[Default]}"
|
||||
[[ -n "$backup_file" ]] &&
|
||||
echo "Backup retained at: ${backup_file}"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
|
||||
if ! apt-get update; then
|
||||
echo -e "${idsCL[LightRed]}APT repository validation failed after ProxMenux post-install.${idsCL[Default]}"
|
||||
[[ -n "$backup_file" ]] &&
|
||||
echo "Removed sources were retained at: ${backup_file}"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
|
||||
if ! touch /opt/.PROXMENUX_POST_INSTALL; then
|
||||
echo -e "${idsCL[LightRed]}Post-install succeeded, but the completion marker could not be created.${idsCL[Default]}"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
|
||||
echo -e "\n${idsCL[Green]}ProxMenux post-install completed and APT sources were validated.${idsCL[Default]}"
|
||||
[[ -n "$backup_file" ]] &&
|
||||
echo "ProxMenux additions to sources.list were saved at: ${backup_file}"
|
||||
FINISH_ACTION
|
||||
}
|
||||
|
||||
INSTALL_GLANCES() {
|
||||
@@ -501,48 +590,193 @@ INSTALL_S1() {
|
||||
FINISH_ACTION
|
||||
}
|
||||
|
||||
TAPM_SYSTEM_PRODUCT_NAME() {
|
||||
local product_name=''
|
||||
|
||||
if [[ -r /sys/class/dmi/id/product_name ]]; then
|
||||
read -r product_name </sys/class/dmi/id/product_name
|
||||
elif command -v dmidecode >/dev/null 2>&1; then
|
||||
product_name="$(dmidecode -s system-product-name 2>/dev/null)"
|
||||
fi
|
||||
|
||||
printf '%s\n' "$product_name"
|
||||
}
|
||||
|
||||
TAPM_OMSA_SUPPORTED_HARDWARE() {
|
||||
local product_name
|
||||
|
||||
product_name="$(TAPM_SYSTEM_PRODUCT_NAME)"
|
||||
[[ "$product_name" =~ PowerEdge[[:space:]]+[[:alpha:]]+[0-9](3|4)[0-9][[:alnum:]-]* ]]
|
||||
}
|
||||
|
||||
TAPM_OMSA_SUPPORTED_PLATFORM() {
|
||||
local architecture
|
||||
local codename
|
||||
local os_version
|
||||
local pve_version
|
||||
|
||||
architecture="$(dpkg --print-architecture 2>/dev/null)"
|
||||
os_version="$(. /etc/os-release 2>/dev/null; printf '%s' "${VERSION_ID:-}")"
|
||||
codename="$(. /etc/os-release 2>/dev/null; printf '%s' "${VERSION_CODENAME:-}")"
|
||||
pve_version="$(pveversion 2>/dev/null | head -n 1)"
|
||||
|
||||
[[ "$architecture" == "amd64" &&
|
||||
"$os_version" == "13" &&
|
||||
"$codename" == "trixie" &&
|
||||
"$pve_version" == pve-manager/9.* ]]
|
||||
}
|
||||
|
||||
INSTALL_OMSA() {
|
||||
echo
|
||||
mkdir -p /tmp/omsa
|
||||
cd /tmp/omsa || return 1
|
||||
apt install -y gnupg libcurl4t64 libncurses6 libxslt1.1 libgpm2 libtinfo6
|
||||
mkdir -p /etc/apt/keyrings
|
||||
wget -qO - https://linux.dell.com/repo/pgp_pubkeys/0x1285491434D8786F.asc | gpg --dearmor -o /etc/apt/keyrings/linux.dell.com.gpg
|
||||
chmod +r /etc/apt/keyrings/linux.dell.com.gpg
|
||||
echo "deb [signed-by=/etc/apt/keyrings/linux.dell.com.gpg] http://linux.dell.com/repo/community/openmanage/11000/jammy jammy main" > /etc/apt/sources.list.d/linux.dell.com.list
|
||||
apt update
|
||||
wget -c http://archive.ubuntu.com/ubuntu/pool/universe/o/openwsman/libwsman-curl-client-transport1_2.6.5-0ubuntu16_amd64.deb
|
||||
wget -c http://archive.ubuntu.com/ubuntu/pool/universe/o/openwsman/libwsman-client4t64_2.6.5-0ubuntu16_amd64.deb
|
||||
wget -c http://archive.ubuntu.com/ubuntu/pool/universe/o/openwsman/libwsman1t64_2.6.5-0ubuntu16_amd64.deb
|
||||
# wget -c http://http.us.debian.org/debian/pool/main/libx/libxml2/libxml2-16_2.15.1+dfsg-2+b1_amd64.deb
|
||||
wget -c http://http.us.debian.org/debian/pool/main/libx/libxml2/libxml2-16_2.15.2+dfsg-0.1_amd64.deb
|
||||
wget -c http://archive.ubuntu.com/ubuntu/pool/universe/o/openwsman/libwsman-server1t64_2.6.5-0ubuntu16_amd64.deb
|
||||
wget -c http://archive.ubuntu.com/ubuntu/pool/universe/s/sblim-sfcc/libcimcclient0_2.2.8-0ubuntu2_amd64.deb
|
||||
wget -c http://archive.ubuntu.com/ubuntu/pool/universe/o/openwsman/openwsman_2.6.5-0ubuntu16_amd64.deb
|
||||
wget -c http://archive.ubuntu.com/ubuntu/pool/multiverse/c/cim-schema/cim-schema_2.48.0-0ubuntu1_all.deb
|
||||
wget -c http://archive.ubuntu.com/ubuntu/pool/universe/s/sblim-sfc-common/libsfcutil0_1.0.1-0ubuntu4_amd64.deb
|
||||
wget -c http://archive.ubuntu.com/ubuntu/pool/multiverse/s/sblim-sfcb/sfcb_1.4.9-0ubuntu7_amd64.deb
|
||||
wget -c http://archive.ubuntu.com/ubuntu/pool/universe/s/sblim-cmpi-devel/libcmpicppimpl0_2.0.3-0ubuntu2_amd64.deb
|
||||
wget -c http://ftp.us.debian.org/debian/pool/main/o/openssl/libssl1.1_1.1.1w-0+deb11u1_amd64.deb
|
||||
dpkg -i libwsman-curl-client-transport1_2.6.5-0ubuntu16_amd64.deb
|
||||
dpkg -i libwsman-client4t64_2.6.5-0ubuntu16_amd64.deb
|
||||
dpkg -i libxml2-16_2.15.2+dfsg-0.1_amd64.deb
|
||||
dpkg -i libwsman1t64_2.6.5-0ubuntu16_amd64.deb
|
||||
dpkg -i libwsman-server1t64_2.6.5-0ubuntu16_amd64.deb
|
||||
dpkg -i libcimcclient0_2.2.8-0ubuntu2_amd64.deb
|
||||
dpkg -i openwsman_2.6.5-0ubuntu16_amd64.deb
|
||||
dpkg -i cim-schema_2.48.0-0ubuntu1_all.deb
|
||||
dpkg -i libsfcutil0_1.0.1-0ubuntu4_amd64.deb
|
||||
dpkg -i sfcb_1.4.9-0ubuntu7_amd64.deb
|
||||
dpkg -i libcmpicppimpl0_2.0.3-0ubuntu2_amd64.deb
|
||||
dpkg -i libssl1.1_1.1.1w-0+deb11u1_amd64.deb
|
||||
apt install -y srvadmin-all
|
||||
/opt/dell/srvadmin/sbin/srvadmin-services.sh start
|
||||
rm -rf -- /tmp/omsa
|
||||
|
||||
echo -e "\n${idsCL[Green]}Dell OMSA has been installed${idsCL[Default]}"
|
||||
echo -e "\n${idsCL[LightCyan]}Available at: ${idsCL[LightGreen]}https://${RNIP}:1311${idsCL[Default]}"
|
||||
FINISH_ACTION
|
||||
local base_url='https://archive.ubuntu.com/ubuntu/pool'
|
||||
local dell_key
|
||||
local dell_keyring
|
||||
local dell_source
|
||||
local index
|
||||
local product_name
|
||||
local temp_dir
|
||||
local -a filenames=(
|
||||
'libwsman-curl-client-transport1_2.6.5-0ubuntu16_amd64.deb'
|
||||
'libwsman-client4t64_2.6.5-0ubuntu16_amd64.deb'
|
||||
'libxml2-16_2.15.2+dfsg-0.1_amd64.deb'
|
||||
'libwsman1t64_2.6.5-0ubuntu16_amd64.deb'
|
||||
'libwsman-server1t64_2.6.5-0ubuntu16_amd64.deb'
|
||||
'libcimcclient0_2.2.8-0ubuntu2_amd64.deb'
|
||||
'openwsman_2.6.5-0ubuntu16_amd64.deb'
|
||||
'cim-schema_2.48.0-0ubuntu1_all.deb'
|
||||
'libsfcutil0_1.0.1-0ubuntu4_amd64.deb'
|
||||
'sfcb_1.4.9-0ubuntu7_amd64.deb'
|
||||
'libcmpicppimpl0_2.0.3-0ubuntu2_amd64.deb'
|
||||
'libssl1.1_1.1.1w-0+deb11u1_amd64.deb'
|
||||
)
|
||||
local -a urls=(
|
||||
"${base_url}/universe/o/openwsman/${filenames[0]}"
|
||||
"${base_url}/universe/o/openwsman/${filenames[1]}"
|
||||
'https://snapshot.debian.org/file/32f51d914435fd29ce31af7ba17525f6276ea58d'
|
||||
"${base_url}/universe/o/openwsman/${filenames[3]}"
|
||||
"${base_url}/universe/o/openwsman/${filenames[4]}"
|
||||
"${base_url}/universe/s/sblim-sfcc/${filenames[5]}"
|
||||
"${base_url}/universe/o/openwsman/${filenames[6]}"
|
||||
"${base_url}/multiverse/c/cim-schema/${filenames[7]}"
|
||||
"${base_url}/universe/s/sblim-sfc-common/${filenames[8]}"
|
||||
"${base_url}/multiverse/s/sblim-sfcb/${filenames[9]}"
|
||||
"${base_url}/universe/s/sblim-cmpi-devel/${filenames[10]}"
|
||||
"https://deb.debian.org/debian/pool/main/o/openssl/${filenames[11]}"
|
||||
)
|
||||
local -a checksums=(
|
||||
'42fdd34722ac1304427f80c4176ee781d057f05669d485f0ee1da4d87df7488c'
|
||||
'6d1855a2e8263e9a578b4c0bb7a963a6d99dc8d2ef41e287725799dcad0c6cb3'
|
||||
'8571682a07f329bb462569502b57aced4866e5b95c2db3ec7e5414a5b3bbdc14'
|
||||
'61b91e8f234c5f2f87b4bce3534bc2f2304d50cd2fd95f426f12fc73d80e27b4'
|
||||
'5d3f948ab605b4973b399f53bd62bddd70eb01161769a0d39a811399fe7c2daf'
|
||||
'14b9ac374f88bd44e57395e87faa76d99d02e242c813fe30083d5bbfafec5870'
|
||||
'62b30fcf41dae0c1d841f67a46049b7dfa4dfffe314e4226a776eb134605b7fc'
|
||||
'a87d16d41e81092c7ada43824a97cf79fab18c4a3722ef6f0476ad697a3d9ab7'
|
||||
'ba890cf5f2359befd3da1e5763672ef8b03d5424fa4e3d1ef21c9d52884af247'
|
||||
'3eb5dce0a873f8eb77174fdd5e02ac55a989f7a73bd5ef8c8aae501d225d7524'
|
||||
'284acfbb6d675496046ee46e6d5ea6c70ceafa3781cf1eece04f612cbadf117c'
|
||||
'aadf8b4b197335645b230c2839b4517aa444fd2e8f434e5438c48a18857988f7'
|
||||
)
|
||||
local -a package_paths=()
|
||||
|
||||
echo
|
||||
product_name="$(TAPM_SYSTEM_PRODUCT_NAME)"
|
||||
if ! TAPM_OMSA_SUPPORTED_HARDWARE; then
|
||||
echo -e "${idsCL[LightRed]}Dell OMSA legacy installation is limited to PowerEdge x30/x40 systems.${idsCL[Default]}"
|
||||
echo "Detected system: ${product_name:-Unknown}"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
if ! TAPM_OMSA_SUPPORTED_PLATFORM; then
|
||||
echo -e "${idsCL[LightRed]}This legacy OMSA package set requires PVE 9 on Debian 13 (Trixie), amd64.${idsCL[Default]}"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
|
||||
echo -e "${idsCL[LightYellow]}Installing legacy Dell OMSA 11.0 compatibility packages on ${product_name}.${idsCL[Default]}"
|
||||
|
||||
if ! TAPM_CREATE_TEMP_DIR omsa; then
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
temp_dir="$TAPM_TEMP_DIR"
|
||||
dell_key="${temp_dir}/dell-openmanage.asc"
|
||||
dell_keyring="${temp_dir}/linux.dell.com.gpg"
|
||||
dell_source="${temp_dir}/linux.dell.com.list"
|
||||
|
||||
if ! TAPM_DOWNLOAD_SHA256 \
|
||||
'https://linux.dell.com/repo/pgp_pubkeys/0x1285491434D8786F.asc' \
|
||||
"$dell_key" \
|
||||
'92f9622bf300f1fc8a4ef12d8e5efef6511b089c63c15e635cfc7429499e86d4' \
|
||||
'Dell OpenManage signing key'; then
|
||||
TAPM_CLEAN_TEMP_DIR "$temp_dir"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
|
||||
for index in "${!filenames[@]}"; do
|
||||
package_paths+=("${temp_dir}/${filenames[$index]}")
|
||||
if ! TAPM_DOWNLOAD_SHA256 "${urls[$index]}" "${package_paths[$index]}" \
|
||||
"${checksums[$index]}" "${filenames[$index]}"; then
|
||||
TAPM_CLEAN_TEMP_DIR "$temp_dir"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
done
|
||||
|
||||
if ! apt-get update ||
|
||||
! DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
gnupg libcurl4t64 libncurses6 libxslt1.1 libgpm2 libtinfo6 ||
|
||||
! gpg --batch --yes --dearmor --output "$dell_keyring" "$dell_key"; then
|
||||
TAPM_CLEAN_TEMP_DIR "$temp_dir"
|
||||
echo -e "${idsCL[LightRed]}Unable to prepare the Dell OMSA repository.${idsCL[Default]}"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
|
||||
if ! printf '%s\n' \
|
||||
'deb [signed-by=/etc/apt/keyrings/linux.dell.com.gpg] https://linux.dell.com/repo/community/openmanage/11000/jammy jammy main' \
|
||||
>"$dell_source" ||
|
||||
! mkdir -p /etc/apt/keyrings ||
|
||||
! install -m 0644 "$dell_keyring" /etc/apt/keyrings/linux.dell.com.gpg ||
|
||||
! install -m 0644 "$dell_source" /etc/apt/sources.list.d/linux.dell.com.list; then
|
||||
TAPM_CLEAN_TEMP_DIR "$temp_dir"
|
||||
echo -e "${idsCL[LightRed]}Unable to write the Dell OMSA repository configuration.${idsCL[Default]}"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
|
||||
if ! apt-get update; then
|
||||
TAPM_CLEAN_TEMP_DIR "$temp_dir"
|
||||
echo -e "${idsCL[LightRed]}The Dell OMSA repository could not be refreshed.${idsCL[Default]}"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
|
||||
if ! dpkg -i "${package_paths[@]}"; then
|
||||
if ! DEBIAN_FRONTEND=noninteractive apt-get install --fix-broken -y ||
|
||||
! dpkg -i "${package_paths[@]}"; then
|
||||
TAPM_CLEAN_TEMP_DIR "$temp_dir"
|
||||
echo -e "${idsCL[LightRed]}The legacy OMSA compatibility packages could not be installed.${idsCL[Default]}"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! DEBIAN_FRONTEND=noninteractive apt-get install -y srvadmin-all ||
|
||||
! TAPM_PACKAGE_INSTALLED srvadmin-all ||
|
||||
[[ ! -x /opt/dell/srvadmin/sbin/srvadmin-services.sh ]] ||
|
||||
! /opt/dell/srvadmin/sbin/srvadmin-services.sh start ||
|
||||
! TAPM_WAIT_FOR_TCP_PORT 1311 30; then
|
||||
TAPM_CLEAN_TEMP_DIR "$temp_dir"
|
||||
echo -e "${idsCL[LightRed]}Dell OMSA installation failed or port 1311 did not become available.${idsCL[Default]}"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
|
||||
TAPM_CLEAN_TEMP_DIR "$temp_dir"
|
||||
echo -e "\n${idsCL[Green]}Dell OMSA has been installed and verified.${idsCL[Default]}"
|
||||
echo -e "\n${idsCL[LightCyan]}Available at: ${idsCL[LightGreen]}https://${RNIP}:1311${idsCL[Default]}"
|
||||
FINISH_ACTION
|
||||
}
|
||||
|
||||
DOWNLOAD_VIRTIO() {
|
||||
@@ -558,36 +792,198 @@ DOWNLOAD_VIRTIO() {
|
||||
FINISH_ACTION
|
||||
}
|
||||
|
||||
DETECT_CPU(){
|
||||
# if [ ! -f /etc/apt/sources.list.d/proxlb.list ]; then
|
||||
# echo "deb https://repo.gyptazy.com/stable /" > /etc/apt/sources.list.d/proxlb.list
|
||||
# wget -O /etc/apt/trusted.gpg.d/proxlb.asc https://repo.gyptazy.com/repository.gpg
|
||||
# apt-get update
|
||||
# fi
|
||||
if [ ! -f /etc/apt/sources.list.d/gyptazy.list ]; then
|
||||
curl https://git.gyptazy.com/api/packages/gyptazy/debian/repository.key -o /etc/apt/keyrings/gyptazy.asc
|
||||
echo "deb [signed-by=/etc/apt/keyrings/gyptazy.asc] https://packages.gyptazy.com/api/packages/gyptazy/debian trixie main" | sudo tee -a /etc/apt/sources.list.d/gyptazy.list
|
||||
apt update
|
||||
fi
|
||||
if [ "$(dpkg -l | awk '/proxclmc/ {print }'|wc -l)" -eq 0 ]; then
|
||||
apt -y install proxclmc
|
||||
fi
|
||||
TAPM_INSTALL_PROXCLMC() {
|
||||
local key_url='https://git.gyptazy.com/api/packages/gyptazy/debian/repository.key'
|
||||
local keyring='/etc/apt/keyrings/gyptazy.asc'
|
||||
local repository_file='/etc/apt/sources.list.d/gyptazy.list'
|
||||
local repository_line='deb [signed-by=/etc/apt/keyrings/gyptazy.asc] https://packages.gyptazy.com/api/packages/gyptazy/debian trixie main'
|
||||
local temp_dir
|
||||
local temp_key
|
||||
|
||||
TAPM_PACKAGE_INSTALLED proxclmc && command -v proxclmc >/dev/null 2>&1 &&
|
||||
return 0
|
||||
|
||||
TAPM_CREATE_TEMP_DIR proxclmc || return 1
|
||||
temp_dir="$TAPM_TEMP_DIR"
|
||||
temp_key="${temp_dir}/gyptazy.asc"
|
||||
|
||||
TAPM_DOWNLOAD_HTTPS "$key_url" "$temp_key" "ProxCLMC repository key" ||
|
||||
return 1
|
||||
if ! command -v gpg >/dev/null 2>&1 ||
|
||||
! gpg --batch --show-keys "$temp_key" >/dev/null 2>&1; then
|
||||
echo -e "${idsCL[LightRed]}The downloaded ProxCLMC repository key is not a valid OpenPGP key.${idsCL[Default]}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! install -d -m 0755 /etc/apt/keyrings ||
|
||||
! install -m 0644 "$temp_key" "$keyring" ||
|
||||
! printf '%s\n' "$repository_line" >"$repository_file" ||
|
||||
! chmod 0644 "$repository_file"; then
|
||||
echo -e "${idsCL[LightRed]}Could not configure the ProxCLMC package repository.${idsCL[Default]}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! apt-get update ||
|
||||
! apt-get install -y proxclmc ||
|
||||
! command -v proxclmc >/dev/null 2>&1; then
|
||||
echo -e "${idsCL[LightRed]}ProxCLMC could not be installed.${idsCL[Default]}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
TAPM_CLEAN_TEMP_DIR "$temp_dir"
|
||||
}
|
||||
|
||||
TAPM_CLUSTER_QEMU_GUESTS() {
|
||||
pvesh get /cluster/resources --type vm --output-format json 2>/dev/null |
|
||||
python3 -c '
|
||||
import json
|
||||
import sys
|
||||
|
||||
for guest in json.load(sys.stdin):
|
||||
if guest.get("type") != "qemu":
|
||||
continue
|
||||
print(
|
||||
guest.get("vmid", ""),
|
||||
str(guest.get("name", ""))
|
||||
.replace("\x1f", " ")
|
||||
.replace("\r", " ")
|
||||
.replace("\n", " "),
|
||||
guest.get("node", ""),
|
||||
"yes" if guest.get("template") in (1, True, "1") else "no",
|
||||
sep="\x1f",
|
||||
)
|
||||
'
|
||||
}
|
||||
|
||||
TAPM_QEMU_CPU_MODEL() {
|
||||
local vmid="$1"
|
||||
local config_output
|
||||
local cpu_model
|
||||
|
||||
config_output="$(qm config "$vmid" 2>/dev/null)" || return 1
|
||||
cpu_model="$(
|
||||
awk -F': ' '$1 == "cpu" { print $2; exit }' <<< "$config_output"
|
||||
)"
|
||||
[[ -n "$cpu_model" ]] || cpu_model='kvm64'
|
||||
printf '%s\n' "$cpu_model"
|
||||
}
|
||||
|
||||
DETECT_CPU() {
|
||||
local answer
|
||||
local cpu_model
|
||||
local current_cpu
|
||||
local guest
|
||||
local guest_output
|
||||
local name
|
||||
local node
|
||||
local template
|
||||
local vmid
|
||||
local -a changes=()
|
||||
local -a failures=()
|
||||
local -a successes=()
|
||||
|
||||
for command in apt-get curl gpg install pvesh python3 qm; do
|
||||
if ! command -v "$command" >/dev/null 2>&1; then
|
||||
echo -e "${idsCL[LightRed]}${command} is required for CPU compatibility detection.${idsCL[Default]}"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
done
|
||||
|
||||
if ! TAPM_INSTALL_PROXCLMC; then
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
|
||||
echo -e "\n${idsCL[LightCyan]}Analyzing CPU compatibility across the cluster...${idsCL[Default]}"
|
||||
cpu_model="$(proxclmc --list-only 2>/dev/null)" || {
|
||||
echo -e "${idsCL[LightRed]}ProxCLMC could not determine a compatible CPU model.${idsCL[Default]}"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
}
|
||||
cpu_model="${cpu_model//$'\r'/}"
|
||||
cpu_model="${cpu_model//$'\n'/}"
|
||||
if [[ ! "$cpu_model" =~ ^x86-64-v(1|2-AES|3|4)$ ]]; then
|
||||
echo -e "${idsCL[LightRed]}ProxCLMC returned an unexpected CPU model: ${cpu_model:-empty}.${idsCL[Default]}"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
|
||||
guest_output="$(TAPM_CLUSTER_QEMU_GUESTS)" || {
|
||||
echo -e "${idsCL[LightRed]}Could not read cluster QEMU resources.${idsCL[Default]}"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
}
|
||||
if [[ -z "$guest_output" ]]; then
|
||||
echo -e "\n${idsCL[LightCyan]}No QEMU VMs or templates were found in the cluster.${idsCL[Default]}"
|
||||
FINISH_ACTION
|
||||
return
|
||||
fi
|
||||
|
||||
while IFS=$'\x1f' read -r vmid name node template; do
|
||||
[[ -n "$vmid" ]] || continue
|
||||
current_cpu="$(TAPM_QEMU_CPU_MODEL "$vmid")" || {
|
||||
echo -e "${idsCL[LightRed]}Could not read the CPU configuration for VMID ${vmid}.${idsCL[Default]}"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
}
|
||||
[[ "$current_cpu" == "$cpu_model" ]] && continue
|
||||
changes+=(
|
||||
"${vmid}"$'\x1f'"${name}"$'\x1f'"${node}"$'\x1f'"${template}"$'\x1f'"${current_cpu}"
|
||||
)
|
||||
done <<< "$guest_output"
|
||||
|
||||
if (( ${#changes[@]} == 0 )); then
|
||||
echo -e "\n${idsCL[Green]}All QEMU VMs and templates already use ${cpu_model}.${idsCL[Default]}"
|
||||
FINISH_ACTION
|
||||
return
|
||||
fi
|
||||
|
||||
printf '\nRecommended cluster CPU model: %s\n' "$cpu_model"
|
||||
printf '\n%-7s %-28s %-20s %-10s %-24s %s\n' \
|
||||
'VMID' 'NAME' 'NODE' 'TEMPLATE' 'CURRENT CPU' 'PROPOSED CPU'
|
||||
printf '%-7s %-28s %-20s %-10s %-24s %s\n' \
|
||||
'-------' '----------------------------' '--------------------' \
|
||||
'----------' '------------------------' '----------------'
|
||||
for guest in "${changes[@]}"; do
|
||||
IFS=$'\x1f' read -r vmid name node template current_cpu <<< "$guest"
|
||||
printf '%-7s %-28.28s %-20.20s %-10s %-24.24s %s\n' \
|
||||
"$vmid" "${name:-unnamed}" "$node" "$template" "$current_cpu" "$cpu_model"
|
||||
done
|
||||
|
||||
echo -en "\n${idsCL[LightCyan]}Apply this CPU model to ${#changes[@]} VM(s) and template(s) (y/N)?${idsCL[Default]} "
|
||||
read -r -n 1 answer
|
||||
echo
|
||||
proxclmc
|
||||
echo
|
||||
echo -en "${idsCL[LightCyan]}Would you like to set '${idsCL[LightGreen]}cpu: $(proxclmc --list-only)${idsCL[LightCyan]}' on all VMs (y/N)?${idsCL[Default]} "
|
||||
read -n 1 choice
|
||||
case "$choice" in
|
||||
[Yy])
|
||||
sed -i "/cpu:/c cpu: $(proxclmc --list-only)" /etc/pve/nodes/*/qemu-server/*.conf
|
||||
echo
|
||||
echo -e "\n${idsCL[Green]}All VM's have been reconfigured\n${idsCL[LightCyan]}This will require the VM's to be powered off and then turned back on in order to take effect${idsCL[Default]}"
|
||||
FINISH_ACTION
|
||||
;;
|
||||
*) echo;;
|
||||
esac
|
||||
|
||||
[[ "$answer" =~ ^[Yy]$ ]] || return
|
||||
|
||||
for guest in "${changes[@]}"; do
|
||||
IFS=$'\x1f' read -r vmid name node template current_cpu <<< "$guest"
|
||||
if qm set "$vmid" --cpu "$cpu_model" &&
|
||||
[[ "$(TAPM_QEMU_CPU_MODEL "$vmid")" == "$cpu_model" ]]; then
|
||||
successes+=("$guest")
|
||||
else
|
||||
failures+=("$guest")
|
||||
fi
|
||||
done
|
||||
|
||||
printf '\nCPU model update summary:\n'
|
||||
printf ' Successful: %d\n' "${#successes[@]}"
|
||||
printf ' Failed: %d\n' "${#failures[@]}"
|
||||
|
||||
if (( ${#failures[@]} > 0 )); then
|
||||
printf '\nFailed VM/template updates:\n'
|
||||
for guest in "${failures[@]}"; do
|
||||
IFS=$'\x1f' read -r vmid name node template current_cpu <<< "$guest"
|
||||
printf ' %s (%s) on %s\n' "$vmid" "${name:-unnamed}" "$node"
|
||||
done
|
||||
echo -e "\n${idsCL[LightRed]}One or more CPU model updates failed.${idsCL[Default]}"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
|
||||
echo -e "\n${idsCL[Green]}The CPU model was updated to ${cpu_model}.${idsCL[Default]}"
|
||||
echo -e "${idsCL[LightCyan]}Running VMs must be fully shut down and started again before the new CPU model takes effect.${idsCL[Default]}"
|
||||
FINISH_ACTION
|
||||
}
|
||||
|
||||
RESTART_SERVICE_GROUP() {
|
||||
@@ -674,26 +1070,86 @@ RESTART_PVE_SERVICES() {
|
||||
pvedaemon pveproxy pvestatd pvescheduler
|
||||
}
|
||||
|
||||
MAINTENANCE_MODE(){
|
||||
HA_NODE_IN_MAINTENANCE() {
|
||||
local node="$1"
|
||||
local ha_status
|
||||
|
||||
ha_status="$(ha-manager status 2>/dev/null)" || return 2
|
||||
grep -F "lrm ${node} " <<< "$ha_status" |
|
||||
grep -q "maintenance mode"
|
||||
}
|
||||
|
||||
WAIT_FOR_HA_MAINTENANCE_STATE() {
|
||||
local node="$1"
|
||||
local expected_state="$2"
|
||||
local attempts="${3:-30}"
|
||||
local attempt=0
|
||||
local active=0
|
||||
local state_result
|
||||
|
||||
while (( attempt < attempts )); do
|
||||
active=0
|
||||
HA_NODE_IN_MAINTENANCE "$node"
|
||||
state_result=$?
|
||||
[[ "$state_result" -eq 0 ]] && active=1
|
||||
if [[ "$state_result" -gt 1 ]]; then
|
||||
sleep 1
|
||||
((attempt++))
|
||||
continue
|
||||
fi
|
||||
if [[ "$expected_state" == "enabled" && "$active" -eq 1 ]] ||
|
||||
[[ "$expected_state" == "disabled" && "$active" -eq 0 ]]; then
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
((attempt++))
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
MAINTENANCE_MODE() {
|
||||
local choice
|
||||
local local_node
|
||||
local maintenance_state
|
||||
local_node="$(hostname -s)"
|
||||
|
||||
if ha-manager status | grep -F "$local_node" | grep -q "maintenance mode"; then
|
||||
HA_NODE_IN_MAINTENANCE "$local_node"
|
||||
maintenance_state=$?
|
||||
if [[ "$maintenance_state" -gt 1 ]]; then
|
||||
echo -e "\n${idsCL[LightRed]}Could not read HA maintenance status for ${local_node}.${idsCL[Default]}"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ "$maintenance_state" -eq 0 ]]; then
|
||||
echo -en "${idsCL[LightCyan]}Take the local host out of maintenance mode (Y/n)?${idsCL[Default]} "
|
||||
else
|
||||
echo -en "${idsCL[LightCyan]}Put the local host into maintenance mode (Y/n)?${idsCL[Default]} "
|
||||
fi
|
||||
read -n 1 choice
|
||||
read -r -n 1 choice
|
||||
case "$choice" in
|
||||
[Nn]) echo;;
|
||||
*) echo
|
||||
if ha-manager status | grep -F "$local_node" | grep -q "maintenance mode"; then
|
||||
ha-manager crm-command node-maintenance disable "$local_node"
|
||||
[Nn]) echo;;
|
||||
*) echo
|
||||
if [[ "$maintenance_state" -eq 0 ]]; then
|
||||
if ! ha-manager crm-command node-maintenance disable "$local_node" ||
|
||||
! WAIT_FOR_HA_MAINTENANCE_STATE "$local_node" disabled; then
|
||||
echo -e "\n${idsCL[LightRed]}Failed to take ${local_node} out of HA maintenance mode.${idsCL[Default]}"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
echo -e "\n${idsCL[Green]}This host will be taken out of maintenance mode${idsCL[Default]}\n"
|
||||
else
|
||||
ha-manager crm-command node-maintenance enable "$local_node"
|
||||
if ! ha-manager crm-command node-maintenance enable "$local_node"; then
|
||||
echo -e "\n${idsCL[LightRed]}Failed to request HA maintenance mode for ${local_node}.${idsCL[Default]}"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
echo -e "\n${idsCL[Green]}This host will be entered into maintenance mode${idsCL[Default]}\n"
|
||||
bash /opt/idssys/ta-proxmenu/inc/evacuate-proxmox-node.sh
|
||||
if ! bash /opt/idssys/ta-proxmenu/inc/evacuate-proxmox-node.sh; then
|
||||
echo -e "\n${idsCL[LightRed]}Evacuation did not complete. ${local_node} remains in HA maintenance mode.${idsCL[Default]}"
|
||||
FINISH_FAILED_ACTION
|
||||
return
|
||||
fi
|
||||
fi
|
||||
FINISH_ACTION
|
||||
;;
|
||||
@@ -991,19 +1447,15 @@ SHOW_ABOUT() {
|
||||
|
||||
HOST_SETUP_MENU() {
|
||||
local -a labels
|
||||
local -a values=(
|
||||
"post_install"
|
||||
"cpu"
|
||||
"virtio"
|
||||
"glances"
|
||||
"omsa"
|
||||
)
|
||||
local -a values
|
||||
|
||||
while true; do
|
||||
labels=("Run ProxMenux post-install configuration")
|
||||
values=("post_install")
|
||||
[ -f /opt/.PROXMENUX_POST_INSTALL ] &&
|
||||
labels[0]="Run ProxMenux post-install configuration (previously run)"
|
||||
labels+=("Detect CPU model for live migrations")
|
||||
values+=("cpu")
|
||||
|
||||
if [ -f "${DLDIR}/${VIRTIO_FILE}" ]; then
|
||||
labels+=("VirtIO drivers (${VIRTIO_FILE} already downloaded)")
|
||||
@@ -1012,14 +1464,19 @@ HOST_SETUP_MENU() {
|
||||
else
|
||||
labels+=("Download current VirtIO drivers")
|
||||
fi
|
||||
values+=("virtio")
|
||||
|
||||
command -v glances >/dev/null 2>&1 &&
|
||||
labels+=("Glances CLI monitor (installed)") ||
|
||||
labels+=("Install Glances CLI monitor")
|
||||
values+=("glances")
|
||||
|
||||
dpkg-query -W -f='${Status}' srvadmin-all 2>/dev/null | grep -q "install ok installed" &&
|
||||
labels+=("Dell OpenManage Server Administrator (installed)") ||
|
||||
labels+=("Install Dell OpenManage Server Administrator")
|
||||
if TAPM_OMSA_SUPPORTED_HARDWARE; then
|
||||
TAPM_PACKAGE_INSTALLED srvadmin-all &&
|
||||
labels+=("Dell OMSA - Legacy Dell Hosts (installed)") ||
|
||||
labels+=("Install Dell OMSA - Legacy Dell Hosts")
|
||||
values+=("omsa")
|
||||
fi
|
||||
|
||||
SELECT_MENU "Host Setup" labels values
|
||||
case "$MENU_SELECTION" in
|
||||
|
||||
Reference in New Issue
Block a user