KVM Cloud Capacity Planning Script (Enhanced) Rumi, February 20, 2026 Interactive Script with VM Count Estimation (CPU + Memory) + CSV Export Here is the corrected script with proper table formatting throughout and an optional CSV export feature. kvm_capacity_planner.sh #!/bin/bash ############################################################################### # KVM Cloud CPU & Memory Capacity Planner # Calculates usable vCPUs, Memory, and Estimated VM Count ############################################################################### # Function to add commas to numbers for readability add_commas() { local num="$1" # Remove any decimal points first num=$(echo "$num" | cut -d. -f1) printf "%'d\n" "$num" 2>/dev/null || echo "$num" } # Function to draw a table row draw_row() { printf "| %-40s | %25s |\n" "$1" "$2" } # Function to draw a table separator draw_separator() { printf "+------------------------------------------+---------------------------+\n" } # Function to draw a section header draw_section() { echo "" printf "| %-66s |\n" "$1" draw_separator } echo "==========================================" echo " KVM Cloud Capacity Planner (Enhanced)" echo "==========================================" echo "" # --- Section 1: Physical Hardware --- echo "=== PHYSICAL HARDWARE ===" read -p "Enter number of Physical Cores: " PHYSICAL_CORES read -p "Enter Hyperthreading Factor (2 for HT, 1 for None): " HT_FACTOR read -p "Enter Total Physical RAM (GB): " PHYSICAL_RAM_GB # --- Section 2: Overcommitment & Buffer --- echo "" echo "=== OVERCOMMITMENT & SAFETY BUFFER ===" read -p "Enter CPU Overcommitment Ratio (e.g., 3 for 1:3): " CPU_RATIO read -p "Enter Memory Overcommitment Ratio (e.g., 1.5 for 1:1.5): " MEM_RATIO read -p "Enter Safety Buffer Percentage (e.g., 15 for 15%): " BUFFER_PCT # --- Section 3: VM Sizing --- echo "" echo "=== VM SIZING ===" read -p "Enter vCPUs per VM: " VM_VCPU read -p "Enter Memory per VM (GB): " VM_MEMORY_GB # --- Input Validation (Basic) --- if ! [[ "$PHYSICAL_CORES" =~ ^[0-9]+$ ]] || ! [[ "$HT_FACTOR" =~ ^[0-9]+$ ]] || \ ! [[ "$PHYSICAL_RAM_GB" =~ ^[0-9]+$ ]] || ! [[ "$VM_VCPU" =~ ^[0-9]+$ ]] || \ ! [[ "$VM_MEMORY_GB" =~ ^[0-9]+$ ]]; then echo "Error: All inputs must be positive integers (except memory ratio)." exit 1 fi if ! [[ "$CPU_RATIO" =~ ^[0-9]+$ ]] || ! [[ "$BUFFER_PCT" =~ ^[0-9]+$ ]]; then echo "Error: CPU Ratio and Buffer must be integers." exit 1 fi # --- CPU Calculations --- LOGICAL_PROCESSORS=$(echo "$PHYSICAL_CORES * $HT_FACTOR" | bc) THEORETICAL_VCPU=$(echo "$LOGICAL_PROCESSORS * $CPU_RATIO" | bc | cut -d. -f1) RESERVED_PCPU=$(echo "scale=0; $LOGICAL_PROCESSORS * $BUFFER_PCT / 100" | bc | cut -d. -f1) AVAILABLE_PCPU=$(echo "$LOGICAL_PROCESSORS - $RESERVED_PCPU" | bc | cut -d. -f1) USABLE_VCPU=$(echo "$AVAILABLE_PCPU * $CPU_RATIO" | bc | cut -d. -f1) BUFFER_VCPU_EQ=$(echo "$RESERVED_PCPU * $CPU_RATIO" | bc | cut -d. -f1) # Max VMs by CPU if [ "$VM_VCPU" -gt 0 ]; then MAX_VMS_CPU=$(echo "$USABLE_VCPU / $VM_VCPU" | bc | cut -d. -f1) else MAX_VMS_CPU=0 fi # --- Memory Calculations --- # Reserve RAM for host (same buffer %) RESERVED_RAM_GB=$(echo "scale=0; $PHYSICAL_RAM_GB * $BUFFER_PCT / 100" | bc | cut -d. -f1) AVAILABLE_RAM_GB=$(echo "$PHYSICAL_RAM_GB - $RESERVED_RAM_GB" | bc | cut -d. -f1) THEORETICAL_MEM_GB=$(echo "scale=0; $AVAILABLE_RAM_GB * $MEM_RATIO" | bc | cut -d. -f1) USABLE_MEM_GB=$THEORETICAL_MEM_GB BUFFER_MEM_GB=$(echo "scale=0; $RESERVED_RAM_GB * $MEM_RATIO" | bc | cut -d. -f1) # Max VMs by Memory if [ "$VM_MEMORY_GB" -gt 0 ]; then MAX_VMS_MEM=$(echo "$USABLE_MEM_GB / $VM_MEMORY_GB" | bc | cut -d. -f1) else MAX_VMS_MEM=0 fi # --- Determine Limiting Factor --- if [ "$MAX_VMS_CPU" -le "$MAX_VMS_MEM" ]; then LIMITING_FACTOR="CPU" MAX_VMS_TOTAL=$MAX_VMS_CPU else LIMITING_FACTOR="Memory" MAX_VMS_TOTAL=$MAX_VMS_MEM fi # --- Calculate Actual Resource Usage at Max VMs --- ACTUAL_VCPU_USED=$(echo "$MAX_VMS_TOTAL * $VM_VCPU" | bc | cut -d. -f1) ACTUAL_MEM_USED=$(echo "$MAX_VMS_TOTAL * $VM_MEMORY_GB" | bc | cut -d. -f1) # Handle division for percentages (avoid divide by zero) if [ "$USABLE_VCPU" -gt 0 ]; then CPU_UTILIZATION_PCT=$(echo "scale=2; $ACTUAL_VCPU_USED * 100 / $USABLE_VCPU" | bc) else CPU_UTILIZATION_PCT="0.00" fi if [ "$USABLE_MEM_GB" -gt 0 ]; then MEM_UTILIZATION_PCT=$(echo "scale=2; $ACTUAL_MEM_USED * 100 / $USABLE_MEM_GB" | bc) else MEM_UTILIZATION_PCT="0.00" fi # --- Format Numbers with Commas --- F_PHYSICAL=$(add_commas "$PHYSICAL_CORES") F_LOGICAL=$(add_commas "$LOGICAL_PROCESSORS") F_THEORETICAL_VCPU=$(add_commas "$THEORETICAL_VCPU") F_RESERVED_PCPU=$(add_commas "$RESERVED_PCPU") F_AVAILABLE_PCPU=$(add_commas "$AVAILABLE_PCPU") F_USABLE_VCPU=$(add_commas "$USABLE_VCPU") F_BUFFER_VCPU=$(add_commas "$BUFFER_VCPU_EQ") F_PHYSICAL_RAM=$(add_commas "$PHYSICAL_RAM_GB") F_RESERVED_RAM=$(add_commas "$RESERVED_RAM_GB") F_AVAILABLE_RAM=$(add_commas "$AVAILABLE_RAM_GB") F_USABLE_MEM=$(add_commas "$USABLE_MEM_GB") F_BUFFER_MEM=$(add_commas "$BUFFER_MEM_GB") F_MAX_VMS_CPU=$(add_commas "$MAX_VMS_CPU") F_MAX_VMS_MEM=$(add_commas "$MAX_VMS_MEM") F_MAX_VMS_TOTAL=$(add_commas "$MAX_VMS_TOTAL") F_ACTUAL_VCPU=$(add_commas "$ACTUAL_VCPU_USED") F_ACTUAL_MEM=$(add_commas "$ACTUAL_MEM_USED") # --- ASCII Table Output --- echo "" draw_separator draw_row "Parameter" "Value" draw_separator draw_section "PHYSICAL HARDWARE" draw_row "Physical Cores" "$F_PHYSICAL" draw_row "Hyperthreading Factor" "$HT_FACTOR" draw_row "Total Logical Processors" "$F_LOGICAL" draw_row "Physical RAM (GB)" "$F_PHYSICAL_RAM" draw_section "OVERCOMMITMENT & BUFFER" draw_row "CPU Overcommitment Ratio" "1:$CPU_RATIO" draw_row "Memory Overcommitment Ratio" "1:$MEM_RATIO" draw_row "Safety Buffer Percentage" "${BUFFER_PCT}%" draw_section "CPU CAPACITY" draw_row "Theoretical Max vCPUs (0% Buffer)" "$F_THEORETICAL_VCPU" draw_row "Reserved pCPUs (Buffer)" "$F_RESERVED_PCPU" draw_row "Available pCPUs for VMs" "$F_AVAILABLE_PCPU" draw_row "Usable vCPUs (With Buffer)" "$F_USABLE_VCPU" draw_row "Buffer Capacity (vCPU equiv.)" "$F_BUFFER_VCPU" draw_section "MEMORY CAPACITY" draw_row "Theoretical Max Memory (0% Buffer) (GB)" "$F_THEORETICAL_MEM_GB" draw_row "Reserved RAM (Buffer) (GB)" "$F_RESERVED_RAM" draw_row "Available RAM for VMs (GB)" "$F_AVAILABLE_RAM" draw_row "Usable Memory (With Overcommit) (GB)" "$F_USABLE_MEM" draw_row "Buffer Capacity (Memory equiv.) (GB)" "$F_BUFFER_MEM" draw_section "VM SIZING" draw_row "vCPUs per VM" "$VM_VCPU" draw_row "Memory per VM (GB)" "$VM_MEMORY_GB" draw_section "ESTIMATED VM COUNT" draw_row "Max VMs by CPU Constraint" "$F_MAX_VMS_CPU" draw_row "Max VMs by Memory Constraint" "$F_MAX_VMS_MEM" draw_separator draw_row "LIMITING FACTOR" "$LIMITING_FACTOR" draw_row "MAXIMUM VMs SUPPORTED" "$F_MAX_VMS_TOTAL" draw_separator draw_section "RESOURCE UTILIZATION AT MAX VMs" draw_row "Total vCPUs Allocated" "$F_ACTUAL_VCPU" draw_row "CPU Utilization of Usable Capacity" "${CPU_UTILIZATION_PCT}%" draw_row "Total Memory Allocated (GB)" "$F_ACTUAL_MEM" draw_row "Memory Utilization of Usable Capacity" "${MEM_UTILIZATION_PCT}%" draw_separator echo "" echo "Recommendation: Deploy maximum of $F_MAX_VMS_TOTAL VMs ($LIMITING_FACTOR-limited)" echo " - Each VM: $VM_VCPU vCPU(s), $VM_MEMORY_GB GB RAM" echo " - Keep $BUFFER_PCT% buffer for host overhead and burst capacity" echo "" # --- CSV Export Option --- read -p "Do you want to export this data to a CSV file? (y/n): " EXPORT_CSV if [[ "$EXPORT_CSV" =~ ^[Yy]$ ]]; then # Generate timestamp for filename TIMESTAMP=$(date +"%Y%m%d_%H%M%S") CSV_FILE="kvm_capacity_report_${TIMESTAMP}.csv" # Create CSV file cat > "$CSV_FILE" << EOF Section,Parameter,Value Physical Hardware,Physical Cores,$PHYSICAL_CORES Physical Hardware,Hyperthreading Factor,$HT_FACTOR Physical Hardware,Total Logical Processors,$LOGICAL_PROCESSORS Physical Hardware,Physical RAM (GB),$PHYSICAL_RAM_GB Overcommitment & Buffer,CPU Overcommitment Ratio,1:$CPU_RATIO Overcommitment & Buffer,Memory Overcommitment Ratio,1:$MEM_RATIO Overcommitment & Buffer,Safety Buffer Percentage,${BUFFER_PCT}% CPU Capacity,Theoretical Max vCPUs (0% Buffer),$THEORETICAL_VCPU CPU Capacity,Reserved pCPUs (Buffer),$RESERVED_PCPU CPU Capacity,Available pCPUs for VMs,$AVAILABLE_PCPU CPU Capacity,Usable vCPUs (With Buffer),$USABLE_VCPU CPU Capacity,Buffer Capacity (vCPU equiv.),$BUFFER_VCPU_EQ Memory Capacity,Theoretical Max Memory (0% Buffer) (GB),$THEORETICAL_MEM_GB Memory Capacity,Reserved RAM (Buffer) (GB),$RESERVED_RAM_GB Memory Capacity,Available RAM for VMs (GB),$AVAILABLE_RAM_GB Memory Capacity,Usable Memory (With Overcommit) (GB),$USABLE_MEM_GB Memory Capacity,Buffer Capacity (Memory equiv.) (GB),$BUFFER_MEM_GB VM Sizing,vCPUs per VM,$VM_VCPU VM Sizing,Memory per VM (GB),$VM_MEMORY_GB Estimated VM Count,Max VMs by CPU Constraint,$MAX_VMS_CPU Estimated VM Count,Max VMs by Memory Constraint,$MAX_VMS_MEM Estimated VM Count,LIMITING FACTOR,$LIMITING_FACTOR Estimated VM Count,MAXIMUM VMs SUPPORTED,$MAX_VMS_TOTAL Resource Utilization,Total vCPUs Allocated,$ACTUAL_VCPU_USED Resource Utilization,CPU Utilization of Usable Capacity,${CPU_UTILIZATION_PCT}% Resource Utilization,Total Memory Allocated (GB),$ACTUAL_MEM_USED Resource Utilization,Memory Utilization of Usable Capacity,${MEM_UTILIZATION_PCT}% EOF echo "" echo "CSV file created: $CSV_FILE" echo "You can open this file in Excel, LibreOffice Calc, or any spreadsheet application." fi echo "" echo "Script completed." Administrations Scripts Cloud CapacityKVMOvercimmitting CalculatorQemu