Files
ProxMenux/scripts/global/iso_storage_helpers.sh
T
2026-05-14 14:45:45 +02:00

147 lines
3.6 KiB
Bash

#!/usr/bin/env bash
# ==========================================================
# ProxMenux - ISO Storage Helpers
# ==========================================================
# Shared helpers for VM ISO selection. Proxmox identifies ISO media by
# volume ID (for example: local:iso/debian.iso or nas:iso/win11.iso);
# using the volid lets VMs boot ISOs stored on local, NFS, CIFS or any
# other storage that advertises content=iso.
# ==========================================================
ISO_FALLBACK_DIR="${ISO_FALLBACK_DIR:-/var/lib/vz/template/iso}"
iso_name_from_volid() {
local volid="$1"
local rel="${volid#*:}"
basename "${rel#iso/}"
}
iso_storage_from_volid() {
local volid="$1"
echo "${volid%%:*}"
}
iso_volid_matches_filter() {
local volid="$1"
local filter="${2:-all}"
local name lower
name=$(iso_name_from_volid "$volid")
lower=$(printf '%s' "$name" | tr '[:upper:]' '[:lower:]')
[[ "$lower" == *.iso ]] || return 1
case "$filter" in
windows)
[[ "$lower" != virtio*.iso ]]
;;
virtio)
[[ "$lower" == virtio*.iso ]]
;;
all|*)
return 0
;;
esac
}
iso_path_to_volid() {
local path="$1"
local rest storage file
case "$path" in
/var/lib/vz/template/iso/*)
echo "local:iso/$(basename "$path")"
return 0
;;
/mnt/pve/*/template/iso/*)
rest="${path#/mnt/pve/}"
storage="${rest%%/*}"
file="$(basename "$path")"
echo "${storage}:iso/${file}"
return 0
;;
esac
return 1
}
iso_volid_to_path() {
local volid="$1"
local storage rel file path
if command -v pvesm >/dev/null 2>&1; then
path=$(pvesm path "$volid" 2>/dev/null || true)
if [[ -n "$path" ]]; then
echo "$path"
return 0
fi
fi
storage=$(iso_storage_from_volid "$volid")
rel="${volid#*:}"
file="$(basename "${rel#iso/}")"
if [[ "$storage" == "local" ]]; then
echo "/var/lib/vz/template/iso/$file"
else
echo "/mnt/pve/$storage/template/iso/$file"
fi
}
iso_list_volids() {
local filter="${1:-all}"
local storage volid path
local -a volids=()
if command -v pvesm >/dev/null 2>&1; then
while read -r storage; do
[[ -z "$storage" ]] && continue
while read -r volid; do
[[ -z "$volid" ]] && continue
if iso_volid_matches_filter "$volid" "$filter"; then
volids+=("$volid")
fi
done < <(pvesm list "$storage" --content iso 2>/dev/null | awk 'NR>1 {print $1}')
done < <(pvesm status -content iso 2>/dev/null | awk 'NR>1 && $3 == "active" {print $1}')
fi
if [[ ${#volids[@]} -eq 0 && -d "$ISO_FALLBACK_DIR" ]]; then
while read -r path; do
volid=$(iso_path_to_volid "$path" 2>/dev/null || true)
[[ -z "$volid" ]] && continue
if iso_volid_matches_filter "$volid" "$filter"; then
volids+=("$volid")
fi
done < <(find "$ISO_FALLBACK_DIR" -maxdepth 1 -type f -iname "*.iso" | sort)
fi
[[ ${#volids[@]} -gt 0 ]] && printf '%s\n' "${volids[@]}" | sort -u
}
iso_human_size() {
local path="$1"
local bytes
[[ -f "$path" ]] || { echo "-"; return 0; }
if command -v du >/dev/null 2>&1; then
du -h "$path" 2>/dev/null | awk '{print $1}'
return 0
fi
bytes=$(wc -c < "$path" 2>/dev/null || echo "")
[[ -n "$bytes" ]] && echo "${bytes}B" || echo "-"
}
iso_dialog_description() {
local volid="$1"
local name storage path size
name=$(iso_name_from_volid "$volid")
storage=$(iso_storage_from_volid "$volid")
path=$(iso_volid_to_path "$volid")
size=$(iso_human_size "$path")
printf '%-42s │ %-14s │ %s' "$name" "$storage" "$size"
}