Created
March 27, 2026 04:23
-
-
Save swateek/1bbd781eda99f2e9019044cc5e38dcdf to your computer and use it in GitHub Desktop.
Repairs Vagrant VMs By Removing Lock and Swap Files
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| ############################################################################### | |
| # Vagrant VMware Repair Script | |
| # | |
| # Purpose: Fix "Directory not empty" and disk access errors when a computer | |
| # restarts while Vagrant is running or the VM crashes unexpectedly. | |
| # | |
| # Usage: | |
| # bash vagrant-vmware-repair.sh <vm-name> # Interactive mode (recommended) | |
| # bash vagrant-vmware-repair.sh <vm-name> --force # Skip confirmations | |
| # bash vagrant-vmware-repair.sh --help # Show this help | |
| # | |
| # Author: Generated for Vagrant troubleshooting | |
| # License: MIT | |
| ############################################################################### | |
| set -e | |
| # Colors for output | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| BLUE='\033[0;34m' | |
| NC='\033[0m' # No Color | |
| # Default settings | |
| FORCE_MODE=false | |
| VAGRANT_DIR="" | |
| VM_NAME="" | |
| # Functions | |
| show_help() { | |
| cat << EOF | |
| ${BLUE}Vagrant VMware Repair Script${NC} | |
| This script fixes common Vagrant VMware issues caused by: | |
| - Computer restarts during VM operation | |
| - VM crashes or hard shutdowns | |
| - Corrupted lock files (.lck, .vswp) | |
| - "Directory not empty" errors | |
| ${YELLOW}Usage:${NC} | |
| bash vagrant-vmware-repair.sh <vm-name> # Interactive mode | |
| bash vagrant-vmware-repair.sh <vm-name> --force # Skip confirmations | |
| bash vagrant-vmware-repair.sh --help # Show this help | |
| ${YELLOW}Arguments:${NC} | |
| <vm-name> Name of the Vagrant VM to repair (REQUIRED) | |
| Example: ubuntu24-apple-m1 | |
| ${YELLOW}Options:${NC} | |
| --force Skip confirmation prompts (useful for automation) | |
| --help Show this help message | |
| ${YELLOW}What it does:${NC} | |
| 1. Searches for your Vagrant project (.vagrant directory) | |
| 2. Locates the specified VM | |
| 3. Force halts the VM | |
| 4. Removes lock files (.lck, .vswp) that block disk access | |
| 5. Prepares VM for restart with 'vagrant up' | |
| ${YELLOW}Examples:${NC} | |
| bash vagrant-vmware-repair.sh ubuntu24-apple-m1 | |
| bash vagrant-vmware-repair.sh my-dev-vm --force | |
| bash vagrant-vmware-repair.sh --help | |
| ${YELLOW}Tip:${NC} | |
| This script can be run from ANY directory - it will find your | |
| Vagrant project automatically. Just make sure you're within the | |
| same project hierarchy. | |
| EOF | |
| } | |
| log_info() { | |
| echo -e "${BLUE}ℹ${NC} $1" | |
| } | |
| log_success() { | |
| echo -e "${GREEN}✓${NC} $1" | |
| } | |
| log_warning() { | |
| echo -e "${YELLOW}⚠${NC} $1" | |
| } | |
| log_error() { | |
| echo -e "${RED}✗${NC} $1" | |
| } | |
| confirm() { | |
| local prompt="$1" | |
| local default="${2:-n}" | |
| if [ "$FORCE_MODE" = true ]; then | |
| return 0 | |
| fi | |
| local response | |
| if [ "$default" = "y" ]; then | |
| read -p "$(echo -e ${YELLOW}$prompt${NC} [Y/n]: )" response | |
| response=${response:-y} | |
| else | |
| read -p "$(echo -e ${YELLOW}$prompt${NC} [y/N]: )" response | |
| response=${response:-n} | |
| fi | |
| [[ "$response" =~ ^[Yy]$ ]] | |
| } | |
| find_vagrant_root() { | |
| # Search up the directory tree for .vagrant directory | |
| local current_dir=$(pwd) | |
| while [ "$current_dir" != "/" ]; do | |
| if [ -d "$current_dir/.vagrant" ]; then | |
| VAGRANT_DIR="$current_dir" | |
| return 0 | |
| fi | |
| current_dir=$(dirname "$current_dir") | |
| done | |
| return 1 | |
| } | |
| find_vmware_vm_dir() { | |
| local vm_name="$1" | |
| local vagrant_machines_dir="$VAGRANT_DIR/.vagrant/machines" | |
| if [ ! -d "$vagrant_machines_dir" ]; then | |
| return 1 | |
| fi | |
| # Look for the specific VM in vmware_desktop | |
| if [ -d "$vagrant_machines_dir/$vm_name/vmware_desktop" ]; then | |
| echo "$vagrant_machines_dir/$vm_name/vmware_desktop" | |
| return 0 | |
| fi | |
| return 1 | |
| } | |
| list_available_vms() { | |
| local vagrant_machines_dir="$VAGRANT_DIR/.vagrant/machines" | |
| if [ ! -d "$vagrant_machines_dir" ]; then | |
| return 1 | |
| fi | |
| echo "" | |
| log_info "Available Vagrant VMs in this project:" | |
| for vm_dir in "$vagrant_machines_dir"/*; do | |
| if [ -d "$vm_dir" ]; then | |
| local vm=$(basename "$vm_dir") | |
| if [ -d "$vm_dir/vmware_desktop" ]; then | |
| echo " • $vm" | |
| fi | |
| fi | |
| done | |
| } | |
| repair_vm() { | |
| local vm_dir="$1" | |
| local vm_name=$(basename $(dirname "$vm_dir")) | |
| log_info "Repairing VM: ${BLUE}$vm_name${NC}" | |
| if [ ! -d "$vm_dir" ]; then | |
| log_error "VM directory not found: $vm_dir" | |
| return 1 | |
| fi | |
| # Count lock files before | |
| local lock_files=$(find "$vm_dir" -type f \( -name "*.lck" -o -name "*.vswp" \) 2>/dev/null | wc -l) | |
| if [ "$lock_files" -gt 0 ]; then | |
| log_warning "Found $lock_files lock file(s)" | |
| # Remove lock files | |
| if find "$vm_dir" -type f \( -name "*.lck" -o -name "*.vswp" \) -delete 2>/dev/null; then | |
| log_success "Removed lock files" | |
| else | |
| log_error "Failed to remove some lock files (may need sudo)" | |
| fi | |
| else | |
| log_info "No lock files found" | |
| fi | |
| # Check for corrupted snapshots | |
| if [ -d "$vm_dir" ] && [ -n "$(find "$vm_dir" -name "*.vmsd" 2>/dev/null)" ]; then | |
| log_warning "Found snapshot metadata files" | |
| fi | |
| } | |
| main() { | |
| echo -e "${BLUE}╔════════════════════════════════════════════════════╗${NC}" | |
| echo -e "${BLUE}║ Vagrant VMware Repair Script${NC}" | |
| echo -e "${BLUE}╚════════════════════════════════════════════════════╝${NC}" | |
| echo "" | |
| # Parse arguments | |
| while [ $# -gt 0 ]; do | |
| case "$1" in | |
| --help) | |
| show_help | |
| exit 0 | |
| ;; | |
| --force) | |
| FORCE_MODE=true | |
| log_info "Force mode enabled (skipping confirmations)" | |
| ;; | |
| -*) | |
| log_error "Unknown option: $1" | |
| show_help | |
| exit 1 | |
| ;; | |
| *) | |
| # First non-option argument is the VM name | |
| if [ -z "$VM_NAME" ]; then | |
| VM_NAME="$1" | |
| else | |
| log_error "Unexpected argument: $1" | |
| show_help | |
| exit 1 | |
| fi | |
| ;; | |
| esac | |
| shift | |
| done | |
| # Validate VM name was provided | |
| if [ -z "$VM_NAME" ]; then | |
| log_error "VM name is required!" | |
| echo "" | |
| show_help | |
| exit 1 | |
| fi | |
| log_info "Target VM: ${BLUE}$VM_NAME${NC}" | |
| echo "" | |
| # Find Vagrant root directory | |
| log_info "Looking for Vagrant project (.vagrant directory)..." | |
| if ! find_vagrant_root; then | |
| log_error ".vagrant directory not found in current directory or parents" | |
| echo "" | |
| log_info "Make sure you're within a Vagrant project hierarchy" | |
| exit 1 | |
| fi | |
| log_success "Found Vagrant project: ${BLUE}$VAGRANT_DIR${NC}" | |
| echo "" | |
| # Find the specific VM | |
| log_info "Looking for VM: ${BLUE}$VM_NAME${NC}..." | |
| local vm_dir=$(find_vmware_vm_dir "$VM_NAME") | |
| if [ -z "$vm_dir" ]; then | |
| log_error "VMware VM not found: ${BLUE}$VM_NAME${NC}" | |
| list_available_vms | |
| exit 1 | |
| fi | |
| log_success "Found VM at: ${BLUE}$vm_dir${NC}" | |
| echo "" | |
| # Confirm before proceeding | |
| if ! confirm "Repair VM '${BLUE}$VM_NAME${NC}'? This will halt the VM and remove lock files." "y"; then | |
| log_warning "Cancelled" | |
| exit 0 | |
| fi | |
| echo "" | |
| # Halt VMs | |
| log_info "Halting VM: ${BLUE}$VM_NAME${NC}..." | |
| cd "$VAGRANT_DIR" | |
| if vagrant halt "$VM_NAME" -f 2>/dev/null; then | |
| log_success "VM halted" | |
| else | |
| log_warning "VM was already stopped (this is OK)" | |
| fi | |
| echo "" | |
| # Repair the VM | |
| log_info "Removing lock files..." | |
| if repair_vm "$vm_dir"; then | |
| echo "" | |
| echo -e "${BLUE}╔════════════════════════════════════════════════════╗${NC}" | |
| log_success "Repair complete!" | |
| echo "" | |
| echo -e "${GREEN}Next steps:${NC}" | |
| echo " 1. cd $VAGRANT_DIR" | |
| echo " 2. vagrant up $VM_NAME" | |
| echo "" | |
| log_info "Your VM should start normally now" | |
| echo -e "${BLUE}╚════════════════════════════════════════════════════╝${NC}" | |
| else | |
| echo "" | |
| echo -e "${BLUE}╔════════════════════════════════════════════════════╗${NC}" | |
| log_error "Repair encountered errors" | |
| echo "" | |
| echo -e "${YELLOW}Try these next:${NC}" | |
| echo " 1. Run: vagrant destroy $VM_NAME -f" | |
| echo " 2. Then: vagrant up $VM_NAME" | |
| echo -e "${BLUE}╚════════════════════════════════════════════════════╝${NC}" | |
| exit 1 | |
| fi | |
| } | |
| # Run main function | |
| main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment