From 9de1189e02a0d5a5a5dbff49a76fd5bb97a2019f Mon Sep 17 00:00:00 2001 From: Asainte Bueno-Villanueva Date: Sun, 8 Feb 2026 03:35:45 -0500 Subject: [PATCH] Update modules/proxmox-commander --- modules/proxmox-commander | 69 ++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/modules/proxmox-commander b/modules/proxmox-commander index aeba7d3..4732497 100644 --- a/modules/proxmox-commander +++ b/modules/proxmox-commander @@ -5,9 +5,12 @@ BLUE='\033[38;5;45m'; PURPLE='\033[38;5;127m'; GOLD='\033[38;5;178m'; RED='\033[38;5;196m'; NC='\033[0m' HOST_FILE="$HOME/.dynr/.pve_hosts"; mkdir -p "$HOME/.dynr" +# --- 1. DETECT ENVIRONMENT --- +IS_MAC=false; [[ "$OSTYPE" == "darwin"* ]] && IS_MAC=true + get_input() { local p=$1; local h=$2 - if [[ "$OSTYPE" == "darwin"* ]]; then + if [ "$IS_MAC" = true ]; then local s=""; [[ "$h" == "true" ]] && s="with hidden answer" res=$(osascript -e "display dialog \"$p\" default answer \"\" with title \"Dynasty Setup\" $s" -e 'text returned of result' 2>/dev/null) [[ $? -ne 0 ]] && echo "ABORT" || echo "$res" @@ -16,9 +19,11 @@ get_input() { fi } -# --- 1. HOST SELECTION --- +# --- 2. HOST SELECTION --- if ! command -v pct &> /dev/null; then - [[ -f "$HOST_FILE" ]] && { [[ "$OSTYPE" == "darwin"* ]] && sed -i '' '/^$/d' "$HOST_FILE" || sed -i '/^$/d' "$HOST_FILE"; } + if [ -f "$HOST_FILE" ]; then + if [ "$IS_MAC" = true ]; then sed -i '' '/^$/d' "$HOST_FILE"; else sed -i '/^$/d' "$HOST_FILE"; fi + fi if [[ ! -s "$HOST_FILE" ]]; then echo -e "${RED}No Proxmox hosts found.${NC}" @@ -26,26 +31,24 @@ if ! command -v pct &> /dev/null; then [[ "$ADD_NOW" =~ ^[Yy]$ ]] && HP="n" || exit 0 else echo -e "${PURPLE}🐉 Your Proxmox VE Hosts:${NC}" - cat -n "$HOST_FILE" | while read -r line; do - num=$(echo "$line" | awk '{print $1}') - content=$(echo "$line" | awk '{$1=""; print $0}') - ip=$(echo "$content" | cut -d'|' -f1); usr=$(echo "$content" | cut -d'|' -f2); nick=$(echo "$content" | cut -d'|' -f5) - echo -e " $num) $usr@$ip ($nick)" - done + i=1; while read -r line; do + ip=$(echo "$line" | cut -d'|' -f1); usr=$(echo "$line" | cut -d'|' -f2); nick=$(echo "$line" | cut -d'|' -f5) + echo -e " $i) $usr@$ip ($nick)"; ((i++)) + done < "$HOST_FILE" read -p "Selection (ID#, n=new, m=manage, q=exit): " HP < /dev/tty fi [[ "$HP" == "q" ]] && exit 0 if [[ "$HP" == "m" ]]; then - if [[ "$OSTYPE" == "darwin"* ]]; then + if [ "$IS_MAC" = true ]; then MA=$(osascript -e 'choose from list {"1. Remove Host", "2. Back"} with title "Manage"') else MA=$(whiptail --menu "Manage" 15 60 2 "1" "Remove" "2" "Back" 3>&1 1>&2 2>&3) fi [[ "$MA" == *"1"* ]] && { read -p "ID to delete: " RID - [[ "$OSTYPE" == "darwin"* ]] && sed -i '' "${RID}d" "$HOST_FILE" || sed -i "${RID}d" "$HOST_FILE" + if [ "$IS_MAC" = true ]; then sed -i '' "${RID}d" "$HOST_FILE"; else sed -i "${RID}d" "$HOST_FILE"; fi } exec "$0" fi @@ -54,7 +57,7 @@ if ! command -v pct &> /dev/null; then IP=$(get_input "IP Address" "false"); [[ "$IP" == "ABORT" || -z "$IP" ]] && exit 0 USR=$(get_input "User (root)" "false"); [[ "$USR" == "ABORT" ]] && exit 0; USR=${USR:-root} while true; do - [[ "$OSTYPE" == "darwin"* ]] && AT=$(osascript -e 'choose from list {"Key", "Pass"}') || AT=$(whiptail --menu "Auth" 15 60 2 "Key" "" "Pass" "" 3>&1 1>&2 2>&3) + if [ "$IS_MAC" = true ]; then AT=$(osascript -e 'choose from list {"Key", "Pass"}'); else AT=$(whiptail --menu "Auth" 15 60 2 "Key" "" "Pass" "" 3>&1 1>&2 2>&3); fi if [[ "$AT" == *"Key"* ]]; then [[ ! -f "$HOME/.ssh/id_rsa.pub" ]] && ssh-keygen -t rsa -b 4096 -f "$HOME/.ssh/id_rsa" -N "" ssh-copy-id -o ConnectTimeout=5 "$USR@$IP" @@ -71,20 +74,21 @@ if ! command -v pct &> /dev/null; then LINE=$(sed -n "${HP}p" "$HOST_FILE") [[ -z "$LINE" ]] && { echo -e "${RED}Invalid ID.${NC}"; sleep 1; exec "$0"; } IP=$(echo "$LINE" | cut -d'|' -f1); USR=$(echo "$LINE" | cut -d'|' -f2); AM=$(echo "$LINE" | cut -d'|' -f3); P_DEC=$(echo "$LINE" | cut -d'|' -f4 | base64 --decode) - [[ "$AM" == "PASS" ]] && REMOTE="sshpass -p '$P_DEC' ssh -o StrictHostKeyChecking=no -t $USR@$IP" || REMOTE="ssh -o StrictHostKeyChecking=no -t $USR@$IP" + [[ "$AM" == "PASS" ]] && REMOTE="sshpass -p '$P_DEC' ssh -o StrictHostKeyChecking=no -t $USR@$ip" || REMOTE="ssh -o StrictHostKeyChecking=no -t $USR@$ip" fi else - REMOTE=""; IP="LocalHost"; fi + REMOTE=""; IP="LocalHost" +fi -# --- 2. FLEET OPS MENU --- +# --- 3. FLEET OPS MENU --- while true; do clear; echo -e "${BLUE}🐉 Proxmox Commander | Connected: $IP${NC}" - echo -e "1) ${GOLD}Create LXC(s)${NC}\n2) ${BLUE}Dashboard${NC}\n3) ${PURPLE}Console Gateway${NC}\n4) Selective Update\n5) Switch Host\n6) Exit to Dynasty" + echo -e "1) ${GOLD}Create LXC(s)${NC}\n2) ${BLUE}Dashboard${NC}\n3) ${PURPLE}Console Gateway${NC}\n4) Selective Update\n5) Switch Host\n6) Exit" read -p "Select: " OPT < /dev/tty case $OPT in - 1) read -p "🚢 Count (q=back): " CT; [[ "$CT" == "q" ]] && continue - read -p "🔢 Start ID: " SID; read -p "📏 Disk (GB): " DSZ; $REMOTE "pvesm status" - read -p "📥 Template Store: " TS; read -p "💾 Disk Store: " DS + 1) read -p "🚢 Count: " CT; [[ "$CT" == "q" ]] && continue + read -p "🔢 Start ID: " SID; read -p "📏 Disk (GB): " DSZ + $REMOTE "pvesm status"; read -p "📥 Template Store: " TS; read -p "💾 Disk Store: " DS RP=""; for (( i=0; i1 {print \$1 \"-\" \$2}'") - if [[ "$OSTYPE" == "darwin"* ]]; then + if [ "$IS_MAC" = true ]; then TID_R=$(osascript -e "set theList to every paragraph of \"$LD\"" -e 'choose from list theList with prompt "Select LXC Console:"); TID=$(echo "$TID_R" | cut -d'-' -f1) else WL=$(echo "$LD" | awk -F'-' '{print $1 \" \" $2}'); TID=$(whiptail --menu "Console" 20 60 10 $WL 3>&1 1>&2 2>&3) fi [[ -n "$TID" && "$TID" != "false" ]] && CMD="$REMOTE \"pct enter $TID\"" - [[ -n "$CMD" ]] && { [[ "$OSTYPE" == "darwin"* ]] && osascript -e "tell application \"Terminal\" to do script \"$CMD\"" || eval "$CMD"; } + [[ -n "$CMD" ]] && { if [ "$IS_MAC" = true ]; then osascript -e "tell application \"Terminal\" to do script \"$CMD\""; else eval "$CMD"; fi; } } ;; - 4) echo -e "1) ${GOLD}Update Proxmox Host ($IP)${NC}\n2) ${BLUE}Surgical Selection (Choose LXCs)${NC}\n3) ${PURPLE}Update ALL LXCs (Select All)${NC}\n4) Back" + 4) echo -e "1) Host 2) Select LXCs 3) All LXCs 4) Back" read -p "Choice: " U_OPT < /dev/tty - if [[ "$U_OPT" == "1" ]]; then - echo -e "${GOLD}⚔️ Updating Host...${NC}"; $REMOTE "apt update && apt upgrade -y" + if [[ "$U_OPT" == "1" ]]; then $REMOTE "apt update && apt upgrade -y" elif [[ "$U_OPT" == "2" ]]; then LD=$($REMOTE "pct list | awk 'NR>1 {print \$1 \"-\" \$2}'") - if [[ "$OSTYPE" == "darwin"* ]]; then - PK=$(osascript -e "set theList to every paragraph of \"$LD\"" -e 'choose from list theList with title "Surgical Update" with prompt "Cmd+Click to select targets:" with multiple selections allowed') + if [ "$IS_MAC" = true ]; then + PK=$(osascript -e "set theList to every paragraph of \"$LD\"" -e 'choose from list theList with multiple selections allowed') [[ "$PK" == "false" ]] && continue IFS=',' read -ra ADDR <<< "$PK"; TG=$(for p in "${ADDR[@]}"; do echo "${p%%-*}" | xargs; done) else WL=$(echo "$LD" | awk -F'-' '{print $1 \" \" $2 \" off\"}') - TG=$(whiptail --title "Surgical Update" --checklist "Spacebar to select targets:" 20 60 10 $WL 3>&1 1>&2 2>&3); TG=${TG//\"/} + TG=$(whiptail --checklist "Select targets:" 20 60 10 $WL 3>&1 1>&2 2>&3); TG=${TG//\"/} fi - for id in $TG; do echo -e "${BLUE}Updating LXC $id...${NC}"; $REMOTE "pct exec $id -- apt update && apt upgrade -y"; done + for id in $TG; do $REMOTE "pct exec $id -- apt update && apt upgrade -y"; done elif [[ "$U_OPT" == "3" ]]; then - echo -e "${PURPLE}🚀 Mass-updating ALL containers...${NC}" - $REMOTE "for id in \$(pct list | awk 'NR>1 {print \$1}'); do echo \"Updating \$id...\"; pct exec \$id -- apt update && apt upgrade -y; done" - fi - read -p "Cycle complete. Enter..." < /dev/tty ;; + $REMOTE "for id in \$(pct list | awk 'NR>1 {print \$1}'); do pct exec \$id -- apt update && apt upgrade -y; done" + fi; read -p "Done. Enter..." < /dev/tty ;; 5) exec "$0" ;; 6) exit 0 ;; esac