UmbrelOS: Refactor / use q35 / better import (#7329)

* UmbrelOS: Improve VM Import Process

* q35 Feature-Bump

* Update umbrel-os-vm.sh

* Update umbrel-os-vm.sh

* Update umbrel-os-vm.sh

* temp folder for big file

* Update umbrel-os-vm.sh

* update MACH (adv. Settings)

* Update umbrel-os-vm.sh

* Formatting

* Update umbrel-os-vm.sh

* Refactor

* Update umbrel-os-vm.sh

* Update umbrel-os-vm.sh
This commit is contained in:
CanbiZ 2025-09-01 15:00:23 +02:00 committed by GitHub
parent 6a69185a2d
commit 5572a7a0ab
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -203,10 +203,9 @@ function exit-script() {
function default_settings() { function default_settings() {
VMID=$(get_valid_nextid) VMID=$(get_valid_nextid)
FORMAT=",efitype=4m" MACHINE="q35"
MACHINE="" FORMAT=""
DISK_SIZE="32G" DISK_SIZE="32G"
DISK_CACHE=""
HN="umbrelos" HN="umbrelos"
CPU_TYPE="" CPU_TYPE=""
CORE_COUNT="2" CORE_COUNT="2"
@ -218,9 +217,8 @@ function default_settings() {
START_VM="yes" START_VM="yes"
METHOD="default" METHOD="default"
echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}${VMID}${CL}" echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}${VMID}${CL}"
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}i440fx${CL}" echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}q35${CL}"
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE}${CL}" echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE}${CL}"
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}${HN}${CL}" echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}${HN}${CL}"
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}" echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}"
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}" echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}"
@ -253,16 +251,16 @@ function advanced_settings() {
fi fi
done done
if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Machine Type" 10 58 2 \
"i440fx" "Machine i440fx" ON \ "q35" "Modern (PCIe, UEFI, default)" ON \
"q35" "Machine q35" OFF \ "i440fx" "Legacy (older compatibility)" OFF \
3>&1 1>&2 2>&3); then 3>&1 1>&2 2>&3); then
if [ $MACH = q35 ]; then if [ "$MACH" = "q35" ]; then
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}" echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}q35${CL}"
FORMAT="" FORMAT=""
MACHINE=" -machine q35" MACHINE=" -machine q35"
else else
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}" echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}i440fx${CL}"
FORMAT=",efitype=4m" FORMAT=",efitype=4m"
MACHINE="" MACHINE=""
fi fi
@ -312,17 +310,20 @@ function advanced_settings() {
exit-script exit-script
fi fi
if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose CPU Model" --cancel-button Exit-Script 10 58 2 \
"0" "KVM64 (Default)" ON \ "KVM64" "Default safe for migration/compatibility" ON \
"1" "Host" OFF \ "Host" "Use host CPU features (faster, no migration)" OFF \
3>&1 1>&2 2>&3); then 3>&1 1>&2 2>&3); then
if [ $CPU_TYPE1 = "1" ]; then case "$CPU_TYPE1" in
"Host")
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}" echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}"
CPU_TYPE=" -cpu host" CPU_TYPE=" -cpu host"
else ;;
*)
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}" echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}"
CPU_TYPE="" CPU_TYPE=""
fi ;;
esac
else else
exit-script exit-script
fi fi
@ -433,86 +434,71 @@ pve_check
ssh_check ssh_check
start_script start_script
post_to_api_vm
msg_info "Validating Storage" msg_info "Validating Storage"
while read -r line; do STORAGE_MENU=()
TAG=$(echo $line | awk '{print $1}') while read -r tag type free; do
TYPE=$(echo $line | awk '{printf "%-10s", $2}') ITEM="Type: $type Free: $free"
FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') STORAGE_MENU+=("$tag" "$ITEM" "OFF")
ITEM=" Type: $TYPE Free: $FREE " done < <(pvesm status -content images | awk 'NR>1 {printf "%s %s %s\n", $1, $2, $6}')
OFFSET=2
if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then if [ ${#STORAGE_MENU[@]} -eq 0 ]; then
MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))
fi
STORAGE_MENU+=("$TAG" "$ITEM" "OFF")
done < <(pvesm status -content images | awk 'NR>1')
VALID=$(pvesm status -content images | awk 'NR>1')
if [ -z "$VALID" ]; then
msg_error "Unable to detect a valid storage location." msg_error "Unable to detect a valid storage location."
exit exit 1
elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then
STORAGE=${STORAGE_MENU[0]} STORAGE=${STORAGE_MENU[0]}
else else
while [ -z "${STORAGE:+x}" ]; do while [ -z "${STORAGE:+x}" ]; do
STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \
"Which storage pool would you like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \ "Which storage pool would you like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \
16 $(($MSG_MAX_LENGTH + 23)) 6 \ 16 70 6 \
"${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3)
done done
fi fi
msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location."
msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}."
msg_info "Retrieving the URL for $APP"
URL="https://download.umbrel.com/release/latest/umbrelos-amd64.img.xz"
FILE="$(basename "$URL")"
sleep 2
msg_ok "${CL}${BL}${URL}${CL}"
curl -f#SL -o "$FILE" "$URL"
msg_ok "Downloaded ${CL}${BL}${FILE}${CL}"
if ! command -v pv &>/dev/null; then msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}."
apt-get update &>/dev/null && apt-get install -y pv &>/dev/null
URL="https://download.umbrel.com/release/latest/umbrelos-amd64.img.xz"
CACHE_DIR="/var/lib/vz/template/cache"
CACHE_FILE="$CACHE_DIR/$(basename "$URL")"
FILE_IMG="/var/lib/vz/template/tmp/${CACHE_FILE##*/%.xz}"
mkdir -p "$CACHE_DIR" "$(dirname "$FILE_IMG")"
if [[ ! -s "$CACHE_FILE" ]]; then
msg_ok "Downloading Umbrel OS image"
curl -f#SL -o "$CACHE_FILE" "$URL"
else
msg_ok "Using cached Umbrel OS image"
fi fi
msg_info "Decompressing $FILE with progress${CL}\n" if ! command -v pv &>/dev/null; then
FILE_IMG="${FILE%.xz}" apt-get update -qq &>/dev/null && apt-get install -y pv &>/dev/null
SIZE=$(xz --robot -l "$FILE" | awk -F '\t' '/^totals/ { print $5 }') &>/dev/null fi
xz -dc "$FILE" | pv -s "$SIZE" -N "Extracting" >"$FILE_IMG"
msg_ok "Decompressed to ${CL}${BL}${FILE%.xz}${CL}"
STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') set -o pipefail
case $STORAGE_TYPE in qm create "$VMID" -machine q35 -bios ovmf -agent 1 -tablet 0 -localtime 1 ${CPU_TYPE} \
nfs | dir) -cores "$CORE_COUNT" -memory "$RAM_SIZE" -name "$HN" -tags community-script \
DISK_EXT=".raw" -net0 "virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU" -onboot 1 -ostype l26 -scsihw virtio-scsi-pci >/dev/null
DISK_REF="$VMID/"
DISK_IMPORT="-format raw"
THIN=""
;;
btrfs)
DISK_EXT=".raw"
DISK_REF="$VMID/"
DISK_IMPORT="-format raw"
FORMAT=",efitype=4m"
THIN=""
;;
esac
for i in {0,1,2}; do
disk="DISK$i"
eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-}
eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk}
done
msg_info "Creating a Umbrel OS VM" xz -dc "$CACHE_FILE" | pv -N "Extracting" >"$FILE_IMG"
qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \
-name $HN -tags community-script -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci >/dev/null if qm disk import --help >/dev/null 2>&1; then
pvesm alloc $STORAGE $VMID $DISK0 4M >/dev/null IMPORT_CMD=(qm disk import)
qm importdisk $VMID ${FILE_IMG} $STORAGE ${DISK_IMPORT:-} >/dev/null else
qm set $VMID \ IMPORT_CMD=(qm importdisk)
-efidisk0 ${DISK0_REF}${FORMAT} \ fi
-scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=${DISK_SIZE} \ IMPORT_OUT="$("${IMPORT_CMD[@]}" "$VMID" "$FILE_IMG" "$STORAGE" --format raw 2>&1 || true)"
-boot order=scsi0 \ DISK_REF="$(printf '%s\n' "$IMPORT_OUT" | sed -n "s/.*imported disk '\([^']\+\)'.*/\1/p" | tr -d "\r\"'")"
-serial0 socket >/dev/null [[ -z "$DISK_REF" ]] && DISK_REF="$(pvesm list "$STORAGE" | awk -v id="$VMID" '$5 ~ ("vm-"id"-disk-") {print $1":"$5}' | sort | tail -n1)"
qm set $VMID --agent enabled=1 >/dev/null
qm set "$VMID" \
--efidisk0 "${STORAGE}:0,efitype=4m" \
--scsi0 "${DISK_REF},ssd=1,discard=on" \
--boot order=scsi0 \
--serial0 socket >/dev/null
qm set "$VMID" --agent enabled=1 >/dev/null
qm resize "$VMID" scsi0 "${DISK_SIZE}" >/dev/null
DESCRIPTION=$( DESCRIPTION=$(
cat <<EOF cat <<EOF
@ -546,13 +532,14 @@ EOF
) )
qm set "$VMID" -description "$DESCRIPTION" >/dev/null qm set "$VMID" -description "$DESCRIPTION" >/dev/null
if [ -n "$DISK_SIZE" ]; then if whiptail --backtitle "Proxmox VE Helper Scripts" --title "Image Cache" \
msg_info "Resizing disk to $DISK_SIZE GB" --yesno "Keep downloaded Umbrel OS image for future VMs?\n\nFile: $CACHE_FILE" 10 70; then
qm resize $VMID scsi0 ${DISK_SIZE} >/dev/null msg_ok "Keeping cached image"
else else
msg_info "Using default disk size of $DEFAULT_DISK_SIZE GB" rm -f "$CACHE_FILE"
qm resize $VMID scsi0 ${DEFAULT_DISK_SIZE} >/dev/null msg_ok "Deleted cached image"
fi fi
rm -f "$FILE_IMG"
msg_ok "Created a Umbrel OS VM ${CL}${BL}(${HN})" msg_ok "Created a Umbrel OS VM ${CL}${BL}(${HN})"
if [ "$START_VM" == "yes" ]; then if [ "$START_VM" == "yes" ]; then