516 lines
13 KiB
Markdown
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.
|