...
This commit is contained in:
parent
13839041ff
commit
69c6a57fa4
178
tools/install_cloudhypervisor.sh
Executable file
178
tools/install_cloudhypervisor.sh
Executable file
@ -0,0 +1,178 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Cloud Hypervisor Installation Script
|
||||||
|
# Downloads and installs Cloud Hypervisor from GitHub releases
|
||||||
|
# Compatible with Ubuntu/Debian systems
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Cloud Hypervisor configuration
|
||||||
|
CH_VERSION="v46.0"
|
||||||
|
CH_URL="https://github.com/cloud-hypervisor/cloud-hypervisor/releases/download/${CH_VERSION}/cloud-hypervisor-static"
|
||||||
|
CH_BINARY="cloud-hypervisor"
|
||||||
|
MIN_SIZE_MB=4
|
||||||
|
|
||||||
|
log() {
|
||||||
|
echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] $1${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
warn() {
|
||||||
|
echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING: $1${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: $1${NC}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if running as root
|
||||||
|
if [ "$EUID" -eq 0 ]; then
|
||||||
|
log "Running as root. Cloud Hypervisor will be installed system-wide."
|
||||||
|
INSTALL_DIR="/usr/local/bin"
|
||||||
|
else
|
||||||
|
log "Installing Cloud Hypervisor for current user"
|
||||||
|
INSTALL_DIR="$HOME/.local/bin"
|
||||||
|
# Create local bin directory if it doesn't exist
|
||||||
|
mkdir -p "$INSTALL_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if Cloud Hypervisor is already installed
|
||||||
|
if command -v cloud-hypervisor &> /dev/null; then
|
||||||
|
CH_CURRENT_VERSION=$(cloud-hypervisor --version 2>/dev/null | head -n1 || echo "")
|
||||||
|
if [ -n "$CH_CURRENT_VERSION" ]; then
|
||||||
|
warn "Cloud Hypervisor is already installed: $CH_CURRENT_VERSION"
|
||||||
|
read -p "Do you want to update/reinstall? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
log "Installation cancelled"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for required dependencies
|
||||||
|
log "Checking system dependencies..."
|
||||||
|
MISSING_DEPS=()
|
||||||
|
|
||||||
|
# Check for curl
|
||||||
|
if ! command -v curl &> /dev/null; then
|
||||||
|
MISSING_DEPS+=("curl")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install missing dependencies
|
||||||
|
if [ ${#MISSING_DEPS[@]} -gt 0 ]; then
|
||||||
|
log "Installing missing dependencies: ${MISSING_DEPS[*]}"
|
||||||
|
if [ "$EUID" -eq 0 ]; then
|
||||||
|
apt update
|
||||||
|
apt install -y "${MISSING_DEPS[@]}"
|
||||||
|
else
|
||||||
|
log "Please install the following packages and run this script again:"
|
||||||
|
log "sudo apt update && sudo apt install -y ${MISSING_DEPS[*]}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "Starting Cloud Hypervisor installation..."
|
||||||
|
log "Version: $CH_VERSION"
|
||||||
|
log "Install directory: $INSTALL_DIR"
|
||||||
|
|
||||||
|
# Create temporary directory for download
|
||||||
|
TEMP_DIR=$(mktemp -d)
|
||||||
|
TEMP_FILE="$TEMP_DIR/$CH_BINARY"
|
||||||
|
|
||||||
|
# Cleanup function
|
||||||
|
cleanup() {
|
||||||
|
rm -rf "$TEMP_DIR"
|
||||||
|
}
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
log "Downloading Cloud Hypervisor from $CH_URL..."
|
||||||
|
|
||||||
|
# Download with size verification
|
||||||
|
if ! curl -L --fail --progress-bar -o "$TEMP_FILE" "$CH_URL"; then
|
||||||
|
error "Failed to download Cloud Hypervisor from $CH_URL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check file size
|
||||||
|
FILE_SIZE=$(stat -c%s "$TEMP_FILE" 2>/dev/null || stat -f%z "$TEMP_FILE" 2>/dev/null || echo "0")
|
||||||
|
FILE_SIZE_MB=$((FILE_SIZE / 1024 / 1024))
|
||||||
|
|
||||||
|
log "Downloaded file size: ${FILE_SIZE_MB}MB"
|
||||||
|
|
||||||
|
if [ "$FILE_SIZE_MB" -lt "$MIN_SIZE_MB" ]; then
|
||||||
|
error "Downloaded file is too small (${FILE_SIZE_MB}MB). Expected at least ${MIN_SIZE_MB}MB. Download may be corrupted."
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "✅ Download size verification passed (${FILE_SIZE_MB}MB >= ${MIN_SIZE_MB}MB)"
|
||||||
|
|
||||||
|
# Make the binary executable
|
||||||
|
chmod +x "$TEMP_FILE"
|
||||||
|
|
||||||
|
# Test the binary before installation
|
||||||
|
log "Testing downloaded binary..."
|
||||||
|
if ! "$TEMP_FILE" --version &> /dev/null; then
|
||||||
|
error "Downloaded binary is not working correctly"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "✅ Binary test passed"
|
||||||
|
|
||||||
|
# Install the binary
|
||||||
|
log "Installing Cloud Hypervisor to $INSTALL_DIR..."
|
||||||
|
if [ "$EUID" -eq 0 ]; then
|
||||||
|
cp "$TEMP_FILE" "$INSTALL_DIR/$CH_BINARY"
|
||||||
|
else
|
||||||
|
cp "$TEMP_FILE" "$INSTALL_DIR/$CH_BINARY"
|
||||||
|
# Add to PATH if not already there
|
||||||
|
if [[ ":$PATH:" != *":$INSTALL_DIR:"* ]]; then
|
||||||
|
warn "Adding $INSTALL_DIR to PATH in ~/.bashrc"
|
||||||
|
echo "export PATH=\"$INSTALL_DIR:\$PATH\"" >> ~/.bashrc
|
||||||
|
export PATH="$INSTALL_DIR:$PATH"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify installation
|
||||||
|
log "Verifying Cloud Hypervisor installation..."
|
||||||
|
|
||||||
|
# Set PATH for verification
|
||||||
|
if [ "$EUID" -ne 0 ]; then
|
||||||
|
export PATH="$INSTALL_DIR:$PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v cloud-hypervisor &> /dev/null; then
|
||||||
|
CH_VERSION_OUTPUT=$(cloud-hypervisor --version 2>/dev/null || echo "")
|
||||||
|
if [ -n "$CH_VERSION_OUTPUT" ]; then
|
||||||
|
log "✅ Cloud Hypervisor installation successful!"
|
||||||
|
log "Version: $CH_VERSION_OUTPUT"
|
||||||
|
log "Location: $(which cloud-hypervisor)"
|
||||||
|
|
||||||
|
# Test basic functionality
|
||||||
|
log "Testing basic functionality..."
|
||||||
|
if cloud-hypervisor --help &> /dev/null; then
|
||||||
|
log "✅ Basic functionality test passed"
|
||||||
|
else
|
||||||
|
warn "Basic functionality test failed, but binary is installed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "✅ Cloud Hypervisor installation completed successfully!"
|
||||||
|
log ""
|
||||||
|
log "Next steps:"
|
||||||
|
if [ "$EUID" -eq 0 ]; then
|
||||||
|
log "- Cloud Hypervisor is available system-wide"
|
||||||
|
else
|
||||||
|
log "- Run 'source ~/.bashrc' to update PATH in this session"
|
||||||
|
log "- Or restart your terminal"
|
||||||
|
fi
|
||||||
|
log "- Run 'cloud-hypervisor --help' to see available options"
|
||||||
|
log "- Check the documentation at: https://github.com/cloud-hypervisor/cloud-hypervisor"
|
||||||
|
else
|
||||||
|
error "Cloud Hypervisor was installed but version check failed"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
error "Cloud Hypervisor installation failed. Binary not found in PATH."
|
||||||
|
fi
|
293
tools/ubuntu_vm_start.sh
Executable file
293
tools/ubuntu_vm_start.sh
Executable file
@ -0,0 +1,293 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Ubuntu VM Start Script with Cloud Hypervisor and Btrfs Thin Provisioning
|
||||||
|
# Usage: ubuntu_vm_start.sh $name $mem $cores
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
BASE_IMAGE_NAME="ubuntu-24.04-server-cloudimg-amd64"
|
||||||
|
BASE_IMAGE_URL="https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img"
|
||||||
|
FIRMWARE_URL="https://github.com/cloud-hypervisor/rust-hypervisor-firmware/releases/download/0.5.0/hypervisor-fw"
|
||||||
|
VM_BASE_DIR="/var/lib/vms"
|
||||||
|
BTRFS_MOUNT_POINT="/var/lib/vms"
|
||||||
|
BASE_SUBVOL="$BTRFS_MOUNT_POINT/base"
|
||||||
|
VMS_SUBVOL="$BTRFS_MOUNT_POINT/vms"
|
||||||
|
|
||||||
|
log() {
|
||||||
|
echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] $1${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
warn() {
|
||||||
|
echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING: $1${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: $1${NC}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
info() {
|
||||||
|
echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')] INFO: $1${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if running as root
|
||||||
|
if [ "$EUID" -ne 0 ]; then
|
||||||
|
error "This script must be run as root for btrfs operations"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
if [ $# -ne 3 ]; then
|
||||||
|
error "Usage: $0 <vm_name> <memory_mb> <cpu_cores>"
|
||||||
|
fi
|
||||||
|
|
||||||
|
VM_NAME="$1"
|
||||||
|
MEMORY_MB="$2"
|
||||||
|
CPU_CORES="$3"
|
||||||
|
|
||||||
|
# Validate arguments
|
||||||
|
if ! [[ "$MEMORY_MB" =~ ^[0-9]+$ ]]; then
|
||||||
|
error "Memory must be a number (in MB)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! [[ "$CPU_CORES" =~ ^[0-9]+$ ]]; then
|
||||||
|
error "CPU cores must be a number"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$VM_NAME" =~ [^a-zA-Z0-9_-] ]]; then
|
||||||
|
error "VM name can only contain alphanumeric characters, hyphens, and underscores"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "Starting VM: $VM_NAME with ${MEMORY_MB}MB RAM and $CPU_CORES CPU cores"
|
||||||
|
|
||||||
|
# Check if cloud-hypervisor is available
|
||||||
|
if ! command -v cloud-hypervisor &> /dev/null; then
|
||||||
|
error "cloud-hypervisor not found. Please install it first."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if qemu-img is available (for image conversion)
|
||||||
|
if ! command -v qemu-img &> /dev/null; then
|
||||||
|
warn "qemu-img not found. Installing qemu-utils..."
|
||||||
|
apt update && apt install -y qemu-utils
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create base directory structure
|
||||||
|
mkdir -p "$VM_BASE_DIR"
|
||||||
|
|
||||||
|
# Check if the base directory is on btrfs
|
||||||
|
if ! btrfs filesystem show "$VM_BASE_DIR" &>/dev/null; then
|
||||||
|
error "Base directory $VM_BASE_DIR is not on a btrfs filesystem. Please create a btrfs filesystem first."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create base and vms subvolumes if they don't exist
|
||||||
|
if [ ! -d "$BASE_SUBVOL" ]; then
|
||||||
|
log "Creating base subvolume at $BASE_SUBVOL"
|
||||||
|
btrfs subvolume create "$BASE_SUBVOL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "$VMS_SUBVOL" ]; then
|
||||||
|
log "Creating VMs subvolume at $VMS_SUBVOL"
|
||||||
|
btrfs subvolume create "$VMS_SUBVOL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Define paths
|
||||||
|
BASE_IMAGE_PATH="$BASE_SUBVOL/${BASE_IMAGE_NAME}.raw"
|
||||||
|
FIRMWARE_PATH="$BASE_SUBVOL/hypervisor-fw"
|
||||||
|
VM_SUBVOL_PATH="$VMS_SUBVOL/$VM_NAME"
|
||||||
|
VM_IMAGE_PATH="$VM_SUBVOL_PATH/${VM_NAME}.raw"
|
||||||
|
CLOUD_INIT_PATH="$VM_SUBVOL_PATH/cloud-init.img"
|
||||||
|
|
||||||
|
# Download and prepare base image if it doesn't exist
|
||||||
|
if [ ! -f "$BASE_IMAGE_PATH" ]; then
|
||||||
|
log "Base image not found. Downloading Ubuntu cloud image..."
|
||||||
|
|
||||||
|
# Download the qcow2 image
|
||||||
|
TEMP_QCOW2="/tmp/${BASE_IMAGE_NAME}.img"
|
||||||
|
if ! curl -L --fail --progress-bar -o "$TEMP_QCOW2" "$BASE_IMAGE_URL"; then
|
||||||
|
error "Failed to download Ubuntu cloud image from $BASE_IMAGE_URL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "Converting qcow2 image to raw format..."
|
||||||
|
qemu-img convert -p -f qcow2 -O raw "$TEMP_QCOW2" "$BASE_IMAGE_PATH"
|
||||||
|
|
||||||
|
# Cleanup temporary file
|
||||||
|
rm -f "$TEMP_QCOW2"
|
||||||
|
|
||||||
|
log "Base image created at $BASE_IMAGE_PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Download firmware if it doesn't exist
|
||||||
|
if [ ! -f "$FIRMWARE_PATH" ]; then
|
||||||
|
log "Downloading Cloud Hypervisor firmware..."
|
||||||
|
if ! curl -L --fail --progress-bar -o "$FIRMWARE_PATH" "$FIRMWARE_URL"; then
|
||||||
|
error "Failed to download firmware from $FIRMWARE_URL"
|
||||||
|
fi
|
||||||
|
chmod +x "$FIRMWARE_PATH"
|
||||||
|
log "Firmware downloaded to $FIRMWARE_PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create VM subvolume by cloning from base
|
||||||
|
if [ -d "$VM_SUBVOL_PATH" ]; then
|
||||||
|
warn "VM subvolume $VM_NAME already exists. Removing it..."
|
||||||
|
btrfs subvolume delete "$VM_SUBVOL_PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "Creating VM subvolume by cloning base subvolume..."
|
||||||
|
btrfs subvolume snapshot "$BASE_SUBVOL" "$VM_SUBVOL_PATH"
|
||||||
|
|
||||||
|
# Copy the base image to VM subvolume (this will be a CoW copy initially)
|
||||||
|
log "Creating VM disk image (thin provisioned)..."
|
||||||
|
cp --reflink=always "$BASE_IMAGE_PATH" "$VM_IMAGE_PATH"
|
||||||
|
|
||||||
|
# Create cloud-init image for first boot
|
||||||
|
log "Creating cloud-init configuration..."
|
||||||
|
cat > "/tmp/user-data" << EOF
|
||||||
|
#cloud-config
|
||||||
|
users:
|
||||||
|
- name: ubuntu
|
||||||
|
sudo: ALL=(ALL) NOPASSWD:ALL
|
||||||
|
shell: /bin/bash
|
||||||
|
lock_passwd: false
|
||||||
|
passwd: \$6\$rounds=4096\$saltsalt\$L9.LKkHxeed8Kn9.Kk8nNWn8W.XhHPyjKJJXYqKoTFJJy7P8dMCFK
|
||||||
|
ssh_authorized_keys:
|
||||||
|
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC... # Add your SSH public key here
|
||||||
|
groups: sudo
|
||||||
|
home: /home/ubuntu
|
||||||
|
|
||||||
|
ssh_pwauth: true
|
||||||
|
disable_root: false
|
||||||
|
chpasswd:
|
||||||
|
expire: false
|
||||||
|
|
||||||
|
# Enable SSH
|
||||||
|
ssh_authorized_keys: []
|
||||||
|
|
||||||
|
# Package updates and installs
|
||||||
|
package_update: true
|
||||||
|
package_upgrade: true
|
||||||
|
packages:
|
||||||
|
- curl
|
||||||
|
- wget
|
||||||
|
- git
|
||||||
|
- htop
|
||||||
|
- vim
|
||||||
|
|
||||||
|
# Final message
|
||||||
|
final_message: "Cloud-init setup complete. VM is ready!"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Create meta-data file
|
||||||
|
cat > "/tmp/meta-data" << EOF
|
||||||
|
instance-id: $VM_NAME
|
||||||
|
local-hostname: $VM_NAME
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Create cloud-init ISO
|
||||||
|
log "Creating cloud-init ISO..."
|
||||||
|
if command -v genisoimage &> /dev/null; then
|
||||||
|
genisoimage -output "$CLOUD_INIT_PATH" -volid cidata -joliet -rock /tmp/user-data /tmp/meta-data
|
||||||
|
elif command -v mkisofs &> /dev/null; then
|
||||||
|
mkisofs -o "$CLOUD_INIT_PATH" -V cidata -J -r /tmp/user-data /tmp/meta-data
|
||||||
|
else
|
||||||
|
error "Neither genisoimage nor mkisofs found. Please install genisoimage or cdrtools."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Cleanup temporary files
|
||||||
|
rm -f /tmp/user-data /tmp/meta-data
|
||||||
|
|
||||||
|
log "Cloud-init ISO created at $CLOUD_INIT_PATH"
|
||||||
|
|
||||||
|
# Resize the VM disk to give it more space (optional, expand to 20GB)
|
||||||
|
log "Resizing VM disk to 20GB..."
|
||||||
|
qemu-img resize "$VM_IMAGE_PATH" 20G
|
||||||
|
|
||||||
|
# Create network configuration
|
||||||
|
BRIDGE_NAME="br0"
|
||||||
|
TAP_NAME="tap-$VM_NAME"
|
||||||
|
|
||||||
|
# Check if bridge exists, create if not
|
||||||
|
if ! ip link show "$BRIDGE_NAME" &>/dev/null; then
|
||||||
|
log "Creating bridge interface $BRIDGE_NAME..."
|
||||||
|
ip link add name "$BRIDGE_NAME" type bridge
|
||||||
|
ip link set dev "$BRIDGE_NAME" up
|
||||||
|
# You may want to configure the bridge with an IP address
|
||||||
|
# ip addr add 192.168.100.1/24 dev "$BRIDGE_NAME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create TAP interface for the VM
|
||||||
|
log "Creating TAP interface $TAP_NAME..."
|
||||||
|
ip tuntap add dev "$TAP_NAME" mode tap
|
||||||
|
ip link set dev "$TAP_NAME" up
|
||||||
|
ip link set dev "$TAP_NAME" master "$BRIDGE_NAME"
|
||||||
|
|
||||||
|
# Start the VM with Cloud Hypervisor
|
||||||
|
log "Starting VM $VM_NAME..."
|
||||||
|
VM_SOCKET="/tmp/cloud-hypervisor-$VM_NAME.sock"
|
||||||
|
|
||||||
|
# Remove existing socket if it exists
|
||||||
|
rm -f "$VM_SOCKET"
|
||||||
|
|
||||||
|
# Start Cloud Hypervisor in background
|
||||||
|
cloud-hypervisor \
|
||||||
|
--api-socket "$VM_SOCKET" \
|
||||||
|
--memory "size=${MEMORY_MB}M" \
|
||||||
|
--cpus "boot=$CPU_CORES" \
|
||||||
|
--kernel "$FIRMWARE_PATH" \
|
||||||
|
--disk "path=$VM_IMAGE_PATH" \
|
||||||
|
--disk "path=$CLOUD_INIT_PATH,readonly=on" \
|
||||||
|
--net "tap=$TAP_NAME,mac=52:54:00:$(printf '%02x:%02x:%02x' $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)))" \
|
||||||
|
--serial tty \
|
||||||
|
--console off \
|
||||||
|
--log-level info &
|
||||||
|
|
||||||
|
VM_PID=$!
|
||||||
|
|
||||||
|
log "VM $VM_NAME started with PID $VM_PID"
|
||||||
|
log "VM socket: $VM_SOCKET"
|
||||||
|
log "TAP interface: $TAP_NAME"
|
||||||
|
log "Bridge interface: $BRIDGE_NAME"
|
||||||
|
|
||||||
|
# Save VM information for management
|
||||||
|
VM_INFO_FILE="$VM_SUBVOL_PATH/vm-info.txt"
|
||||||
|
cat > "$VM_INFO_FILE" << EOF
|
||||||
|
VM_NAME=$VM_NAME
|
||||||
|
VM_PID=$VM_PID
|
||||||
|
VM_SOCKET=$VM_SOCKET
|
||||||
|
TAP_NAME=$TAP_NAME
|
||||||
|
BRIDGE_NAME=$BRIDGE_NAME
|
||||||
|
MEMORY_MB=$MEMORY_MB
|
||||||
|
CPU_CORES=$CPU_CORES
|
||||||
|
VM_IMAGE_PATH=$VM_IMAGE_PATH
|
||||||
|
CLOUD_INIT_PATH=$CLOUD_INIT_PATH
|
||||||
|
STARTED=$(date)
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log "VM information saved to $VM_INFO_FILE"
|
||||||
|
|
||||||
|
# Function to cleanup on exit
|
||||||
|
cleanup() {
|
||||||
|
log "Cleaning up VM $VM_NAME..."
|
||||||
|
if kill -0 "$VM_PID" 2>/dev/null; then
|
||||||
|
kill "$VM_PID"
|
||||||
|
wait "$VM_PID" 2>/dev/null
|
||||||
|
fi
|
||||||
|
ip link delete "$TAP_NAME" 2>/dev/null || true
|
||||||
|
rm -f "$VM_SOCKET"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set trap for cleanup on script exit
|
||||||
|
trap cleanup EXIT INT TERM
|
||||||
|
|
||||||
|
log "VM $VM_NAME is running. Press Ctrl+C to stop."
|
||||||
|
log "To connect via SSH (once VM is booted): ssh ubuntu@<vm-ip>"
|
||||||
|
log "Default password: ubuntu (change after first login)"
|
||||||
|
|
||||||
|
# Wait for the VM process
|
||||||
|
wait "$VM_PID"
|
Loading…
Reference in New Issue
Block a user