rr-dsm.jpeg
rr-dsm.jpeg

Introduction

Thanks to RROrg for providing the RR: Redpill’s Preinstallation and Recovery Environment, which offers a straightforward way to install Synology DSM OS on any x86/x64 architecture machine.

One-Click to Deploy a DSM VM and Disk Mapping

This script consolidates all functionalities and makes it interactive.🚀

  • Creating the virtual machine in PVE
  • Handling dynamic disk imports
  • Adding options such as local-lvm
bash -c "$(wget -qLO - https://kingtam.win/usr/uploads/script/rr-dsm.sh)"

Start the VM and initialize the preinstallation environment by accessing http://rr.7681 (where rr represents the VM's IP address assigned by the DHCP server).

Alternatively, you can configure the loader via SSH using the following credentials:

  • Username: root
  • Password: rr
menu.sh

2025-03-23_175743.png
2025-03-23_175743.png

2025-03-23_175817.png
2025-03-23_175817.png

2025-03-23_175824.png
2025-03-23_175824.png

2025-03-23_175829.png
2025-03-23_175829.png

2025-03-23_175837.png
2025-03-23_175837.png

2025-03-23_175842.png
2025-03-23_175842.png

2025-03-23_175849.png
2025-03-23_175849.png

2025-03-23_180121.png
2025-03-23_180121.png

2025-03-23_180136.png
2025-03-23_180136.png

2025-03-23_180200.png
2025-03-23_180200.png

2025-03-23_180425.png
2025-03-23_180425.png


Let's Breakdown the Part of the Shell Script

Part 1: and Error Handling Functionality

This part introduces the script's structure and defines a custom error-handling function. Here's the first part:

#!/bin/bash

set -e  # Exit immediately on error

# Function to display error and exit
error_exit() {
    echo "Error: $1"
    exit 1
}

This ensures that the script terminates safely with meaningful error messages if something goes wrong.

Part 2: Display Main Menu and Disk Selection

This section covers creating a menu to offer the user various disk management options for the virtual machine.

# Function to display the main menu
show_menu() {
    echo "Please select an option for VM $VMID:"
    echo "0) Quit"
    echo "1) Add a local-lvm disk to SATA1 (size: 32GB)"
    for i in "${!DISKS[@]}"; do
        echo "$((i + 2))) Import ${DISKS[i]}"
    done
}

Part 3: Dynamically Adding Disks to Available SATA Ports

This function automatically adds a disk to the next free SATA port.

# Function to add disks dynamically
add_disk_to_vm() {
    SELECTED_DISK=$1
    for PORT in {1..10}; do
        if ! qm config "$VMID" | grep -q "sata${PORT}"; then
            qm set "$VMID" --sata${PORT} "$SELECTED_DISK" || error_exit "Failed to assign disk $SELECTED_DISK."
            echo "Disk $SELECTED_DISK has been successfully assigned to SATA${PORT} of VM $VMID."
            return
        fi
    done
    error_exit "No available SATA ports found for VM $VMID."
}

Part 4: Validating VMID and Removing Existing VMs

This part explains how the script handles VMID validation and removes existing VMs if the same ID is reused.

# Ask for VMID
read -p "Enter Virtual Machine ID for Synology DSM install: " VMID

# Check if VMID is valid (numeric and not empty)
if ! [[ $VMID =~ ^[0-9]+$ ]]; then
    error_exit "Invalid VMID. Please enter a numeric value."
fi

# Check if VMID already exists
if qm status "$VMID" &> /dev/null; then
    read -p "VM $VMID already exists. Do you want to remove it? (y/n) " choice
    case "$choice" in
        y|Y )
            echo "Stopping and removing VM $VMID..."
            qm stop "$VMID" || true  # Allow stop command to fail gracefully
            qm destroy "$VMID" --purge || error_exit "Failed to remove VM $VMID."
            echo "VM $VMID has been removed."
            ;;
        * )
            error_exit "Please enter a different VMID."
            ;;
    esac
fi

Part 5: Downloading and Extracting the Latest Release

The script fetches the latest release URL dynamically, downloads the file, and extracts it into a specified folder.

