From 2bdfb518317c10a18530ebeb3e90c8bac0df9d1d Mon Sep 17 00:00:00 2001 From: Asainte Bueno-Villanueva Date: Sun, 8 Feb 2026 03:37:25 -0500 Subject: [PATCH] Update modules/proxmox-commander --- modules/proxmox-commander | 148 +++++++++++--------------------------- 1 file changed, 42 insertions(+), 106 deletions(-) diff --git a/modules/proxmox-commander b/modules/proxmox-commander index 4732497..1de857f 100644 --- a/modules/proxmox-commander +++ b/modules/proxmox-commander @@ -1,28 +1,15 @@ #!/bin/bash # ----------------------------------------------------------------------- -# Dynasty Module: Proxmox Commander (v1.0.0) +# Dynasty Module: Proxmox Commander (v1.1.2 - Mac EOF Fix) # ----------------------------------------------------------------------- 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 [ "$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" - else - local r=""; [[ "$h" == "true" ]] && { read -rs -p "$p: " r < /dev/tty; echo "" > /dev/tty; } || read -p "$p: " r < /dev/tty; echo "$r" - fi -} - -# --- 2. HOST SELECTION --- +# --- 1. HOST SELECTION --- if ! command -v pct &> /dev/null; then if [ -f "$HOST_FILE" ]; then - if [ "$IS_MAC" = true ]; then sed -i '' '/^$/d' "$HOST_FILE"; else sed -i '/^$/d' "$HOST_FILE"; fi + [ "$IS_MAC" = true ] && sed -i '' '/^$/d' "$HOST_FILE" || sed -i '/^$/d' "$HOST_FILE" fi if [[ ! -s "$HOST_FILE" ]]; then @@ -31,109 +18,58 @@ if ! command -v pct &> /dev/null; then [[ "$ADD_NOW" =~ ^[Yy]$ ]] && HP="n" || exit 0 else echo -e "${PURPLE}🐉 Your Proxmox VE Hosts:${NC}" - 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++)) + i=1 + while IFS='|' read -r ip usr am pe nick; do + 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 [ "$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 - if [ "$IS_MAC" = true ]; then sed -i '' "${RID}d" "$HOST_FILE"; else sed -i "${RID}d" "$HOST_FILE"; fi - } - exec "$0" - fi - if [[ "$HP" == "n" ]]; 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 - 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" - if [ $? -eq 0 ]; then AM="KEY"; PE="NONE"; break; else - read -p "Failed. 1) Retry 2) Pass 3) Abort: " FO; [[ "$FO" == "2" ]] && continue || exit 0; fi - else - P=$(get_input "Password" "true"); [[ "$P" == "ABORT" ]] && exit 0 - AM="PASS"; PE=$(echo -n "$P" | base64); break; fi - done - [[ "$AM" == "PASS" ]] && P_DEC=$(echo "$PE" | base64 --decode) && RW="sshpass -p '$P_DEC' ssh -o StrictHostKeyChecking=no $USR@$IP" || RW="ssh -o StrictHostKeyChecking=no $USR@$IP" - HN=$($RW "hostname" 2>/dev/null); [[ -z "$HN" ]] && HN=$(get_input "Nickname" "false") - echo "$IP|$USR|$AM|$PE|$HN" >> "$HOST_FILE"; exec "$0" - else + read -p "IP: " IP; read -p "User: " USR; USR=${USR:-root} + echo "1) Key 2) Pass"; read -p ": " AT + if [[ "$AT" == "1" ]]; then + [[ ! -f "$HOME/.ssh/id_rsa.pub" ]] && ssh-keygen -t rsa -b 4096 -f "$HOME/.ssh/id_rsa" -N "" + ssh-copy-id "$USR@$IP" && { AM="KEY"; PE="NONE"; } + else + read -rs -p "Pass: " P; echo ""; AM="PASS"; PE=$(echo -n "$P" | base64); fi + read -p "Nickname: " HN; echo "$IP|$USR|$AM|$PE|$HN" >> "$HOST_FILE"; exec "$0" + elif [[ "$HP" =~ ^[0-9]+$ ]]; 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" - fi + IP=$(echo "$LINE" | cut -d'|' -f1); USR=$(echo "$LINE" | cut -d'|' -f2); AM=$(echo "$LINE" | cut -d'|' -f3); PE=$(echo "$LINE" | cut -d'|' -f4) + if [[ "$AM" == "PASS" ]]; then + P_DEC=$(echo "$PE" | base64 --decode); REMOTE="sshpass -p '$P_DEC' ssh -o StrictHostKeyChecking=no -t $USR@$IP" + else + REMOTE="ssh -o StrictHostKeyChecking=no -t $USR@$IP"; fi + else + exec "$0"; fi else - REMOTE=""; IP="LocalHost" -fi + REMOTE=""; IP="LocalHost"; fi -# --- 3. FLEET OPS MENU --- +# --- 2. 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" + clear; echo -e "${BLUE}🐉 Proxmox Commander | $IP${NC}" + echo -e "1) Create LXC(s)\n2) Dashboard\n3) Console Gateway\n4) Selective Update\n5) Switch Host\n6) Exit" read -p "Select: " OPT < /dev/tty case $OPT in - 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 {printf " 🐉 [%s] ID: %-5s Name: %-15s\n", $3, $1, $2}' - read -p "ID (q=back): " TID < /dev/tty - [[ "$TID" != "q" ]] && { echo "1)Start 2)Stop 3)Exec"; read -p ": " A; [[ "$A" == "1" ]] && $REMOTE "pct start $TID"; [[ "$A" == "2" ]] && $REMOTE "pct stop $TID"; [[ "$A" == "3" ]] && { read -p "Cmd: " C; $REMOTE "pct exec $TID -- $C"; }; } ;; - 3) echo -e "1) Host 2) Specific LXC 3) Back"; read -p ": " CG - [[ "$CG" == "1" ]] && { if [ "$IS_MAC" = true ]; then osascript -e "tell application \"Terminal\" to do script \"$REMOTE\""; else eval "$REMOTE"; fi; } - [[ "$CG" == "2" ]] && { - LD=$($REMOTE "pct list | awk 'NR>1 {print \$1 \"-\" \$2}'") - 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" ]] && { if [ "$IS_MAC" = true ]; then osascript -e "tell application \"Terminal\" to do script \"$CMD\""; else eval "$CMD"; fi; } - } ;; - 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 $REMOTE "apt update && apt upgrade -y" - elif [[ "$U_OPT" == "2" ]]; then - LD=$($REMOTE "pct list | awk 'NR>1 {print \$1 \"-\" \$2}'") - 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 --checklist "Select targets:" 20 60 10 $WL 3>&1 1>&2 2>&3); TG=${TG//\"/} - fi - for id in $TG; do $REMOTE "pct exec $id -- apt update && apt upgrade -y"; done - elif [[ "$U_OPT" == "3" ]]; then - $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 ;; + 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 + for (( i=0; i1 {print \$1}'); do pct exec \$id -- apt update && apt upgrade -y; done" + read -p "Done..." ;; 5) exec "$0" ;; 6) exit 0 ;; esac