Some checks failed
Test / test (push) Has been cancelled
Co-authored-by: Cursor <cursoragent@cursor.com>
723 lines
18 KiB
Bash
Executable File
723 lines
18 KiB
Bash
Executable File
#!/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 "$@"
|
|
|