|
|
|
@@ -0,0 +1,120 @@
|
|
|
|
|
#!/bin/bash
|
|
|
|
|
# Usage: import-vhdx-dir.sh <VMID> <VMNAME> <BASE_DIR_ON_NFS> <ENR>
|
|
|
|
|
# If VMID is 0 or already taken, the script will pick the first available VMID.
|
|
|
|
|
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
|
|
# -----------------------
|
|
|
|
|
# Inputs and defaults
|
|
|
|
|
# -----------------------
|
|
|
|
|
INPUT_VMID="${1:-0}"
|
|
|
|
|
VMNAME="${2:?VM name required}"
|
|
|
|
|
BASEDIR="${3:?Base directory required}"
|
|
|
|
|
ENR="${4:-}"
|
|
|
|
|
STORAGE="ZFS-01"
|
|
|
|
|
ISO_STORAGE="tscale04-nfs"
|
|
|
|
|
ISO_NAME="virtio-win.iso"
|
|
|
|
|
|
|
|
|
|
# -----------------------
|
|
|
|
|
# Helpers
|
|
|
|
|
# -----------------------
|
|
|
|
|
get_free_vmid() {
|
|
|
|
|
# Get sorted list of used VMIDs
|
|
|
|
|
mapfile -t USED < <(qm list | awk 'NR>1{print $1}' | sort -n)
|
|
|
|
|
local id=100
|
|
|
|
|
while true; do
|
|
|
|
|
local taken=0
|
|
|
|
|
for u in "${USED[@]}"; do
|
|
|
|
|
if [[ "$u" == "$id" ]]; then
|
|
|
|
|
taken=1
|
|
|
|
|
break
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
if [[ $taken -eq 0 ]]; then
|
|
|
|
|
echo "$id"
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
((id++))
|
|
|
|
|
done
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
is_vmid_taken() {
|
|
|
|
|
local vmid="$1"
|
|
|
|
|
qm list | awk 'NR>1{print $1}' | grep -qx "$vmid"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Determine VMID (auto-pick if 0 or taken)
|
|
|
|
|
if [[ "$INPUT_VMID" == "0" || "$(is_vmid_taken "$INPUT_VMID"; echo $?)" -eq 0 ]]; then
|
|
|
|
|
VMID="$(get_free_vmid)"
|
|
|
|
|
echo ">>> Requested VMID '$INPUT_VMID' is invalid/taken. Using first available VMID: $VMID"
|
|
|
|
|
else
|
|
|
|
|
VMID="$INPUT_VMID"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# -----------------------
|
|
|
|
|
# Create VM (TPM/UEFI + SATA)
|
|
|
|
|
# -----------------------
|
|
|
|
|
case "$ENR" in
|
|
|
|
|
ENR)
|
|
|
|
|
echo ">>> Creating VM $VMID ($VMNAME) with TPM KEY not enrolled..."
|
|
|
|
|
qm create "$VMID" --name "$VMNAME" --memory 4096 --cores 4 --machine q35 \
|
|
|
|
|
--bios ovmf --efidisk0 ${STORAGE}:1,efitype=4m,pre-enrolled-keys=1 \
|
|
|
|
|
--tpmstate0 ${STORAGE}:1,version=v2.0
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
echo ">>> Creating VM $VMID ($VMNAME) with TPM and UEFI..."
|
|
|
|
|
qm create "$VMID" --name "$VMNAME" --memory 4096 --cores 4 --machine q35 \
|
|
|
|
|
--bios ovmf --efidisk0 ${STORAGE}:1,efitype=4m,pre-enrolled-keys=0 \
|
|
|
|
|
--tpmstate0 ${STORAGE}:1,version=v2.0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
|
|
|
|
|
# -----------------------
|
|
|
|
|
# Find VHDX files, sort by size (largest first), space-safe
|
|
|
|
|
# -----------------------
|
|
|
|
|
declare -a VHDX_FILES
|
|
|
|
|
while IFS= read -r -d '' line; do
|
|
|
|
|
# line format: "<size>\t<path>"
|
|
|
|
|
size="${line%%$'\t'*}"
|
|
|
|
|
path="${line#*$'\t'}"
|
|
|
|
|
VHDX_FILES+=( "$path" )
|
|
|
|
|
done < <(find "$BASEDIR" -type f -iname "*.vhdx" -printf "%s\t%p\0" | sort -z -nr -k1,1)
|
|
|
|
|
|
|
|
|
|
if [ ${#VHDX_FILES[@]} -eq 0 ]; then
|
|
|
|
|
echo "!!! No VHDX files found in $BASEDIR"
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
echo ">>> Found ${#VHDX_FILES[@]} VHDX file(s), sorted by size:"
|
|
|
|
|
for f in "${VHDX_FILES[@]}"; do
|
|
|
|
|
echo " $f"
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
# -----------------------
|
|
|
|
|
# Import and attach disks as SATA (largest -> sata0)
|
|
|
|
|
# -----------------------
|
|
|
|
|
DISK_INDEX=0
|
|
|
|
|
for VHDX in "${VHDX_FILES[@]}"; do
|
|
|
|
|
echo ">>> Importing disk: $VHDX -> $STORAGE"
|
|
|
|
|
qm importdisk "$VMID" "$VHDX" "$STORAGE" --format=raw
|
|
|
|
|
|
|
|
|
|
# Identify the last unused disk created by import (space-safe parsing)
|
|
|
|
|
LASTDISK="$(qm config "$VMID" | awk '/^unused[0-9]+: /{print $2}' | tail -n1)"
|
|
|
|
|
|
|
|
|
|
if [[ -z "$LASTDISK" ]]; then
|
|
|
|
|
echo "!!! Could not detect imported disk for $VHDX"
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
DISK_NAME="sata${DISK_INDEX}"
|
|
|
|
|
echo ">>> Attaching '$LASTDISK' as '$DISK_NAME'..."
|
|
|
|
|
qm set "$VMID" --${DISK_NAME} "$LASTDISK"
|
|
|
|
|
|
|
|
|
|
((DISK_INDEX++))
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
# -----------------------
|
|
|
|
|
# Boot order: sata0 (largest disk)
|
|
|
|
|
# -----------------------
|
|
|
|
|
echo ">>> Setting boot order to sata0..."
|
|
|
|
|
qm set "$VMID" --boot order=sata0
|