1
0
mirror of https://github.com/community-scripts/ProxmoxVE.git synced 2025-02-01 23:51:54 +00:00

fix spinner on lxc-ip-tag (#876)

* fix spinner on lxc-ip-tag

* fix indention
This commit is contained in:
CanbiZ 2024-12-17 15:30:51 +01:00 committed by GitHub
parent b18b49ef6f
commit c60b16229b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -7,8 +7,8 @@
# Source: https://github.com/gitsang/lxc-iptag # Source: https://github.com/gitsang/lxc-iptag
function header_info { function header_info {
clear clear
cat <<"EOF" cat <<"EOF"
__ _ ________ ________ ______ __ _ ________ ________ ______
/ / | |/ / ____/ / _/ __ \ /_ __/___ _____ _ / / | |/ / ____/ / _/ __ \ /_ __/___ _____ _
/ / | / / / // /_/ /_____/ / / __ `/ __ `/ / / | / / / // /_/ /_____/ / / __ `/ __ `/
@ -41,7 +41,7 @@ catch_errors() {
# This function is called when an error occurs. It receives the exit code, line number, and command that caused the error, and displays an error message. # This function is called when an error occurs. It receives the exit code, line number, and command that caused the error, and displays an error message.
error_handler() { error_handler() {
if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then kill $SPINNER_PID >/dev/null; fi
printf "\e[?25h" printf "\e[?25h"
local exit_code="$?" local exit_code="$?"
local line_number="$1" local line_number="$1"
@ -50,51 +50,56 @@ error_handler() {
echo -e "\n$error_message\n" echo -e "\n$error_message\n"
} }
# This function displays a spinner.
spinner() { spinner() {
local frames=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏') local frames=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏')
local spin_i=0 local spin_i=0
local interval=0.1 local interval=0.1
printf "\e[?25l" printf "\e[?25l"
local orange="\e[38;5;214m"
while true; do local color="${YWB}"
printf "\r ${orange}%s\e[0m " "${frames[spin_i]}"
spin_i=$(( (spin_i + 1) % ${#frames[@]} )) while true; do
sleep "$interval" printf "\r ${color}%s${CL}" "${frames[spin_i]}"
done spin_i=$(((spin_i + 1) % ${#frames[@]}))
sleep "$interval"
done
} }
# This function displays an informational message with a yellow color. # This function displays an informational message with a yellow color.
msg_info() { msg_info() {
local msg="$1" local msg="$1"
echo -ne " ${HOLD} ${YW}${msg} " echo -ne "${TAB}${YW}${HOLD}${msg}${HOLD}"
spinner & spinner &
SPINNER_PID=$! SPINNER_PID=$!
} }
# This function displays a success message with a green color. # This function displays a success message with a green color.
msg_ok() { msg_ok() {
if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then kill $SPINNER_PID >/dev/null; fi
printf "\e[?25h" printf "\e[?25h"
local msg="$1" local msg="$1"
echo -e "${BFR}${CM} ${GN}${msg}${CL}" echo -e "${BFR}${CM}${GN}${msg}${CL}"
} }
# This function displays a error message with a red color. # This function displays a error message with a red color.
msg_error() { msg_error() {
if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then kill $SPINNER_PID >/dev/null; fi
printf "\e[?25h" printf "\e[?25h"
local msg="$1" local msg="$1"
echo -e "${BFR}${CROSS} ${RD}${msg}${CL}" echo -e "${BFR}${CROSS}${RD}${msg}${CL}"
} }
while true; do while true; do
read -p "This will install ${APP} on ${hostname}. Proceed? (y/n): " yn read -p "This will install ${APP} on ${hostname}. Proceed? (y/n): " yn
case $yn in case $yn in
[Yy]*) break ;; [Yy]*) break ;;
[Nn]*) msg_info "Installation cancelled."; exit ;; [Nn]*)
*) msg_info "Please answer yes or no." ;; msg_error "Installation cancelled."
esac exit
;;
*) msg_error "Please answer yes or no." ;;
esac
done done
if ! pveversion | grep -Eq "pve-manager/8.[0-3]"; then if ! pveversion | grep -Eq "pve-manager/8.[0-3]"; then
@ -118,17 +123,18 @@ msg_ok "Installed Dependencies"
msg_info "Setting up IP-Tag Scripts" msg_info "Setting up IP-Tag Scripts"
mkdir -p /opt/lxc-iptag mkdir -p /opt/lxc-iptag
msg_ok "Setup IP-Tag Scripts"
msg_info "Setup Default Config" msg_info "Setup Default Config"
if [[ ! -f /opt/lxc-iptag/iptag.conf ]]; then if [[ ! -f /opt/lxc-iptag/iptag.conf ]]; then
cat <<EOF > /opt/lxc-iptag/iptag.conf cat <<EOF >/opt/lxc-iptag/iptag.conf
# Configuration file for LXC IP tagging # Configuration file for LXC IP tagging
# List of allowed CIDRs # List of allowed CIDRs
CIDR_LIST=( CIDR_LIST=(
192.168.0.0/16 192.168.0.0/16
100.64.0.0/10 100.64.0.0/10
10.0.0.0/8 10.0.0.0/8
) )
# Interval settings (in seconds) # Interval settings (in seconds)
@ -137,14 +143,14 @@ FW_NET_INTERFACE_CHECK_INTERVAL=60
LXC_STATUS_CHECK_INTERVAL=-1 LXC_STATUS_CHECK_INTERVAL=-1
FORCE_UPDATE_INTERVAL=1800 FORCE_UPDATE_INTERVAL=1800
EOF EOF
msg_ok "Setup default config" msg_ok "Setup default config"
else else
msg_ok "Default config already exists" msg_ok "Default config already exists"
fi fi
msg_info "Setup Main Function" msg_info "Setup Main Function"
if [[ ! -f /opt/lxc-iptag/iptag ]]; then if [[ ! -f /opt/lxc-iptag/iptag ]]; then
cat <<'EOF' > /opt/lxc-iptag/iptag cat <<'EOF' >/opt/lxc-iptag/iptag
#!/bin/bash #!/bin/bash
# =============== CONFIGURATION =============== # # =============== CONFIGURATION =============== #
@ -153,177 +159,176 @@ CONFIG_FILE="/opt/lxc-iptag/iptag.conf"
# Load the configuration file if it exists # Load the configuration file if it exists
if [ -f "$CONFIG_FILE" ]; then if [ -f "$CONFIG_FILE" ]; then
# shellcheck source=./lxc-iptag.conf # shellcheck source=./lxc-iptag.conf
source "$CONFIG_FILE" source "$CONFIG_FILE"
fi fi
# Convert IP to integer for comparison # Convert IP to integer for comparison
ip_to_int() { ip_to_int() {
local ip="${1}" local ip="${1}"
local a b c d local a b c d
IFS=. read -r a b c d <<< "${ip}" IFS=. read -r a b c d <<< "${ip}"
echo "$((a << 24 | b << 16 | c << 8 | d))" echo "$((a << 24 | b << 16 | c << 8 | d))"
} }
# Check if IP is in CIDR # Check if IP is in CIDR
ip_in_cidr() { ip_in_cidr() {
local ip="${1}" local ip="${1}"
local cidr="${2}" local cidr="${2}"
ip_int=$(ip_to_int "${ip}") ip_int=$(ip_to_int "${ip}")
netmask_int=$(ip_to_int "$(ipcalc -b "${cidr}" | grep Broadcast | awk '{print $2}')") netmask_int=$(ip_to_int "$(ipcalc -b "${cidr}" | grep Broadcast | awk '{print $2}')")
masked_ip_int=$(( "${ip_int}" & "${netmask_int}" )) masked_ip_int=$(( "${ip_int}" & "${netmask_int}" ))
[[ ${ip_int} -eq ${masked_ip_int} ]] && return 0 || return 1 [[ ${ip_int} -eq ${masked_ip_int} ]] && return 0 || return 1
} }
# Check if IP is in any CIDRs # Check if IP is in any CIDRs
ip_in_cidrs() { ip_in_cidrs() {
local ip="${1}" local ip="${1}"
local cidrs=() local cidrs=()
mapfile -t cidrs < <(echo "${2}" | tr ' ' '\n') mapfile -t cidrs < <(echo "${2}" | tr ' ' '\n')
for cidr in "${cidrs[@]}"; do for cidr in "${cidrs[@]}"; do
ip_in_cidr "${ip}" "${cidr}" && return 0 ip_in_cidr "${ip}" "${cidr}" && return 0
done done
return 1 return 1
} }
# Check if IP is valid # Check if IP is valid
is_valid_ipv4() { is_valid_ipv4() {
local ip=$1 local ip=$1
local regex="^([0-9]{1,3}\.){3}[0-9]{1,3}$" local regex="^([0-9]{1,3}\.){3}[0-9]{1,3}$"
if [[ $ip =~ $regex ]]; then if [[ $ip =~ $regex ]]; then
IFS='.' read -r -a parts <<< "$ip" IFS='.' read -r -a parts <<< "$ip"
for part in "${parts[@]}"; do for part in "${parts[@]}"; do
if ! [[ $part =~ ^[0-9]+$ ]] || ((part < 0 || part > 255)); then if ! [[ $part =~ ^[0-9]+$ ]] || ((part < 0 || part > 255)); then
return 1
fi
done
return 0
else
return 1 return 1
fi fi
done
return 0
else
return 1
fi
} }
lxc_status_changed() { lxc_status_changed() {
current_lxc_status=$(pct list 2>/dev/null) current_lxc_status=$(pct list 2>/dev/null)
if [ "${last_lxc_status}" == "${current_lxc_status}" ]; then if [ "${last_lxc_status}" == "${current_lxc_status}" ]; then
return 1 return 1
else else
last_lxc_status="${current_lxc_status}" last_lxc_status="${current_lxc_status}"
return 0 return 0
fi fi
} }
fw_net_interface_changed() { fw_net_interface_changed() {
current_net_interface=$(ifconfig | grep "^fw") current_net_interface=$(ifconfig | grep "^fw")
if [ "${last_net_interface}" == "${current_net_interface}" ]; then if [ "${last_net_interface}" == "${current_net_interface}" ]; then
return 1 return 1
else else
last_net_interface="${current_net_interface}" last_net_interface="${current_net_interface}"
return 0 return 0
fi fi
} }
# =============== MAIN =============== # # =============== MAIN =============== #
update_lxc_iptags() { update_lxc_iptags() {
vmid_list=$(pct list 2>/dev/null | grep -v VMID | awk '{print $1}') vmid_list=$(pct list 2>/dev/null | grep -v VMID | awk '{print $1}')
for vmid in ${vmid_list}; do for vmid in ${vmid_list}; do
last_tagged_ips=() last_tagged_ips=()
current_valid_ips=() current_valid_ips=()
next_tags=() next_tags=()
# Parse current tags # Parse current tags
mapfile -t current_tags < <(pct config "${vmid}" | grep tags | awk '{print $2}' | sed 's/;/\n/g') mapfile -t current_tags < <(pct config "${vmid}" | grep tags | awk '{print $2}' | sed 's/;/\n/g')
for current_tag in "${current_tags[@]}"; do for current_tag in "${current_tags[@]}"; do
if is_valid_ipv4 "${current_tag}"; then if is_valid_ipv4 "${current_tag}"; then
last_tagged_ips+=("${current_tag}") last_tagged_ips+=("${current_tag}")
continue continue
fi fi
next_tags+=("${current_tag}") next_tags+=("${current_tag}")
done
# Get current IPs
current_ips_full=$(lxc-info -n "${vmid}" -i | awk '{print $2}')
for ip in ${current_ips_full}; do
if is_valid_ipv4 "${ip}" && ip_in_cidrs "${ip}" "${CIDR_LIST[*]}"; then
current_valid_ips+=("${ip}")
next_tags+=("${ip}")
fi
done
# Skip if no ip change
if [[ "$(echo "${last_tagged_ips[@]}" | tr ' ' '\n' | sort -u)" == "$(echo "${current_valid_ips[@]}" | tr ' ' '\n' | sort -u)" ]]; then
echo "Skipping ${vmid} cause ip no changes"
continue
fi
# Set tags
echo "Setting ${vmid} tags from ${current_tags[*]} to ${next_tags[*]}"
pct set "${vmid}" -tags "$(IFS=';'; echo "${next_tags[*]}")"
done done
# Get current IPs
current_ips_full=$(lxc-info -n "${vmid}" -i | awk '{print $2}')
for ip in ${current_ips_full}; do
if is_valid_ipv4 "${ip}" && ip_in_cidrs "${ip}" "${CIDR_LIST[*]}"; then
current_valid_ips+=("${ip}")
next_tags+=("${ip}")
fi
done
# Skip if no ip change
if [[ "$(echo "${last_tagged_ips[@]}" | tr ' ' '\n' | sort -u)" == "$(echo "${current_valid_ips[@]}" | tr ' ' '\n' | sort -u)" ]]; then
echo "Skipping ${vmid} cause ip no changes"
continue
fi
# Set tags
echo "Setting ${vmid} tags from ${current_tags[*]} to ${next_tags[*]}"
pct set "${vmid}" -tags "$(IFS=';'; echo "${next_tags[*]}")"
done
} }
check() { check() {
current_time=$(date +%s) current_time=$(date +%s)
time_since_last_lxc_status_check=$((current_time - last_lxc_status_check_time)) time_since_last_lxc_status_check=$((current_time - last_lxc_status_check_time))
if [[ "${LXC_STATUS_CHECK_INTERVAL}" -gt 0 ]] \ if [[ "${LXC_STATUS_CHECK_INTERVAL}" -gt 0 ]] \
&& [[ "${time_since_last_lxc_status_check}" -ge "${STATUS_CHECK_INTERVAL}" ]]; then && [[ "${time_since_last_lxc_status_check}" -ge "${STATUS_CHECK_INTERVAL}" ]]; then
echo "Checking lxc status..." echo "Checking lxc status..."
last_lxc_status_check_time=${current_time} last_lxc_status_check_time=${current_time}
if lxc_status_changed; then if lxc_status_changed; then
update_lxc_iptags update_lxc_iptags
last_update_time=${current_time} last_update_time=${current_time}
return return
fi
fi fi
fi
time_since_last_fw_net_interface_check=$((current_time - last_fw_net_interface_check_time)) time_since_last_fw_net_interface_check=$((current_time - last_fw_net_interface_check_time))
if [[ "${FW_NET_INTERFACE_CHECK_INTERVAL}" -gt 0 ]] \ if [[ "${FW_NET_INTERFACE_CHECK_INTERVAL}" -gt 0 ]] \
&& [[ "${time_since_last_fw_net_interface_check}" -ge "${FW_NET_INTERFACE_CHECK_INTERVAL}" ]]; then && [[ "${time_since_last_fw_net_interface_check}" -ge "${FW_NET_INTERFACE_CHECK_INTERVAL}" ]]; then
echo "Checking fw net interface..." echo "Checking fw net interface..."
last_fw_net_interface_check_time=${current_time} last_fw_net_interface_check_time=${current_time}
if fw_net_interface_changed; then if fw_net_interface_changed; then
update_lxc_iptags update_lxc_iptags
last_update_time=${current_time} last_update_time=${current_time}
return return
fi
fi fi
fi
time_since_last_update=$((current_time - last_update_time)) time_since_last_update=$((current_time - last_update_time))
if [ ${time_since_last_update} -ge ${FORCE_UPDATE_INTERVAL} ]; then if [ ${time_since_last_update} -ge ${FORCE_UPDATE_INTERVAL} ]; then
echo "Force updating lxc iptags..." echo "Force updating lxc iptags..."
update_lxc_iptags update_lxc_iptags
last_update_time=${current_time} last_update_time=${current_time}
return return
fi fi
} }
# main: Set the IP tags for all LXC containers # main: Set the IP tags for all LXC containers
main() { main() {
while true; do while true; do
check check
sleep "${LOOP_INTERVAL}" sleep "${LOOP_INTERVAL}"
done done
} }
main main
EOF EOF
msg_ok "Setup Main Function" msg_ok "Setup Main Function"
else else
msg_ok "Main Function already exists" msg_ok "Main Function already exists"
fi fi
chmod +x /opt/lxc-iptag/iptag chmod +x /opt/lxc-iptag/iptag
msg_info "Creating Service" msg_info "Creating Service"
if [[ ! -f /lib/systemd/system/iptag.service ]]; then if [[ ! -f /lib/systemd/system/iptag.service ]]; then
echo "Systemd service file not found. Creating it now..." cat <<EOF >/lib/systemd/system/iptag.service
cat <<EOF > /lib/systemd/system/iptag.service
[Unit] [Unit]
Description=LXC IP-Tag service Description=LXC IP-Tag service
After=network.target After=network.target
@ -336,9 +341,9 @@ Restart=always
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
EOF EOF
msg_ok "Created Service" msg_ok "Created Service"
else else
msg_ok "Service already exists." msg_ok "Service already exists."
fi fi
msg_ok "Setup IP-Tag Scripts" msg_ok "Setup IP-Tag Scripts"
@ -347,5 +352,5 @@ msg_info "Starting Service"
systemctl daemon-reload &>/dev/null systemctl daemon-reload &>/dev/null
systemctl enable -q --now iptag.service &>/dev/null systemctl enable -q --now iptag.service &>/dev/null
msg_ok "Started Service" msg_ok "Started Service"
SPINNER_PID=""
echo -e "\n${APP} installation completed successfully! ${CL}\n" echo -e "\n${APP} installation completed successfully! ${CL}\n"