#!/usr/bin/env bash
set -euo pipefail

VM_NAME=""

# ===== 默认参数，可被命令行覆盖 =====
VM_MEMORY="8192"
VM_VCPUS="8"
VM_DISK_SIZE="40G"
CLOUD_USER="ubuntu"
CLOUD_PASS="123456"
# ==================================

usage() {
        echo "用法: $0 <vm-name> [-m memory_mb] [-c vcpus] [-d disk_size] [-u user] [-p password]"
        echo
        echo "示例:"
        echo "  $0 dt4124-vm-1"
        echo "  $0 dt4124-vm-1 -m 8192 -c 4 -d 80G -u ubuntu -p 123456"
        exit 1
}

if [ $# -lt 1 ]; then
        usage
fi

VM_NAME="$1"
shift

while getopts ":m:c:d:u:p:h" opt; do
        case "$opt" in
                m)
                        VM_MEMORY="$OPTARG"
                        ;;
                c)
                        VM_VCPUS="$OPTARG"
                        ;;
                d)
                        VM_DISK_SIZE="$OPTARG"
                        ;;
                u)
                        CLOUD_USER="$OPTARG"
                        ;;
                p)
                        CLOUD_PASS="$OPTARG"
                        ;;
                h)
                        usage
                        ;;
                :)
                        echo "错误: 参数 -$OPTARG 需要值"
                        usage
                        ;;
                \?)
                        echo "错误: 未知参数 -$OPTARG"
                        usage
                        ;;
        esac
done
# ===== 可按需修改 =====
BASE_IMG="/var/lib/libvirt/images/ubuntu-22.04-server-cloudimg-amd64.img"
IMAGE_DIR="/var/lib/libvirt/images"
CLOUDINIT_DIR="/var/lib/libvirt/cloudinit"

VM_DISK="${IMAGE_DIR}/${VM_NAME}.qcow2"
VM_CIDATA_DIR="${CLOUDINIT_DIR}/${VM_NAME}"
SEED_ISO="${VM_CIDATA_DIR}/seed.iso"

OS_VARIANT="ubuntu22.04"
BRIDGE_NAME="virbr0"
# ======================

if [ ! -f "$BASE_IMG" ]; then
        echo "错误: 找不到基础镜像: $BASE_IMG"
        exit 1
fi

if virsh dominfo "$VM_NAME" >/dev/null 2>&1; then
        echo "错误: 虚拟机已存在: $VM_NAME"
        echo "如需重建，先执行:"
        echo "virsh destroy $VM_NAME 2>/dev/null || true"
        echo "virsh undefine $VM_NAME --remove-all-storage"
        exit 1
fi

echo ">>> 检查依赖"

for cmd in qemu-img cloud-localds virt-install virsh; do
        if ! command -v "$cmd" >/dev/null 2>&1; then
                echo "错误: 缺少命令 $cmd"
                echo "请先安装:"
                echo "apt install -y qemu-utils cloud-image-utils virtinst libvirt-daemon-system libvirt-clients"
                exit 1
        fi
done

echo ">>> 创建目录"

mkdir -p "$IMAGE_DIR"
mkdir -p "$VM_CIDATA_DIR"

echo ">>> 创建虚拟机磁盘: $VM_DISK"

qemu-img create -f qcow2 -F qcow2 -b "$BASE_IMG" "$VM_DISK"
qemu-img resize "$VM_DISK" "$VM_DISK_SIZE"

echo ">>> 生成 cloud-init 配置"

cat > "${VM_CIDATA_DIR}/user-data" <<USERDATA
#cloud-config
hostname: ${VM_NAME}
manage_etc_hosts: true

users:
  - default
  - name: ${CLOUD_USER}
    gecos: ${CLOUD_USER}
    sudo: ALL=(ALL) NOPASSWD:ALL
    groups: users, admin, sudo
    shell: /bin/bash
    lock_passwd: false
    plain_text_passwd: '${CLOUD_PASS}'

chpasswd:
  expire: false
  list: |
    ${CLOUD_USER}:${CLOUD_PASS}
    root:${CLOUD_PASS}

ssh_pwauth: true
disable_root: false

package_update: false

growpart:
  mode: auto
  devices: ['/']
  ignore_growroot_disabled: false

resize_rootfs: true

runcmd:
  - sed -i 's/^#\?PasswordAuthentication .*/PasswordAuthentication yes/' /etc/ssh/sshd_config
  - sed -i 's/^#\?PermitRootLogin .*/PermitRootLogin yes/' /etc/ssh/sshd_config
  - sed -i 's/^#\?KbdInteractiveAuthentication .*/KbdInteractiveAuthentication yes/' /etc/ssh/sshd_config
  - sed -i 's/^#\?ChallengeResponseAuthentication .*/ChallengeResponseAuthentication yes/' /etc/ssh/sshd_config
  - systemctl enable ssh || true
  - systemctl restart ssh || true
USERDATA

cat > "${VM_CIDATA_DIR}/meta-data" <<METADATA
instance-id: ${VM_NAME}
local-hostname: ${VM_NAME}
METADATA

cloud-localds "$SEED_ISO" "${VM_CIDATA_DIR}/user-data" "${VM_CIDATA_DIR}/meta-data"

echo ">>> 修复 libvirt/qemu 文件权限"

# Ubuntu/Debian 常见是 libvirt-qemu:kvm
if id libvirt-qemu >/dev/null 2>&1 && getent group kvm >/dev/null 2>&1; then
        QEMU_USER="libvirt-qemu"
        QEMU_GROUP="kvm"

elif id qemu >/dev/null 2>&1 && getent group qemu >/dev/null 2>&1; then
        QEMU_USER="qemu"
        QEMU_GROUP="qemu"

else
        echo "警告: 未识别 qemu 用户，跳过 chown，仅设置 chmod"
        QEMU_USER=""
        QEMU_GROUP=""
fi

chmod 755 "$IMAGE_DIR"
chmod 755 "$CLOUDINIT_DIR"
chmod 755 "$VM_CIDATA_DIR"

chmod 644 "$BASE_IMG"
chmod 644 "$VM_DISK"
chmod 644 "$SEED_ISO"

if [ -n "$QEMU_USER" ]; then
        chown "$QEMU_USER:$QEMU_GROUP" "$BASE_IMG"
        chown "$QEMU_USER:$QEMU_GROUP" "$VM_DISK"
        chown "$QEMU_USER:$QEMU_GROUP" "$SEED_ISO"
        chown "$QEMU_USER:$QEMU_GROUP" "$VM_CIDATA_DIR"
fi

echo ">>> 创建 libvirt 虚拟机"

virt-install \
        --name "$VM_NAME" \
        --memory "$VM_MEMORY" \
        --vcpus "$VM_VCPUS" \
        --disk path="$VM_DISK",format=qcow2,bus=virtio \
        --disk path="$SEED_ISO",device=cdrom \
        --os-variant "$OS_VARIANT" \
        --virt-type kvm \
        --graphics vnc,listen=0.0.0.0 \
        --network bridge="$BRIDGE_NAME",model=virtio \
        --import \
        --noautoconsole

echo
echo ">>> 创建完成"
echo "虚拟机名称: $VM_NAME"
echo "用户名: $CLOUD_USER"
echo "密码: $CLOUD_PASS"
echo
echo "查看状态:"
echo "virsh list --all"
echo
echo "查看 IP:"
echo "virsh net-dhcp-leases default | grep -w $VM_NAME"
