From c60b16229b40477eae69e645c0389d638520af4e Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 17 Dec 2024 15:30:51 +0100 Subject: [PATCH] fix spinner on lxc-ip-tag (#876) * fix spinner on lxc-ip-tag * fix indention --- misc/add-lxc-iptag.sh | 309 +++++++++++++++++++++--------------------- 1 file changed, 157 insertions(+), 152 deletions(-) diff --git a/misc/add-lxc-iptag.sh b/misc/add-lxc-iptag.sh index 093faaa7f..4222694de 100644 --- a/misc/add-lxc-iptag.sh +++ b/misc/add-lxc-iptag.sh @@ -7,8 +7,8 @@ # Source: https://github.com/gitsang/lxc-iptag function header_info { - clear - cat <<"EOF" +clear +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. 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" local exit_code="$?" local line_number="$1" @@ -50,51 +50,56 @@ error_handler() { echo -e "\n$error_message\n" } +# This function displays a spinner. spinner() { - local frames=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏') - local spin_i=0 - local interval=0.1 - printf "\e[?25l" - local orange="\e[38;5;214m" + local frames=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏') + local spin_i=0 + local interval=0.1 + printf "\e[?25l" - while true; do - printf "\r ${orange}%s\e[0m " "${frames[spin_i]}" - spin_i=$(( (spin_i + 1) % ${#frames[@]} )) - sleep "$interval" - done + 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 " ${HOLD} ${YW}${msg} " - spinner & - SPINNER_PID=$! + 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 + 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}" + 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 + 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}" + echo -e "${BFR}${CROSS}${RD}${msg}${CL}" } while true; do - read -p "This will install ${APP} on ${hostname}. Proceed? (y/n): " yn - case $yn in - [Yy]*) break ;; - [Nn]*) msg_info "Installation cancelled."; exit ;; - *) msg_info "Please answer yes or no." ;; - esac + read -p "This will install ${APP} on ${hostname}. Proceed? (y/n): " yn + case $yn in + [Yy]*) break ;; + [Nn]*) + msg_error "Installation cancelled." + exit + ;; + *) msg_error "Please answer yes or no." ;; + esac done 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" mkdir -p /opt/lxc-iptag +msg_ok "Setup IP-Tag Scripts" msg_info "Setup Default Config" if [[ ! -f /opt/lxc-iptag/iptag.conf ]]; then - cat < /opt/lxc-iptag/iptag.conf + cat </opt/lxc-iptag/iptag.conf # Configuration file for LXC IP tagging # List of allowed CIDRs CIDR_LIST=( - 192.168.0.0/16 - 100.64.0.0/10 - 10.0.0.0/8 + 192.168.0.0/16 + 100.64.0.0/10 + 10.0.0.0/8 ) # Interval settings (in seconds) @@ -137,14 +143,14 @@ FW_NET_INTERFACE_CHECK_INTERVAL=60 LXC_STATUS_CHECK_INTERVAL=-1 FORCE_UPDATE_INTERVAL=1800 EOF - msg_ok "Setup default config" + msg_ok "Setup default config" else - msg_ok "Default config already exists" + msg_ok "Default config already exists" fi msg_info "Setup Main Function" if [[ ! -f /opt/lxc-iptag/iptag ]]; then - cat <<'EOF' > /opt/lxc-iptag/iptag + cat <<'EOF' >/opt/lxc-iptag/iptag #!/bin/bash # =============== CONFIGURATION =============== # @@ -153,177 +159,176 @@ CONFIG_FILE="/opt/lxc-iptag/iptag.conf" # Load the configuration file if it exists if [ -f "$CONFIG_FILE" ]; then - # shellcheck source=./lxc-iptag.conf - source "$CONFIG_FILE" + # shellcheck source=./lxc-iptag.conf + source "$CONFIG_FILE" fi # Convert IP to integer for comparison ip_to_int() { - local ip="${1}" - local a b c d + local ip="${1}" + local a b c d - IFS=. read -r a b c d <<< "${ip}" - echo "$((a << 24 | b << 16 | c << 8 | d))" + IFS=. read -r a b c d <<< "${ip}" + echo "$((a << 24 | b << 16 | c << 8 | d))" } # Check if IP is in CIDR ip_in_cidr() { - local ip="${1}" - local cidr="${2}" + local ip="${1}" + local cidr="${2}" - ip_int=$(ip_to_int "${ip}") - netmask_int=$(ip_to_int "$(ipcalc -b "${cidr}" | grep Broadcast | awk '{print $2}')") - masked_ip_int=$(( "${ip_int}" & "${netmask_int}" )) - [[ ${ip_int} -eq ${masked_ip_int} ]] && return 0 || return 1 + ip_int=$(ip_to_int "${ip}") + netmask_int=$(ip_to_int "$(ipcalc -b "${cidr}" | grep Broadcast | awk '{print $2}')") + masked_ip_int=$(( "${ip_int}" & "${netmask_int}" )) + [[ ${ip_int} -eq ${masked_ip_int} ]] && return 0 || return 1 } # Check if IP is in any CIDRs ip_in_cidrs() { - local ip="${1}" - local cidrs=() + local ip="${1}" + local cidrs=() - mapfile -t cidrs < <(echo "${2}" | tr ' ' '\n') - for cidr in "${cidrs[@]}"; do - ip_in_cidr "${ip}" "${cidr}" && return 0 - done + mapfile -t cidrs < <(echo "${2}" | tr ' ' '\n') + for cidr in "${cidrs[@]}"; do + ip_in_cidr "${ip}" "${cidr}" && return 0 + done - return 1 + return 1 } # Check if IP is valid is_valid_ipv4() { - local ip=$1 - local regex="^([0-9]{1,3}\.){3}[0-9]{1,3}$" + local ip=$1 + local regex="^([0-9]{1,3}\.){3}[0-9]{1,3}$" - if [[ $ip =~ $regex ]]; then - IFS='.' read -r -a parts <<< "$ip" - for part in "${parts[@]}"; do - if ! [[ $part =~ ^[0-9]+$ ]] || ((part < 0 || part > 255)); then - return 1 - fi - done - return 0 - else + if [[ $ip =~ $regex ]]; then + IFS='.' read -r -a parts <<< "$ip" + for part in "${parts[@]}"; do + if ! [[ $part =~ ^[0-9]+$ ]] || ((part < 0 || part > 255)); then return 1 - fi + fi + done + return 0 + else + return 1 + fi } lxc_status_changed() { - current_lxc_status=$(pct list 2>/dev/null) - if [ "${last_lxc_status}" == "${current_lxc_status}" ]; then - return 1 - else - last_lxc_status="${current_lxc_status}" - return 0 - fi + current_lxc_status=$(pct list 2>/dev/null) + if [ "${last_lxc_status}" == "${current_lxc_status}" ]; then + return 1 + else + last_lxc_status="${current_lxc_status}" + return 0 + fi } fw_net_interface_changed() { - current_net_interface=$(ifconfig | grep "^fw") - if [ "${last_net_interface}" == "${current_net_interface}" ]; then - return 1 - else - last_net_interface="${current_net_interface}" - return 0 - fi + current_net_interface=$(ifconfig | grep "^fw") + if [ "${last_net_interface}" == "${current_net_interface}" ]; then + return 1 + else + last_net_interface="${current_net_interface}" + return 0 + fi } # =============== MAIN =============== # update_lxc_iptags() { - vmid_list=$(pct list 2>/dev/null | grep -v VMID | awk '{print $1}') - for vmid in ${vmid_list}; do - last_tagged_ips=() - current_valid_ips=() - next_tags=() + vmid_list=$(pct list 2>/dev/null | grep -v VMID | awk '{print $1}') + for vmid in ${vmid_list}; do + last_tagged_ips=() + current_valid_ips=() + next_tags=() - # Parse current tags - mapfile -t current_tags < <(pct config "${vmid}" | grep tags | awk '{print $2}' | sed 's/;/\n/g') - for current_tag in "${current_tags[@]}"; do - if is_valid_ipv4 "${current_tag}"; then - last_tagged_ips+=("${current_tag}") - continue - fi - 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[*]}")" + # Parse current tags + mapfile -t current_tags < <(pct config "${vmid}" | grep tags | awk '{print $2}' | sed 's/;/\n/g') + for current_tag in "${current_tags[@]}"; do + if is_valid_ipv4 "${current_tag}"; then + last_tagged_ips+=("${current_tag}") + continue + fi + 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 } check() { - current_time=$(date +%s) + current_time=$(date +%s) - time_since_last_lxc_status_check=$((current_time - last_lxc_status_check_time)) - if [[ "${LXC_STATUS_CHECK_INTERVAL}" -gt 0 ]] \ - && [[ "${time_since_last_lxc_status_check}" -ge "${STATUS_CHECK_INTERVAL}" ]]; then - echo "Checking lxc status..." - last_lxc_status_check_time=${current_time} - if lxc_status_changed; then - update_lxc_iptags - last_update_time=${current_time} - return - fi + time_since_last_lxc_status_check=$((current_time - last_lxc_status_check_time)) + if [[ "${LXC_STATUS_CHECK_INTERVAL}" -gt 0 ]] \ + && [[ "${time_since_last_lxc_status_check}" -ge "${STATUS_CHECK_INTERVAL}" ]]; then + echo "Checking lxc status..." + last_lxc_status_check_time=${current_time} + if lxc_status_changed; then + update_lxc_iptags + last_update_time=${current_time} + return fi + fi - time_since_last_fw_net_interface_check=$((current_time - last_fw_net_interface_check_time)) - if [[ "${FW_NET_INTERFACE_CHECK_INTERVAL}" -gt 0 ]] \ - && [[ "${time_since_last_fw_net_interface_check}" -ge "${FW_NET_INTERFACE_CHECK_INTERVAL}" ]]; then - echo "Checking fw net interface..." - last_fw_net_interface_check_time=${current_time} - if fw_net_interface_changed; then - update_lxc_iptags - last_update_time=${current_time} - return - fi + time_since_last_fw_net_interface_check=$((current_time - last_fw_net_interface_check_time)) + if [[ "${FW_NET_INTERFACE_CHECK_INTERVAL}" -gt 0 ]] \ + && [[ "${time_since_last_fw_net_interface_check}" -ge "${FW_NET_INTERFACE_CHECK_INTERVAL}" ]]; then + echo "Checking fw net interface..." + last_fw_net_interface_check_time=${current_time} + if fw_net_interface_changed; then + update_lxc_iptags + last_update_time=${current_time} + return fi + fi - time_since_last_update=$((current_time - last_update_time)) - if [ ${time_since_last_update} -ge ${FORCE_UPDATE_INTERVAL} ]; then - echo "Force updating lxc iptags..." - update_lxc_iptags - last_update_time=${current_time} - return - fi + time_since_last_update=$((current_time - last_update_time)) + if [ ${time_since_last_update} -ge ${FORCE_UPDATE_INTERVAL} ]; then + echo "Force updating lxc iptags..." + update_lxc_iptags + last_update_time=${current_time} + return + fi } # main: Set the IP tags for all LXC containers main() { - while true; do - check - sleep "${LOOP_INTERVAL}" - done + while true; do + check + sleep "${LOOP_INTERVAL}" + done } main EOF - msg_ok "Setup Main Function" + msg_ok "Setup Main Function" else - msg_ok "Main Function already exists" + msg_ok "Main Function already exists" fi -chmod +x /opt/lxc-iptag/iptag +chmod +x /opt/lxc-iptag/iptag msg_info "Creating Service" if [[ ! -f /lib/systemd/system/iptag.service ]]; then - echo "Systemd service file not found. Creating it now..." - cat < /lib/systemd/system/iptag.service + cat </lib/systemd/system/iptag.service [Unit] Description=LXC IP-Tag service After=network.target @@ -336,9 +341,9 @@ Restart=always [Install] WantedBy=multi-user.target EOF - msg_ok "Created Service" + msg_ok "Created Service" else - msg_ok "Service already exists." + msg_ok "Service already exists." fi msg_ok "Setup IP-Tag Scripts" @@ -347,5 +352,5 @@ msg_info "Starting Service" systemctl daemon-reload &>/dev/null systemctl enable -q --now iptag.service &>/dev/null msg_ok "Started Service" - +SPINNER_PID="" echo -e "\n${APP} installation completed successfully! ${CL}\n"