This commit is contained in:
2025-06-15 19:31:47 +02:00
parent 63f4f77366
commit d336f36929
2 changed files with 225 additions and 78 deletions

View File

@@ -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"