# Simple Bootc Installer

## Overview

A minimal, web-based installer for bootc that follows the standard "curl | sh" pattern. This approach works with bootc's design rather than against it, providing a simple way to install bootc containers on bare metal.

## Concept

```bash
# Simple one-liner installation
curl -fsSL https://install.bootc.dev | sh

# Or with specific container
curl -fsSL https://install.bootc.dev | sh -s -- quay.io/centos-bootc/centos-bootc:stream9
```

## Architecture

### 1. Web-Based Installer Script
- **Single shell script** hosted on a website
- **Self-contained** - no external dependencies beyond curl
- **Interactive prompts** for configuration
- **Validation** of system requirements

### 2. Live CD Environment
- **Minimal live environment** (Debian-based)
- **Pre-installed tools**: podman, bootc, curl
- **Network connectivity** for container pulling
- **No complex installer** - just a shell script

### 3. Installation Flow
```
1. Boot live CD
2. Run: curl -fsSL https://install.bootc.dev | sh
3. Follow interactive prompts
4. Install completes automatically
5. Reboot into installed system
```

## Implementation Plan

### Phase 1: Core Installer Script (Week 1-2)

#### 1.1 Basic Script Structure
```bash
#!/bin/bash
# bootc-installer.sh

set -euo pipefail

# Configuration
CONTAINER_URL="${1:-quay.io/centos-bootc/centos-bootc:stream9}"
TARGET_DEVICE=""
USERNAME=""
SSH_KEY=""

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# Logging functions
log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# Main installer function
main() {
    log_info "Bootc Installer v1.0"
    log_info "Installing container: $CONTAINER_URL"
    
    check_requirements
    detect_target_device
    prompt_user_config
    install_bootc
    configure_system
    finalize_installation
}
```

#### 1.2 System Requirements Check
```bash
check_requirements() {
    log_info "Checking system requirements..."
    
    # Check if running as root
    if [[ $EUID -ne 0 ]]; then
        log_error "This script must be run as root"
        exit 1
    fi
    
    # Check for required tools
    local required_tools=("podman" "bootc" "curl" "parted" "mkfs.ext4")
    for tool in "${required_tools[@]}"; do
        if ! command -v "$tool" &> /dev/null; then
            log_error "Required tool '$tool' not found"
            exit 1
        fi
    done
    
    # Check for internet connectivity
    if ! curl -s --connect-timeout 5 https://quay.io > /dev/null; then
        log_error "No internet connectivity. Required for container pulling."
        exit 1
    fi
    
    log_info "System requirements satisfied"
}
```

#### 1.3 Device Detection and Selection
```bash
detect_target_device() {
    log_info "Detecting available storage devices..."
    
    # List available block devices
    local devices=($(lsblk -d -n -o NAME | grep -E '^[sv]d[a-z]$'))
    
    if [[ ${#devices[@]} -eq 0 ]]; then
        log_error "No suitable storage devices found"
        exit 1
    fi
    
    # Display available devices
    echo "Available storage devices:"
    for i in "${!devices[@]}"; do
        local device="/dev/${devices[$i]}"
        local size=$(lsblk -d -n -o SIZE "$device")
        local model=$(lsblk -d -n -o MODEL "$device" | head -1)
        echo "  $((i+1)). $device ($size) - $model"
    done
    
    # Prompt user for selection
    while true; do
        read -p "Select device number (1-${#devices[@]}): " choice
        if [[ "$choice" =~ ^[0-9]+$ ]] && [[ "$choice" -ge 1 ]] && [[ "$choice" -le "${#devices[@]}" ]]; then
            TARGET_DEVICE="/dev/${devices[$((choice-1))]}"
            break
        else
            log_warn "Invalid selection. Please try again."
        fi
    done
    
    log_info "Selected device: $TARGET_DEVICE"
}
```

#### 1.4 User Configuration Prompts
```bash
prompt_user_config() {
    log_info "Configuring user account..."
    
    # Get username
    while true; do
        read -p "Enter username for the system: " USERNAME
        if [[ -n "$USERNAME" ]] && [[ "$USERNAME" =~ ^[a-zA-Z0-9_-]+$ ]]; then
            break
        else
            log_warn "Invalid username. Use only letters, numbers, underscores, and hyphens."
        fi
    done
    
    # Get SSH key
    echo "Enter SSH public key for root access (optional):"
    echo "You can paste your public key here (it will be hidden):"
    read -s SSH_KEY
    echo
    
    log_info "User configuration complete"
}
```