# Ensure unzip is installed
if ! command -v unzip &> /dev/null; then
    echo "Unzip is not installed. Installing it now..."
    apt update && apt install -y unzip || error_exit "Failed to install unzip."
fi

# Get the latest release version dynamically
echo "Fetching the latest release version from GitHub..."
latest_url=$(curl -s https://api.github.com/repos/RROrg/rr/releases/latest | grep -oP '"browser_download_url": "\K(https.*?\.img\.zip)(?=")')
if [ -z "$latest_url" ]; then
    error_exit "Failed to fetch the latest release URL."
fi

echo "Latest release URL: $latest_url"

# Download the image
image_folder="/var/lib/vz/template/iso/"
output_file="rr.img.zip"

echo "Downloading the image..."
wget -O "$output_file" "$latest_url" || error_exit "Failed to download the image."

# Extract the image
echo "Extracting the image to $image_folder..."
mkdir -p "$image_folder"
unzip -o "$output_file" -d "$image_folder" || error_exit "Failed to extract the image."
rm -f "$output_file"

Part 6: Virtual Machine Creation

This part handles creating the VM and configuring the boot disk.

# Identify the extracted image file
image=$(find "$image_folder" -name "*.img" -type f | head -n 1)
if [ -z "$image" ]; then
    error_exit "Image file not found after extraction."
fi

echo "Image file located at: $image"

# Create virtual machine
echo "Creating VM $VMID..."
qm create "$VMID" --name DSM --memory 4096 --sockets 1 --cores 2 --cpu host --net0 virtio,bridge=vmbr0 --ostype l26 || error_exit "Failed to create VM."

# Import image as boot disk
echo "Importing image as boot disk..."
qm importdisk "$VMID" "$image" local-lvm || error_exit "Failed to import disk."
qm set "$VMID" --sata0 local-lvm:vm-"$VMID"-disk-0 || error_exit "Failed to set SATA disk."
qm set "$VMID" --boot c --bootdisk sata0 || error_exit "Failed to configure boot disk."

Part 7: Disk Management Menu

This part covers how the script interacts with the user to handle dynamic disk imports or adding a local-lvm disk.

# Gather the list of ATA devices (excluding duplicates and partitions)
DISK_LIST=$(ls /dev/disk/by-id/ | grep -ia ata | grep -v '\-part' | uniq)

# Check if any disks were found
if [ -z "$DISK_LIST" ]; then
    echo "No ATA devices found. Proceeding without additional disks..."
    exit 0
fi

# Convert the list of disks into an array
DISKS=()
while IFS= read -r line; do
    DISKS+=("/dev/disk/by-id/$line")
done <<< "$DISK_LIST"

# Main loop
while true; do
    show_menu  # Show the menu

    # Get user choice
    read -p "Enter your choice [0-$(( ${#DISKS[@]} + 1 ))]: " CHOICE
    if [[ "$CHOICE" -eq 0 ]]; then
        echo "Exiting. Goodbye!"
        exit 0
    elif [[ "$CHOICE" -eq 1 ]]; then
        # Add a 32GB local-lvm disk to SATA1
        if qm config "$VMID" | grep -q "sata1"; then
            echo "SATA1 is already in use. Please free it or choose another option."
        else
            qm set "$VMID" --sata1 local-lvm:32 || error_exit "Failed to add local-lvm disk."
            echo "A 32GB local-lvm disk has been added to SATA1 of VM $VMID."
        fi
    elif [[ "$CHOICE" -ge 2 && "$CHOICE" -le $(( ${#DISKS[@]} + 1 )) ]]; then
        SELECTED_DISK=${DISKS[CHOICE-2]}
        echo "You selected: $SELECTED_DISK"
        add_disk_to_vm "$SELECTED_DISK"
    else
        echo "Invalid choice. Please try again."
    fi
done

Customization (OPTION)

Configures the VM to use UEFI firmware and sets the machine type to Q35, which provides better PCIe support.
# Set BIOS to UEFI
qm set "$VMID" --bios ovmf
# Set machine type to P35
qm set "$VMID" --machine pc-q35-6.2
Add a virtual serial port to the VM and uses a serial terminal as the display output.
qm set "$VMID" --serial0 socket --vga serial0

Related