...
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Ubuntu VM Delete Script with Comprehensive Cleanup
|
||||
# Usage: ubuntu_vm_delete.sh <vm_name|all>
|
||||
# Usage: ubuntu_vm_delete.sh <vm_number|all>
|
||||
# Use 'all' to delete all VMs
|
||||
|
||||
set -e
|
||||
@@ -39,15 +39,18 @@ info() {
|
||||
show_usage() {
|
||||
echo "Ubuntu VM Delete Script"
|
||||
echo ""
|
||||
echo "Usage: $0 <vm_name|all>"
|
||||
echo "Usage: $0 <vm_number|all|list>"
|
||||
echo ""
|
||||
echo "Arguments:"
|
||||
echo " vm_name - Name of the VM to delete"
|
||||
echo " vm_number - Number of the VM to delete (1-200)"
|
||||
echo " all - Delete ALL VMs (use with extreme caution)"
|
||||
echo " list - List all existing VMs"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 test-vm # Delete specific VM"
|
||||
echo " $0 1 # Delete VM number 1"
|
||||
echo " $0 42 # Delete VM number 42"
|
||||
echo " $0 all # Delete all VMs"
|
||||
echo " $0 list # List all VMs"
|
||||
echo ""
|
||||
echo "This script will:"
|
||||
echo " - Stop running VM processes"
|
||||
@@ -70,9 +73,15 @@ fi
|
||||
|
||||
VM_TARGET="$1"
|
||||
|
||||
# Validate VM name (unless it's 'all')
|
||||
if [ "$VM_TARGET" != "all" ] && [[ "$VM_TARGET" =~ [^a-zA-Z0-9_-] ]]; then
|
||||
error "VM name can only contain alphanumeric characters, hyphens, and underscores"
|
||||
# Validate VM number (unless it's 'all' or 'list')
|
||||
if [ "$VM_TARGET" != "all" ] && [ "$VM_TARGET" != "list" ]; then
|
||||
if ! [[ "$VM_TARGET" =~ ^[0-9]+$ ]]; then
|
||||
error "VM number must be a number"
|
||||
fi
|
||||
|
||||
if [ "$VM_TARGET" -lt 1 ] || [ "$VM_TARGET" -gt 200 ]; then
|
||||
error "VM number must be between 1 and 200"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if VMs directory exists
|
||||
@@ -159,7 +168,7 @@ cleanup_network() {
|
||||
# Function to clean up VM files and sockets
|
||||
cleanup_vm_files() {
|
||||
local vm_socket="$1"
|
||||
local vm_name="$2"
|
||||
local vm_number="$2"
|
||||
|
||||
# Remove VM socket
|
||||
if [ -n "$vm_socket" ] && [ -e "$vm_socket" ]; then
|
||||
@@ -168,28 +177,28 @@ cleanup_vm_files() {
|
||||
fi
|
||||
|
||||
# Remove log files
|
||||
local log_file="/tmp/cloud-hypervisor-$vm_name.log"
|
||||
local log_file="/tmp/cloud-hypervisor-vm$vm_number.log"
|
||||
if [ -f "$log_file" ]; then
|
||||
log "Removing VM log file '$log_file'"
|
||||
rm -f "$log_file" || warn "Failed to remove log file '$log_file'"
|
||||
fi
|
||||
|
||||
# Remove any other temporary files
|
||||
rm -f "/tmp/cloud-hypervisor-$vm_name"* 2>/dev/null || true
|
||||
rm -f "/tmp/cloud-hypervisor-vm$vm_number"* 2>/dev/null || true
|
||||
}
|
||||
|
||||
# Function to delete a single VM
|
||||
delete_single_vm() {
|
||||
local vm_name="$1"
|
||||
local vm_dir="$VMS_SUBVOL/$vm_name"
|
||||
local vm_number="$1"
|
||||
local vm_dir="$VMS_SUBVOL/vm$vm_number"
|
||||
local vm_info_file="$vm_dir/vm-info.txt"
|
||||
|
||||
if [ ! -d "$vm_dir" ]; then
|
||||
warn "VM '$vm_name' not found at '$vm_dir'"
|
||||
warn "VM number '$vm_number' not found at '$vm_dir'"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log "Deleting VM: $vm_name"
|
||||
log "Deleting VM number: $vm_number"
|
||||
|
||||
# Initialize variables with defaults
|
||||
local VM_PID=""
|
||||
@@ -210,33 +219,33 @@ delete_single_vm() {
|
||||
else
|
||||
warn "VM info file not found at '$vm_info_file', proceeding with best-effort cleanup"
|
||||
# Try to guess some values
|
||||
TAP_NAME="tap-$vm_name"
|
||||
TAP_NAME="tap-vm$vm_number"
|
||||
BRIDGE_NAME="br0"
|
||||
VM_SOCKET="/tmp/cloud-hypervisor-$vm_name.sock"
|
||||
VM_SOCKET="/tmp/cloud-hypervisor-vm$vm_number.sock"
|
||||
fi
|
||||
|
||||
# Stop VM process
|
||||
if [ -n "$VM_PID" ]; then
|
||||
stop_vm_process "$VM_PID" "$vm_name"
|
||||
stop_vm_process "$VM_PID" "vm$vm_number"
|
||||
else
|
||||
# Try to find the process by name
|
||||
local found_pids=$(pgrep -f "cloud-hypervisor.*$vm_name" 2>/dev/null || echo "")
|
||||
local found_pids=$(pgrep -f "cloud-hypervisor.*vm$vm_number" 2>/dev/null || echo "")
|
||||
if [ -n "$found_pids" ]; then
|
||||
warn "Found VM process(es) by name: $found_pids"
|
||||
# Process each PID separately
|
||||
echo "$found_pids" | while read -r pid; do
|
||||
if [ -n "$pid" ]; then
|
||||
stop_vm_process "$pid" "$vm_name"
|
||||
stop_vm_process "$pid" "vm$vm_number"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
# Clean up network interfaces
|
||||
cleanup_network "$TAP_NAME" "$BRIDGE_NAME" "$vm_name"
|
||||
cleanup_network "$TAP_NAME" "$BRIDGE_NAME" "vm$vm_number"
|
||||
|
||||
# Clean up VM files and sockets
|
||||
cleanup_vm_files "$VM_SOCKET" "$vm_name"
|
||||
cleanup_vm_files "$VM_SOCKET" "$vm_number"
|
||||
|
||||
# Verify the directory is a btrfs subvolume before attempting deletion
|
||||
if btrfs subvolume show "$vm_dir" &>/dev/null; then
|
||||
@@ -253,7 +262,7 @@ delete_single_vm() {
|
||||
log "Directory '$vm_dir' removed successfully"
|
||||
fi
|
||||
|
||||
log "VM '$vm_name' deleted successfully"
|
||||
log "VM number '$vm_number' deleted successfully"
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -265,33 +274,93 @@ list_all_vms() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
for vm_dir in "$VMS_SUBVOL"/*; do
|
||||
for vm_dir in "$VMS_SUBVOL"/vm*; do
|
||||
if [ -d "$vm_dir" ]; then
|
||||
local vm_name=$(basename "$vm_dir")
|
||||
vm_list+=("$vm_name")
|
||||
# Extract number from vm directory name (vm1, vm2, etc.)
|
||||
local vm_number=${vm_name#vm}
|
||||
if [[ "$vm_number" =~ ^[0-9]+$ ]]; then
|
||||
vm_list+=("$vm_number")
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
printf '%s\n' "${vm_list[@]}"
|
||||
# Sort numerically
|
||||
if [ ${#vm_list[@]} -gt 0 ]; then
|
||||
printf '%s\n' "${vm_list[@]}" | sort -n
|
||||
fi
|
||||
}
|
||||
|
||||
# Main deletion logic
|
||||
if [ "$VM_TARGET" = "all" ]; then
|
||||
# Function to show detailed VM list
|
||||
show_vm_list() {
|
||||
local vm_numbers=($(list_all_vms))
|
||||
|
||||
if [ ${#vm_numbers[@]} -eq 0 ]; then
|
||||
info "No VMs found"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Existing VMs:"
|
||||
echo "============="
|
||||
|
||||
for vm_number in "${vm_numbers[@]}"; do
|
||||
local vm_dir="$VMS_SUBVOL/vm$vm_number"
|
||||
local vm_info_file="$vm_dir/vm-info.txt"
|
||||
local vm_ip="192.168.100.$vm_number"
|
||||
|
||||
echo -n "VM $vm_number: "
|
||||
|
||||
# Check if VM is running
|
||||
if [ -f "$vm_info_file" ]; then
|
||||
local VM_PID=""
|
||||
local VM_NAME=""
|
||||
local STARTED=""
|
||||
source "$vm_info_file" 2>/dev/null || true
|
||||
|
||||
if [ -n "$VM_PID" ] && kill -0 "$VM_PID" 2>/dev/null; then
|
||||
echo -e "${GREEN}RUNNING${NC} (PID: $VM_PID, IP: $vm_ip)"
|
||||
if [ -n "$VM_NAME" ]; then
|
||||
echo " Name: $VM_NAME"
|
||||
fi
|
||||
if [ -n "$STARTED" ]; then
|
||||
echo " Started: $STARTED"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}STOPPED${NC} (IP: $vm_ip)"
|
||||
if [ -n "$VM_NAME" ]; then
|
||||
echo " Name: $VM_NAME"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo -e "${RED}UNKNOWN${NC} (no info file)"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Main logic
|
||||
if [ "$VM_TARGET" = "list" ]; then
|
||||
# List all VMs
|
||||
show_vm_list
|
||||
exit 0
|
||||
|
||||
elif [ "$VM_TARGET" = "all" ]; then
|
||||
# Delete all VMs
|
||||
warn "You are about to delete ALL VMs!"
|
||||
echo ""
|
||||
|
||||
# List all VMs
|
||||
vm_list=($(list_all_vms))
|
||||
vm_numbers=($(list_all_vms))
|
||||
|
||||
if [ ${#vm_list[@]} -eq 0 ]; then
|
||||
if [ ${#vm_numbers[@]} -eq 0 ]; then
|
||||
info "No VMs found to delete"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "VMs to be deleted:"
|
||||
for vm in "${vm_list[@]}"; do
|
||||
echo " - $vm"
|
||||
echo "VM numbers to be deleted:"
|
||||
for vm_number in "${vm_numbers[@]}"; do
|
||||
echo " - VM $vm_number (IP: 192.168.100.$vm_number)"
|
||||
done
|
||||
echo ""
|
||||
|
||||
@@ -301,8 +370,8 @@ if [ "$VM_TARGET" = "all" ]; then
|
||||
success_count=0
|
||||
failure_count=0
|
||||
|
||||
for vm_name in "${vm_list[@]}"; do
|
||||
if delete_single_vm "$vm_name"; then
|
||||
for vm_number in "${vm_numbers[@]}"; do
|
||||
if delete_single_vm "$vm_number"; then
|
||||
success_count=$((success_count + 1))
|
||||
else
|
||||
failure_count=$((failure_count + 1))
|
||||
@@ -338,14 +407,14 @@ if [ "$VM_TARGET" = "all" ]; then
|
||||
|
||||
else
|
||||
# Delete single VM
|
||||
vm_name="$VM_TARGET"
|
||||
vm_number="$VM_TARGET"
|
||||
|
||||
if [ ! -d "$VMS_SUBVOL/$vm_name" ]; then
|
||||
error "VM '$vm_name' not found"
|
||||
if [ ! -d "$VMS_SUBVOL/vm$vm_number" ]; then
|
||||
error "VM number '$vm_number' not found"
|
||||
fi
|
||||
|
||||
log "Deleting VM '$vm_name' without confirmation..."
|
||||
delete_single_vm "$vm_name"
|
||||
log "Deleting VM number '$vm_number' without confirmation..."
|
||||
delete_single_vm "$vm_number"
|
||||
fi
|
||||
|
||||
log "VM deletion script completed successfully"
|
||||
Reference in New Issue
Block a user