### Phase 2: Bootc Installation (Week 2-3)

#### 2.1 Container Installation
```bash
install_bootc() {
    log_info "Installing bootc container..."
    
    # Pull the container image
    log_info "Pulling container image: $CONTAINER_URL"
    if ! podman pull "$CONTAINER_URL"; then
        log_error "Failed to pull container image"
        exit 1
    fi
    
    # Install bootc to disk
    log_info "Installing to device: $TARGET_DEVICE"
    if ! podman run \
        --rm \
        --privileged \
        --pid=host \
        -v /dev:/dev \
        -v /var/lib/containers:/var/lib/containers \
        --security-opt label=type:unconfined_t \
        "$CONTAINER_URL" \
        bootc install to-disk "$TARGET_DEVICE"; then
        log_error "Bootc installation failed"
        exit 1
    fi
    
    log_info "Bootc installation completed successfully"
}
```

#### 2.2 Post-Install Configuration
```bash
configure_system() {
    log_info "Configuring installed system..."
    
    # Mount the installed system
    local mount_point="/mnt/bootc-install"
    mkdir -p "$mount_point"
    
    # Find the root partition
    local root_partition=$(find_root_partition)
    if [[ -z "$root_partition" ]]; then
        log_error "Could not find root partition"
        exit 1
    fi
    
    # Mount root partition
    if ! mount "$root_partition" "$mount_point"; then
        log_error "Failed to mount root partition"
        exit 1
    fi
    
    # Configure user account
    configure_user_account "$mount_point"
    
    # Configure SSH access
    if [[ -n "$SSH_KEY" ]]; then
        configure_ssh_access "$mount_point"
    fi
    
    # Unmount
    umount "$mount_point"
    
    log_info "System configuration completed"
}

find_root_partition() {
    # Look for the root partition on the target device
    local partitions=($(lsblk -n -o NAME "$TARGET_DEVICE" | tail -n +2))
    
    for partition in "${partitions[@]}"; do
        local part_path="/dev/$partition"
        # Check if this looks like a root partition
        if mount "$part_path" /mnt 2>/dev/null; then
            if [[ -d "/mnt/usr" ]] && [[ -d "/mnt/etc" ]]; then
                umount /mnt
                echo "$part_path"
                return
            fi
            umount /mnt
        fi
    done
}

configure_user_account() {
    local mount_point="$1"
    
    # Create user configuration for systemd-sysusers
    local sysusers_config="$mount_point/etc/sysusers.d/installer-user.conf"
    cat > "$sysusers_config" << EOF
u $USERNAME 1000 "$USERNAME" /home/$USERNAME
g $USERNAME 1000
m $USERNAME $USERNAME
EOF
    
    log_info "User account '$USERNAME' configured"
}

configure_ssh_access() {
    local mount_point="$1"
    
    # Create .ssh directory for root
    local ssh_dir="$mount_point/root/.ssh"
    mkdir -p "$ssh_dir"
    
    # Add SSH key
    echo "$SSH_KEY" > "$ssh_dir/authorized_keys"
    
    # Set proper permissions
    chmod 700 "$ssh_dir"
    chmod 600 "$ssh_dir/authorized_keys"
    
    log_info "SSH access configured for root"
}
```

### Phase 3: Live CD Creation (Week 3-4)

#### 3.1 Live CD Build Script
```bash
#!/bin/bash
# build-live-cd.sh

set -euo pipefail

# Configuration
LIVE_CD_NAME="bootc-installer-live"
LIVE_CD_VERSION="1.0"
OUTPUT_DIR="./live-cd-build"

# Create build directory
mkdir -p "$OUTPUT_DIR"
cd "$OUTPUT_DIR"

# Create live CD structure
mkdir -p {live,chroot}

# Install debootstrap
apt-get update
apt-get install -y debootstrap

# Bootstrap minimal Debian system
debootstrap --arch=amd64 trixie chroot/

# Install required packages
chroot chroot/ apt-get update
chroot chroot/ apt-get install -y \
    podman \
    bootc \
    curl \
    parted \
    e2fsprogs \
    grub-efi-amd64 \
    systemd \
    openssh-server \
    vim \
    nano

# Create installer script
cat > chroot/usr/local/bin/bootc-installer << 'EOF'
#!/bin/bash
# ... (installer script content)
EOF

chmod +x chroot/usr/local/bin/bootc-installer

# Create auto-run script
cat > chroot/etc/profile.d/bootc-installer.sh << 'EOF'
#!/bin/bash
if [[ -z "$BOOTC_INSTALLER_RUN" ]]; then
    export BOOTC_INSTALLER_RUN=1
    echo "Bootc Installer Live CD"
    echo "Run: bootc-installer"
    echo "Or: curl -fsSL https://install.bootc.dev | sh"
fi
EOF

# Build ISO
apt-get install -y live-build
lb config --binary-images iso-hybrid
lb build
```

