From 399740ed56c3780ca8bc6b21c90ab9f57a565a13 Mon Sep 17 00:00:00 2001 From: "Oritorius(Denis Rykov)" Date: Wed, 9 Jul 2025 23:52:45 +0500 Subject: [PATCH 1/6] Update install.sh feat(installer): add automated OSX-PROXMOX installation script with progress bar and error handling - Added bash script to automate installation of OSX-PROXMOX on Proxmox VE - Includes visual progress bar for step tracking - Implements cleanup of previous installation data and apt source fixes - Adds auto-mirror detection using IP geolocation - Handles Git installation and repository cloning - Validates presence of setup script and ensures execution permissions - Provides detailed logging to /tmp/install-osx-proxmox.log - Displays success/failure messages for each stage --- install.sh | 127 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 93 insertions(+), 34 deletions(-) diff --git a/install.sh b/install.sh index 853f575..62930d8 100755 --- a/install.sh +++ b/install.sh @@ -1,47 +1,106 @@ #!/bin/bash -######################################################################################################################### -# -# Script: install -# -# https://luchina.com.br -# -######################################################################################################################### +############################################################################################################ +# Script: install.sh +# Purpose: Automated setup for OSX-PROXMOX environment on Proxmox VE +# Source: https://luchina.com.br +# Author: luchina-gabriel (https://github.com/luchina-gabriel/OSX-PROXMOX) +############################################################################################################ clear -if [ -e /root/OSX-PROXMOX ]; then rm -rf /root/OSX-PROXMOX; fi; -if [ -e /etc/apt/sources.list.d/pve-enterprise.list ]; then rm -rf /etc/apt/sources.list.d/pve-enterprise.list; fi; -if [ -e /etc/apt/sources.list.d/ceph.list ]; then rm -rf /etc/apt/sources.list.d/ceph.list; fi; -# Is this better? -echo "Waiting to install OSX-PROXMOX..." -echo " " +# Function to render a simple progress bar +progress_bar() { + local percent=$1 + local bar="" + for ((i=0; i /tmp/install-osx-proxmox.log 2>> /tmp/install-osx-proxmox.log +echo "Initializing OSX-PROXMOX installation..." +sleep 1 -if [ $? -ne 0 ] -then - echo " " - echo "Error with 'apt-get update' ..." - echo "Trying to change /etc/apt/sources.list" - echo " " - # Always using a Brazilian server will not be fast... - # I suggest using the users home country, As it will always be faster. - Country=$(curl -s https://ipinfo.io/country | tr '[:upper:]' '[:lower:]') - sed -i "s/ftp.$Country.debian.org/ftp.debian.org/g" /etc/apt/sources.list - - echo "Retrying 'apt-get update' ..." - echo " " +TOTAL_STEPS=8 +CURRENT_STEP=0 - apt-get update >> /tmp/install-osx-proxmox.log 2>> /tmp/install-osx-proxmox.log - - if [ $? -ne 0 ]; then echo "Error with 'apt-get update' ..."; exit; fi +# Progress bar updater +update_progress() { + CURRENT_STEP=$((CURRENT_STEP + 1)) + progress_bar $((CURRENT_STEP * 100 / TOTAL_STEPS)) + sleep 0.3 +} + +# Initialize progress display +progress_bar 0 +sleep 1 + +# Step 1: Cleanup previous installations +echo "[*] Cleaning up previous installation (if any)..." +rm -rf /root/OSX-PROXMOX +rm -f /etc/apt/sources.list.d/pve-enterprise.list +rm -f /etc/apt/sources.list.d/ceph.list +update_progress + +# Step 2: Update system packages +echo -e "\n[*] Updating package lists..." +apt update > /tmp/install-osx-proxmox.log 2>&1 +if [ $? -ne 0 ]; then + echo "[!] 'apt update' failed. Attempting to fix mirrors..." + + # Auto-detect user's country for better mirror selection + COUNTRY=$(curl -s https://ipinfo.io/country | tr '[:upper:]' '[:lower:]') + MIRROR="ftp.${COUNTRY}.debian.org" + + if ! grep -q "$MIRROR" /etc/apt/sources.list; then + echo "[*] Updating Debian mirror in sources.list..." + sed -i "s|$MIRROR|ftp.debian.org|g" /etc/apt/sources.list + fi + + echo "[*] Retrying 'apt update'..." + apt update >> /tmp/install-osx-proxmox.log 2>&1 + if [ $? -ne 0 ]; then + echo "[!] Failed to update package list even after adjusting mirrors. Aborting." + exit 1 + fi fi +update_progress -apt install git -y >> /tmp/install-osx-proxmox.log 2>> /tmp/install-osx-proxmox.log +# Step 3: Install Git +echo "[*] Installing Git..." +apt install -y git >> /tmp/install-osx-proxmox.log 2>&1 +update_progress -git clone https://github.com/luchina-gabriel/OSX-PROXMOX.git >> /tmp/install-osx-proxmox.log 2>> /tmp/install-osx-proxmox.log +# Step 4: Clone OSX-PROXMOX repository +echo "[*] Cloning OSX-PROXMOX repository..." +git clone https://github.com/luchina-gabriel/OSX-PROXMOX.git /root/OSX-PROXMOX >> /tmp/install-osx-proxmox.log 2>&1 +if [ $? -ne 0 ]; then + echo "[!] Failed to clone the repository. Check your internet connection or GitHub availability." + exit 1 +fi +update_progress -if [ ! -e /root/OSX-PROXMOX ]; then mkdir -p /root/OSX-PROXMOX; fi; +# Step 5: Validate setup script presence +if [ ! -f /root/OSX-PROXMOX/setup ]; then + echo "[!] Setup script not found in the repository. Aborting installation." + exit 1 +fi +update_progress -/root/OSX-PROXMOX/setup +# Step 6: Make the setup script executable +chmod +x /root/OSX-PROXMOX/setup +update_progress + +# Step 7: Run the setup +echo -e "\n[*] Executing OSX-PROXMOX setup script..." +cd /root/OSX-PROXMOX && ./setup +if [ $? -ne 0 ]; then + echo -e "\n[!] An error occurred during setup. Please check the log at: /tmp/install-osx-proxmox.log" + exit 1 +fi +update_progress + +# Step 8: Finalization +echo -e "\n[+] OSX-PROXMOX setup completed successfully!" +update_progress + +echo -e "\nInstallation finished.\n" From f17155490f0b886fe08c8b72f00e728cce76ed18 Mon Sep 17 00:00:00 2001 From: "Oritorius(Denis Rykov)" Date: Wed, 9 Jul 2025 23:56:42 +0500 Subject: [PATCH 2/6] Update IOMMU-Groups.sh Add IOMMU-Groups.sh: List PCI devices grouped by IOMMU group This script scans IOMMU groups on the system and lists all associated PCI devices in a clear format. Features: - Lists each IOMMU group numerically. - Displays detailed device info using lspci. - Safe globbing with nullglob enabled. - Works in headless and minimal environments (no color output). Useful for troubleshooting PCIe passthrough setups in KVM/Proxmox environments. --- tools/IOMMU-Groups.sh | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/tools/IOMMU-Groups.sh b/tools/IOMMU-Groups.sh index 32544af..b9ce965 100755 --- a/tools/IOMMU-Groups.sh +++ b/tools/IOMMU-Groups.sh @@ -1,19 +1,35 @@ #!/bin/bash -# +# # Script: IOMMU-Groups.sh -# Goal: List PCI devices in IOMMU Groups -# +# Goal: List PCI devices in IOMMU Groups (no color output) +# # Author: Gabriel Luchina # https://luchina.com.br -# 20211118T0010 +# Original: 20211118T0010 +# Updated: 2025-04-05 +# + +# Check for root privileges +if [ "$EUID" -ne 0 ]; then + echo "Warning: It is recommended to run as root for full access." + echo "Press Enter to continue as a regular user, or CTRL+C to exit..." + read -r +fi shopt -s nullglob -for group in `ls /sys/kernel/iommu_groups/ | sort -V` -do - echo "IOMMU Group ${group##*/}:" - for device in /sys/kernel/iommu_groups/$group/devices/* - do - echo -e "\t$(lspci -nns ${device##*/})" +echo "IOMMU Group Devices:" + +for group in $(ls /sys/kernel/iommu_groups/ | sort -V); do + group_num=$(echo "$group" | sed 's/[^0-9]*//g') + echo "Group $group_num:" + for device in /sys/kernel/iommu_groups/$group/devices/*; do + dev_id="${device##*/}" + info=$(lspci -nns "$dev_id" 2>/dev/null || true) + if [[ -z "$info" ]]; then + echo -e "\t$dev_id (Unable to get info)" + else + echo -e "\t$info" + fi done done From ce79223f49d6f84943dca53ce3f752d884dd9f23 Mon Sep 17 00:00:00 2001 From: "Oritorius(Denis Rykov)" Date: Wed, 9 Jul 2025 23:58:51 +0500 Subject: [PATCH 3/6] Update build-image.sh Add create-recovery-disk.sh: Generate macOS Recovery RAW disk for QEMU This script automates the creation of a macOS Recovery disk image suitable for use with QEMU/KVM environments. Features: - Creates a sparse DMG image and formats it as FAT32 - Mounts and populates the recovery partition with .dmg and .chunklist files - Converts the final image to raw format using qemu-img - Includes cleanup on exit and error handling - Outputs Recovery.RO.raw ready for use in macOS VM setups Useful for Proxmox or QEMU-based macOS virtualization workflows. --- tools/macrecovery/build-image.sh | 88 ++++++++++++++++++++++++++------ 1 file changed, 73 insertions(+), 15 deletions(-) diff --git a/tools/macrecovery/build-image.sh b/tools/macrecovery/build-image.sh index 8dc7107..100b41b 100755 --- a/tools/macrecovery/build-image.sh +++ b/tools/macrecovery/build-image.sh @@ -1,18 +1,76 @@ #!/bin/bash -e -rm -rf Recovery.RO.dmg Recovery.RO.raw Recovery.dmg.sparseimage +# Script: create-recovery-disk.sh +# Author: Gabriel Luchina +# https://luchina.com.br +# Description: Creates a Recovery DMG and converts it to raw for QEMU use + +# Clean up on exit +cleanup() { + echo "Cleaning up temporary files..." + hdiutil verify "$SPARSE_IMAGE" &>/dev/null || true + hdiutil detach "$DEVICE" &>/dev/null || true + rm -f "$SPARSE_IMAGE" "$OUTPUT_DMG" &>/dev/null || true +} +trap cleanup EXIT + +# Constants +SPARSE_IMAGE="Recovery.dmg.sparseimage" +OUTPUT_DMG="Recovery.RO.dmg" +OUTPUT_RAW="Recovery.RO.raw" + +# Check prerequisites +if ! command -v hdiutil &>/dev/null; then + echo "Error: hdiutil not found. Install macOS command-line tools." >&2 + exit 1 +fi + +if ! command -v qemu-img &>/dev/null; then + echo "Error: qemu-img not found. Please install qemu-utils." >&2 + exit 1 +fi + +# Clean previous builds +echo "Removing old recovery disk files..." +rm -f "$SPARSE_IMAGE" "$OUTPUT_DMG" "$OUTPUT_RAW" + +# Create sparse image +echo "Creating sparse disk image..." hdiutil create -size 800m -layout "UNIVERSAL HD" -type SPARSE -o Recovery.dmg -newDevice=$(hdiutil attach -nomount Recovery.dmg.sparseimage | head -n 1 | awk '{print $1}') -echo newdevice "$newDevice" -diskutil partitionDisk "${newDevice}" 1 MBR fat32 RECOVERY R -N=$(echo "$newDevice" | tr -dc '0-9') -diskutil mount disk"${N}"s1 -MOUNT="$(diskutil info disk"${N}"s1 | sed -n 's/.*Mount Point: *//p')" -mkdir -p "$MOUNT/com.apple.recovery.boot" -cp ./*.dmg ./*.chunklist "$MOUNT/com.apple.recovery.boot/" -diskutil umount disk"${N}"s1 -hdiutil detach "$newDevice" -hdiutil convert -format UDZO Recovery.dmg.sparseimage -o Recovery.RO.dmg -rm Recovery.dmg.sparseimage -qemu-img convert -f dmg -O raw Recovery.RO.dmg Recovery.raw -rm Recovery.RO.dmg + +# Mount the sparse image +echo "Mounting disk image..." +DEVICE=$(hdiutil attach -nomount "$SPARSE_IMAGE" | head -n 1 | awk '{print $1}') +echo "New device: $DEVICE" + +# Partition the disk +echo "Partitioning disk..." +N=$(echo "$DEVICE" | tr -dc '0-9') +diskutil partitionDisk "$DEVICE" 1 MBR fat32 RECOVERY R +diskutil mount "disk${N}s1" + +# Find mount point +MOUNT_POINT="$(diskutil info "disk${N}s1" | sed -n 's/.*Mount Point: *//p')" +echo "Mounted at: $MOUNT_POINT" + +# Prepare Recovery folder +RECOVERY_FOLDER="$MOUNT_POINT/com.apple.recovery.boot" +mkdir -p "$RECOVERY_FOLDER" + +# Copy required files +echo "Copying .dmg and .chunklist files to recovery partition..." +cp *.dmg *.chunklist "$RECOVERY_FOLDER/" + +# Unmount and convert +echo "Unmounting and finalizing image..." +hdiutil detach "$DEVICE" +hdiutil convert -format UDZO "$SPARSE_IMAGE" -o "$OUTPUT_DMG" +rm -f "$SPARSE_IMAGE" + +# Convert to raw format +echo "Converting DMG to RAW format..." +qemu-img convert -f dmg -O raw "$OUTPUT_DMG" "$OUTPUT_RAW" +rm -f "$OUTPUT_DMG" + +echo "✅ Recovery disk created successfully!" +echo "Output file: $OUTPUT_RAW" From 99b66bddd02c7401cc10255de328fbbd95715799 Mon Sep 17 00:00:00 2001 From: "Oritorius(Denis Rykov)" Date: Thu, 10 Jul 2025 00:00:48 +0500 Subject: [PATCH 4/6] Update CHECK-IOMMU.sh feat(script): add IOMMU enablement check with kernel log analysis - Introduced check-iommu-enabled.sh to verify if IOMMU is enabled in the current system - Parses 'dmesg' output for common Intel (VT-d), AMD (SVM), and DMAR/IOMMU entries - Displays diagnostic result with a helpful recommendation if IOMMU is not active - Includes root privilege warning and user-friendly output with ANSI color codes - Useful for verifying virtualization passthrough readiness (e.g., PCIe, GPU) --- tools/CHECK-IOMMU.sh | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/tools/CHECK-IOMMU.sh b/tools/CHECK-IOMMU.sh index 453f2b7..a2bc5e5 100755 --- a/tools/CHECK-IOMMU.sh +++ b/tools/CHECK-IOMMU.sh @@ -1,16 +1,43 @@ #!/bin/bash # # Script: check-iommu-enabled.sh -# Goal: Check if IOMMU are Enabled in your system +# Goal: Check if IOMMU is enabled in the system # # Author: Gabriel Luchina -# https://luchina.com.br +# https://luchina.com.br # 20220128T1112 +# Updated: 2025-04-06 +# -if [ `dmesg | grep -e DMAR -e IOMMU | wc -l` -gt 0 ] -then - echo "IOMMU Enabled" -else - echo "IOMMU NOT Enabled" - echo "Check file /etc/default/grub contains 'intel_iommu=on' in 'GRUB_CMDLINE_LINUX_DEFAULT' line" +# ANSI Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +NC='\033[0m' # No Color + +# Check for root +if [ "$EUID" -ne 0 ]; then + echo -e "${YELLOW}Предупреждение: Рекомендуется запускать от root для полного доступа.${NC}" +fi + +echo "Checking if IOMMU is enabled..." + +# Check dmesg output for IOMMU-related messages +iommu_check=$(dmesg | grep -i -E 'iommu|DMAR|amd-vi') + +if [[ -n "$iommu_check" ]]; then + echo -e "${GREEN}✅ IOMMU активирован в ядре!${NC}" + echo + echo "Найденные записи:" + echo "$iommu_check" +else + echo -e "${RED}❌ IOMMU не обнаружен или выключен.${NC}" + echo + echo -e "${YELLOW}Возможные причины:${NC}" + echo "1. В BIOS/UEFI отключена поддержка IOMMU (SVM Mode для AMD / VT-d для Intel)" + echo "2. Не добавлен параметр загрузки ядра:" + echo " Для Intel: intel_iommu=on" + echo " Для AMD: amd_iommu=on" + echo " Добавьте их в GRUB_CMDLINE_LINUX_DEFAULT в /etc/default/grub" + echo " Затем выполните: update-grub" fi From 54bae608cfc94a7096d66ee27d78ca712f87a1c9 Mon Sep 17 00:00:00 2001 From: "Oritorius(Denis Rykov)" Date: Thu, 10 Jul 2025 00:02:43 +0500 Subject: [PATCH 5/6] Update CREATE-ISO-macOS.command feat(script): add create-iso-macOS.sh to generate macOS installer ISO for Proxmox VE - Added an interactive Bash script to generate a macOS install ISO from an .app installer - Designed for use in Proxmox VE virtual machines - Performs validation for root privileges, target directory, and installer path - Automates DMG creation, mounting, installation media injection, and ISO conversion - Includes colored output for improved UX during interactive execution - Final output is a .iso file ready to be attached as a CD-ROM in Proxmox (IDE or VirtIO) --- tools/CREATE-ISO-macOS.command | 91 ++++++++++++++++++++++++++-------- 1 file changed, 69 insertions(+), 22 deletions(-) diff --git a/tools/CREATE-ISO-macOS.command b/tools/CREATE-ISO-macOS.command index 49279b3..643a163 100755 --- a/tools/CREATE-ISO-macOS.command +++ b/tools/CREATE-ISO-macOS.command @@ -1,34 +1,81 @@ #!/bin/bash + # -# Script: create-iso-macOS -# Goal: create "ISO" file for use in the Proxmox VE Environment +# Script: create-iso-macOS.sh +# Goal: Create macOS ISO-like image for use in Proxmox VE # # Author: Gabriel Luchina -# https://luchina.com.br -# 20211116T2245 +# https://luchina.com.br +# Updated: 2025-04-06 +# + +# ANSI Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +NC='\033[0m' # No Color clear -echo -e "\nAutomate script for create \"ISO\" file of macOS Install in Proxmox VE Environament" -echo -e "BY: https://luchina.com.br" -echo -e "SUPPORT: https://osx-proxmox.com" +echo -e "${GREEN}Automate script for creating macOS Install ISO for Proxmox VE${NC}" +echo -e "BY: ${YELLOW}https://luchina.com.br ${NC}" +echo -e "SUPPORT: ${YELLOW}https://osx-proxmox.com ${NC}" -echo -n -e "\nPath to temporary files (work dir): " -read TEMPDIR +# Check for root +if [ "$EUID" -ne 0 ]; then + echo -e "${YELLOW}[!] Рекомендуется запускать от root для корректной работы.${NC}" + echo -e "Продолжить как обычный пользователь? (y/n)" + read -r answer + if [[ ! "$answer" =~ ^[Yy]$ ]]; then + echo "Выход." + exit 1 + fi +fi -echo -n -e "Path to macOS Installation (.app) file: " -read APPOSX +# Ask for temp directory +read -p $'\n'"Введите путь к рабочей директории (work dir): " TEMPDIR +if [ ! -d "$TEMPDIR" ]; then + echo -e "${RED}[!] Указанная директория не существует.${NC}" + exit 1 +fi -echo " " +# Ask for macOS app path +read -p "Введите путь к macOS Installer (.app): " APPOSX +if [ ! -d "$APPOSX" ]; then + echo -e "${RED}[!] Указанный .app файл не найден.${NC}" + exit 1 +fi -## Core -cd ${TEMPDIR} > /dev/null 2> /dev/null -rm -rf macOS-install* > /dev/null 2> /dev/null -hdiutil create -o macOS-install -size 16g -layout GPTSPUD -fs HFS+J > /dev/null 2> /dev/null -hdiutil attach -noverify -mountpoint /Volumes/install_build macOS-install.dmg > /dev/null 2> /dev/null -sudo "${APPOSX}/Contents/Resources/createinstallmedia" --volume /Volumes/install_build --nointeraction -hdiutil detach -force "/Volumes/Install macOS"* > /dev/null 2> /dev/null && sleep 3s > /dev/null 2> /dev/null -hdiutil detach -force "/Volumes/Shared Support"* > /dev/null 2> /dev/null -mv macOS-install.dmg macOS-install.iso > /dev/null 2> /dev/null +cd "$TEMPDIR" || { echo -e "${RED}[!] Не могу перейти в указанную директорию.${NC}"; exit 1; } -echo " " +# Clean up previous files +echo -e "\n${YELLOW}[*] Очистка старых файлов...${NC}" +rm -rf macOS-install.dmg* > /dev/null 2>&1 + +# Create DMG +echo -e "${YELLOW}[*] Создание временного дискового образа...${NC}" +hdiutil create -o macOS-install.dmg -size 16g -layout GPTSPUD -fs HFS+J > /dev/null 2>&1 + +# Mount DMG +echo -e "${YELLOW}[*] Подключение образа...${NC}" +hdiutil verify macOS-install.dmg > /dev/null 2>&1 +hdiutil mount macOS-install.dmg > /dev/null 2>&1 +MOUNT_POINT="/Volumes/install_build" + +# Run createinstallmedia +echo -e "${YELLOW}[*] Заливка macOS установщика в образ... Это может занять несколько минут.${NC}" +sudo "$APPOSX/Contents/Resources/createinstallmedia" --volume "$MOUNT_POINT" --nointeraction + +# Unmount volumes +echo -e "${YELLOW}[*] Отключение томов...${NC}" +diskutil list | grep "Install macOS" | awk '{print $1}' | xargs -I {} hdiutil detach {} > /dev/null 2>&1 +sleep 3 + +# Convert to ISO-style file +echo -e "${YELLOW}[*] Конвертация в формат ISO...${NC}" +mv macOS-install.dmg macOS-install.iso + +# Final message +echo -e "\n${GREEN}[✓] Готово! Образ создан:${NC}" +echo "Файл: macOS-install.iso" +echo "Теперь вы можете загрузить его в Proxmox как CD-ROM (VirtIO или IDE)." From f656a94fabe70fb9a7360da4d48f27b031902fd5 Mon Sep 17 00:00:00 2001 From: "Oritorius(Denis Rykov)" Date: Thu, 10 Jul 2025 00:05:31 +0500 Subject: [PATCH 6/6] Update build-image.sh feat(script): add create-recovery-disk.sh to build macOS recovery image for QEMU/Proxmox - Added script to automate creation of a macOS recovery disk image compatible with QEMU - Generates a sparse disk, partitions it, and prepares a minimal recovery volume - Copies BaseSystem.dmg and optional .chunklist into the recovery partition - Converts resulting DMG to a raw image for direct use in Proxmox VE VMs - Includes cleanup routines and device mount management via diskutil/hdiutil - Requires: macOS with hdiutil, diskutil, and qemu-img installed --- tools/macrecovery/build-image.sh | 72 ++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 23 deletions(-) diff --git a/tools/macrecovery/build-image.sh b/tools/macrecovery/build-image.sh index 100b41b..a4c3862 100755 --- a/tools/macrecovery/build-image.sh +++ b/tools/macrecovery/build-image.sh @@ -3,11 +3,17 @@ # Script: create-recovery-disk.sh # Author: Gabriel Luchina # https://luchina.com.br -# Description: Creates a Recovery DMG and converts it to raw for QEMU use +# Description: Creates a macOS Recovery DMG and converts it to raw for QEMU use + +# ANSI Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +NC='\033[0m' # Clean up on exit cleanup() { - echo "Cleaning up temporary files..." + echo -e "${YELLOW}[*] Cleaning up temporary files...${NC}" hdiutil verify "$SPARSE_IMAGE" &>/dev/null || true hdiutil detach "$DEVICE" &>/dev/null || true rm -f "$SPARSE_IMAGE" "$OUTPUT_DMG" &>/dev/null || true @@ -20,57 +26,77 @@ OUTPUT_DMG="Recovery.RO.dmg" OUTPUT_RAW="Recovery.RO.raw" # Check prerequisites +echo -e "${YELLOW}[*] Checking prerequisites...${NC}" if ! command -v hdiutil &>/dev/null; then - echo "Error: hdiutil not found. Install macOS command-line tools." >&2 + echo -e "${RED}[!] hdiutil not found. Install macOS command-line tools.${NC}" exit 1 fi if ! command -v qemu-img &>/dev/null; then - echo "Error: qemu-img not found. Please install qemu-utils." >&2 + echo -e "${RED}[!] qemu-img not found. Please install qemu-utils.${NC}" exit 1 fi # Clean previous builds -echo "Removing old recovery disk files..." -rm -f "$SPARSE_IMAGE" "$OUTPUT_DMG" "$OUTPUT_RAW" +echo -e "${YELLOW}[*] Removing old recovery disk files...${NC}" +rm -f "$SPARSE_IMAGE" "$OUTPUT_DMG" "$OUTPUT_RAW" > /dev/null 2>&1 || true # Create sparse image -echo "Creating sparse disk image..." -hdiutil create -size 800m -layout "UNIVERSAL HD" -type SPARSE -o Recovery.dmg +echo -e "${YELLOW}[*] Creating sparse disk image...${NC}" +hdiutil create -size 800m -layout "UNIVERSAL HD" -type SPARSE -o Recovery.dmg > /dev/null # Mount the sparse image -echo "Mounting disk image..." +echo -e "${YELLOW}[*] Mounting disk image...${NC}" DEVICE=$(hdiutil attach -nomount "$SPARSE_IMAGE" | head -n 1 | awk '{print $1}') -echo "New device: $DEVICE" +echo -e "${YELLOW}[*] New device: ${GREEN}${DEVICE}${NC}" # Partition the disk -echo "Partitioning disk..." +echo -e "${YELLOW}[*] Partitioning disk...${NC}" N=$(echo "$DEVICE" | tr -dc '0-9') -diskutil partitionDisk "$DEVICE" 1 MBR fat32 RECOVERY R -diskutil mount "disk${N}s1" +diskutil partitionDisk "$DEVICE" 1 MBR fat32 RECOVERY R > /dev/null +diskutil mount "disk${N}s1" > /dev/null # Find mount point MOUNT_POINT="$(diskutil info "disk${N}s1" | sed -n 's/.*Mount Point: *//p')" -echo "Mounted at: $MOUNT_POINT" +echo -e "${YELLOW}[*] Mounted at: ${GREEN}${MOUNT_POINT}${NC}" # Prepare Recovery folder RECOVERY_FOLDER="$MOUNT_POINT/com.apple.recovery.boot" mkdir -p "$RECOVERY_FOLDER" +# Find BaseSystem.dmg and .chunklist +echo -e "${YELLOW}[*] Searching for macOS recovery files...${NC}" +DMG_FILE=$(find . -maxdepth 1 -name "*.dmg" -not -name "*Recovery*" | head -n 1) +CHUNKLIST_FILE=$(find . -maxdepth 1 -name "*.chunklist" | head -n 1) + +if [[ -z "$DMG_FILE" ]]; then + echo -e "${RED}[!] BaseSystem.dmg or equivalent not found in current directory.${NC}" + exit 1 +fi + +if [[ -z "$CHUNKLIST_FILE" ]]; then + echo -e "${YELLOW}[!] .chunklist file not found, continuing without it...${NC}" +fi + # Copy required files -echo "Copying .dmg and .chunklist files to recovery partition..." -cp *.dmg *.chunklist "$RECOVERY_FOLDER/" +echo -e "${YELLOW}[*] Copying files to recovery partition...${NC}" +cp "$DMG_FILE" "$RECOVERY_FOLDER/" + +if [[ -n "$CHUNKLIST_FILE" ]]; then + cp "$CHUNKLIST_FILE" "$RECOVERY_FOLDER/" +fi # Unmount and convert -echo "Unmounting and finalizing image..." -hdiutil detach "$DEVICE" -hdiutil convert -format UDZO "$SPARSE_IMAGE" -o "$OUTPUT_DMG" +echo -e "${YELLOW}[*] Unmounting and finalizing image...${NC}" +hdiutil detach "$DEVICE" > /dev/null +hdiutil convert -format UDZO "$SPARSE_IMAGE" -o "$OUTPUT_DMG" > /dev/null rm -f "$SPARSE_IMAGE" # Convert to raw format -echo "Converting DMG to RAW format..." -qemu-img convert -f dmg -O raw "$OUTPUT_DMG" "$OUTPUT_RAW" +echo -e "${YELLOW}[*] Converting DMG to RAW format...${NC}" +qemu-img convert -f dmg -O raw "$OUTPUT_DMG" "$OUTPUT_RAW" > /dev/null rm -f "$OUTPUT_DMG" -echo "✅ Recovery disk created successfully!" -echo "Output file: $OUTPUT_RAW" +# Done! +echo -e "\n${GREEN}✅ Recovery disk created successfully!${NC}" +echo -e "Output file: ${GREEN}${OUTPUT_RAW}${NC}"