From 32cfc2b25786b6f0087edc7bfd33909a811ffa2f Mon Sep 17 00:00:00 2001 From: Ing Date: Tue, 16 Sep 2025 03:11:01 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=20pve.sh=20=E8=84=9A?= =?UTF-8?q?=E6=9C=AC=EF=BC=8C=E5=A2=9E=E5=8A=A0=E5=8F=82=E6=95=B0=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=92=8C=E9=94=99=E8=AF=AF=E5=A4=84=E7=90=86=EF=BC=8C?= =?UTF-8?q?=E6=94=B9=E8=BF=9B=E9=95=9C=E5=83=8F=E4=B8=8B=E8=BD=BD=E5=92=8C?= =?UTF-8?q?=E5=AF=BC=E5=85=A5=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 10 ++- scripts/pve.sh | 164 +++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 147 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index ed384165..83887839 100644 --- a/README.md +++ b/README.md @@ -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 Bootloader disk type, default sata + --9ppath Set to /path/to/9p to mount 9p share + --tag Image tag, download latest release if not set + --img Local image path, use local image if set ``` diff --git a/scripts/pve.sh b/scripts/pve.sh index 12ac4ccc..ce0e8a72 100644 --- a/scripts/pve.sh +++ b/scripts/pve.sh @@ -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 ] [--9ppath ] [--tag ] [--img ]" + echo " --onboot <0|1> Enable VM on boot, default 1 (enable)" + echo " --efi <0|1> Enable UEFI boot, default 1 (enable)" + echo " --bltype Bootloader disk type, default sata" + echo " --9ppath Set to /path/to/9p to mount 9p share" + echo " --tag Image tag, download latest release if not set" + echo " --img 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 ] [--tag ] [--img ]" - echo "Usage: $0 [--onboot <0|1>] [--tag ] [--img ]" + 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"