#### 3.2 Live CD Features
- **Minimal Debian Trixie** base
- **Pre-installed tools**: podman, bootc, curl, parted
- **Network configuration** via DHCP
- **Auto-mount** of installer script
- **GRUB2 bootloader** with UEFI support

### Phase 4: Web Hosting and Distribution (Week 4)

#### 4.1 Web Server Setup
```nginx
# nginx configuration for install.bootc.dev
server {
    listen 443 ssl;
    server_name install.bootc.dev;
    
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    
    location / {
        add_header Content-Type text/plain;
        add_header Cache-Control no-cache;
        return 200 "$(cat /var/www/install.bootc.dev/installer.sh)";
    }
    
    location /latest {
        return 302 https://install.bootc.dev/;
    }
}
```

#### 4.2 Installer Script Hosting
```bash
# Simple script to serve the installer
#!/bin/bash
# serve-installer.sh

while true; do
    echo "Serving installer script..."
    cat installer.sh | nc -l 8080
done
```

## Usage Examples

### Basic Installation
```bash
# Boot from live CD, then:
curl -fsSL https://install.bootc.dev | sh
```

### Install Specific Container
```bash
curl -fsSL https://install.bootc.dev | sh -s -- quay.io/myorg/my-bootc:latest
```

### Install with Pre-configured Settings
```bash
# Set environment variables
export BOOTC_USERNAME="admin"
export BOOTC_SSH_KEY="ssh-rsa AAAAB3NzaC1yc2E..."
export BOOTC_DEVICE="/dev/sda"

curl -fsSL https://install.bootc.dev | sh
```

## Advantages of This Approach

### 1. **Simplicity**
- Single shell script
- No complex dependencies
- Easy to understand and modify

### 2. **Compatibility**
- Works with bootc's design
- No fighting against OSTree internals
- Uses standard Linux tools

### 3. **Flexibility**
- Easy to customize for different containers
- Can be extended with additional features
- Works with any bootc-compatible container

### 4. **Reliability**
- Minimal failure points
- Easy to debug and troubleshoot
- Can be tested in virtual machines

### 5. **User Experience**
- Familiar "curl | sh" pattern
- Interactive prompts for configuration
- Clear progress indicators

## Implementation Timeline

- **Week 1-2**: Core installer script development
- **Week 2-3**: Bootc integration and testing
- **Week 3-4**: Live CD creation and testing
- **Week 4**: Web hosting and distribution setup

## Testing Strategy

### 1. **Virtual Machine Testing**
- Test with different container images
- Test with various disk configurations
- Test error handling and recovery

### 2. **Hardware Testing**
- Test on different hardware configurations
- Test with UEFI and legacy BIOS
- Test with different storage devices

### 3. **Network Testing**
- Test with different network configurations
- Test with proxy/firewall environments
- Test with slow/unreliable connections

## Future Enhancements

### 1. **Advanced Features**
- Multiple container selection
- Custom partitioning options
- Network configuration
- Timezone and locale settings

### 2. **Enterprise Features**
- Corporate registry integration
- Signed installer verification
- Audit logging
- Remote management integration

### 3. **UI Improvements**
- Web-based configuration interface
- Progress bars and better feedback
- Error recovery suggestions
- Installation validation

## Conclusion

This simple installer approach provides a practical, reliable way to install bootc containers while working with the tools rather than against them. The "curl | sh" pattern is familiar to users and the implementation is straightforward and maintainable.

The key advantages are:
- **Simplicity**: Easy to understand and modify
- **Compatibility**: Works with bootc's design
- **Reliability**: Minimal failure points
- **Flexibility**: Easy to extend and customize
- **User Experience**: Familiar and intuitive

This approach can be implemented quickly and provides a solid foundation for more advanced features in the future.
