mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2025-06-28 04:06:54 +00:00
Update import-disk-image.sh
This commit is contained in:
parent
cb12b162b7
commit
211f89e03e
@ -1,7 +1,30 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Source utility functions from local installation
|
||||
source "/usr/local/share/proxmenux/utils.sh"
|
||||
# ==========================================================
|
||||
# ProxMenu - A menu-driven script for Proxmox VE management
|
||||
# ==========================================================
|
||||
# Author : MacRimi
|
||||
# Copyright : (c) 2024 MacRimi
|
||||
# License : MIT (https://raw.githubusercontent.com/MacRimi/ProxMenux/main/LICENSE)
|
||||
# Version : 1.0
|
||||
# Last Updated: 28/01/2025
|
||||
# ==========================================================
|
||||
|
||||
|
||||
# Configuration
|
||||
UTILS_URL="https://raw.githubusercontent.com/MacRimi/ProxMenux/main/scripts/utils.sh"
|
||||
BASE_DIR="/usr/local/share/proxmenux"
|
||||
CACHE_FILE="$BASE_DIR/cache.json"
|
||||
VENV_PATH="/opt/googletrans-env"
|
||||
LANGUAGE=$(jq -r '.language' "$BASE_DIR/config.json" 2>/dev/null || echo "en")
|
||||
|
||||
|
||||
|
||||
# Try to load utils.sh from GitHub
|
||||
if ! source <(curl -sSf "$UTILS_URL"); then
|
||||
echo "$(translate 'Error: Could not load utils.sh from') $UTILS_URL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Path where disk images are stored
|
||||
IMAGES_DIR="/var/lib/vz/template/images/"
|
||||
@ -9,31 +32,35 @@ IMAGES_DIR="/var/lib/vz/template/images/"
|
||||
# Check if there are any images in the directory
|
||||
IMAGES=$(ls -A "$IMAGES_DIR" | grep -E "\.(img|qcow2|vmdk)$")
|
||||
if [ -z "$IMAGES" ]; then
|
||||
whiptail --title "$(translate 'No Images Available')" --msgbox "$(translate 'No disk images available for import in') $IMAGES_DIR\n\n$(translate 'Supported formats: .img, .qcow2, .vmdk')\n\n$(translate 'Please add some images and try again.')" 12 60
|
||||
msg_error "$(translate 'No images available for import in') $IMAGES_DIR"
|
||||
echo -e "${YW}$(translate 'Supported formats: .img, .qcow2, .vmdk')${CL}"
|
||||
echo -e "${YW}$(translate 'Please add some images and try again.')${CL}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Check dependencies
|
||||
check_dependencies qm whiptail jq
|
||||
check_dependencies qm whiptail jq || exit 1
|
||||
|
||||
# Initial setup
|
||||
if ! [ -d "$IMAGES_DIR" ]; then
|
||||
msg_info "$(translate 'Creating images directory...')"
|
||||
msg_info "$(translate 'Creating images directory')"
|
||||
mkdir -p "$IMAGES_DIR"
|
||||
msg_ok "$(translate 'Images directory created')"
|
||||
fi
|
||||
|
||||
# Display initial message
|
||||
whiptail --title "$(translate 'Import Disk Image')" --msgbox "$(translate 'Please ensure that the disk images you want to import are located in:')\n\n$IMAGES_DIR\n\n$(translate 'Supported formats: .img, .qcow2, .vmdk.')" 12 60
|
||||
whiptail --title "$(translate 'Import Disk Image')" --msgbox "$(translate 'Make sure the disk images you want to import are located in:')\n\n$IMAGES_DIR\n\n$(translate 'Supported formats: .img, .qcow2, .vmdk.')" 12 60
|
||||
|
||||
|
||||
|
||||
# 1. Select VM
|
||||
msg_info "$(translate 'Getting VM list...')"
|
||||
VM_LIST=$(qm list | awk 'NR>1 {print $1, $2}')
|
||||
msg_info "$(translate 'Getting VM list')"
|
||||
VM_LIST=$(qm list | awk 'NR>1 {print $1" "$2}')
|
||||
if [ -z "$VM_LIST" ]; then
|
||||
msg_error "$(translate 'No VMs available in the system')"
|
||||
exit 1
|
||||
fi
|
||||
msg_ok "$(translate 'VM list retrieved')"
|
||||
msg_ok "$(translate 'VM list obtained')"
|
||||
|
||||
VMID=$(whiptail --title "$(translate 'Select VM')" --menu "$(translate 'Select the VM where you want to import the disk image:')" 15 60 8 $VM_LIST 3>&1 1>&2 2>&3)
|
||||
|
||||
@ -42,20 +69,22 @@ if [ -z "$VMID" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# 2. Select storage volume
|
||||
msg_info "$(translate 'Getting storage volumes...')"
|
||||
msg_info "$(translate 'Getting storage volumes')"
|
||||
STORAGE_LIST=$(pvesm status -content images | awk 'NR>1 {print $1}')
|
||||
if [ -z "$STORAGE_LIST" ]; then
|
||||
msg_error "$(translate 'No storage volumes available')"
|
||||
exit 1
|
||||
fi
|
||||
msg_ok "$(translate 'Storage volumes retrieved')"
|
||||
msg_ok "$(translate 'Storage volumes obtained')"
|
||||
|
||||
# Create an array of storage options for whiptail
|
||||
STORAGE_OPTIONS=()
|
||||
for storage in $STORAGE_LIST; do
|
||||
STORAGE_OPTIONS+=("$storage" "$storage")
|
||||
done
|
||||
while read -r storage; do
|
||||
STORAGE_OPTIONS+=("$storage" "")
|
||||
done <<< "$STORAGE_LIST"
|
||||
|
||||
STORAGE=$(whiptail --title "$(translate 'Select Storage')" --menu "$(translate 'Select the storage volume for disk import:')" 15 60 8 "${STORAGE_OPTIONS[@]}" 3>&1 1>&2 2>&3)
|
||||
|
||||
@ -64,20 +93,22 @@ if [ -z "$STORAGE" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# 3. Select disk images
|
||||
msg_info "$(translate 'Scanning for disk images...')"
|
||||
msg_info "$(translate 'Scanning disk images')"
|
||||
if [ -z "$IMAGES" ]; then
|
||||
msg_error "$(translate 'No compatible disk images found in') $IMAGES_DIR"
|
||||
exit 0
|
||||
fi
|
||||
msg_ok "$(translate 'Disk images found')"
|
||||
|
||||
IMAGE_LIST=""
|
||||
for img in $IMAGES; do
|
||||
IMAGE_LIST="$IMAGE_LIST $img OFF"
|
||||
done
|
||||
IMAGE_OPTIONS=()
|
||||
while read -r img; do
|
||||
IMAGE_OPTIONS+=("$img" "" "OFF")
|
||||
done <<< "$IMAGES"
|
||||
|
||||
SELECTED_IMAGES=$(whiptail --title "$(translate 'Select Disk Images')" --checklist "$(translate 'Select the disk images to import:')" 20 60 10 $IMAGE_LIST 3>&1 1>&2 2>&3)
|
||||
SELECTED_IMAGES=$(whiptail --title "$(translate 'Select Disk Images')" --checklist "$(translate 'Select the disk images to import:')" 20 60 10 "${IMAGE_OPTIONS[@]}" 3>&1 1>&2 2>&3)
|
||||
|
||||
if [ -z "$SELECTED_IMAGES" ]; then
|
||||
msg_error "$(translate 'No images selected')"
|
||||
@ -86,26 +117,16 @@ fi
|
||||
|
||||
# 4. Import each selected image
|
||||
for IMAGE in $SELECTED_IMAGES; do
|
||||
|
||||
# Remove quotes from selected image
|
||||
IMAGE=$(echo "$IMAGE" | tr -d '"')
|
||||
|
||||
# 5. Select disk format for each image
|
||||
FORMAT=$(whiptail --title "$(translate 'Disk Format')" --menu "$(translate 'Select disk format for image:') $IMAGE" 15 40 4 \
|
||||
"raw" "$(translate 'Raw format')" \
|
||||
"qcow2" "$(translate 'QCOW2 format')" \
|
||||
"vmdk" "$(translate 'VMDK format')" 3>&1 1>&2 2>&3)
|
||||
|
||||
if [ -z "$FORMAT" ]; then
|
||||
msg_error "$(translate 'No disk format selected for') $IMAGE"
|
||||
continue
|
||||
fi
|
||||
|
||||
# 6. Select interface type for each image
|
||||
INTERFACE=$(whiptail --title "$(translate 'Interface Type')" --menu "$(translate 'Select interface type for image:') $IMAGE" 15 40 4 \
|
||||
"scsi" "$(translate 'SCSI')" \
|
||||
"sata" "$(translate 'SATA')" \
|
||||
"virtio" "$(translate 'VirtIO')" \
|
||||
"ide" "$(translate 'IDE')" 3>&1 1>&2 2>&3)
|
||||
# 5. Select interface type for each image
|
||||
INTERFACE=$(whiptail --title "$(translate 'Interface Type')" --menu "$(translate 'Select the interface type for the image:') $IMAGE" 15 40 4 \
|
||||
"sata" "SATA" \
|
||||
"scsi" "SCSI" \
|
||||
"virtio" "VirtIO" \
|
||||
"ide" "IDE" 3>&1 1>&2 2>&3)
|
||||
|
||||
if [ -z "$INTERFACE" ]; then
|
||||
msg_error "$(translate 'No interface type selected for') $IMAGE"
|
||||
@ -114,34 +135,86 @@ for IMAGE in $SELECTED_IMAGES; do
|
||||
|
||||
FULL_PATH="$IMAGES_DIR/$IMAGE"
|
||||
|
||||
msg_info "$(translate 'Importing image:') $IMAGE $(translate 'as') ${FORMAT}..."
|
||||
# Show initial message
|
||||
msg_info "$(translate 'Importing image:')"
|
||||
|
||||
(
|
||||
if qm importdisk "$VMID" "$FULL_PATH" "$STORAGE" --format "$FORMAT"; then
|
||||
# Find the next available disk slot
|
||||
NEXT_SLOT=$(qm config "$VMID" | grep -oP "${INTERFACE}\d+" | sort -n | tail -n1 | sed "s/${INTERFACE}//")
|
||||
NEXT_SLOT=$((NEXT_SLOT + 1))
|
||||
# Temporary file to capture the imported disk
|
||||
TEMP_DISK_FILE=$(mktemp)
|
||||
|
||||
IMPORTED_DISK=$(qm config "$VMID" | grep -oP "${STORAGE}:[^\s]+")
|
||||
|
||||
# Execute the command and process its output in real-time
|
||||
qm importdisk "$VMID" "$FULL_PATH" "$STORAGE" 2>&1 | while read -r line; do
|
||||
if [[ "$line" =~ transferred ]]; then
|
||||
|
||||
# Extract the progress percentage
|
||||
PERCENT=$(echo "$line" | grep -oP "\(\d+\.\d+%\)" | tr -d '()%')
|
||||
|
||||
# Show progress with custom format without translation
|
||||
echo -ne "\r${TAB}${YW}-$(translate 'Importing image:') $IMAGE-${CL} ${PERCENT}%"
|
||||
|
||||
elif [[ "$line" =~ successfully\ imported\ disk ]]; then
|
||||
|
||||
# Extract the imported disk name and save it to the temporary file
|
||||
echo "$line" | grep -oP "(?<=successfully imported disk ').*(?=')" > "$TEMP_DISK_FILE"
|
||||
fi
|
||||
done
|
||||
echo -ne "\n"
|
||||
|
||||
|
||||
IMPORT_STATUS=${PIPESTATUS[0]} # Capture the exit status of the main command
|
||||
|
||||
if [ $IMPORT_STATUS -eq 0 ]; then
|
||||
msg_ok "$(translate 'Image imported successfully')"
|
||||
|
||||
# Read the imported disk from the temporary file
|
||||
IMPORTED_DISK=$(cat "$TEMP_DISK_FILE")
|
||||
rm -f "$TEMP_DISK_FILE" # Delete the temporary file
|
||||
|
||||
if [ -n "$IMPORTED_DISK" ]; then
|
||||
if qm set "$VMID" --${INTERFACE}${NEXT_SLOT} "$IMPORTED_DISK"; then
|
||||
msg_ok "$(translate 'Successfully imported') $IMAGE $(translate 'as') ${INTERFACE}${NEXT_SLOT}"
|
||||
else
|
||||
msg_error "$(translate 'Failed to configure disk') ${INTERFACE}${NEXT_SLOT} $(translate 'for VM') $VMID"
|
||||
fi
|
||||
else
|
||||
msg_error "$(translate 'Failed to find imported disk')"
|
||||
fi
|
||||
else
|
||||
msg_error "$(translate 'Failed to import') $IMAGE"
|
||||
fi
|
||||
) &
|
||||
|
||||
spinner
|
||||
wait
|
||||
# Find the next available disk slot
|
||||
EXISTING_DISKS=$(qm config "$VMID" | grep -oP "${INTERFACE}\d+" | sort -n)
|
||||
if [ -z "$EXISTING_DISKS" ]; then
|
||||
|
||||
# If there are no existing disks, start from 0
|
||||
NEXT_SLOT=0
|
||||
else
|
||||
# If there are existing disks, take the last one and add 1
|
||||
LAST_SLOT=$(echo "$EXISTING_DISKS" | tail -n1 | sed "s/${INTERFACE}//")
|
||||
NEXT_SLOT=$((LAST_SLOT + 1))
|
||||
fi
|
||||
|
||||
# Ask if SSD emulation is desired
|
||||
if (whiptail --title "$(translate 'SSD Emulation')" --yesno "$(translate 'Do you want to use SSD emulation for this disk?')" 10 60); then
|
||||
SSD_OPTION=",ssd=1"
|
||||
else
|
||||
SSD_OPTION=""
|
||||
fi
|
||||
|
||||
msg_info "$(translate 'Configuring disk')"
|
||||
|
||||
# Configure the disk in the VM
|
||||
if qm set "$VMID" --${INTERFACE}${NEXT_SLOT} "$IMPORTED_DISK${SSD_OPTION}" &>/dev/null; then
|
||||
msg_ok "$(translate 'Image') $IMAGE $(translate 'configured as') ${INTERFACE}${NEXT_SLOT}"
|
||||
|
||||
# Ask if the disk should be bootable
|
||||
if (whiptail --title "$(translate 'Make Bootable')" --yesno "$(translate 'Do you want to make this disk bootable?')" 10 60); then
|
||||
msg_info "$(translate 'Configuring disk as bootable')"
|
||||
if qm set "$VMID" --boot c --bootdisk ${INTERFACE}${NEXT_SLOT} &>/dev/null; then
|
||||
msg_ok "$(translate 'Disk configured as bootable')"
|
||||
else
|
||||
msg_error "$(translate 'Could not configure the disk as bootable')"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
msg_error "$(translate 'Could not configure disk') ${INTERFACE}${NEXT_SLOT} $(translate 'for VM') $VMID"
|
||||
fi
|
||||
else
|
||||
msg_error "$(translate 'Could not find the imported disk')"
|
||||
fi
|
||||
else
|
||||
msg_error "$(translate 'Could not import') $IMAGE"
|
||||
fi
|
||||
done
|
||||
|
||||
msg_ok "$(translate 'All selected images have been processed')"
|
||||
exit 0
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user