#!/bin/bash # Build custom Fedora Kinoite ISO script # Version: 1.0 # Date: 2026-04-02 # # This script builds a custom Fedora Kinoite ISO for the SAW implementation # It requires a base Fedora Kinoite ISO and the custom kickstart file set -e # Configuration SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" BUILD_DIR="${SCRIPT_DIR}/build" OUTPUT_DIR="${SCRIPT_DIR}/output" KICKSTART_FILE="${SCRIPT_DIR}/kinoite-saw.ks" BASE_ISO="" ISO_NAME="Fedora-Kinoite-SAW.iso" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # Print functions print_info() { echo -e "${GREEN}[INFO]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } # Usage usage() { echo "Usage: $0 -i [-o ]" echo "" echo "Options:" echo " -i Path to base Fedora Kinoite ISO (required)" echo " -o Output ISO name (optional, default: $ISO_NAME)" echo " -h Show this help message" echo "" echo "Example:" echo " $0 -i Fedora-Kinoite-43-x86_64-latest.iso" exit 1 } # Parse arguments while getopts "i:o:h" opt; do case $opt in i) BASE_ISO="$OPTARG" ;; o) ISO_NAME="$OPTARG" ;; h) usage ;; \?) usage ;; esac done # Check requirements check_requirements() { print_info "Checking requirements..." # Check if lorax is installed if ! command -v lorax &> /dev/null; then print_error "lorax is not installed" echo "Install with: sudo dnf install -y lorax anaconda-tools" exit 1 fi # Check if base ISO is provided if [ -z "$BASE_ISO" ]; then print_error "Base ISO not specified" usage fi # Check if base ISO exists if [ ! -f "$BASE_ISO" ]; then print_error "Base ISO not found: $BASE_ISO" exit 1 fi # Check if kickstart file exists if [ ! -f "$KICKSTART_FILE" ]; then print_error "Kickstart file not found: $KICKSTART_FILE" exit 1 fi print_info "All requirements met" } # Create build directory create_build_dir() { print_info "Creating build directory..." mkdir -p "$BUILD_DIR" mkdir -p "$OUTPUT_DIR" } # Mount base ISO mount_iso() { print_info "Mounting base ISO..." # Create mount point MOUNT_POINT="${BUILD_DIR}/iso-mount" mkdir -p "$MOUNT_POINT" # Mount ISO sudo mount -o loop "$BASE_ISO" "$MOUNT_POINT" print_info "ISO mounted at: $MOUNT_POINT" } # Copy ISO contents copy_iso_contents() { print_info "Copying ISO contents..." # Create working directory WORK_DIR="${BUILD_DIR}/work" mkdir -p "$WORK_DIR" # Copy ISO contents cp -r "$MOUNT_POINT"/* "$WORK_DIR/" cp -r "$MOUNT_POINT"/.discinfo "$WORK_DIR/" print_info "ISO contents copied to: $WORK_DIR" } # Copy kickstart file copy_kickstart() { print_info "Copying kickstart file..." # Copy kickstart to ISO cp "$KICKSTART_FILE" "$WORK_DIR/kickstart.ks" print_info "Kickstart file copied" } # Update isolinux configuration update_isolinux() { print_info "Updating boot configuration..." ISOLINUX_DIR="${WORK_DIR}/isolinux" # Check if isolinux directory exists if [ ! -d "$ISOLINUX_DIR" ]; then print_warning "isolinux directory not found, using GRUB" return fi # Create custom isolinux configuration cat > "${ISOLINUX_DIR}/isolinux.cfg" << 'ISOLINUX' default menu timeout 600 menu clear menu background isolinux-bg.png menu title Fedora Kinoite SAW menu vshift 8 menu rows 18 menu margin 16 menu helpmsgrow 15 menu tabmsgrow 13 label install menu label Install Fedora Kinoite SAW menu default kernel vmlinuz append initrd=initrd.img inst.ks=hd:UUID=:kickstart.ks inst.stage2=hd:UUID=: inst.gpt quiet text help Install Fedora Kinoite SAW with automated configuration endtext label live menu label Try Fedora Kinoite SAW kernel vmlinuz append initrd=initrd.img inst.stage2=hd:UUID=: quiet label memtest menu label Memory Test kernel memtest append initrd=initrd.img inst.stage2=hd:UUID=: label local menu label Boot from local drive localboot 0x80 menu end ISOLINUX print_info "isolinux configuration updated" } # Update GRUB configuration update_grub() { print_info "Updating GRUB configuration..." GRUB_DIR="${WORK_DIR}/EFI/BOOT" # Check if GRUB directory exists if [ ! -d "$GRUB_DIR" ]; then print_warning "GRUB directory not found, skipping GRUB update" return fi # Create custom GRUB configuration cat > "${GRUB_DIR}/grub.cfg" << 'GRUB' set timeout=10 set default=0 menuentry 'Install Fedora Kinoite SAW' { linux /isolinux/vmlinuz inst.ks=hd:UUID=:kickstart.ks inst.stage2=hd:UUID=: quiet initrd /isolinux/initrd.img } menuentry 'Try Fedora Kinoite SAW' { linux /isolinux/vmlinuz inst.stage2=hd:UUID=: quiet initrd /isolinux/initrd.img } menuentry 'Boot from local drive' { chainloader (hd0,1) } GRUB print_info "GRUB configuration updated" } # Update repository configuration update_repos() { print_info "Updating repository configuration..." REPOS_DIR="${WORK_DIR}/LiveOS" # Create custom repository configuration cat > "${WORK_DIR}/Packages/repodata/repomd.xml" << 'REPO' 1 file:///mnt/source REPO print_info "Repository configuration updated" } # Generate ISO generate_iso() { print_info "Generating ISO..." OUTPUT_ISO="${OUTPUT_DIR}/${ISO_NAME}" # Create ISO using xorriso sudo xorriso -as mkisofs \ -o "$OUTPUT_ISO" \ -J -R -T \ -volid "Fedora-Kinoite-SAW" \ -b isolinux/isolinux.bin \ -c isolinux/boot.cat \ -no-emul-boot \ -boot-load-size 4 \ -boot-info-table \ -eltorito-alt-boot \ -e EFI/gpt_plpmt.efi \ -no-emul-boot \ -hfs-plus-wrap-aps \ -V "Fedora-Kinoite-SAW" \ "$WORK_DIR/" print_info "ISO generated: $OUTPUT_ISO" } # Unmount ISO umount_iso() { print_info "Unmounting ISO..." sudo umount "$MOUNT_POINT" rmdir "$MOUNT_POINT" } # Cleanup cleanup() { print_info "Cleaning up..." rm -rf "$BUILD_DIR" } # Main execution main() { print_info "Starting Fedora Kinoite SAW ISO build..." print_info "Base ISO: $BASE_ISO" print_info "Output: $OUTPUT_DIR/$ISO_NAME" check_requirements create_build_dir mount_iso copy_iso_contents copy_kickstart update_isolinux update_grub update_repos generate_iso umount_iso cleanup print_info "Build completed successfully!" print_info "ISO location: $OUTPUT_DIR/$ISO_NAME" print_info "Size: $(du -h "$OUTPUT_ISO" | cut -f1)" } # Run main function main "$@"