testing & remove some things
This commit is contained in:
parent
436026dc1c
commit
8a875044f0
@ -22,19 +22,19 @@ $STD apt-get install -y \
|
||||
htop \
|
||||
ca-certificates \
|
||||
apt-transport-https \
|
||||
tesseract-ocr \
|
||||
tesseract-ocr-deu \
|
||||
tesseract-ocr-eng \
|
||||
unpaper \
|
||||
unoconv \
|
||||
wkhtmltopdf \
|
||||
ocrmypdf
|
||||
tesseract-ocr
|
||||
#tesseract-ocr-deu \
|
||||
#tesseract-ocr-eng \
|
||||
#unpaper \
|
||||
#unoconv \
|
||||
#wkhtmltopdf \
|
||||
#ocrmypdf
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
|
||||
setup_gs
|
||||
JAVA_VERSION="21" setup_java
|
||||
POSTGRES_VERSION="16" setup_postgres
|
||||
POSTGRES_VERSION="16" setup_postgresql
|
||||
setup_yq
|
||||
|
||||
msg_info "Set up PostgreSQL Database"
|
||||
|
@ -1,277 +0,0 @@
|
||||
# Copyright (c) 2021-2025 tteck
|
||||
# Author: tteck (tteckster)
|
||||
# Co-Author: MickLesk
|
||||
# License: MIT
|
||||
# https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
||||
|
||||
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func)
|
||||
load_functions
|
||||
|
||||
# This function sets color variables for formatting output in the terminal
|
||||
# color() {
|
||||
# # Colors
|
||||
# YW=$(echo "\033[33m")
|
||||
# YWB=$(echo "\033[93m")
|
||||
# BL=$(echo "\033[36m")
|
||||
# RD=$(echo "\033[01;31m")
|
||||
# GN=$(echo "\033[1;92m")
|
||||
|
||||
# # Formatting
|
||||
# CL=$(echo "\033[m")
|
||||
# BFR="\\r\\033[K"
|
||||
# BOLD=$(echo "\033[1m")
|
||||
# TAB=" "
|
||||
|
||||
# # System
|
||||
# RETRY_NUM=10
|
||||
# RETRY_EVERY=3
|
||||
# i=$RETRY_NUM
|
||||
|
||||
# # Icons
|
||||
# CM="${TAB}✔️${TAB}${CL}"
|
||||
# CROSS="${TAB}✖️${TAB}${CL}"
|
||||
# INFO="${TAB}💡${TAB}${CL}"
|
||||
# NETWORK="${TAB}📡${TAB}${CL}"
|
||||
# OS="${TAB}🖥️${TAB}${CL}"
|
||||
# OSVERSION="${TAB}🌟${TAB}${CL}"
|
||||
# HOSTNAME="${TAB}🏠${TAB}${CL}"
|
||||
# GATEWAY="${TAB}🌐${TAB}${CL}"
|
||||
# DEFAULT="${TAB}⚙️${TAB}${CL}"
|
||||
# }
|
||||
|
||||
# Function to set STD mode based on verbosity
|
||||
set_std_mode() {
|
||||
if [ "$VERBOSE" = "yes" ]; then
|
||||
STD=""
|
||||
else
|
||||
STD="silent"
|
||||
fi
|
||||
}
|
||||
|
||||
# Silent execution function
|
||||
silent() {
|
||||
"$@" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# This function enables IPv6 if it's not disabled and sets verbose mode
|
||||
verb_ip6() {
|
||||
set_std_mode # Set STD mode based on VERBOSE
|
||||
|
||||
if [ "$DISABLEIPV6" == "yes" ]; then
|
||||
$STD sysctl -w net.ipv6.conf.all.disable_ipv6=1
|
||||
echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf
|
||||
$STD rc-update add sysctl default
|
||||
fi
|
||||
}
|
||||
|
||||
# This function catches errors and handles them with the error handler function
|
||||
catch_errors() {
|
||||
unset SPINNER_PID
|
||||
set -Eeuo pipefail
|
||||
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
|
||||
}
|
||||
|
||||
# This function handles errors
|
||||
error_handler() {
|
||||
local exit_code="$?"
|
||||
local line_number="$1"
|
||||
local command="$2"
|
||||
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
|
||||
echo -e "\n$error_message\n"
|
||||
[[ -n "${SPINNER_PID:-}" ]] && kill "$SPINNER_PID" &>/dev/null || true
|
||||
}
|
||||
|
||||
# # This function displays an informational message with logging support.
|
||||
# declare -A MSG_INFO_SHOWN
|
||||
# SPINNER_ACTIVE=0
|
||||
# SPINNER_PID=""
|
||||
# SPINNER_MSG=""
|
||||
|
||||
# trap 'stop_spinner' EXIT INT TERM HUP
|
||||
|
||||
# start_spinner() {
|
||||
# local msg="$1"
|
||||
# local frames=(⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏)
|
||||
# local spin_i=0
|
||||
# local interval=0.1
|
||||
|
||||
# SPINNER_MSG="$msg"
|
||||
# printf "\r\e[2K" >&2
|
||||
|
||||
# {
|
||||
# while [[ "$SPINNER_ACTIVE" -eq 1 ]]; do
|
||||
# printf "\r\e[2K%s %b" "${frames[spin_i]}" "${YW}${SPINNER_MSG}${CL}" >&2
|
||||
# spin_i=$(((spin_i + 1) % ${#frames[@]}))
|
||||
# sleep "$interval"
|
||||
# done
|
||||
# } &
|
||||
|
||||
# SPINNER_PID=$!
|
||||
# disown "$SPINNER_PID"
|
||||
# }
|
||||
|
||||
# stop_spinner() {
|
||||
# if [[ ${SPINNER_PID+v} && -n "$SPINNER_PID" ]] && kill -0 "$SPINNER_PID" 2>/dev/null; then
|
||||
# kill "$SPINNER_PID" 2>/dev/null
|
||||
# sleep 0.1
|
||||
# kill -0 "$SPINNER_PID" 2>/dev/null && kill -9 "$SPINNER_PID" 2>/dev/null
|
||||
# wait "$SPINNER_PID" 2>/dev/null || true
|
||||
# fi
|
||||
# SPINNER_ACTIVE=0
|
||||
# unset SPINNER_PID
|
||||
# }
|
||||
|
||||
# spinner_guard() {
|
||||
# if [[ "$SPINNER_ACTIVE" -eq 1 ]] && [[ -n "$SPINNER_PID" ]]; then
|
||||
# kill "$SPINNER_PID" 2>/dev/null
|
||||
# wait "$SPINNER_PID" 2>/dev/null || true
|
||||
# SPINNER_ACTIVE=0
|
||||
# unset SPINNER_PID
|
||||
# fi
|
||||
# }
|
||||
|
||||
# msg_info() {
|
||||
# local msg="$1"
|
||||
# [[ -n "${MSG_INFO_SHOWN["$msg"]+x}" ]] && return
|
||||
# MSG_INFO_SHOWN["$msg"]=1
|
||||
|
||||
# spinner_guard
|
||||
# SPINNER_ACTIVE=1
|
||||
# start_spinner "$msg"
|
||||
# }
|
||||
|
||||
# msg_ok() {
|
||||
# local msg="$1"
|
||||
# stop_spinner
|
||||
# printf "\r\e[2K%s %b\n" "${CM}" "${GN}${msg}${CL}" >&2
|
||||
# unset MSG_INFO_SHOWN["$msg"]
|
||||
# }
|
||||
|
||||
# msg_error() {
|
||||
# stop_spinner
|
||||
# local msg="$1"
|
||||
# printf "\r\e[2K%s %b\n" "${CROSS}" "${RD}${msg}${CL}" >&2
|
||||
# #log_message "ERROR" "$msg"
|
||||
# }
|
||||
|
||||
# This function sets up the Container OS by generating the locale, setting the timezone, and checking the network connection
|
||||
setting_up_container() {
|
||||
msg_info "Setting up Container OS"
|
||||
while [ $i -gt 0 ]; do
|
||||
if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" != "" ]; then
|
||||
break
|
||||
fi
|
||||
echo 1>&2 -en "${CROSS}${RD} No Network! "
|
||||
sleep $RETRY_EVERY
|
||||
i=$((i - 1))
|
||||
done
|
||||
|
||||
if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" = "" ]; then
|
||||
echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}"
|
||||
echo -e "${NETWORK}Check Network Settings"
|
||||
exit 1
|
||||
fi
|
||||
msg_ok "Set up Container OS"
|
||||
msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}"
|
||||
}
|
||||
|
||||
# This function checks the network connection by pinging a known IP address and prompts the user to continue if the internet is not connected
|
||||
network_check() {
|
||||
set +e
|
||||
trap - ERR
|
||||
if ping -c 1 -W 1 1.1.1.1 &>/dev/null || ping -c 1 -W 1 8.8.8.8 &>/dev/null || ping -c 1 -W 1 9.9.9.9 &>/dev/null; then
|
||||
msg_ok "Internet Connected"
|
||||
else
|
||||
msg_error "Internet NOT Connected"
|
||||
read -r -p "Would you like to continue anyway? <y/N> " prompt
|
||||
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
echo -e "${INFO}${RD}Expect Issues Without Internet${CL}"
|
||||
else
|
||||
echo -e "${NETWORK}Check Network Settings"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }')
|
||||
if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi
|
||||
set -e
|
||||
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
|
||||
}
|
||||
|
||||
# This function updates the Container OS by running apt-get update and upgrade
|
||||
update_os() {
|
||||
msg_info "Updating Container OS"
|
||||
$STD apk update
|
||||
$STD apk upgrade
|
||||
msg_ok "Updated Container OS"
|
||||
|
||||
msg_info "Installing core dependencies"
|
||||
$STD apk update
|
||||
$STD apk add newt curl openssh nano mc ncurses
|
||||
msg_ok "Core dependencies installed"
|
||||
}
|
||||
|
||||
# This function modifies the message of the day (motd) and SSH settings
|
||||
motd_ssh() {
|
||||
echo "export TERM='xterm-256color'" >>/root/.bashrc
|
||||
IP=$(ip -4 addr show eth0 | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1)
|
||||
|
||||
if [ -f "/etc/os-release" ]; then
|
||||
OS_NAME=$(grep ^NAME /etc/os-release | cut -d= -f2 | tr -d '"')
|
||||
OS_VERSION=$(grep ^VERSION_ID /etc/os-release | cut -d= -f2 | tr -d '"')
|
||||
else
|
||||
OS_NAME="Alpine Linux"
|
||||
OS_VERSION="Unknown"
|
||||
fi
|
||||
|
||||
PROFILE_FILE="/etc/profile.d/00_lxc-details.sh"
|
||||
echo "echo -e \"\"" >"$PROFILE_FILE"
|
||||
echo -e "echo -e \"${BOLD}${YW}${APPLICATION} LXC Container - DEV Repository${CL}\"" >>"$PROFILE_FILE"
|
||||
echo -e "echo -e \"${RD}WARNING: This is a DEVELOPMENT version (ProxmoxVED). Do NOT use in production!${CL}\"" >>"$PROFILE_FILE"
|
||||
echo -e "echo -e \"${YW} OS: ${GN}${OS_NAME} - Version: ${OS_VERSION}${CL}\"" >>"$PROFILE_FILE"
|
||||
echo -e "echo -e \"${YW} Hostname: ${GN}\$(hostname)${CL}\"" >>"$PROFILE_FILE"
|
||||
echo -e "echo -e \"${YW} IP Address: ${GN}${IP}${CL}\"" >>"$PROFILE_FILE"
|
||||
echo -e "echo -e \"${YW} Repository: ${GN}https://github.com/community-scripts/ProxmoxVED${CL}\"" >>"$PROFILE_FILE"
|
||||
echo "echo \"\"" >>"$PROFILE_FILE"
|
||||
|
||||
if [[ "${SSH_ROOT}" == "yes" ]]; then
|
||||
$STD rc-update add sshd
|
||||
sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config
|
||||
$STD /etc/init.d/sshd start
|
||||
fi
|
||||
}
|
||||
|
||||
# Validate Timezone for some LXC's
|
||||
validate_tz() {
|
||||
[[ -f "/usr/share/zoneinfo/$1" ]]
|
||||
}
|
||||
|
||||
# This function customizes the container and enables passwordless login for the root user
|
||||
customize() {
|
||||
if [[ "$PASSWORD" == "" ]]; then
|
||||
msg_info "Customizing Container"
|
||||
passwd -d root >/dev/null 2>&1
|
||||
|
||||
# Ensure agetty is available
|
||||
apk add --no-cache --force-broken-world util-linux >/dev/null 2>&1
|
||||
|
||||
# Create persistent autologin boot script
|
||||
mkdir -p /etc/local.d
|
||||
cat <<'EOF' >/etc/local.d/autologin.start
|
||||
#!/bin/sh
|
||||
sed -i 's|^tty1::respawn:.*|tty1::respawn:/sbin/agetty --autologin root --noclear tty1 38400 linux|' /etc/inittab
|
||||
kill -HUP 1
|
||||
EOF
|
||||
touch /root/.hushlogin
|
||||
|
||||
chmod +x /etc/local.d/autologin.start
|
||||
rc-update add local >/dev/null 2>&1
|
||||
|
||||
# Apply autologin immediately for current session
|
||||
/etc/local.d/autologin.start
|
||||
|
||||
msg_ok "Customized Container"
|
||||
fi
|
||||
|
||||
echo "bash -c \"\$(curl -fsSL https://github.com/community-scripts/ProxmoxVED/raw/main/ct/${app}.sh)\"" >/usr/bin/update
|
||||
chmod +x /usr/bin/update
|
||||
}
|
@ -1,189 +0,0 @@
|
||||
# Copyright (c) 2021-2025 community-scripts ORG
|
||||
# Author: michelroegl-brunner
|
||||
# License: MIT | https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/LICENSE
|
||||
|
||||
get_error_description() {
|
||||
local exit_code="$1"
|
||||
case "$exit_code" in
|
||||
0) echo " " ;;
|
||||
1) echo "General error: An unspecified error occurred." ;;
|
||||
2) echo "Incorrect shell usage or invalid command arguments." ;;
|
||||
3) echo "Unexecuted function or invalid shell condition." ;;
|
||||
4) echo "Error opening a file or invalid path." ;;
|
||||
5) echo "I/O error: An input/output failure occurred." ;;
|
||||
6) echo "No such device or address." ;;
|
||||
7) echo "Insufficient memory or resource exhaustion." ;;
|
||||
8) echo "Non-executable file or invalid file format." ;;
|
||||
9) echo "Failed child process execution." ;;
|
||||
18) echo "Connection to a remote server failed." ;;
|
||||
22) echo "Invalid argument or faulty network connection." ;;
|
||||
28) echo "No space left on device." ;;
|
||||
35) echo "Timeout while establishing a connection." ;;
|
||||
56) echo "Faulty TLS connection." ;;
|
||||
60) echo "SSL certificate error." ;;
|
||||
100) echo "LXC install error: Unexpected error in create_lxc.sh." ;;
|
||||
101) echo "LXC install error: No network connection detected." ;;
|
||||
200) echo "LXC creation failed." ;;
|
||||
201) echo "LXC error: Invalid Storage class." ;;
|
||||
202) echo "User aborted menu in create_lxc.sh." ;;
|
||||
203) echo "CTID not set in create_lxc.sh." ;;
|
||||
204) echo "PCT_OSTYPE not set in create_lxc.sh." ;;
|
||||
205) echo "CTID cannot be less than 100 in create_lxc.sh." ;;
|
||||
206) echo "CTID already in use in create_lxc.sh." ;;
|
||||
207) echo "Template not found in create_lxc.sh." ;;
|
||||
208) echo "Error downloading template in create_lxc.sh." ;;
|
||||
209) echo "Container creation failed, but template is intact in create_lxc.sh." ;;
|
||||
125) echo "Docker error: Container could not start." ;;
|
||||
126) echo "Command not executable: Incorrect permissions or missing dependencies." ;;
|
||||
127) echo "Command not found: Incorrect path or missing dependency." ;;
|
||||
128) echo "Invalid exit signal, e.g., incorrect Git command." ;;
|
||||
129) echo "Signal 1 (SIGHUP): Process terminated due to hangup." ;;
|
||||
130) echo "Signal 2 (SIGINT): Manual termination via Ctrl+C." ;;
|
||||
132) echo "Signal 4 (SIGILL): Illegal machine instruction." ;;
|
||||
133) echo "Signal 5 (SIGTRAP): Debugging error or invalid breakpoint signal." ;;
|
||||
134) echo "Signal 6 (SIGABRT): Program aborted itself." ;;
|
||||
135) echo "Signal 7 (SIGBUS): Memory error, invalid memory address." ;;
|
||||
137) echo "Signal 9 (SIGKILL): Process forcibly terminated (OOM-killer or 'kill -9')." ;;
|
||||
139) echo "Signal 11 (SIGSEGV): Segmentation fault, possibly due to invalid pointer access." ;;
|
||||
141) echo "Signal 13 (SIGPIPE): Pipe closed unexpectedly." ;;
|
||||
143) echo "Signal 15 (SIGTERM): Process terminated normally." ;;
|
||||
152) echo "Signal 24 (SIGXCPU): CPU time limit exceeded." ;;
|
||||
255) echo "Unknown critical error, often due to missing permissions or broken scripts." ;;
|
||||
*) echo "Unknown error code ($exit_code)." ;;
|
||||
esac
|
||||
}
|
||||
|
||||
post_to_api() {
|
||||
|
||||
if ! command -v curl &>/dev/null; then
|
||||
return
|
||||
fi
|
||||
|
||||
if [ "$DIAGNOSTICS" = "no" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -z "$RANDOM_UUID" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local API_URL="http://api.community-scripts.org/dev/upload"
|
||||
local pve_version="not found"
|
||||
pve_version=$(pveversion | awk -F'[/ ]' '{print $2}')
|
||||
|
||||
JSON_PAYLOAD=$(
|
||||
cat <<EOF
|
||||
{
|
||||
"ct_type": $CT_TYPE,
|
||||
"type":"lxc",
|
||||
"disk_size": $DISK_SIZE,
|
||||
"core_count": $CORE_COUNT,
|
||||
"ram_size": $RAM_SIZE,
|
||||
"os_type": "$var_os",
|
||||
"os_version": "$var_version",
|
||||
"disableip6": "$DISABLEIP6",
|
||||
"nsapp": "$NSAPP",
|
||||
"method": "$METHOD",
|
||||
"pve_version": "$pve_version",
|
||||
"status": "installing",
|
||||
"random_id": "$RANDOM_UUID"
|
||||
}
|
||||
EOF
|
||||
)
|
||||
RESPONSE=$(curl -s -w "%{http_code}" -L -X POST "$API_URL" --post301 --post302 \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$JSON_PAYLOAD") || true
|
||||
}
|
||||
|
||||
post_to_api_vm() {
|
||||
|
||||
if [[ ! -f /usr/local/community-scripts/diagnostics ]]; then
|
||||
return
|
||||
fi
|
||||
DIAGNOSTICS=$(grep -i "^DIAGNOSTICS=" /usr/local/community-scripts/diagnostics | awk -F'=' '{print $2}')
|
||||
if ! command -v curl &>/dev/null; then
|
||||
return
|
||||
fi
|
||||
|
||||
if [ "$DIAGNOSTICS" = "no" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -z "$RANDOM_UUID" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local API_URL="http://api.community-scripts.org/dev/upload"
|
||||
local pve_version="not found"
|
||||
pve_version=$(pveversion | awk -F'[/ ]' '{print $2}')
|
||||
|
||||
DISK_SIZE_API=${DISK_SIZE%G}
|
||||
|
||||
JSON_PAYLOAD=$(
|
||||
cat <<EOF
|
||||
{
|
||||
"ct_type": 2,
|
||||
"type":"vm",
|
||||
"disk_size": $DISK_SIZE_API,
|
||||
"core_count": $CORE_COUNT,
|
||||
"ram_size": $RAM_SIZE,
|
||||
"os_type": "$var_os",
|
||||
"os_version": "$var_version",
|
||||
"disableip6": "",
|
||||
"nsapp": "$NSAPP",
|
||||
"method": "$METHOD",
|
||||
"pve_version": "$pve_version",
|
||||
"status": "installing",
|
||||
"random_id": "$RANDOM_UUID"
|
||||
}
|
||||
EOF
|
||||
)
|
||||
RESPONSE=$(curl -s -w "%{http_code}" -L -X POST "$API_URL" --post301 --post302 \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$JSON_PAYLOAD") || true
|
||||
}
|
||||
|
||||
POST_UPDATE_DONE=false
|
||||
post_update_to_api() {
|
||||
|
||||
if ! command -v curl &>/dev/null; then
|
||||
return
|
||||
fi
|
||||
|
||||
if [ "$POST_UPDATE_DONE" = true ]; then
|
||||
return 0
|
||||
fi
|
||||
exit_code=${2:-1}
|
||||
local API_URL="http://api.community-scripts.org/dev/upload/updatestatus"
|
||||
local status="${1:-failed}"
|
||||
if [[ "$status" == "failed" ]]; then
|
||||
local exit_code="${2:-1}"
|
||||
elif [[ "$status" == "success" ]]; then
|
||||
local exit_code="${2:-0}"
|
||||
fi
|
||||
|
||||
if [[ -z "$exit_code" ]]; then
|
||||
exit_code=1
|
||||
fi
|
||||
|
||||
error=$(get_error_description "$exit_code")
|
||||
|
||||
if [ -z "$error" ]; then
|
||||
error="Unknown error"
|
||||
fi
|
||||
|
||||
JSON_PAYLOAD=$(
|
||||
cat <<EOF
|
||||
{
|
||||
"status": "$status",
|
||||
"error": "$error",
|
||||
"random_id": "$RANDOM_UUID"
|
||||
}
|
||||
EOF
|
||||
)
|
||||
RESPONSE=$(curl -s -w "%{http_code}" -L -X POST "$API_URL" --post301 --post302 \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$JSON_PAYLOAD") || true
|
||||
|
||||
POST_UPDATE_DONE=true
|
||||
}
|
@ -1,139 +0,0 @@
|
||||
# backup.func – Snapshot/Backup-Logik mit Rollback via trap + Rotation + flexible Pfaderkennung
|
||||
|
||||
# Globale Variable (automatisch gesetzt)
|
||||
SNAPSHOT_DIR=""
|
||||
|
||||
create_snapshot() {
|
||||
local app_name=$1
|
||||
local base_dir
|
||||
|
||||
# Autodetect base_dir, bevorzugt /opt/<app>, sonst Arbeitsverzeichnis oder APP_DIR gesetzt vom Script
|
||||
base_dir="${APP_DIR:-/opt/$app_name}"
|
||||
if [[ ! -d "$base_dir" ]]; then
|
||||
msg_error "Cannot determine base directory for $app_name"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local snapshot_base="${base_dir}-snapshot"
|
||||
SNAPSHOT_DIR="${snapshot_base}-$(date +%F_%T | tr ':' '-')"
|
||||
|
||||
msg_info "Creating snapshot for $app_name"
|
||||
|
||||
mkdir -p "$SNAPSHOT_DIR"
|
||||
cp -a "$base_dir" "$SNAPSHOT_DIR/base" || {
|
||||
msg_error "Failed to backup base directory"
|
||||
return 1
|
||||
}
|
||||
|
||||
mkdir -p "$SNAPSHOT_DIR/systemd"
|
||||
cp -a /etc/systemd/system/${app_name}-*.service "$SNAPSHOT_DIR/systemd/" 2>/dev/null || true
|
||||
|
||||
[[ -f "/etc/default/$app_name" ]] && cp "/etc/default/$app_name" "$SNAPSHOT_DIR/"
|
||||
[[ -f "$base_dir/${app_name}_version.txt" ]] && cp "$base_dir/${app_name}_version.txt" "$SNAPSHOT_DIR/"
|
||||
|
||||
rotate_snapshots "$snapshot_base"
|
||||
|
||||
msg_ok "Snapshot created at $SNAPSHOT_DIR"
|
||||
return 0
|
||||
}
|
||||
|
||||
rotate_snapshots() {
|
||||
local snapshot_base=$1
|
||||
local snapshots
|
||||
|
||||
# Sortiert nach Datum absteigend, behalte nur die 3 neuesten
|
||||
mapfile -t snapshots < <(ls -dt ${snapshot_base}-* 2>/dev/null)
|
||||
if ((${#snapshots[@]} > 3)); then
|
||||
for ((i = 3; i < ${#snapshots[@]}; i++)); do
|
||||
rm -rf "${snapshots[$i]}"
|
||||
msg_info "Old snapshot removed: ${snapshots[$i]}"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
rollback_snapshot() {
|
||||
local app_name=$1
|
||||
local base_dir
|
||||
|
||||
base_dir="${APP_DIR:-/opt/$app_name}"
|
||||
if [[ -z "$SNAPSHOT_DIR" || ! -d "$SNAPSHOT_DIR" ]]; then
|
||||
msg_error "No snapshot found. Cannot rollback."
|
||||
return 1
|
||||
fi
|
||||
|
||||
msg_info "Rolling back $app_name from snapshot"
|
||||
|
||||
systemctl stop ${app_name}-* 2>/dev/null || true
|
||||
|
||||
rm -rf "$base_dir"
|
||||
cp -a "$SNAPSHOT_DIR/base" "$base_dir" || {
|
||||
msg_error "Failed to restore base directory"
|
||||
return 1
|
||||
}
|
||||
|
||||
if [[ -d "$SNAPSHOT_DIR/systemd" ]]; then
|
||||
cp "$SNAPSHOT_DIR/systemd/"*.service /etc/systemd/system/ 2>/dev/null || true
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
[[ -f "$SNAPSHOT_DIR/$app_name" ]] && cp "$SNAPSHOT_DIR/$app_name" "/etc/default/$app_name"
|
||||
[[ -f "$SNAPSHOT_DIR/${app_name}_version.txt" ]] && cp "$SNAPSHOT_DIR/${app_name}_version.txt" "$base_dir/"
|
||||
|
||||
systemctl start ${app_name}-* 2>/dev/null || true
|
||||
|
||||
msg_ok "Rollback for $app_name completed"
|
||||
return 0
|
||||
}
|
||||
|
||||
cleanup_snapshot() {
|
||||
if [[ -n "$SNAPSHOT_DIR" && -d "$SNAPSHOT_DIR" ]]; then
|
||||
rm -rf "$SNAPSHOT_DIR"
|
||||
msg_ok "Cleaned up snapshot at $SNAPSHOT_DIR"
|
||||
fi
|
||||
}
|
||||
|
||||
handle_failure() {
|
||||
local app_name=$1
|
||||
local line=$2
|
||||
msg_error "Update failed at line $line. Rolling back..."
|
||||
rollback_snapshot "$app_name"
|
||||
exit 1
|
||||
}
|
||||
|
||||
safe_run_update_script() {
|
||||
local app_name="${APP:-paperless}"
|
||||
|
||||
if ! create_snapshot "$app_name"; then
|
||||
msg_error "Snapshot creation failed. Aborting update."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
trap 'handle_failure "$app_name" $LINENO' ERR
|
||||
set -eE
|
||||
|
||||
update_script
|
||||
|
||||
cleanup_snapshot
|
||||
}
|
||||
|
||||
wrap_update_script_with_snapshot() {
|
||||
local original_func
|
||||
original_func=$(declare -f update_script) || return 1
|
||||
|
||||
eval "
|
||||
original_update_script() {
|
||||
${original_func#*\{}
|
||||
}
|
||||
update_script() {
|
||||
local app_name=\"\${APP:-paperless}\"
|
||||
if ! create_snapshot \"\$app_name\"; then
|
||||
msg_error \"Snapshot creation failed. Aborting update.\"
|
||||
exit 1
|
||||
fi
|
||||
trap 'handle_failure \"\$app_name\" \$LINENO' ERR
|
||||
set -eE
|
||||
original_update_script
|
||||
cleanup_snapshot
|
||||
}
|
||||
"
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,220 +0,0 @@
|
||||
# Copyright (c) 2021-2025 community-scripts ORG
|
||||
# Author: michelroegl-brunner
|
||||
# License: MIT | https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/LICENSE
|
||||
|
||||
color() {
|
||||
# Colors
|
||||
YW=$(echo "\033[33m")
|
||||
YWB=$(echo "\033[93m")
|
||||
BL=$(echo "\033[36m")
|
||||
RD=$(echo "\033[01;31m")
|
||||
BGN=$(echo "\033[4;92m")
|
||||
GN=$(echo "\033[1;92m")
|
||||
DGN=$(echo "\033[32m")
|
||||
|
||||
# Formatting
|
||||
CL=$(echo "\033[m")
|
||||
BOLD=$(echo "\033[1m")
|
||||
HOLD=" "
|
||||
TAB=" "
|
||||
|
||||
# Icons
|
||||
CM="${TAB}✔️${TAB}"
|
||||
CROSS="${TAB}✖️${TAB}${CL}"
|
||||
INFO="${TAB}💡${TAB}${CL}"
|
||||
OS="${TAB}🖥️${TAB}${CL}"
|
||||
OSVERSION="${TAB}🌟${TAB}${CL}"
|
||||
CONTAINERTYPE="${TAB}📦${TAB}${CL}"
|
||||
DISKSIZE="${TAB}💾${TAB}${CL}"
|
||||
CPUCORE="${TAB}🧠${TAB}${CL}"
|
||||
RAMSIZE="${TAB}🛠️${TAB}${CL}"
|
||||
SEARCH="${TAB}🔍${TAB}${CL}"
|
||||
VERBOSE_CROPPED="🔍${TAB}"
|
||||
VERIFYPW="${TAB}🔐${TAB}${CL}"
|
||||
CONTAINERID="${TAB}🆔${TAB}${CL}"
|
||||
HOSTNAME="${TAB}🏠${TAB}${CL}"
|
||||
BRIDGE="${TAB}🌉${TAB}${CL}"
|
||||
NETWORK="${TAB}📡${TAB}${CL}"
|
||||
GATEWAY="${TAB}🌐${TAB}${CL}"
|
||||
DISABLEIPV6="${TAB}🚫${TAB}${CL}"
|
||||
DEFAULT="${TAB}⚙️${TAB}${CL}"
|
||||
MACADDRESS="${TAB}🔗${TAB}${CL}"
|
||||
VLANTAG="${TAB}🏷️${TAB}${CL}"
|
||||
ROOTSSH="${TAB}🔑${TAB}${CL}"
|
||||
CREATING="${TAB}🚀${TAB}${CL}"
|
||||
ADVANCED="${TAB}🧩${TAB}${CL}"
|
||||
FUSE="${TAB}🔧${TAB}${CL}"
|
||||
}
|
||||
|
||||
declare -A MSG_INFO_SHOWN
|
||||
SPINNER_ACTIVE=0
|
||||
SPINNER_PID=""
|
||||
SPINNER_MSG=""
|
||||
|
||||
start_spinner() {
|
||||
local msg="$1"
|
||||
local frames=(⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏)
|
||||
local spin_i=0
|
||||
local interval=0.1
|
||||
|
||||
SPINNER_MSG="$msg"
|
||||
printf "\r\e[2K" >&2
|
||||
|
||||
{
|
||||
while [[ "$SPINNER_ACTIVE" -eq 1 ]]; do
|
||||
printf "\r\e[2K%s %b" "${frames[spin_i]}" "${YW}${SPINNER_MSG}${CL}" >&2
|
||||
spin_i=$(((spin_i + 1) % ${#frames[@]}))
|
||||
sleep "$interval"
|
||||
done
|
||||
} &
|
||||
|
||||
SPINNER_PID=$!
|
||||
disown "$SPINNER_PID"
|
||||
}
|
||||
|
||||
stop_spinner() {
|
||||
if [[ ${SPINNER_PID+v} && -n "$SPINNER_PID" ]] && kill -0 "$SPINNER_PID" 2>/dev/null; then
|
||||
kill "$SPINNER_PID" 2>/dev/null
|
||||
sleep 0.1
|
||||
kill -0 "$SPINNER_PID" 2>/dev/null && kill -9 "$SPINNER_PID" 2>/dev/null
|
||||
wait "$SPINNER_PID" 2>/dev/null || true
|
||||
fi
|
||||
SPINNER_ACTIVE=0
|
||||
unset SPINNER_PID
|
||||
}
|
||||
|
||||
spinner_guard() {
|
||||
if [[ "$SPINNER_ACTIVE" -eq 1 ]] && [[ -n "$SPINNER_PID" ]]; then
|
||||
kill "$SPINNER_PID" 2>/dev/null
|
||||
wait "$SPINNER_PID" 2>/dev/null || true
|
||||
SPINNER_ACTIVE=0
|
||||
unset SPINNER_PID
|
||||
fi
|
||||
}
|
||||
|
||||
log_message() {
|
||||
local level="$1"
|
||||
local message="$2"
|
||||
local timestamp
|
||||
local logdate
|
||||
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
logdate=$(date '+%Y-%m-%d')
|
||||
|
||||
LOGDIR="/usr/local/community-scripts/logs"
|
||||
mkdir -p "$LOGDIR"
|
||||
|
||||
LOGFILE="${LOGDIR}/${logdate}_${NSAPP}.log"
|
||||
echo "$timestamp - $level: $message" >>"$LOGFILE"
|
||||
}
|
||||
|
||||
msg_info() {
|
||||
local msg="$1"
|
||||
if [ "${SPINNER_ACTIVE:-0}" -eq 1 ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
SPINNER_ACTIVE=1
|
||||
start_spinner "$msg"
|
||||
}
|
||||
|
||||
msg_ok() {
|
||||
if [ -n "${SPINNER_PID:-}" ] && ps -p "$SPINNER_PID" >/dev/null 2>&1; then
|
||||
kill "$SPINNER_PID" >/dev/null 2>&1
|
||||
wait "$SPINNER_PID" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
local msg="$1"
|
||||
printf "\r\e[2K${CM}${GN}%b${CL}\n" "$msg" >&2
|
||||
unset SPINNER_PID
|
||||
SPINNER_ACTIVE=0
|
||||
|
||||
log_message "OK" "$msg"
|
||||
}
|
||||
|
||||
msg_error() {
|
||||
if [ -n "${SPINNER_PID:-}" ] && ps -p "$SPINNER_PID" >/dev/null 2>&1; then
|
||||
kill "$SPINNER_PID" >/dev/null 2>&1
|
||||
wait "$SPINNER_PID" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
local msg="$1"
|
||||
printf "\r\e[2K${CROSS}${RD}%b${CL}\n" "$msg" >&2
|
||||
unset SPINNER_PID
|
||||
SPINNER_ACTIVE=0
|
||||
log_message "ERROR" "$msg"
|
||||
}
|
||||
|
||||
shell_check() {
|
||||
if [[ "$(basename "$SHELL")" != "bash" ]]; then
|
||||
clear
|
||||
msg_error "Your default shell is currently not set to Bash. To use these scripts, please switch to the Bash shell."
|
||||
echo -e "\nExiting..."
|
||||
sleep 2
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
root_check() {
|
||||
if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then
|
||||
clear
|
||||
msg_error "Please run this script as root."
|
||||
echo -e "\nExiting..."
|
||||
sleep 2
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
pve_check() {
|
||||
if ! pveversion | grep -Eq "pve-manager/8\.[1-9](\.[0-9]+)*"; then
|
||||
msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported"
|
||||
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
|
||||
echo -e "Exiting..."
|
||||
sleep 2
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
arch_check() {
|
||||
if [ "$(dpkg --print-architecture)" != "amd64" ]; then
|
||||
echo -e "\n ${INFO}${YWB}This script will not work with PiMox! \n"
|
||||
echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n"
|
||||
echo -e "Exiting..."
|
||||
sleep 2
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
ssh_check() {
|
||||
if command -v pveversion >/dev/null 2>&1; then
|
||||
if [ -n "${SSH_CLIENT:+x}" ]; then
|
||||
if whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then
|
||||
echo "you've been warned"
|
||||
else
|
||||
clear
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
exit-script() {
|
||||
clear
|
||||
echo -e "\n${CROSS}${RD}User exited script${CL}\n"
|
||||
exit
|
||||
}
|
||||
|
||||
set_std_mode() {
|
||||
if [ "$VERB" = "yes" ]; then
|
||||
STD=""
|
||||
else
|
||||
STD="silent"
|
||||
fi
|
||||
}
|
||||
|
||||
silent() {
|
||||
if [ "$VERB" = "no" ]; then
|
||||
"$@" >>"$LOGFILE" 2>&1
|
||||
else
|
||||
"$@" 2>&1 | tee -a "$LOGFILE"
|
||||
fi
|
||||
}
|
@ -1,850 +0,0 @@
|
||||
|
||||
# dialog_input() {
|
||||
# local title="$1"
|
||||
# local prompt="$2"
|
||||
# local default="$3"
|
||||
# local result
|
||||
# apt-get install -y dialog
|
||||
# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "$title" \
|
||||
# --extra-button --extra-label "Back" \
|
||||
# --ok-label "Next" --cancel-label "Exit" \
|
||||
# --inputbox "$prompt" 10 58 "$default" 2>&1 >/dev/tty)
|
||||
|
||||
# local exitcode=$?
|
||||
|
||||
# case $exitcode in
|
||||
# 0)
|
||||
# REPLY_RESULT="$result"
|
||||
# return 0
|
||||
# ;; # OK
|
||||
# 3) return 2 ;; # Back
|
||||
# *) return 1 ;; # Cancel/Exit
|
||||
# esac
|
||||
# }
|
||||
|
||||
# advanced_settings() {
|
||||
# local step=1
|
||||
|
||||
# while true; do
|
||||
# case $step in
|
||||
# 1)
|
||||
# show_intro_messages && ((step++))
|
||||
# ;;
|
||||
# 2)
|
||||
# select_distribution
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && ((step++))
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# 3)
|
||||
# select_version
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && ((step++))
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# 4)
|
||||
# select_container_type
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && ((step++))
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# 5)
|
||||
# set_root_password
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && ((step++))
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# 6)
|
||||
# set_container_id
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && ((step++))
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# 7)
|
||||
# set_hostname
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && ((step++))
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# 8)
|
||||
# set_disk_size
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && ((step++))
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# 9)
|
||||
# set_cpu_cores
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && ((step++))
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# 10)
|
||||
# set_ram_size
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && ((step++))
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# 11)
|
||||
# set_bridge
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && ((step++))
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# 12)
|
||||
# set_ip_address
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && ((step++))
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# 13)
|
||||
# set_gateway
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && ((step++))
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# 14)
|
||||
# set_apt_cacher
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && ((step++))
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# 15)
|
||||
# toggle_ipv6
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && ((step++))
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# 16)
|
||||
# set_mtu
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && ((step++))
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# 17)
|
||||
# set_dns_search_domain
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && ((step++))
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# 18)
|
||||
# set_dns_server
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && ((step++))
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# 19)
|
||||
# set_mac_address
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && ((step++))
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# 20)
|
||||
# set_vlan
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && ((step++))
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# 21)
|
||||
# set_tags
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && ((step++))
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# 22)
|
||||
# set_ssh_access
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && ((step++))
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# 23)
|
||||
# set_fuse
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && ((step++))
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# 24)
|
||||
# set_verbose
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && ((step++))
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# 25)
|
||||
# confirm_creation
|
||||
# result=$?
|
||||
# [[ $result -eq 0 ]] && break
|
||||
# [[ $result -eq 2 && $step -gt 1 ]] && ((step--))
|
||||
# [[ $result -eq 1 ]] && return
|
||||
# ;;
|
||||
# esac
|
||||
# done
|
||||
# }
|
||||
|
||||
# show_intro_messages() {
|
||||
# dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "Instructional Tip" \
|
||||
# --msgbox "To make a selection, use the Spacebar." 8 58 || return 1
|
||||
|
||||
# dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "Default distribution for $APP" \
|
||||
# --msgbox "Default is: ${var_os} ${var_version}\n\nIf the default Linux distribution is not adhered to, script support will be discontinued." 10 58 || return 1
|
||||
# return 0
|
||||
# }
|
||||
|
||||
# select_distribution() {
|
||||
# [[ "$var_os" == "alpine" ]] && return 0
|
||||
|
||||
# local default result exitcode
|
||||
# default="${var_os:-debian}"
|
||||
# var_os=""
|
||||
|
||||
# local debian_flag ubuntu_flag
|
||||
# [[ "$default" == "debian" ]] && debian_flag="on" || debian_flag="off"
|
||||
# [[ "$default" == "ubuntu" ]] && ubuntu_flag="on" || ubuntu_flag="off"
|
||||
|
||||
# while [[ -z "$var_os" ]]; do
|
||||
# exec 3>&1
|
||||
# result=$(dialog --clear \
|
||||
# --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "DISTRIBUTION" \
|
||||
# --radiolist "Choose Distribution:" 15 60 4 \
|
||||
# "debian" "" "$debian_flag" \
|
||||
# "ubuntu" "" "$ubuntu_flag" \
|
||||
# --ok-label "Next" \
|
||||
# --cancel-label "Exit" \
|
||||
# --extra-button \
|
||||
# --extra-label "Back" \
|
||||
# 2>&1 1>&3)
|
||||
# exitcode=$?
|
||||
# exec 3>&-
|
||||
|
||||
# case "$exitcode" in
|
||||
# 0)
|
||||
# if [[ "$result" =~ ^(debian|ubuntu)$ ]]; then
|
||||
# var_os="$result"
|
||||
# printf "%bOperating System: %b%s%b\n" "$OS$BOLD$DGN" "$BGN" "$var_os" "$CL"
|
||||
# return 0
|
||||
# else
|
||||
# printf "[DEBUG] No valid selection made (result='%s'), repeating...\n" "$result"
|
||||
# fi
|
||||
# ;;
|
||||
# 3)
|
||||
# return 2
|
||||
# ;;
|
||||
# 1 | 255)
|
||||
# return 1
|
||||
# ;;
|
||||
# *)
|
||||
# printf "[DEBUG] Unexpected exit code: %s\n" "$exitcode" >&2
|
||||
# return 1
|
||||
# ;;
|
||||
# esac
|
||||
# done
|
||||
# }
|
||||
|
||||
# select_version() {
|
||||
# local default="${var_version}"
|
||||
# var_version=""
|
||||
# local list result exitcode
|
||||
|
||||
# if [[ "$var_os" == "debian" ]]; then
|
||||
# case "$default" in
|
||||
# 11) list=("11" "Bullseye" on "12" "Bookworm" off) ;;
|
||||
# 12) list=("11" "Bullseye" off "12" "Bookworm" on) ;;
|
||||
# *) list=("11" "Bullseye" off "12" "Bookworm" off) ;;
|
||||
# esac
|
||||
# elif [[ "$var_os" == "ubuntu" ]]; then
|
||||
# case "$default" in
|
||||
# 20.04) list=("20.04" "Focal" on "22.04" "Jammy" off "24.04" "Noble" off "24.10" "Oracular" off) ;;
|
||||
# 22.04) list=("20.04" "Focal" off "22.04" "Jammy" on "24.04" "Noble" off "24.10" "Oracular" off) ;;
|
||||
# 24.04) list=("20.04" "Focal" off "22.04" "Jammy" off "24.04" "Noble" on "24.10" "Oracular" off) ;;
|
||||
# 24.10) list=("20.04" "Focal" off "22.04" "Jammy" off "24.04" "Noble" off "24.10" "Oracular" on) ;;
|
||||
# *) list=("20.04" "Focal" off "22.04" "Jammy" off "24.04" "Noble" off "24.10" "Oracular" off) ;;
|
||||
# esac
|
||||
# fi
|
||||
|
||||
# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "VERSION" \
|
||||
# --radiolist "Choose Version:" 15 58 5 \
|
||||
# "${list[@]}" \
|
||||
# --ok-label "Next" \
|
||||
# --cancel-label "Exit" \
|
||||
# --extra-button --extra-label "Back" \
|
||||
# 3>&1 1>&2 2>&3)
|
||||
|
||||
# exitcode=$?
|
||||
|
||||
# case $exitcode in
|
||||
# 0)
|
||||
# var_version="$result"
|
||||
# printf "%bVersion: %b%s%b\n" "$OSVERSION$BOLD$DGN" "$BGN" "$var_version" "$CL"
|
||||
# return 0
|
||||
# ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# }
|
||||
|
||||
# select_container_type() {
|
||||
# local default="${CT_TYPE}"
|
||||
# CT_TYPE=""
|
||||
# local list result exitcode
|
||||
|
||||
# [[ "$default" == "1" ]] && list=("1" "Unprivileged" on "0" "Privileged" off) || list=("1" "Unprivileged" off "0" "Privileged" on)
|
||||
|
||||
# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "CONTAINER TYPE" \
|
||||
# --radiolist "Choose Type:" 10 58 2 "${list[@]}" \
|
||||
# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3)
|
||||
|
||||
# exitcode=$?
|
||||
|
||||
# case $exitcode in
|
||||
# 0)
|
||||
# CT_TYPE="$result"
|
||||
# [[ "$CT_TYPE" == "0" ]] && desc="Privileged" || desc="Unprivileged"
|
||||
# printf "%bContainer Type: %b%s%b\n" "$CONTAINERTYPE$BOLD$DGN" "$BGN" "$desc" "$CL"
|
||||
# return 0
|
||||
# ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# }
|
||||
# set_root_password() {
|
||||
# local pw1 pw2 exitcode
|
||||
|
||||
# while true; do
|
||||
# pw1=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "PASSWORD (leave blank for automatic login)" \
|
||||
# --insecure --passwordbox "\nSet Root Password (needed for root ssh access)" 10 58 \
|
||||
# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3)
|
||||
# exitcode=$?
|
||||
|
||||
# case $exitcode in
|
||||
# 0)
|
||||
# if [[ -z "$pw1" ]]; then
|
||||
# PW1="Automatic Login"
|
||||
# PW=""
|
||||
# printf "%bRoot Password: %b%s%b\n" "$VERIFYPW$BOLD$DGN" "$BGN" "$PW1" "$CL"
|
||||
# return 0
|
||||
# fi
|
||||
# if [[ "$pw1" == *" "* ]]; then
|
||||
# dialog --msgbox "Password cannot contain spaces. Please try again." 8 58
|
||||
# continue
|
||||
# fi
|
||||
# if [[ ${#pw1} -lt 5 ]]; then
|
||||
# dialog --msgbox "Password must be at least 5 characters long. Please try again." 8 58
|
||||
# continue
|
||||
# fi
|
||||
# pw2=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "PASSWORD VERIFICATION" \
|
||||
# --insecure --passwordbox "\nVerify Root Password" 10 58 \
|
||||
# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3)
|
||||
# exitcode=$?
|
||||
# case $exitcode in
|
||||
# 0)
|
||||
# if [[ "$pw1" == "$pw2" ]]; then
|
||||
# PW="-password $pw1"
|
||||
# printf "%bRoot Password: %b********%b\n" "$VERIFYPW$BOLD$DGN" "$BGN" "$CL"
|
||||
# return 0
|
||||
# else
|
||||
# dialog --msgbox "Passwords do not match. Please try again." 8 58
|
||||
# continue
|
||||
# fi
|
||||
# ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# done
|
||||
# }
|
||||
|
||||
# set_container_id() {
|
||||
# local result exitcode
|
||||
# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "CONTAINER ID" \
|
||||
# --inputbox "Set Container ID" 8 58 "$NEXTID" \
|
||||
# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3)
|
||||
# exitcode=$?
|
||||
|
||||
# case $exitcode in
|
||||
# 0)
|
||||
# CT_ID="${result:-$NEXTID}"
|
||||
# printf "%bContainer ID: %b%s%b\n" "$CONTAINERID$BOLD$DGN" "$BGN" "$CT_ID" "$CL"
|
||||
# return 0
|
||||
# ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# }
|
||||
|
||||
# set_hostname() {
|
||||
# local result exitcode
|
||||
# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "HOSTNAME" \
|
||||
# --inputbox "Set Hostname" 8 58 "$NSAPP" \
|
||||
# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3)
|
||||
# exitcode=$?
|
||||
|
||||
# case $exitcode in
|
||||
# 0)
|
||||
# if [[ -z "$result" ]]; then
|
||||
# HN="$NSAPP"
|
||||
# else
|
||||
# HN=$(tr -d ' ' <<<"${result,,}")
|
||||
# fi
|
||||
# printf "%bHostname: %b%s%b\n" "$HOSTNAME$BOLD$DGN" "$BGN" "$HN" "$CL"
|
||||
# return 0
|
||||
# ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# }
|
||||
|
||||
# set_disk_size() {
|
||||
# local result exitcode
|
||||
# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "DISK SIZE" \
|
||||
# --inputbox "Set Disk Size in GB" 8 58 "$var_disk" \
|
||||
# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3)
|
||||
# exitcode=$?
|
||||
|
||||
# case $exitcode in
|
||||
# 0)
|
||||
# if [[ -z "$result" ]]; then
|
||||
# DISK_SIZE="$var_disk"
|
||||
# elif [[ "$result" =~ ^[0-9]+$ ]]; then
|
||||
# DISK_SIZE="$result"
|
||||
# else
|
||||
# dialog --msgbox "Disk size must be an integer!" 8 58
|
||||
# return 2
|
||||
# fi
|
||||
# printf "%bDisk Size: %b%s GB%b\n" "$DISKSIZE$BOLD$DGN" "$BGN" "$DISK_SIZE" "$CL"
|
||||
# return 0
|
||||
# ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# }
|
||||
|
||||
# set_cpu_cores() {
|
||||
# local result exitcode
|
||||
# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "CORE COUNT" \
|
||||
# --inputbox "Allocate CPU Cores" 8 58 "$var_cpu" \
|
||||
# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3)
|
||||
# exitcode=$?
|
||||
|
||||
# case $exitcode in
|
||||
# 0)
|
||||
# CORE_COUNT="${result:-$var_cpu}"
|
||||
# printf "%bCPU Cores: %b%s%b\n" "$CPUCORE$BOLD$DGN" "$BGN" "$CORE_COUNT" "$CL"
|
||||
# return 0
|
||||
# ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# }
|
||||
|
||||
# set_ram_size() {
|
||||
# local result exitcode
|
||||
# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "RAM" \
|
||||
# --inputbox "Allocate RAM in MiB" 8 58 "$var_ram" \
|
||||
# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3)
|
||||
# exitcode=$?
|
||||
|
||||
# case $exitcode in
|
||||
# 0)
|
||||
# RAM_SIZE="${result:-$var_ram}"
|
||||
# printf "%bRAM Size: %b%s MiB%b\n" "$RAMSIZE$BOLD$DGN" "$BGN" "$RAM_SIZE" "$CL"
|
||||
# return 0
|
||||
# ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# }
|
||||
|
||||
# set_bridge() {
|
||||
# local result exitcode
|
||||
# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "BRIDGE" \
|
||||
# --inputbox "Set a Bridge" 8 58 "vmbr0" \
|
||||
# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3)
|
||||
# exitcode=$?
|
||||
|
||||
# case $exitcode in
|
||||
# 0)
|
||||
# BRG="${result:-vmbr0}"
|
||||
# printf "%bBridge: %b%s%b\n" "$BRIDGE$BOLD$DGN" "$BGN" "$BRG" "$CL"
|
||||
# return 0
|
||||
# ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# }
|
||||
|
||||
# set_ip_address() {
|
||||
# local result exitcode
|
||||
# while true; do
|
||||
# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "IP ADDRESS" \
|
||||
# --inputbox "Set a Static IPv4 CIDR Address (/24)" 8 58 "dhcp" \
|
||||
# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3)
|
||||
# exitcode=$?
|
||||
|
||||
# case $exitcode in
|
||||
# 0)
|
||||
# if [[ "$result" == "dhcp" ]]; then
|
||||
# NET="dhcp"
|
||||
# printf "%bIP Address: %b%s%b\n" "$NETWORK$BOLD$DGN" "$BGN" "$NET" "$CL"
|
||||
# return 0
|
||||
# elif [[ "$result" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$ ]]; then
|
||||
# NET="$result"
|
||||
# printf "%bIP Address: %b%s%b\n" "$NETWORK$BOLD$DGN" "$BGN" "$NET" "$CL"
|
||||
# return 0
|
||||
# else
|
||||
# dialog --msgbox "$result is an invalid IPv4 CIDR address. Please enter a valid address or 'dhcp'." 8 58
|
||||
# continue
|
||||
# fi
|
||||
# ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# done
|
||||
# }
|
||||
|
||||
# set_gateway() {
|
||||
# local result exitcode
|
||||
# if [[ "$NET" == "dhcp" ]]; then
|
||||
# GATE=""
|
||||
# printf "%bGateway IP Address: %bDefault%b\n" "$GATEWAY$BOLD$DGN" "$BGN" "$CL"
|
||||
# return 0
|
||||
# fi
|
||||
|
||||
# while true; do
|
||||
# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "Gateway IP" \
|
||||
# --inputbox "Enter gateway IP address" 8 58 \
|
||||
# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3)
|
||||
# exitcode=$?
|
||||
|
||||
# case $exitcode in
|
||||
# 0)
|
||||
# if [[ -z "$result" ]]; then
|
||||
# dialog --msgbox "Gateway IP address cannot be empty" 8 58
|
||||
# continue
|
||||
# elif [[ "$result" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
|
||||
# GATE=",gw=$result"
|
||||
# printf "%bGateway IP Address: %b%s%b\n" "$GATEWAY$BOLD$DGN" "$BGN" "$result" "$CL"
|
||||
# return 0
|
||||
# else
|
||||
# dialog --msgbox "Invalid IP address format" 8 58
|
||||
# fi
|
||||
# ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# done
|
||||
# }
|
||||
|
||||
# set_apt_cacher() {
|
||||
# local result exitcode
|
||||
# if [[ "$var_os" == "alpine" ]]; then
|
||||
# APT_CACHER=""
|
||||
# APT_CACHER_IP=""
|
||||
# return 0
|
||||
# fi
|
||||
|
||||
# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "APT-Cacher IP" \
|
||||
# --inputbox "Set APT-Cacher IP (leave blank for none)" 8 58 \
|
||||
# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3)
|
||||
# exitcode=$?
|
||||
|
||||
# case $exitcode in
|
||||
# 0)
|
||||
# APT_CACHER_IP="$result"
|
||||
# APT_CACHER="${APT_CACHER_IP:+yes}"
|
||||
# printf "%bAPT-Cacher IP Address: %b%s%b\n" "$NETWORK$BOLD$DGN" "$BGN" "${APT_CACHER_IP:-Default}" "$CL"
|
||||
# return 0
|
||||
# ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# }
|
||||
|
||||
# toggle_ipv6() {
|
||||
# dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "IPv6" \
|
||||
# --yesno "Disable IPv6?" 10 58 \
|
||||
# --extra-button --extra-label "Back" --ok-label "Yes" --cancel-label "No"
|
||||
# case $? in
|
||||
# 0) DISABLEIP6="yes" ;;
|
||||
# 1) DISABLEIP6="no" ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# printf "%bDisable IPv6: %b%s%b\n" "$DISABLEIPV6$BOLD$DGN" "$BGN" "$DISABLEIP6" "$CL"
|
||||
# return 0
|
||||
# }
|
||||
# set_mtu() {
|
||||
# local result exitcode
|
||||
# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "MTU SIZE" \
|
||||
# --inputbox "Set Interface MTU Size (leave blank for default [1500])" 8 58 "" \
|
||||
# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3)
|
||||
# exitcode=$?
|
||||
|
||||
# case $exitcode in
|
||||
# 0)
|
||||
# if [[ -z "$result" ]]; then
|
||||
# MTU1="Default"
|
||||
# MTU=""
|
||||
# else
|
||||
# MTU1="$result"
|
||||
# MTU=",mtu=$MTU1"
|
||||
# fi
|
||||
# printf "%bInterface MTU Size: %b%s%b\n" "$DEFAULT$BOLD$DGN" "$BGN" "$MTU1" "$CL"
|
||||
# return 0
|
||||
# ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# }
|
||||
|
||||
# set_dns_search_domain() {
|
||||
# local result exitcode
|
||||
# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "DNS Search Domain" \
|
||||
# --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 "" \
|
||||
# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3)
|
||||
# exitcode=$?
|
||||
|
||||
# case $exitcode in
|
||||
# 0)
|
||||
# if [[ -z "$result" ]]; then
|
||||
# SX="Host"
|
||||
# SD=""
|
||||
# else
|
||||
# SX="$result"
|
||||
# SD="-searchdomain=$result"
|
||||
# fi
|
||||
# printf "%bDNS Search Domain: %b%s%b\n" "$SEARCH$BOLD$DGN" "$BGN" "$SX" "$CL"
|
||||
# return 0
|
||||
# ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# }
|
||||
|
||||
# set_dns_server() {
|
||||
# local result exitcode
|
||||
# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "DNS SERVER IP" \
|
||||
# --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 "" \
|
||||
# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3)
|
||||
# exitcode=$?
|
||||
|
||||
# case $exitcode in
|
||||
# 0)
|
||||
# if [[ -z "$result" ]]; then
|
||||
# NX="Host"
|
||||
# NS=""
|
||||
# else
|
||||
# NX="$result"
|
||||
# NS="-nameserver=$result"
|
||||
# fi
|
||||
# printf "%bDNS Server IP Address: %b%s%b\n" "$NETWORK$BOLD$DGN" "$BGN" "$NX" "$CL"
|
||||
# return 0
|
||||
# ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# }
|
||||
|
||||
# set_mac_address() {
|
||||
# local result exitcode
|
||||
# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "MAC ADDRESS" \
|
||||
# --inputbox "Set a MAC Address (leave blank for generated MAC)" 8 58 "" \
|
||||
# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3)
|
||||
# exitcode=$?
|
||||
|
||||
# case $exitcode in
|
||||
# 0)
|
||||
# if [[ -z "$result" ]]; then
|
||||
# MAC1="Default"
|
||||
# MAC=""
|
||||
# else
|
||||
# MAC1="$result"
|
||||
# MAC=",hwaddr=$MAC1"
|
||||
# fi
|
||||
# printf "%bMAC Address: %b%s%b\n" "$MACADDRESS$BOLD$DGN" "$BGN" "$MAC1" "$CL"
|
||||
# return 0
|
||||
# ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# }
|
||||
|
||||
# set_vlan() {
|
||||
# local result exitcode
|
||||
# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "VLAN" \
|
||||
# --inputbox "Set a VLAN (leave blank for no VLAN)" 8 58 "" \
|
||||
# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3)
|
||||
# exitcode=$?
|
||||
|
||||
# case $exitcode in
|
||||
# 0)
|
||||
# if [[ -z "$result" ]]; then
|
||||
# VLAN1="Default"
|
||||
# VLAN=""
|
||||
# else
|
||||
# VLAN1="$result"
|
||||
# VLAN=",tag=$VLAN1"
|
||||
# fi
|
||||
# printf "%bVlan: %b%s%b\n" "$VLANTAG$BOLD$DGN" "$BGN" "$VLAN1" "$CL"
|
||||
# return 0
|
||||
# ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# }
|
||||
|
||||
# set_tags() {
|
||||
# local result exitcode
|
||||
# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "Advanced Tags" \
|
||||
# --inputbox "Set Custom Tags? [If you remove all, there will be no tags!]" 8 58 "$TAGS" \
|
||||
# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3)
|
||||
# exitcode=$?
|
||||
|
||||
# case $exitcode in
|
||||
# 0)
|
||||
# if [[ -n "$result" ]]; then
|
||||
# ADV_TAGS=$(tr -d '[:space:]' <<<"$result")
|
||||
# TAGS="$ADV_TAGS"
|
||||
# else
|
||||
# TAGS=";"
|
||||
# fi
|
||||
# printf "%bTags: %b%s%b\n" "$NETWORK$BOLD$DGN" "$BGN" "$TAGS" "$CL"
|
||||
# return 0
|
||||
# ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# }
|
||||
|
||||
# set_ssh_access() {
|
||||
# local result exitcode
|
||||
|
||||
# if [[ "$PW" == -password* ]]; then
|
||||
# dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "SSH ACCESS" \
|
||||
# --yesno "Enable Root SSH Access?" 10 58 \
|
||||
# --extra-button --extra-label "Back" --ok-label "Yes" --cancel-label "No"
|
||||
# exitcode=$?
|
||||
# case $exitcode in
|
||||
# 0) SSH="yes" ;;
|
||||
# 1) SSH="no" ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# else
|
||||
# SSH="no"
|
||||
# fi
|
||||
|
||||
# printf "%bRoot SSH Access: %b%s%b\n" "$ROOTSSH$BOLD$DGN" "$BGN" "$SSH" "$CL"
|
||||
|
||||
# if [[ "$SSH" == "yes" ]]; then
|
||||
# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "SSH Key" \
|
||||
# --inputbox "SSH Authorized key for root (leave empty for none)" 8 58 "" \
|
||||
# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3)
|
||||
# exitcode=$?
|
||||
# case $exitcode in
|
||||
# 0)
|
||||
# SSH_AUTHORIZED_KEY="$result"
|
||||
# return 0
|
||||
# ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# else
|
||||
# SSH_AUTHORIZED_KEY=""
|
||||
# return 0
|
||||
# fi
|
||||
# }
|
||||
|
||||
# set_fuse() {
|
||||
# dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "FUSE Support" \
|
||||
# --yesno "Enable FUSE (Filesystem in Userspace) support in the container?" 10 58 \
|
||||
# --extra-button --extra-label "Back" --ok-label "Yes" --cancel-label "No"
|
||||
# case $? in
|
||||
# 0) ENABLE_FUSE="yes" ;;
|
||||
# 1) ENABLE_FUSE="no" ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# printf "%bFUSE (Filesystem in Userspace) Support: %b%s%b\n" "$FUSE$BOLD$DGN" "$BGN" "$ENABLE_FUSE" "$CL"
|
||||
# return 0
|
||||
# }
|
||||
|
||||
# set_verbose() {
|
||||
# dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "VERBOSE MODE" \
|
||||
# --yesno "Enable Verbose Mode?" 10 58 \
|
||||
# --extra-button --extra-label "Back" --ok-label "Yes" --cancel-label "No"
|
||||
# case $? in
|
||||
# 0) VERB="yes" ;;
|
||||
# 1) VERB="no" ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# printf "%bVerbose Mode: %b%s%b\n" "$SEARCH$BOLD$DGN" "$BGN" "$VERB" "$CL"
|
||||
# return 0
|
||||
# }
|
||||
|
||||
# confirm_creation() {
|
||||
# dialog --backtitle "[dev] Proxmox VE Helper Scripts" \
|
||||
# --title "ADVANCED SETTINGS COMPLETE" \
|
||||
# --yesno "Ready to create ${APP} LXC?" 10 58 \
|
||||
# --extra-button --extra-label "Back" --ok-label "Yes" --cancel-label "No"
|
||||
# case $? in
|
||||
# 0)
|
||||
# printf "%bCreating a %s LXC using the above advanced settings%b\n" "$CREATING$BOLD$RD" "$APP" "$CL"
|
||||
# return 0
|
||||
# ;;
|
||||
# 3) return 2 ;;
|
||||
# *) return 1 ;;
|
||||
# esac
|
||||
# }
|
@ -1,281 +0,0 @@
|
||||
# Copyright (c) 2021-2025 tteck
|
||||
# Author: tteck (tteckster)
|
||||
# Co-Author: MickLesk
|
||||
# Co-Author: michelroegl-brunner
|
||||
# License: MIT
|
||||
# https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
||||
|
||||
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func)
|
||||
load_functions
|
||||
|
||||
# color() {
|
||||
# # Colors
|
||||
# YW=$(echo "\033[33m")
|
||||
# YWB=$(echo "\033[93m")
|
||||
# BL=$(echo "\033[36m")
|
||||
# RD=$(echo "\033[01;31m")
|
||||
# GN=$(echo "\033[1;92m")
|
||||
|
||||
# # Formatting
|
||||
# CL=$(echo "\033[m")
|
||||
# BFR="\\r\\033[K"
|
||||
# BOLD=$(echo "\033[1m")
|
||||
# HOLD=" "
|
||||
# TAB=" "
|
||||
|
||||
# # System
|
||||
# RETRY_NUM=10
|
||||
# RETRY_EVERY=3
|
||||
|
||||
# # Icons
|
||||
# CM="${TAB}✔️${TAB}${CL}"
|
||||
# CROSS="${TAB}✖️${TAB}${CL}"
|
||||
# INFO="${TAB}💡${TAB}${CL}"
|
||||
# NETWORK="${TAB}📡${TAB}${CL}"
|
||||
# OS="${TAB}🖥️${TAB}${CL}"
|
||||
# OSVERSION="${TAB}🌟${TAB}${CL}"
|
||||
# HOSTNAME="${TAB}🏠${TAB}${CL}"
|
||||
# GATEWAY="${TAB}🌐${TAB}${CL}"
|
||||
# DEFAULT="${TAB}⚙️${TAB}${CL}"
|
||||
# }
|
||||
|
||||
# Function to set STD mode based on verbosity
|
||||
set_std_mode() {
|
||||
if [ "$VERBOSE" = "yes" ]; then
|
||||
STD=""
|
||||
else
|
||||
STD="silent"
|
||||
fi
|
||||
}
|
||||
|
||||
# Silent execution function
|
||||
silent() {
|
||||
"$@" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# This function enables IPv6 if it's not disabled and sets verbose mode
|
||||
verb_ip6() {
|
||||
set_std_mode # Set STD mode based on VERBOSE
|
||||
|
||||
if [ "$DISABLEIPV6" == "yes" ]; then
|
||||
echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf
|
||||
$STD sysctl -p
|
||||
fi
|
||||
}
|
||||
|
||||
# This function sets error handling options and defines the error_handler function to handle errors
|
||||
catch_errors() {
|
||||
set -Eeuo pipefail
|
||||
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
|
||||
}
|
||||
|
||||
# This function handles errors
|
||||
error_handler() {
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func)
|
||||
if [ -n "$SPINNER_PID" ] && ps -p "$SPINNER_PID" >/dev/null; then kill "$SPINNER_PID" >/dev/null; fi
|
||||
printf "\e[?25h"
|
||||
local exit_code="$?"
|
||||
local line_number="$1"
|
||||
local command="$2"
|
||||
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
|
||||
echo -e "\n$error_message"
|
||||
[[ -n "${SPINNER_PID:-}" ]] && kill "$SPINNER_PID" &>/dev/null || true
|
||||
|
||||
if [[ "$line_number" -eq 50 ]]; then
|
||||
echo -e "The silent function has suppressed the error, run the script with verbose mode enabled, which will provide more detailed output.\n"
|
||||
post_update_to_api "failed" "No error message, script ran in silent mode"
|
||||
else
|
||||
post_update_to_api "failed" "${command}"
|
||||
fi
|
||||
}
|
||||
|
||||
# # This function displays a spinner.
|
||||
# spinner() {
|
||||
# local frames=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏')
|
||||
# local spin_i=0
|
||||
# local interval=0.1
|
||||
# printf "\e[?25l"
|
||||
|
||||
# local color="${YWB}"
|
||||
|
||||
# while true; do
|
||||
# printf "\r ${color}%s${CL}" "${frames[spin_i]}"
|
||||
# spin_i=$(((spin_i + 1) % ${#frames[@]}))
|
||||
# sleep "$interval"
|
||||
# done
|
||||
# }
|
||||
|
||||
# # This function displays an informational message with a yellow color.
|
||||
# msg_info() {
|
||||
# local msg="$1"
|
||||
# echo -ne "${TAB}${YW}${HOLD}${msg}${HOLD}"
|
||||
# spinner &
|
||||
# SPINNER_PID=$!
|
||||
# }
|
||||
|
||||
# # This function displays a success message with a green color.
|
||||
# msg_ok() {
|
||||
# if [ -n "$SPINNER_PID" ] && ps -p "$SPINNER_PID" >/dev/null; then kill "$SPINNER_PID" >/dev/null; fi
|
||||
# printf "\e[?25h"
|
||||
# local msg="$1"
|
||||
# echo -e "${BFR}${CM}${GN}${msg}${CL}"
|
||||
# }
|
||||
|
||||
# # This function displays a error message with a red color.
|
||||
# msg_error() {
|
||||
# if [ -n "$SPINNER_PID" ] && ps -p "$SPINNER_PID" >/dev/null; then kill "$SPINNER_PID" >/dev/null; fi
|
||||
# printf "\e[?25h"
|
||||
# local msg="$1"
|
||||
# echo -e "${BFR}${CROSS}${RD}${msg}${CL}"
|
||||
# }
|
||||
|
||||
# This function sets up the Container OS by generating the locale, setting the timezone, and checking the network connection
|
||||
setting_up_container() {
|
||||
msg_info "Setting up Container OS"
|
||||
sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen
|
||||
locale_line=$(grep -v '^#' /etc/locale.gen | grep -E '^[a-zA-Z]' | awk '{print $1}' | head -n 1)
|
||||
echo "LANG=${locale_line}" >/etc/default/locale
|
||||
locale-gen >/dev/null
|
||||
export LANG=${locale_line}
|
||||
echo $tz >/etc/timezone
|
||||
ln -sf /usr/share/zoneinfo/$tz /etc/localtime
|
||||
for ((i = RETRY_NUM; i > 0; i--)); do
|
||||
if [ "$(hostname -I)" != "" ]; then
|
||||
break
|
||||
fi
|
||||
echo 1>&2 -en "${CROSS}${RD} No Network! "
|
||||
sleep $RETRY_EVERY
|
||||
done
|
||||
if [ "$(hostname -I)" = "" ]; then
|
||||
echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}"
|
||||
echo -e "${NETWORK}Check Network Settings"
|
||||
exit 1
|
||||
fi
|
||||
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
|
||||
systemctl disable -q --now systemd-networkd-wait-online.service
|
||||
msg_ok "Set up Container OS"
|
||||
msg_ok "Network Connected: ${BL}$(hostname -I)"
|
||||
}
|
||||
|
||||
# This function checks the network connection by pinging a known IP address and prompts the user to continue if the internet is not connected
|
||||
network_check() {
|
||||
set +e
|
||||
trap - ERR
|
||||
ipv4_connected=false
|
||||
ipv6_connected=false
|
||||
sleep 1
|
||||
# Check IPv4 connectivity to Google, Cloudflare & Quad9 DNS servers.
|
||||
if ping -c 1 -W 1 1.1.1.1 &>/dev/null || ping -c 1 -W 1 8.8.8.8 &>/dev/null || ping -c 1 -W 1 9.9.9.9 &>/dev/null; then
|
||||
msg_ok "IPv4 Internet Connected"
|
||||
ipv4_connected=true
|
||||
else
|
||||
msg_error "IPv4 Internet Not Connected"
|
||||
fi
|
||||
|
||||
# Check IPv6 connectivity to Google, Cloudflare & Quad9 DNS servers.
|
||||
if ping6 -c 1 -W 1 2606:4700:4700::1111 &>/dev/null || ping6 -c 1 -W 1 2001:4860:4860::8888 &>/dev/null || ping6 -c 1 -W 1 2620:fe::fe &>/dev/null; then
|
||||
msg_ok "IPv6 Internet Connected"
|
||||
ipv6_connected=true
|
||||
else
|
||||
msg_error "IPv6 Internet Not Connected"
|
||||
fi
|
||||
|
||||
# If both IPv4 and IPv6 checks fail, prompt the user
|
||||
if [[ $ipv4_connected == false && $ipv6_connected == false ]]; then
|
||||
read -r -p "No Internet detected,would you like to continue anyway? <y/N> " prompt
|
||||
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
echo -e "${INFO}${RD}Expect Issues Without Internet${CL}"
|
||||
else
|
||||
echo -e "${NETWORK}Check Network Settings"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }')
|
||||
if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi
|
||||
set -e
|
||||
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
|
||||
}
|
||||
|
||||
# This function updates the Container OS by running apt-get update and upgrade
|
||||
update_os() {
|
||||
msg_info "Updating Container OS"
|
||||
if [[ "$CACHER" == "yes" ]]; then
|
||||
echo "Acquire::http::Proxy-Auto-Detect \"/usr/local/bin/apt-proxy-detect.sh\";" >/etc/apt/apt.conf.d/00aptproxy
|
||||
cat <<EOF >/usr/local/bin/apt-proxy-detect.sh
|
||||
#!/bin/bash
|
||||
if nc -w1 -z "${CACHER_IP}" 3142; then
|
||||
echo -n "http://${CACHER_IP}:3142"
|
||||
else
|
||||
echo -n "DIRECT"
|
||||
fi
|
||||
EOF
|
||||
chmod +x /usr/local/bin/apt-proxy-detect.sh
|
||||
fi
|
||||
$STD apt-get update
|
||||
$STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade
|
||||
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
|
||||
msg_ok "Updated Container OS"
|
||||
|
||||
msg_info "Installing core dependencies"
|
||||
$STD apt-get update
|
||||
$STD apt-get install -y sudo curl mc gnupg2
|
||||
msg_ok "Core dependencies installed"
|
||||
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func)
|
||||
|
||||
}
|
||||
|
||||
# This function modifies the message of the day (motd) and SSH settings
|
||||
motd_ssh() {
|
||||
grep -qxF "export TERM='xterm-256color'" /root/.bashrc || echo "export TERM='xterm-256color'" >>/root/.bashrc
|
||||
|
||||
if [ -f "/etc/os-release" ]; then
|
||||
OS_NAME=$(grep ^NAME /etc/os-release | cut -d= -f2 | tr -d '"')
|
||||
OS_VERSION=$(grep ^VERSION_ID /etc/os-release | cut -d= -f2 | tr -d '"')
|
||||
elif [ -f "/etc/debian_version" ]; then
|
||||
OS_NAME="Debian"
|
||||
OS_VERSION=$(cat /etc/debian_version)
|
||||
fi
|
||||
|
||||
PROFILE_FILE="/etc/profile.d/00_lxc-details.sh"
|
||||
echo "echo -e \"\"" >"$PROFILE_FILE"
|
||||
echo -e "echo -e \"${BOLD}${YW}${APPLICATION} LXC Container - DEV Repository${CL}\"" >>"$PROFILE_FILE"
|
||||
echo -e "echo -e \"${RD}WARNING: This is a DEVELOPMENT version (ProxmoxVED). Do NOT use in production!${CL}\"" >>"$PROFILE_FILE"
|
||||
echo -e "echo -e \"${YW} OS: ${GN}${OS_NAME} - Version: ${OS_VERSION}${CL}\"" >>"$PROFILE_FILE"
|
||||
echo -e "echo -e \"${YW} Hostname: ${GN}\$(hostname)${CL}\"" >>"$PROFILE_FILE"
|
||||
echo -e "echo -e \"${YW} IP Address: ${GN}\$(hostname -I | awk '{print \$1}')${CL}\"" >>"$PROFILE_FILE"
|
||||
echo -e "echo -e \"${YW} Repository: ${GN}https://github.com/community-scripts/ProxmoxVED${CL}\"" >>"$PROFILE_FILE"
|
||||
echo "echo \"\"" >>"$PROFILE_FILE"
|
||||
|
||||
chmod -x /etc/update-motd.d/*
|
||||
|
||||
if [[ "${SSH_ROOT}" == "yes" ]]; then
|
||||
sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config
|
||||
systemctl restart sshd
|
||||
fi
|
||||
}
|
||||
|
||||
# This function customizes the container by modifying the getty service and enabling auto-login for the root user
|
||||
customize() {
|
||||
if [[ "$PASSWORD" == "" ]]; then
|
||||
msg_info "Customizing Container"
|
||||
GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf"
|
||||
mkdir -p $(dirname $GETTY_OVERRIDE)
|
||||
cat <<EOF >$GETTY_OVERRIDE
|
||||
[Service]
|
||||
ExecStart=
|
||||
ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM
|
||||
EOF
|
||||
systemctl daemon-reload
|
||||
systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//')
|
||||
msg_ok "Customized Container"
|
||||
fi
|
||||
echo "bash -c \"\$(curl -fsSL https://github.com/community-scripts/ProxmoxVED/raw/main/ct/${app}.sh)\"" >/usr/bin/update
|
||||
chmod +x /usr/bin/update
|
||||
if [[ -n "${SSH_AUTHORIZED_KEY}" ]]; then
|
||||
mkdir -p /root/.ssh
|
||||
echo "${SSH_AUTHORIZED_KEY}" >/root/.ssh/authorized_keys
|
||||
chmod 700 /root/.ssh
|
||||
chmod 600 /root/.ssh/authorized_keys
|
||||
fi
|
||||
}
|
@ -1,98 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Spinner state
|
||||
declare -A SPINNER_PIDS
|
||||
declare -A SPINNER_MSGS
|
||||
declare -A MSG_SHOWN
|
||||
|
||||
# Color definitions (adjust as needed)
|
||||
RD='\033[0;31m'
|
||||
GN='\033[0;32m'
|
||||
YW='\033[0;33m'
|
||||
CL='\033[0m'
|
||||
CM='✔'
|
||||
CROSS='✘'
|
||||
|
||||
# Trap cleanup
|
||||
trap cleanup_spinners EXIT INT TERM HUP
|
||||
|
||||
# Hash function for message ID
|
||||
msg_hash() {
|
||||
local input="$1"
|
||||
echo -n "$input" | sha1sum | awk '{print $1}'
|
||||
}
|
||||
|
||||
# Start a spinner for a specific message
|
||||
start_spinner_for_msg() {
|
||||
local msg="$1"
|
||||
local id
|
||||
id=$(msg_hash "$msg")
|
||||
|
||||
[[ -n "${MSG_SHOWN["$id"]+x}" ]] && return
|
||||
MSG_SHOWN["$id"]=1
|
||||
SPINNER_MSGS["$id"]="$msg"
|
||||
|
||||
local frames=(⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏)
|
||||
local interval=0.1
|
||||
local spin_i=0
|
||||
|
||||
{
|
||||
while true; do
|
||||
printf "\r\e[2K%s %b" "${frames[spin_i]}" "${YW}${msg}${CL}" >&2
|
||||
spin_i=$(((spin_i + 1) % ${#frames[@]}))
|
||||
sleep "$interval"
|
||||
done
|
||||
} &
|
||||
|
||||
SPINNER_PIDS["$id"]=$!
|
||||
disown "${SPINNER_PIDS["$id"]}"
|
||||
}
|
||||
|
||||
# Stop the spinner for a specific message
|
||||
stop_spinner_for_msg() {
|
||||
local msg="$1"
|
||||
local id
|
||||
id=$(msg_hash "$msg")
|
||||
|
||||
if [[ -n "${SPINNER_PIDS["$id"]+x}" ]] && ps -p "${SPINNER_PIDS["$id"]}" >/dev/null 2>&1; then
|
||||
kill "${SPINNER_PIDS["$id"]}" 2>/dev/null
|
||||
wait "${SPINNER_PIDS["$id"]}" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
unset SPINNER_PIDS["$id"]
|
||||
unset SPINNER_MSGS["$id"]
|
||||
unset MSG_SHOWN["$id"]
|
||||
}
|
||||
|
||||
# Cleanup all active spinners
|
||||
cleanup_spinners() {
|
||||
for id in "${!SPINNER_PIDS[@]}"; do
|
||||
if ps -p "${SPINNER_PIDS[$id]}" >/dev/null 2>&1; then
|
||||
kill "${SPINNER_PIDS[$id]}" 2>/dev/null
|
||||
wait "${SPINNER_PIDS[$id]}" 2>/dev/null || true
|
||||
fi
|
||||
unset SPINNER_PIDS["$id"]
|
||||
unset SPINNER_MSGS["$id"]
|
||||
unset MSG_SHOWN["$id"]
|
||||
done
|
||||
}
|
||||
|
||||
# Show info message with spinner
|
||||
msg_info() {
|
||||
local msg="$1"
|
||||
start_spinner_for_msg "$msg"
|
||||
}
|
||||
|
||||
# End spinner and show success message
|
||||
msg_ok() {
|
||||
local msg="$1"
|
||||
stop_spinner_for_msg "$msg"
|
||||
printf "\r\e[2K%s %b\n" "${CM}" "${GN}${msg}${CL}" >&2
|
||||
}
|
||||
|
||||
# End spinner and show error message
|
||||
msg_error() {
|
||||
local msg="$1"
|
||||
stop_spinner_for_msg "$msg"
|
||||
printf "\r\e[2K%s %b\n" "${CROSS}" "${RD}${msg}${CL}" >&2
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user