Initial commit: loc_az_hci (smom-dbis-138 excluded via .gitignore)
Some checks failed
Test / test (push) Has been cancelled
Some checks failed
Test / test (push) Has been cancelled
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
722
scripts/vm-management/create/create-vm-from-image.sh
Executable file
722
scripts/vm-management/create/create-vm-from-image.sh
Executable file
@@ -0,0 +1,722 @@
|
||||
#!/bin/bash
|
||||
source ~/.bashrc
|
||||
# Create Proxmox VM from QCOW2/RAW Image - Comprehensive Automation Script
|
||||
#
|
||||
# This script automates the complete workflow for creating a VM from any disk image
|
||||
# in Proxmox VE using the qm command-line interface.
|
||||
#
|
||||
# Reference: https://pve.proxmox.com/pve-docs/qm.1.html
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/create-vm-from-image.sh --vmid 9000 --name "ubuntu-24.04" \
|
||||
# --image /path/to/image.img --storage local-lvm
|
||||
|
||||
set -e
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Logging functions
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
log_step() {
|
||||
echo -e "${BLUE}[STEP]${NC} $1"
|
||||
}
|
||||
|
||||
# Default values
|
||||
VMID=""
|
||||
VMNAME=""
|
||||
IMAGE=""
|
||||
STORAGE="local-lvm"
|
||||
MEMORY=4096
|
||||
CORES=2
|
||||
BRIDGE="vmbr0"
|
||||
VLAN_TAG=""
|
||||
ENABLE_CLOUD_INIT=false
|
||||
ENABLE_UEFI=false
|
||||
ENABLE_TEMPLATE=false
|
||||
ENABLE_SERIAL=false
|
||||
CIUSER=""
|
||||
CIPASSWORD=""
|
||||
SSHKEY=""
|
||||
IPCONFIG=""
|
||||
NAMESERVER=""
|
||||
SEARCHDOMAIN=""
|
||||
CPU_TYPE="host"
|
||||
ENABLE_AGENT=true
|
||||
IOTHREAD=true
|
||||
CACHE_MODE="none"
|
||||
ENABLE_DISCARD=false
|
||||
BALLOON=0
|
||||
DESCRIPTION=""
|
||||
TAGS=""
|
||||
NODE=""
|
||||
DRY_RUN=false
|
||||
|
||||
# Load environment variables from .env if available
|
||||
if [ -f .env ]; then
|
||||
set -a
|
||||
source <(grep -v '^#' .env | grep -v '^$' | sed 's/#.*$//' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | grep '=')
|
||||
set +a
|
||||
fi
|
||||
|
||||
# Parse command line arguments
|
||||
parse_args() {
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--vmid)
|
||||
VMID="$2"
|
||||
shift 2
|
||||
;;
|
||||
--name)
|
||||
VMNAME="$2"
|
||||
shift 2
|
||||
;;
|
||||
--image)
|
||||
IMAGE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--storage)
|
||||
STORAGE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--memory)
|
||||
MEMORY="$2"
|
||||
shift 2
|
||||
;;
|
||||
--cores)
|
||||
CORES="$2"
|
||||
shift 2
|
||||
;;
|
||||
--bridge)
|
||||
BRIDGE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--vlan)
|
||||
VLAN_TAG="$2"
|
||||
shift 2
|
||||
;;
|
||||
--cloud-init)
|
||||
ENABLE_CLOUD_INIT=true
|
||||
shift
|
||||
;;
|
||||
--uefi)
|
||||
ENABLE_UEFI=true
|
||||
shift
|
||||
;;
|
||||
--template)
|
||||
ENABLE_TEMPLATE=true
|
||||
shift
|
||||
;;
|
||||
--serial)
|
||||
ENABLE_SERIAL=true
|
||||
shift
|
||||
;;
|
||||
--ciuser)
|
||||
CIUSER="$2"
|
||||
shift 2
|
||||
;;
|
||||
--cipassword)
|
||||
CIPASSWORD="$2"
|
||||
shift 2
|
||||
;;
|
||||
--sshkey)
|
||||
SSHKEY="$2"
|
||||
shift 2
|
||||
;;
|
||||
--sshkey-file)
|
||||
if [ -f "$2" ]; then
|
||||
SSHKEY="$(cat "$2")"
|
||||
else
|
||||
log_error "SSH key file not found: $2"
|
||||
exit 1
|
||||
fi
|
||||
shift 2
|
||||
;;
|
||||
--ipconfig)
|
||||
IPCONFIG="$2"
|
||||
shift 2
|
||||
;;
|
||||
--nameserver)
|
||||
NAMESERVER="$2"
|
||||
shift 2
|
||||
;;
|
||||
--searchdomain)
|
||||
SEARCHDOMAIN="$2"
|
||||
shift 2
|
||||
;;
|
||||
--cpu)
|
||||
CPU_TYPE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--no-agent)
|
||||
ENABLE_AGENT=false
|
||||
shift
|
||||
;;
|
||||
--no-iothread)
|
||||
IOTHREAD=false
|
||||
shift
|
||||
;;
|
||||
--cache)
|
||||
CACHE_MODE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--discard)
|
||||
ENABLE_DISCARD=true
|
||||
shift
|
||||
;;
|
||||
--balloon)
|
||||
BALLOON="$2"
|
||||
shift 2
|
||||
;;
|
||||
--description)
|
||||
DESCRIPTION="$2"
|
||||
shift 2
|
||||
;;
|
||||
--tags)
|
||||
TAGS="$2"
|
||||
shift 2
|
||||
;;
|
||||
--node)
|
||||
NODE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--dry-run)
|
||||
DRY_RUN=true
|
||||
shift
|
||||
;;
|
||||
--help)
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
log_error "Unknown option: $1"
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# Show help message
|
||||
show_help() {
|
||||
cat << EOF
|
||||
Create Proxmox VM from QCOW2/RAW Image
|
||||
|
||||
Usage: $0 [OPTIONS]
|
||||
|
||||
Required Options:
|
||||
--vmid ID VM ID (e.g., 9000)
|
||||
--name NAME VM name (e.g., "ubuntu-24.04-cloudinit")
|
||||
--image PATH Full path to image file
|
||||
|
||||
Optional Options:
|
||||
--storage STORAGE Storage pool (default: local-lvm)
|
||||
--memory MB Memory in MB (default: 4096)
|
||||
--cores NUM CPU cores (default: 2)
|
||||
--bridge BRIDGE Network bridge (default: vmbr0)
|
||||
--vlan TAG VLAN tag number
|
||||
|
||||
Cloud-Init Options:
|
||||
--cloud-init Enable Cloud-Init support
|
||||
--ciuser USER Cloud-Init username
|
||||
--cipassword PASS Cloud-Init password (not recommended)
|
||||
--sshkey KEY SSH public key (or use --sshkey-file)
|
||||
--sshkey-file FILE Read SSH key from file
|
||||
--ipconfig CONFIG IP configuration (e.g., "ip=192.168.1.100/24,gw=192.168.1.1")
|
||||
--nameserver DNS DNS servers (space-separated)
|
||||
--searchdomain DOMAIN Search domains
|
||||
|
||||
VM Configuration:
|
||||
--uefi Enable UEFI/OVMF (recommended for modern images)
|
||||
--cpu TYPE CPU type (default: host, options: host, kvm64, etc.)
|
||||
--no-agent Disable QEMU Guest Agent
|
||||
--no-iothread Disable IO thread
|
||||
--cache MODE Disk cache mode (none, writeback, writethrough)
|
||||
--discard Enable discard (for thin provisioning)
|
||||
--balloon MB Memory balloon size in MB
|
||||
|
||||
Other Options:
|
||||
--template Convert to template after creation
|
||||
--serial Enable serial console
|
||||
--description TEXT VM description
|
||||
--tags TAGS Tags (comma-separated, e.g., "dev,web")
|
||||
--node NODE Target Proxmox node
|
||||
--dry-run Show commands without executing
|
||||
--help Show this help message
|
||||
|
||||
Examples:
|
||||
# Basic VM creation
|
||||
$0 --vmid 9000 --name "ubuntu-24.04" \\
|
||||
--image /var/lib/vz/template/iso/ubuntu-24.04-server-cloudimg-amd64.img
|
||||
|
||||
# Full cloud-init VM
|
||||
$0 --vmid 9000 --name "ubuntu-24.04-cloudinit" \\
|
||||
--image /var/lib/vz/template/iso/ubuntu-24.04-server-cloudimg-amd64.img \\
|
||||
--storage local-lvm --memory 4096 --cores 2 \\
|
||||
--cloud-init --uefi --serial \\
|
||||
--ciuser ubuntu --sshkey-file ~/.ssh/id_rsa.pub \\
|
||||
--ipconfig "ip=192.168.1.100/24,gw=192.168.1.1"
|
||||
|
||||
# Create and convert to template
|
||||
$0 --vmid 9000 --name "ubuntu-template" \\
|
||||
--image /var/lib/vz/template/iso/ubuntu-24.04-server-cloudimg-amd64.img \\
|
||||
--cloud-init --uefi --template \\
|
||||
--ciuser ubuntu --sshkey-file ~/.ssh/id_rsa.pub
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
# Validate required arguments
|
||||
validate_args() {
|
||||
if [ -z "$VMID" ]; then
|
||||
log_error "VMID is required. Use --vmid option."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$VMNAME" ]; then
|
||||
log_error "VM name is required. Use --name option."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$IMAGE" ]; then
|
||||
log_error "Image path is required. Use --image option."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$IMAGE" ]; then
|
||||
log_error "Image file not found: $IMAGE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Validate VMID is numeric
|
||||
if ! [[ "$VMID" =~ ^[0-9]+$ ]]; then
|
||||
log_error "VMID must be numeric: $VMID"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if VMID already exists
|
||||
if qm list | grep -q "^\s*$VMID\s"; then
|
||||
log_error "VM with ID $VMID already exists"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Validate storage exists
|
||||
if ! pvesm status | grep -q "^$STORAGE\s"; then
|
||||
log_warn "Storage '$STORAGE' not found in pvesm status"
|
||||
log_info "Available storage:"
|
||||
pvesm status
|
||||
log_warn "Continuing anyway..."
|
||||
fi
|
||||
}
|
||||
|
||||
# Validate image
|
||||
validate_image() {
|
||||
log_step "Validating image: $IMAGE"
|
||||
|
||||
# Check image format
|
||||
if ! command -v qemu-img &> /dev/null; then
|
||||
log_warn "qemu-img not found, skipping image validation"
|
||||
return
|
||||
fi
|
||||
|
||||
local image_info
|
||||
image_info=$(qemu-img info "$IMAGE" 2>&1)
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
log_error "Failed to read image: $IMAGE"
|
||||
log_error "$image_info"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Image format: $(echo "$image_info" | grep "file format" | awk '{print $3}')"
|
||||
log_info "Virtual size: $(echo "$image_info" | grep "virtual size" | awk -F'[()]' '{print $2}')"
|
||||
}
|
||||
|
||||
# Create VM shell
|
||||
create_vm_shell() {
|
||||
log_step "Creating VM shell (ID: $VMID, Name: $VMNAME)"
|
||||
|
||||
local cmd="qm create $VMID --name \"$VMNAME\" --memory $MEMORY --cores $CORES"
|
||||
|
||||
# Add node if specified
|
||||
if [ -n "$NODE" ]; then
|
||||
cmd="$cmd --target $NODE"
|
||||
fi
|
||||
|
||||
# Configure network
|
||||
if [ -n "$VLAN_TAG" ]; then
|
||||
cmd="$cmd --net0 virtio,bridge=$BRIDGE,tag=$VLAN_TAG"
|
||||
else
|
||||
cmd="$cmd --net0 virtio,bridge=$BRIDGE"
|
||||
fi
|
||||
|
||||
# Configure CPU
|
||||
cmd="$cmd --cpu $CPU_TYPE"
|
||||
|
||||
# Enable agent
|
||||
if [ "$ENABLE_AGENT" = true ]; then
|
||||
cmd="$cmd --agent 1"
|
||||
fi
|
||||
|
||||
# Add description if provided
|
||||
if [ -n "$DESCRIPTION" ]; then
|
||||
cmd="$cmd --description \"$DESCRIPTION\""
|
||||
fi
|
||||
|
||||
# Add tags if provided
|
||||
if [ -n "$TAGS" ]; then
|
||||
cmd="$cmd --tags $TAGS"
|
||||
fi
|
||||
|
||||
log_info "Command: $cmd"
|
||||
|
||||
if [ "$DRY_RUN" = false ]; then
|
||||
eval "$cmd"
|
||||
log_info "✓ VM shell created"
|
||||
else
|
||||
log_info "[DRY RUN] Would execute: $cmd"
|
||||
fi
|
||||
}
|
||||
|
||||
# Import disk
|
||||
import_disk() {
|
||||
log_step "Importing disk from image: $IMAGE"
|
||||
|
||||
local cmd="qm importdisk $VMID \"$IMAGE\" $STORAGE"
|
||||
|
||||
log_info "Command: $cmd"
|
||||
log_info "This may take several minutes depending on image size..."
|
||||
|
||||
if [ "$DRY_RUN" = false ]; then
|
||||
eval "$cmd"
|
||||
log_info "✓ Disk imported"
|
||||
|
||||
# Get the volume name (usually vm-<VMID>-disk-0)
|
||||
local volume_name="vm-${VMID}-disk-0"
|
||||
log_info "Imported volume: $volume_name"
|
||||
else
|
||||
log_info "[DRY RUN] Would execute: $cmd"
|
||||
fi
|
||||
}
|
||||
|
||||
# Attach disk
|
||||
attach_disk() {
|
||||
log_step "Attaching imported disk"
|
||||
|
||||
local volume_name="vm-${VMID}-disk-0"
|
||||
local cmd="qm set $VMID --scsihw virtio-scsi-pci --scsi0 ${STORAGE}:${volume_name}"
|
||||
|
||||
# Add IO thread if enabled
|
||||
if [ "$IOTHREAD" = true ]; then
|
||||
cmd="$cmd --iothread 1"
|
||||
fi
|
||||
|
||||
# Add cache mode
|
||||
cmd="$cmd --cache $CACHE_MODE"
|
||||
|
||||
# Add discard if enabled
|
||||
if [ "$ENABLE_DISCARD" = true ]; then
|
||||
cmd="$cmd --discard on"
|
||||
fi
|
||||
|
||||
log_info "Command: $cmd"
|
||||
|
||||
if [ "$DRY_RUN" = false ]; then
|
||||
eval "$cmd"
|
||||
log_info "✓ Disk attached"
|
||||
else
|
||||
log_info "[DRY RUN] Would execute: $cmd"
|
||||
fi
|
||||
}
|
||||
|
||||
# Configure boot
|
||||
configure_boot() {
|
||||
log_step "Configuring boot settings"
|
||||
|
||||
local cmd="qm set $VMID --boot order=scsi0"
|
||||
|
||||
# Configure BIOS/UEFI
|
||||
if [ "$ENABLE_UEFI" = true ]; then
|
||||
cmd="$cmd --bios ovmf --efidisk0 ${STORAGE}:1,format=raw"
|
||||
log_info "UEFI/OVMF enabled"
|
||||
else
|
||||
cmd="$cmd --bios seabios"
|
||||
log_info "BIOS (SeaBIOS) enabled"
|
||||
fi
|
||||
|
||||
log_info "Command: $cmd"
|
||||
|
||||
if [ "$DRY_RUN" = false ]; then
|
||||
eval "$cmd"
|
||||
log_info "✓ Boot configured"
|
||||
else
|
||||
log_info "[DRY RUN] Would execute: $cmd"
|
||||
fi
|
||||
}
|
||||
|
||||
# Configure Cloud-Init
|
||||
configure_cloud_init() {
|
||||
log_step "Configuring Cloud-Init"
|
||||
|
||||
# Add Cloud-Init drive
|
||||
local cmd="qm set $VMID --ide2 ${STORAGE}:cloudinit"
|
||||
|
||||
# Enable serial console if requested
|
||||
if [ "$ENABLE_SERIAL" = true ] || [ "$ENABLE_CLOUD_INIT" = true ]; then
|
||||
cmd="$cmd --serial0 socket --vga serial0"
|
||||
fi
|
||||
|
||||
log_info "Command: $cmd"
|
||||
|
||||
if [ "$DRY_RUN" = false ]; then
|
||||
eval "$cmd"
|
||||
else
|
||||
log_info "[DRY RUN] Would execute: $cmd"
|
||||
fi
|
||||
|
||||
# Configure Cloud-Init user
|
||||
if [ -n "$CIUSER" ]; then
|
||||
cmd="qm set $VMID --ciuser $CIUSER"
|
||||
log_info "Command: $cmd"
|
||||
if [ "$DRY_RUN" = false ]; then
|
||||
eval "$cmd"
|
||||
else
|
||||
log_info "[DRY RUN] Would execute: $cmd"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Configure password (if provided, but not recommended)
|
||||
if [ -n "$CIPASSWORD" ]; then
|
||||
cmd="qm set $VMID --cipassword \"$CIPASSWORD\""
|
||||
log_warn "Setting password via Cloud-Init (not recommended, use SSH keys instead)"
|
||||
log_info "Command: $cmd"
|
||||
if [ "$DRY_RUN" = false ]; then
|
||||
eval "$cmd"
|
||||
else
|
||||
log_info "[DRY RUN] Would execute: $cmd"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Configure SSH key
|
||||
if [ -n "$SSHKEY" ]; then
|
||||
cmd="qm set $VMID --sshkey \"$SSHKEY\""
|
||||
log_info "Command: $cmd"
|
||||
if [ "$DRY_RUN" = false ]; then
|
||||
eval "$cmd"
|
||||
log_info "✓ SSH key configured"
|
||||
else
|
||||
log_info "[DRY RUN] Would execute: $cmd"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Configure IP
|
||||
if [ -n "$IPCONFIG" ]; then
|
||||
cmd="qm set $VMID --ipconfig0 $IPCONFIG"
|
||||
log_info "Command: $cmd"
|
||||
if [ "$DRY_RUN" = false ]; then
|
||||
eval "$cmd"
|
||||
else
|
||||
log_info "[DRY RUN] Would execute: $cmd"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Configure DNS
|
||||
if [ -n "$NAMESERVER" ]; then
|
||||
cmd="qm set $VMID --nameserver \"$NAMESERVER\""
|
||||
log_info "Command: $cmd"
|
||||
if [ "$DRY_RUN" = false ]; then
|
||||
eval "$cmd"
|
||||
else
|
||||
log_info "[DRY RUN] Would execute: $cmd"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Configure search domain
|
||||
if [ -n "$SEARCHDOMAIN" ]; then
|
||||
cmd="qm set $VMID --searchdomain \"$SEARCHDOMAIN\""
|
||||
log_info "Command: $cmd"
|
||||
if [ "$DRY_RUN" = false ]; then
|
||||
eval "$cmd"
|
||||
else
|
||||
log_info "[DRY RUN] Would execute: $cmd"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$DRY_RUN" = false ]; then
|
||||
log_info "✓ Cloud-Init configured"
|
||||
fi
|
||||
}
|
||||
|
||||
# Configure memory balloon
|
||||
configure_balloon() {
|
||||
if [ "$BALLOON" -gt 0 ]; then
|
||||
log_step "Configuring memory balloon: ${BALLOON}MB"
|
||||
local cmd="qm set $VMID --balloon $BALLOON"
|
||||
|
||||
log_info "Command: $cmd"
|
||||
|
||||
if [ "$DRY_RUN" = false ]; then
|
||||
eval "$cmd"
|
||||
log_info "✓ Memory balloon configured"
|
||||
else
|
||||
log_info "[DRY RUN] Would execute: $cmd"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Start VM
|
||||
start_vm() {
|
||||
log_step "Starting VM"
|
||||
|
||||
local cmd="qm start $VMID"
|
||||
|
||||
log_info "Command: $cmd"
|
||||
|
||||
if [ "$DRY_RUN" = false ]; then
|
||||
eval "$cmd"
|
||||
log_info "✓ VM started"
|
||||
|
||||
# Show status
|
||||
sleep 2
|
||||
qm status $VMID
|
||||
else
|
||||
log_info "[DRY RUN] Would execute: $cmd"
|
||||
fi
|
||||
}
|
||||
|
||||
# Convert to template
|
||||
convert_to_template() {
|
||||
if [ "$ENABLE_TEMPLATE" = false ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
log_step "Converting VM to template"
|
||||
|
||||
log_warn "VM must be shut down before converting to template"
|
||||
|
||||
if [ "$DRY_RUN" = false ]; then
|
||||
# Check if VM is running
|
||||
local status
|
||||
status=$(qm status $VMID 2>&1 | grep "status:" | awk '{print $2}')
|
||||
|
||||
if [ "$status" = "running" ]; then
|
||||
log_info "VM is running. Shutting down..."
|
||||
qm shutdown $VMID
|
||||
|
||||
log_info "Waiting for shutdown (this may take a minute)..."
|
||||
local max_wait=60
|
||||
local waited=0
|
||||
while [ $waited -lt $max_wait ]; do
|
||||
status=$(qm status $VMID 2>&1 | grep "status:" | awk '{print $2}')
|
||||
if [ "$status" != "running" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
waited=$((waited + 2))
|
||||
echo -n "."
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Convert to template
|
||||
qm template $VMID
|
||||
log_info "✓ VM converted to template"
|
||||
else
|
||||
log_info "[DRY RUN] Would execute: qm shutdown $VMID && qm template $VMID"
|
||||
fi
|
||||
}
|
||||
|
||||
# Main function
|
||||
main() {
|
||||
echo "========================================="
|
||||
echo "Create Proxmox VM from Image"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
|
||||
parse_args "$@"
|
||||
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
log_warn "DRY RUN MODE - No changes will be made"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
validate_args
|
||||
validate_image
|
||||
|
||||
echo ""
|
||||
log_info "VM Configuration:"
|
||||
log_info " VMID: $VMID"
|
||||
log_info " Name: $VMNAME"
|
||||
log_info " Image: $IMAGE"
|
||||
log_info " Storage: $STORAGE"
|
||||
log_info " Memory: ${MEMORY}MB"
|
||||
log_info " Cores: $CORES"
|
||||
log_info " Bridge: $BRIDGE"
|
||||
[ -n "$VLAN_TAG" ] && log_info " VLAN: $VLAN_TAG"
|
||||
[ "$ENABLE_CLOUD_INIT" = true ] && log_info " Cloud-Init: Enabled"
|
||||
[ "$ENABLE_UEFI" = true ] && log_info " UEFI: Enabled"
|
||||
[ "$ENABLE_TEMPLATE" = true ] && log_info " Convert to Template: Yes"
|
||||
echo ""
|
||||
|
||||
if [ "$DRY_RUN" = false ]; then
|
||||
read -p "Continue with VM creation? (y/N): " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
log_info "Aborted by user"
|
||||
exit 0
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
create_vm_shell
|
||||
import_disk
|
||||
attach_disk
|
||||
configure_boot
|
||||
|
||||
if [ "$ENABLE_CLOUD_INIT" = true ]; then
|
||||
configure_cloud_init
|
||||
fi
|
||||
|
||||
configure_balloon
|
||||
|
||||
if [ "$ENABLE_TEMPLATE" = false ]; then
|
||||
start_vm
|
||||
else
|
||||
log_info "Skipping VM start (will be converted to template)"
|
||||
fi
|
||||
|
||||
convert_to_template
|
||||
|
||||
echo ""
|
||||
log_info "========================================="
|
||||
log_info "VM Creation Complete!"
|
||||
log_info "========================================="
|
||||
|
||||
if [ "$ENABLE_TEMPLATE" = false ] && [ "$DRY_RUN" = false ]; then
|
||||
echo ""
|
||||
log_info "VM Status:"
|
||||
qm status $VMID
|
||||
echo ""
|
||||
log_info "View VM console: qm terminal $VMID"
|
||||
log_info "View VM config: qm config $VMID"
|
||||
fi
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
|
||||
Reference in New Issue
Block a user