deb-bootc-image-builder-new/docs/simple-installer.md
2025-09-05 07:10:12 -07:00

516 lines
13 KiB
Markdown

# 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.