## SystemRescue ISO Customization Guide for Debian/Ubuntu

This guide provides exact steps and folder paths for customizing a SystemRescue ISO on a Debian/Ubuntu host system.

## Prerequisites

```bash
sudo apt update
sudo apt install squashfs-tools xorriso isolinux syslinux-utils wget git
```

**Package breakdown:**

- `squashfs-tools` - Required for `unsquashfs` and `mksquashfs` commands
- `xorriso` - Required for rebuilding the ISO with proper boot structure
- `isolinux` - Provides isolinux boot files
- `syslinux-utils` - Provides `isohybrid` and other syslinux utilities
- `wget` - For downloading the ISO
- `git` - Optional, for cloning repositories if needed

## Step 1: Download SystemRescue ISO

```bash
cd ~/
mkdir -p sysrescue-project
cd sysrescue-project
wget https://sourceforge.net/projects/systemrescuecd/files/sysresccd-x86/12.03/systemrescue-12.03-amd64.iso/download -O systemrescue-12.03-amd64.iso
```

## Step 2: Install sysrescue-customize

### Method A: Using OpenSUSE Build Service Repository (Recommended)

```bash
# Add repository key
wget -qO - https://download.opensuse.org/repositories/home:/g_m_v/xUbuntu_$(lsb_release -rs)/Release.key | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/sysrescue-customize.gpg

# Add repository
echo "deb http://download.opensuse.org/repositories/home:/g_m_v/xUbuntu_$(lsb_release -rs)/ /" | sudo tee /etc/apt/sources.list.d/sysrescue-customize.list

# Update and install
sudo apt update
sudo apt install sysrescue-customize

# Verify installation
sysrescue-customize --version
```

### Method B: Using pipx (Alternative)

```bash
sudo apt install pipx
pipx ensurepath
pipx install sysrescue-customize
sysrescue-customize --version
```

## Step 3: Prepare Project Folder Structure

```bash
cd ~/sysrescue-project
mkdir -p extracted
mkdir -p customization
mkdir -p packages
mkdir -p output
```

## Step 4: Unpack the SystemRescue ISO

### Method A: Using sysrescue-customize (Recommended)

```bash
cd ~/sysrescue-project
sysrescue-customize --unpack --source=systemrescue-12.03-amd64.iso --dest=extracted
```

**Benefits:**

- Cleaner extraction process
- Proper permissions set automatically
- Tool-specific unpacking (may handle special ISO structures better)
- No need for sudo mount/umount

### Method B: Manual mount and copy (Alternative)

```bash
cd ~/sysrescue-project
sudo mount -o loop systemrescue-*.iso /mnt
sudo cp -a /mnt/* extracted/
sudo umount /mnt
sudo chmod -R u+w extracted/
```

## Step 5: Modify YAML Configuration

```bash
cd ~/sysrescue-project/extracted/sysrescue.d
# Edit the YAML file for startup configuration
sudo nano 100-defaults.yaml
```

### Enable Direct GUI Mode Boot and US Keymap

**Important:** The exact YAML syntax may vary between SystemRescue versions. Always check the existing `100-defaults.yaml` file in your extracted ISO to see the correct format and available options.

**Modified 100-defaults.yaml with GUI mode and US keymap:**

```yaml
---
global:
  # Boot directly to graphical mode (X11/GUI)
  dostartx: true
  
  # Set keyboard layout to US
  setkmap: us
  
  # Optional: Set hostname
  hostname: rescue-system
  
autorun:
  - script: /usr/local/bin/custom-startup.sh
```
### Verify Correct YAML Format

```bash
# Check the original 100-defaults.yaml format first
cat ~/sysrescue-project/extracted/sysrescue.d/100-defaults.yaml
```

