优化 pve.sh 脚本,增加参数支持和错误处理,改进镜像下载和导入逻辑

This commit is contained in:
Ing 2025-09-16 03:11:01 +08:00
parent c1de95e364
commit 32cfc2b257
2 changed files with 147 additions and 27 deletions

View File

@ -34,7 +34,15 @@ If you cannot connect to the Internet, please build a pre-compiled bootloader th
- Proxmox VE One Click Install:
```
curl -fsSL https://raw.githubusercontent.com/RROrg/rr/refs/heads/main/scripts/pve.sh | bash -s -- --onboot 1
curl -fsSL https://github.com/RROrg/rr/raw/refs/heads/main/scripts/pve.sh | bash -s -- --bltype usb
# Optional Parameters:
--onboot <0|1> Enable VM on boot, default 1 (enable)
--efi <0|1> Enable UEFI boot, default 1 (enable)
--bltype <sata|usb|nvme> Bootloader disk type, default sata
--9ppath <path> Set to /path/to/9p to mount 9p share
--tag <tag> Image tag, download latest release if not set
--img <path> Local image path, use local image if set
```

View File

@ -9,32 +9,71 @@
REPO="https://github.com/RROrg/rr"
# 参数
ONBOOT=1 # 开机启动默认1
# BLTYPE="usb" # 引导盘类型, 支持 usb,sata,nvme 默认 usb
TAG="" # 镜像tag默认自动获取
IMG="" # 本地镜像路径,默认空
ONBOOT=1 # 开机启动默认1
EFI=1 # 启用 UEFI 引导默认1
BLTYPE="sata" # 引导盘类型, 支持 sata,usb,nvme 默认 sata
NINEPPATH="" # 9p路径默认空不添加
TAG="" # 镜像tag默认自动获取
IMG="" # 本地镜像路径,默认空
while [[ $# -gt 0 ]]; do
usage() {
echo "Usage: $0 [--onboot <0|1>] [--efi <0|1>] [--bltype <sata|usb|nvme>] [--9ppath <path>] [--tag <tag>] [--img <path>]"
echo " --onboot <0|1> Enable VM on boot, default 1 (enable)"
echo " --efi <0|1> Enable UEFI boot, default 1 (enable)"
echo " --bltype <sata|usb|nvme> Bootloader disk type, default sata"
echo " --9ppath <path> Set to /path/to/9p to mount 9p share"
echo " --tag <tag> Image tag, download latest release if not set"
echo " --img <path> Local image path, use local image if set"
exit 1
}
ARGS=$(getopt -o '' --long onboot:,efi:,bltype:,9ppath:,tag:,img: -n "$0" -- "$@")
if [ $? -ne 0 ]; then
usage
exit 1
fi
eval set -- "$ARGS"
while true; do
case "$1" in
--onboot)
ONBOOT="${2}"
ONBOOT="$2"
echo "$ONBOOT" | grep -qvE '^(0|1)$' && ONBOOT=1
shift 2
;;
--efi)
EFI="$2"
echo "$EFI" | grep -qvE '^(0|1)$' && EFI=1
shift 2
;;
--bltype)
BLTYPE="$2"
echo "$BLTYPE" | grep -qvE '^(sata|usb|nvme)$' && BLTYPE="sata"
shift 2
;;
#--bltype)
# BLTYPE="${2}"
# shift 2
# ;;
--tag)
TAG="${2}"
TAG="$2"
[ "${TAG:0:1}" = "v" ] && TAG="${TAG:1}"
shift 2
;;
--img)
IMG="${2}"
IMG="$2"
[ ! -f "${IMG}" ] && IMG=""
[ -n "${IMG}" ] && IMG="$(realpath "${IMG}")"
shift 2
;;
--9ppath)
NINEPPATH="$2"
[ ! -d "${NINEPPATH}" ] && NINEPPATH=""
[ -z "${NINEPPATH}" ] || NINEPPATH="$(realpath "${NINEPPATH}")"
shift 2
;;
--)
shift
break
;;
*)
# echo "Usage: $0 [--onboot <0|1>] [--bltype <usb|sata|nvme>] [--tag <tag>] [--img <path>]"
echo "Usage: $0 [--onboot <0|1>] [--tag <tag>] [--img <path>]"
usage
exit 1
;;
esac
@ -53,33 +92,43 @@ fi
if [ -n "${IMG}" ] && [ -f "${IMG}" ]; then
IMG_PATH="${IMG}"
else
if ! command -v curl >/dev/null 2>&1; then
apt-get update >/dev/null 2>&1 && apt-get install -y curl >/dev/null 2>&1
fi
rm -f "/tmp/rr-${TAG}.img.zip"
echo "Downloading rr-${TAG}.img.zip ... "
STATUS=$(curl -skL --connect-timeout 10 -w "%{http_code}" "${REPO}/releases/download/${TAG}/rr-${TAG}.img.zip" -o "/tmp/rr-${TAG}.img.zip")
if [ $? -ne 0 ] || [ "${STATUS:-0}" -ne 200 ]; then
rm -f "/tmp/rr-${TAG}.img.zip"
echo "Download failed"
echo "Download failed rr-${TAG}.img.zip"
exit 1
fi
if ! command -v unzip >/dev/null 2>&1; then
apt-get update >/dev/null 2>&1 && apt-get install -y unzip >/dev/null 2>&1
fi
rm -f "/tmp/rr.img"
IMG_FILE=$(unzip -l "/tmp/rr-${TAG}.img.zip" | awk '{print $4}' | grep '\.img$' | head -n 1)
if [ -z "${IMG_FILE}" ]; then
echo "No img file found in rr-${TAG}.img.zip"
exit 1
fi
IMG_PATH="/tmp/${IMG_FILE}"
rm -f "${IMG_PATH}"
echo "Unzipping rr-${TAG}.img.zip ... "
unzip -o "/tmp/rr-${TAG}.img.zip" -d /tmp/ >/dev/null 2>&1
unzip -o "/tmp/rr-${TAG}.img.zip" -d /tmp/ "${IMG_FILE}" >/dev/null 2>&1
STATUS=$?
rm -f "/tmp/rr-${TAG}.img.zip"
if [ "${STATUS:-0}" -ne 0 ]; then
echo "Unzip failed"
rm -f "${IMG_PATH}"
echo "Unzip failed rr-${TAG}.img.zip"
exit 1
fi
IMG_PATH="/tmp/rr.img"
fi
echo "Creating VM with RR ... "
# 获取可用的 VMID
VMID="$(($(qm list | awk 'NR>1{print $1}' | sort -n | tail -1 2>/dev/null || echo 99) + 1))"
ARGS=""
# 创建 VM
qm create ${VMID} --name RR-DSM --machine q35 --ostype l26 --vga virtio --sockets 1 --cores 2 --cpu host --numa 0 --memory 4096 --scsihw virtio-scsi-single
@ -88,19 +137,82 @@ if [ $? -ne 0 ]; then
exit 1
fi
# 导入磁盘
qm importdisk ${VMID} "${IMG_PATH}" local-lvm >/dev/null 2>&1
if [ $? -ne 0 ]; then
# 启用 UEFI 引导
if [ "${EFI:-1}" -eq 1 ]; then
if ! qm set ${VMID} --bios ovmf --efidisk0 local-lvm:4,efitype=4m,pre-enrolled-keys=0; then
echo "Set UEFI failed"
qm destroy ${VMID} --purge
exit 1
fi
fi
# 导入 RR 镜像
STORAGE=$(pvesm status -content images | awk 'NR>1 {print $1}')
if [ -z "${STORAGE}" ]; then
echo "No storage for images"
qm destroy ${VMID} --purge
exit 1
fi
BLDISK=$(qm importdisk ${VMID} "${IMG_PATH}" "${STORAGE}" | grep 'successfully imported disk' | sed -n "s/.*'\(.*\)'.*/\1/p")
STATUS=$?
if [ "${STATUS:-0}" -ne 0 ] || [ -z "${BLDISK}" ]; then
echo "Import disk failed"
qm destroy ${VMID} --purge
exit 1
fi
[ -n "${IMG}" ] || rm -f "${IMG_PATH}"
case "${BLTYPE}" in
usb)
ARGS+="-device nec-usb-xhci,id=usb-bus0,multifunction=on -drive file=$(pvesm path ${BLDISK}),media=disk,format=raw,if=none,id=usb1 -device usb-storage,bus=usb-bus0.0,port=1,drive=usb1,bootindex=999,removable=on "
;;
nvme)
ARGS+="-drive file=$(pvesm path ${BLDISK}),media=disk,format=raw,if=none,id=nvme1 -device nvme,drive=nvme1,serial=nvme001 "
;;
sata)
qm set ${VMID} --sata0 "${BLDISK}"
;;
*)
echo "Setting bootloader disk failed"
qm destroy ${VMID} --purge
exit 1
;;
esac
# 设置 VM 配置
qm set ${VMID} --bios ovmf --efidisk0 local-lvm:4,efitype=4m,pre-enrolled-keys=0
qm set ${VMID} --sata0 local-lvm:vm-${VMID}-disk-0
X86_VENDOR=$(awk -F: '/vendor_id/ {gsub(/^[ \t]+/, "", $2); print $2; exit}' /proc/cpuinfo)
case "${X86_VENDOR,,}" in
*intel*)
ARGS+="-cpu host,+kvm_pv_eoi,+kvm_pv_unhalt,+vmx,hv_vendor_id=${X86_VENDOR} "
;;
*amd*)
ARGS+="-cpu host,+kvm_pv_eoi,+kvm_pv_unhalt,+svm,hv_vendor_id=${X86_VENDOR} "
;;
*)
echo "x86_vendor: Unknown"
;;
esac
if [ -d "${NINEPPATH}" ]; then
ARGS+="-fsdev local,security_model=passthrough,id=fsdev0,path=${NINEPPATH} -device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=hostshare "
fi
qm set ${VMID} --args "${ARGS}"
if [ $? -ne 0 ]; then
echo "Set args failed"
qm destroy ${VMID} --purge
exit 1
fi
# 添加 32G 数据盘
qm set ${VMID} --sata1 local-lvm:32
qm set ${VMID} --net0 virtio,bridge=vmbr0
BRIDGE=$(awk -F: '/^iface vmbr/ {print $1}' /etc/network/interfaces | awk '{print $2}' | head -n 1)
if [ -z "${BRIDGE}" ]; then
echo "Get bridge failed"
qm destroy ${VMID} --purge
exit 1
fi
qm set ${VMID} --net0 virtio,bridge=${BRIDGE}
qm set ${VMID} --serial0 socket
qm set ${VMID} --agent enabled=1
qm set ${VMID} --smbios1 "uuid=$(cat /proc/sys/kernel/random/uuid),manufacturer=$(echo -n "RROrg" | base64),product=$(echo -n "RR" | base64),version=$(echo -n "$TAG" | base64),base64=1"