Use a YAML linter like [YAMLIint](https://www.yamllint.com/) to validate syntax.

**Note:** Different SystemRescue versions may use different YAML keys:

- Older versions might use: `graphical: true` and `keymap: us`
- Newer versions use: `dostartx: true` and `setkmap: us`

**Always verify the syntax by examining your specific ISO version's files.**

### Common Keymap Values

- `us` - US English
- `uk` - UK English
- `de` - German
- `fr` - French
- `es` - Spanish
- `it` - Italian
- `jp` - Japanese

**Key Changes Summary:**

1. **`dostartx: true`** - Boots directly into GUI/graphical mode instead of text console
2. **`setkmap: us`** - Sets keyboard layout to US English automatically

## Step 6: Setup Autorun

The autorun is configured via a script in the /autorun folder. Scripts placed in `/usr/local/bin` inside the squashfs can be executed as well, at will.

**To verify autorun script locations in your ISO:**

```bash
# Check for existing autorun scripts
find ~/sysrescue-project/extracted -name "autorun*" -type f
```

## Step 7: Navigate to Architecture Folder

```bash
cd ~/sysrescue-project/extracted/sysrescue.d/x86_64
ls -lh
# You should see airootfs.sfs (the squashfs filesystem)
```

## Step 8: Unsquash the Filesystem

```bash
cd ~/sysrescue-project/extracted/sysrescue.d/x86_64
sudo unsquashfs airootfs.sfs
# This creates a folder called "squashfs-root"
```

## Step 9: Add Custom Scripts and System Configuration

```bash
cd ~/sysrescue-project/extracted/sysrescue.d/x86_64/squashfs-root

# Create your custom script
sudo mkdir -p usr/local/bin
sudo nano usr/local/bin/custom-startup.sh
```

### Reference Custom Scripts from Existing Custom ISO

**If you have an existing custom ISO with scripts you want to reference:**

```bash
# First, unsquash your custom ISO to examine its scripts
cd ~/sysrescue-project
mkdir -p reference-iso
cd reference-iso

# Mount or unpack your custom ISO
sudo mount -o loop /path/to/your-custom.iso /mnt
sudo cp -a /mnt/* .
sudo umount /mnt

# Unsquash to view the custom scripts
cd sysrescue.d/x86_64
sudo unsquashfs airootfs.sfs

# Now you can view and copy custom scripts
cat squashfs-root/usr/local/bin/custom-startup.sh

# Check the sideload directory
ls -lh squashfs-root/sideload/

# Copy or reference the script structure as needed
```

**The sideload directory is not official. In our ISO it's used for offline Zenity.**
### Example Custom Startup Script (Offline Installation with Fallback)

**custom-startup.sh for network install with offline fallback:**

```bash
#!/bin/bash
# Custom SystemRescue startup script

echo "Starting custom SystemRescue configuration..."

# Try to install zenity from network, fallback to sideload if it fails
# SystemRescue handles network detection before autorun, so we don't need to check
echo "Installing zenity..."
pacman -Sy --noconfirm zenity || pacman -U --noconfirm /sideload/zenity-4.0.0-2-x86_64.pkg.tar.zst

# Launch zenity if installed
if command -v zenity &> /dev/null; then
    zenity --info --text="Welcome to Custom SystemRescue - Ready!" --title="System Ready" &
else
    echo "Warning: zenity not installed"
fi

echo "Custom startup complete."
```

**Note:** Replace `zenity-4.0.0-2-x86_64.pkg.tar.zst` with the actual version you download (e.g., `zenity-4.2.1-1-x86_64.pkg.tar.zst in our ISO v1.0`).

```bash
# Make script executable
sudo chmod +x usr/local/bin/custom-startup.sh
```

**Key Points:**

- SystemRescue checks network connectivity during boot before running autorun scripts
- No need to manually check for network in the script
- The `||` operator automatically falls back to local install if network install fails
- This provides a clean, simple fallback mechanism

**To verify existing autorun script examples:**

```bash
# Check for existing startup scripts in the squashfs
find ~/sysrescue-project/extracted/sysrescue.d/x86_64/squashfs-root/usr/local/bin -type f
```

### Required System Configuration Edits

#### Edit DNS Configuration (resolv.conf)

```bash
cd ~/sysrescue-project/extracted/sysrescue.d/x86_64/squashfs-root

# Add Google DNS nameservers
sudo bash -c 'cat > etc/resolv.conf << EOF
nameserver 8.8.8.8
nameserver 8.8.4.4
EOF'

# Verify
cat etc/resolv.conf
```

**This is to enable domain name resolution.**
#### Edit Pacman Configuration (pacman.conf)

```bash
cd ~/sysrescue-project/extracted/sysrescue.d/x86_64/squashfs-root

# Set SigLevel to Never for package installation
sudo sed -i 's/^SigLevel.*$/SigLevel = Never/' etc/pacman.conf

# Verify
grep "^SigLevel" etc/pacman.conf
```

**This is required to run Pacman -Sy during boot.**
### Complete Configuration Script (All-in-One)

```bash
cd ~/sysrescue-project/extracted/sysrescue.d/x86_64/squashfs-root

# Run all configuration changes
sudo bash << 'SETUP_SCRIPT'

# Add DNS nameservers
cat > etc/resolv.conf << EOF
nameserver 8.8.8.8
nameserver 8.8.4.4
EOF

# Set Pacman SigLevel to Never
sed -i 's/^SigLevel.*$/SigLevel = Never/' etc/pacman.conf

# Create custom startup script with offline fallback
mkdir -p usr/local/bin
cat > usr/local/bin/custom-startup.sh << 'EOF'
#!/bin/bash
echo "Starting custom SystemRescue configuration..."

# Install zenity - network first, fallback to sideload
echo "Installing zenity..."
pacman -Sy --noconfirm zenity || pacman -U --noconfirm /sideload/zenity-4.2.1-1-x86_64.pkg.tar.zst

if command -v zenity &> /dev/null; then
    zenity --info --text="Welcome to Custom SystemRescue - Ready!" --title="System Ready" &
fi
echo "Custom startup complete."
EOF

chmod +x usr/local/bin/custom-startup.sh

# Verify changes
echo "=== DNS Configuration ==="
cat etc/resolv.conf
echo ""
echo "=== Pacman SigLevel ==="
grep "^SigLevel" etc/pacman.conf
echo ""
echo "=== Startup Script ==="
ls -lh usr/local/bin/custom-startup.sh

SETUP_SCRIPT
```

## Step 10: Add Offline Packages to Sideload Directory

For offline use with no network connectivity, download Arch packages and place them in a `/sideload` directory within the squashfs. The autorun script will install from this location if the network install fails.

**Note:** SystemRescue is Arch-based, so you must use Arch Linux packages. Many common tools like gparted and testdisk are already included in SystemRescue.

### Download Arch Package (with full version)

```bash
cd ~/sysrescue-project/packages

# Download zenity package (use the full package name with version)
wget https://archlinux.org/packages/extra/x86_64/zenity/download/ -O zenity-4.2.1-1-x86_64.pkg.tar.zst

# Verify download
ls -lh zenity-4.2.1-1-x86_64.pkg.tar.zst
```

**Important:** Check https://archlinux.org/packages/extra/x86_64/zenity/ for the current version number and update the filename accordingly.

### Create Sideload Directory in Squashfs

```bash
cd ~/sysrescue-project/extracted/sysrescue.d/x86_64/squashfs-root

# Create sideload directory
sudo mkdir -p sideload

# Copy the package to sideload (use full package name)
sudo cp ~/sysrescue-project/packages/zenity-4.2.1-1-x86_64.pkg.tar.zst sideload/

# Verify
ls -lh sideload/
```

### How the Autorun Script Uses Sideload

The autorun script from Step 9 will:

1. First attempt to install zenity via network: `pacman -Sy --noconfirm zenity`
2. If that fails (no network or package unavailable), automatically fall back to local package: `pacman -U --noconfirm /sideload/zenity-4.2.1-1-x86_64.pkg.tar.zst`

**The `||` operator handles this automatically - no network checking needed!**

**Example autorun script logic:**

```bash
#!/bin/bash

# Try network install, automatically fallback to sideload if it fails
pacman -Sy --noconfirm zenity || pacman -U --noconfirm /sideload/zenity-4.2.1-1-x86_64.pkg.tar.zst
```

### Adding Additional Packages to Sideload

If you need packages that are **NOT** already in SystemRescue:

```bash
cd ~/sysrescue-project/packages

# Example: Download additional packages with full version names
wget https://archlinux.org/packages/extra/x86_64/PACKAGE/download/ -O PACKAGE-VERSION-ARCH.pkg.tar.zst

# Copy to sideload
sudo cp PACKAGE-VERSION-ARCH.pkg.tar.zst ~/sysrescue-project/extracted/sysrescue.d/x86_64/squashfs-root/sideload/
```

**Update autorun script to install multiple packages:**

```bash
#!/bin/bash

# Install zenity with fallback
pacman -Sy --noconfirm zenity || pacman -U --noconfirm /sideload/zenity-4.2.1-1-x86_64.pkg.tar.zst

# Install other packages (if needed and not already in SystemRescue)
# pacman -Sy --noconfirm package2 || pacman -U --noconfirm /sideload/package2-1.0.0-1-x86_64.pkg.tar.zst
```

### Packages Already Included in SystemRescue

**Do NOT add these to sideload - they're already in SystemRescue:**

- gparted (disk partition editor)
- testdisk (data recovery)
- ddrescue (disk imaging)
- rsync (file sync)
- fsarchiver (filesystem backup)
- clonezilla (disk cloning)
- gsmartcontrol (smartmontools)
- hdparm (drive info)
- nvme-cli (nvme functions, nvme format)

### Finding Arch Packages

To find and download packages:

1. Visit https://archlinux.org/packages/
2. Search for the package name
3. Click on the package to see version and details
4. Note the full package name with version
5. Download using: `https://archlinux.org/packages/REPO/x86_64/PACKAGE/download/`
    - **REPO** can be: `core`, `extra`, or `community`

**Example repositories:**

- Core packages: `https://archlinux.org/packages/core/x86_64/PACKAGE/download/`
- Extra packages: `https://archlinux.org/packages/extra/x86_64/PACKAGE/download/`
- Community: `https://archlinux.org/packages/community/x86_64/PACKAGE/download/`

**Package naming format:**

```
PACKAGENAME-VERSION-RELEASE-ARCH.pkg.tar.zst

Example:
zenity-4.2.1-1-x86_64.pkg.tar.zst
  └─┬──┘ └┬┘ └┘ └──┬──┘
    │     │  │     └── Architecture (x86_64)
    │     │  └──────── Release number (1)
    │     └─────────── Version (4.2.1)
    └───────────────── Package name (zenity)
```

### Verify Sideload Setup

```bash
# Check sideload directory contents
ls -lh ~/sysrescue-project/extracted/sysrescue.d/x86_64/squashfs-root/sideload/

# Verify autorun script references sideload with correct filename
cat ~/sysrescue-project/extracted/sysrescue.d/x86_64/squashfs-root/usr/local/bin/custom-startup.sh | grep sideload
```

## Step 11: Repack the Squashfs

```bash
cd ~/sysrescue-project/extracted/sysrescue.d/x86_64

# DELETE the original squashfs file first
sudo rm airootfs.sfs

# Repack with compression
sudo mksquashfs squashfs-root airootfs.sfs -comp xz -b 1M

# This will take several minutes depending on size
```

## Step 12: Clean Up Extracted Folder

```bash
cd ~/sysrescue-project/extracted/sysrescue.d/x86_64
sudo rm -rf squashfs-root
```

## Step 13: Rebuild the ISO

```bash
cd ~/sysrescue-project

# Option A: Using sysrescue-customize (recommended)
sysrescue-customize --rebuild --source=extracted --dest=output/custom-sysrescue.iso

# Option B: Manual rebuild with xorriso
cd extracted
sudo xorriso -as mkisofs \
    -iso-level 3 \
    -full-iso9660-filenames \
    -volid "SYSRESCUE" \
    -eltorito-boot sysrescue.d/boot/x86_64/isolinux/isolinux.bin \
    -eltorito-catalog sysrescue.d/boot/x86_64/isolinux/boot.cat \
    -no-emul-boot -boot-load-size 4 -boot-info-table \
    -isohybrid-mbr /usr/lib/ISOLINUX/isohdpfx.bin \
    -eltorito-alt-boot \
    -e sysrescue.d/boot/x86_64/efi.img \
    -no-emul-boot -isohybrid-gpt-basdat \
    -output ../output/custom-sysrescue.iso \
    .
```

## Step 14: Burn to USB (Optional)

### Method A: Using GNOME Disks (GUI)

1. Open "Disks" application
2. Select your USB drive
3. Click the menu (⋮) → "Restore Disk Image"
4. Select `~/sysrescue-project/output/custom-sysrescue.iso`
5. Click "Start Restoring"

### Method B: Using dd (CLI)

```bash
# Find your USB device
lsblk

# Write ISO to USB (replace /dev/sdX with your USB device)
sudo dd if=~/sysrescue-project/output/custom-sysrescue.iso of=/dev/sdX bs=4M status=progress && sync
```

### Method C: Using Etcher

```bash
# Download and install Etcher
wget https://github.com/balena-io/etcher/releases/download/v1.18.11/balena-etcher_1.18.11_amd64.deb
sudo dpkg -i balena-etcher_*.deb
# Launch Etcher GUI and select the ISO
```

---

## Complete Folder Structure

```
~/sysrescue-project/
├── systemrescue-12.03-amd64.iso (downloaded)
├── extracted/
│   ├── sysrescue.d/
│   │   ├── 100-defaults.yaml (modified)
│   │   └── x86_64/
│   │       └── airootfs.sfs (repacked)
│   └── [other ISO contents]
├── customization/
├── packages/
│   └── zenity-4.2.1-1-x86_64.pkg.tar.zst (downloaded for sideload)
├── reference-iso/ (optional - for examining existing custom ISO)
└── output/
    └── custom-sysrescue.iso (final result)
```

## Quick Reference Commands - Complete Workflow

```bash
# Setup
cd ~/
mkdir -p sysrescue-project/packages
cd sysrescue-project

# Download ISO
wget https://sourceforge.net/projects/systemrescuecd/files/sysresccd-x86/12.03/systemrescue-12.03-amd64.iso/download -O systemrescue-12.03-amd64.iso

# Unpack ISO
sysrescue-customize --unpack --source=systemrescue-12.03-amd64.iso --dest=extracted

# Download Arch package for sideload (with full version name)
cd packages
wget https://archlinux.org/packages/extra/x86_64/zenity/download/ -O zenity-4.2.1-1-x86_64.pkg.tar.zst
cd ..

# Extract squashfs
cd extracted/sysrescue.d/x86_64
sudo unsquashfs airootfs.sfs
cd squashfs-root

# Create sideload directory and copy package
sudo mkdir -p sideload
sudo cp ~/sysrescue-project/packages/zenity-4.2.1-1-x86_64.pkg.tar.zst sideload/

# Configure system
sudo bash -c 'cat > etc/resolv.conf << EOF
nameserver 8.8.8.8
nameserver 8.8.4.4
EOF'

sudo sed -i 's/^SigLevel.*$/SigLevel = Never/' etc/pacman.conf

# Create startup script with automatic fallback
sudo mkdir -p usr/local/bin
sudo bash -c 'cat > usr/local/bin/custom-startup.sh << "EOF"
#!/bin/bash
echo "Starting custom SystemRescue configuration..."

# Install zenity - network first, automatic fallback to sideload
echo "Installing zenity..."
pacman -Sy --noconfirm zenity || pacman -U --noconfirm /sideload/zenity-4.2.1-1-x86_64.pkg.tar.zst

if command -v zenity &> /dev/null; then
    zenity --info --text="Welcome to Custom SystemRescue - Ready!" --title="System Ready" &
fi
echo "Custom startup complete."
EOF'

sudo chmod +x usr/local/bin/custom-startup.sh

# Modify YAML for GUI mode and US keymap
cd ~/sysrescue-project/extracted/sysrescue.d
sudo bash -c 'cat > 100-defaults.yaml << EOF
---
global:
  dostartx: true
  setkmap: us
  hostname: rescue-system
  
autorun:
  - script: /usr/local/bin/custom-startup.sh
EOF'

# Repack squashfs
cd ~/sysrescue-project/extracted/sysrescue.d/x86_64
sudo rm airootfs.sfs
sudo mksquashfs squashfs-root airootfs.sfs -comp xz -b 1M
sudo rm -rf squashfs-root

# Rebuild ISO
cd ~/sysrescue-project
sysrescue-customize --rebuild --source=extracted --dest=output/custom-sysrescue.iso

# Verify
ls -lh output/custom-sysrescue.iso
```

## Testing Your Custom ISO

### Test in QEMU/KVM (Recommended before USB)

```bash
# Install QEMU if not already installed
sudo apt install qemu-system-x86

# Test the ISO
qemu-system-x86_64 -m 2048 -cdrom output/custom-sysrescue.iso -boot d
```

### Test in VirtualBox

1. Create new VM
2. Mount `output/custom-sysrescue.iso` as optical drive
3. Boot and verify:
    - Boots to GUI automatically (dostartx: true)
    - US keyboard layout active (setkmap: us)
    - Zenity installed (either from network or sideload)
    - Zenity dialog appears
    - Network resolution works (8.8.8.8)

### Test Offline Mode

To test the sideload fallback:

1. Boot the ISO in a VM **without network**
2. Verify that zenity installs from `/sideload/zenity-4.2.1-1-x86_64.pkg.tar.zst`
3. Check the console output for the automatic fallback behavior

---

## Important Notes and Verification

### Referencing Existing Custom Scripts

**If you have an existing custom SystemRescue ISO and want to examine its configuration:**

```bash
# Create a reference directory
mkdir -p ~/sysrescue-project/reference-iso
cd ~/sysrescue-project/reference-iso

# Mount your custom ISO
sudo mount -o loop /path/to/your-custom.iso /mnt
sudo cp -a /mnt/* .
sudo umount /mnt

# Unsquash to view scripts
cd sysrescue.d/x86_64
sudo unsquashfs airootfs.sfs

# Examine custom scripts
cat squashfs-root/usr/local/bin/custom-startup.sh

# Check sideload packages
ls -lh squashfs-root/sideload/

# View YAML configuration
cat ../100-defaults.yaml

# Copy any useful scripts or configurations to your new build
```

**reference-iso means maxxrescue or other custom ISO.**