233 lines
7.3 KiB
Bash
233 lines
7.3 KiB
Bash
#!/bin/bash
|
|
# Traditional layer creation for Ubuntu uBlue apt-layer Tool
|
|
# Provides chroot-based package installation for layer creation
|
|
|
|
# Create traditional layer
|
|
create_layer() {
|
|
local base_image="$1"
|
|
local new_image="$2"
|
|
shift 2
|
|
local packages=("$@")
|
|
|
|
log_layer "Creating traditional layer: $new_image" "apt-layer"
|
|
log_info "Base image: $base_image" "apt-layer"
|
|
log_info "Packages to install: ${packages[*]}" "apt-layer"
|
|
|
|
# Start transaction
|
|
start_transaction "create_layer" "$new_image"
|
|
|
|
# Check if base image exists
|
|
if ! composefs_image_exists "$base_image"; then
|
|
log_error "Base image '$base_image' not found" "apt-layer"
|
|
log_info "Available images:" "apt-layer"
|
|
composefs_list_images
|
|
exit 1
|
|
fi
|
|
|
|
# Prepare temp_layer_dir
|
|
local temp_layer_dir="$BUILD_DIR/temp-layer-$(basename "$new_image")-${TRANSACTION_ID}"
|
|
local final_layer_dir="$BUILD_DIR/layer-$(basename "$new_image")"
|
|
local backup_dir="$BUILD_DIR/backup-layer-$(basename "$new_image")-${TRANSACTION_ID}"
|
|
add_temp_directory "$temp_layer_dir"
|
|
add_temp_directory "$backup_dir"
|
|
rm -rf "$temp_layer_dir" 2>/dev/null || true
|
|
mkdir -p "$temp_layer_dir"
|
|
|
|
update_transaction_phase "checkout_base"
|
|
|
|
# Mount base image to temp_layer_dir
|
|
log_info "Mounting base image..." "apt-layer"
|
|
if ! composefs_mount "$base_image" "$temp_layer_dir"; then
|
|
log_error "Failed to mount base image" "apt-layer"
|
|
exit 1
|
|
fi
|
|
|
|
update_transaction_phase "setup_chroot"
|
|
|
|
# Set up chroot environment
|
|
log_info "Setting up chroot environment..." "apt-layer"
|
|
mount --bind /proc "$temp_layer_dir/proc"
|
|
mount --bind /sys "$temp_layer_dir/sys"
|
|
mount --bind /dev "$temp_layer_dir/dev"
|
|
|
|
# Copy host's resolv.conf for internet access
|
|
cp /etc/resolv.conf "$temp_layer_dir/etc/resolv.conf" 2>/dev/null || true
|
|
|
|
# Ensure /run exists and is writable
|
|
mkdir -p "$temp_layer_dir/run"
|
|
chmod 755 "$temp_layer_dir/run"
|
|
|
|
# Set non-interactive environment for apt
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
|
|
update_transaction_phase "dry_run_check"
|
|
|
|
# Perform dry run to check for conflicts
|
|
log_info "Performing dry run to check for package conflicts..." "apt-layer"
|
|
if ! dry_run_apt_install "$temp_layer_dir" "${packages[@]}"; then
|
|
log_error "Dry run failed - package conflicts detected" "apt-layer"
|
|
log_info "Please resolve conflicts before proceeding" "apt-layer"
|
|
exit 1
|
|
fi
|
|
|
|
update_transaction_phase "install_packages"
|
|
|
|
# Install packages in chroot
|
|
log_info "Installing packages in chroot..." "apt-layer"
|
|
if ! chroot "$temp_layer_dir" apt-get update; then
|
|
log_error "Failed to update package lists in chroot" "apt-layer"
|
|
exit 1
|
|
fi
|
|
|
|
if ! chroot "$temp_layer_dir" apt-get install -y "${packages[@]}"; then
|
|
log_error "Failed to install packages in chroot" "apt-layer"
|
|
exit 1
|
|
fi
|
|
|
|
# Clean up package cache
|
|
chroot "$temp_layer_dir" apt-get clean
|
|
chroot "$temp_layer_dir" apt-get autoremove -y
|
|
|
|
update_transaction_phase "cleanup_mounts"
|
|
|
|
# Clean up mounts
|
|
umount "$temp_layer_dir/proc" 2>/dev/null || true
|
|
umount "$temp_layer_dir/sys" 2>/dev/null || true
|
|
umount "$temp_layer_dir/dev" 2>/dev/null || true
|
|
|
|
# Remove temporary resolv.conf
|
|
rm -f "$temp_layer_dir/etc/resolv.conf"
|
|
|
|
update_transaction_phase "atomic_swap"
|
|
|
|
# Perform atomic directory swap
|
|
if [[ -d "$final_layer_dir" ]]; then
|
|
log_debug "Backing up existing layer directory" "apt-layer"
|
|
if ! atomic_directory_swap "$final_layer_dir" "$backup_dir" ""; then
|
|
log_error "Failed to backup existing layer directory" "apt-layer"
|
|
exit 1
|
|
fi
|
|
add_backup_path "$backup_dir"
|
|
fi
|
|
|
|
# Move temporary directory to final location
|
|
if ! atomic_directory_swap "$temp_layer_dir" "$final_layer_dir" ""; then
|
|
log_error "Failed to perform atomic directory swap" "apt-layer"
|
|
exit 1
|
|
fi
|
|
|
|
update_transaction_phase "create_commit"
|
|
|
|
# Create ComposeFS image from the final layer directory
|
|
log_info "Creating ComposeFS image..." "apt-layer"
|
|
if ! composefs_create "$new_image" "$final_layer_dir"; then
|
|
log_error "Failed to create ComposeFS image" "apt-layer"
|
|
exit 1
|
|
fi
|
|
|
|
# Commit transaction
|
|
commit_transaction
|
|
|
|
log_success "Traditional layer created successfully: $new_image" "apt-layer"
|
|
}
|
|
|
|
# Setup chroot environment for package installation
|
|
setup_chroot_environment() {
|
|
local chroot_dir="$1"
|
|
|
|
log_debug "Setting up chroot environment: $chroot_dir" "apt-layer"
|
|
|
|
# Create necessary directories
|
|
mkdir -p "$chroot_dir"/{proc,sys,dev,run}
|
|
|
|
# Mount essential filesystems
|
|
mount --bind /proc "$chroot_dir/proc"
|
|
mount --bind /sys "$chroot_dir/sys"
|
|
mount --bind /dev "$chroot_dir/dev"
|
|
|
|
# Copy DNS configuration
|
|
cp /etc/resolv.conf "$chroot_dir/etc/resolv.conf" 2>/dev/null || true
|
|
|
|
# Set proper permissions
|
|
chmod 755 "$chroot_dir/run"
|
|
|
|
# Set environment variables
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
|
|
log_debug "Chroot environment setup completed" "apt-layer"
|
|
}
|
|
|
|
# Cleanup chroot environment
|
|
cleanup_chroot_environment() {
|
|
local chroot_dir="$1"
|
|
|
|
log_debug "Cleaning up chroot environment: $chroot_dir" "apt-layer"
|
|
|
|
# Unmount filesystems
|
|
umount "$chroot_dir/proc" 2>/dev/null || true
|
|
umount "$chroot_dir/sys" 2>/dev/null || true
|
|
umount "$chroot_dir/dev" 2>/dev/null || true
|
|
|
|
# Remove temporary files
|
|
rm -f "$chroot_dir/etc/resolv.conf"
|
|
|
|
log_debug "Chroot environment cleanup completed" "apt-layer"
|
|
}
|
|
|
|
# Install packages in chroot with error handling
|
|
install_packages_in_chroot() {
|
|
local chroot_dir="$1"
|
|
shift
|
|
local packages=("$@")
|
|
|
|
log_info "Installing packages in chroot: ${packages[*]}" "apt-layer"
|
|
|
|
# Update package lists
|
|
if ! chroot "$chroot_dir" apt-get update; then
|
|
log_error "Failed to update package lists in chroot" "apt-layer"
|
|
return 1
|
|
fi
|
|
|
|
# Install packages
|
|
if ! chroot "$chroot_dir" apt-get install -y "${packages[@]}"; then
|
|
log_error "Failed to install packages in chroot" "apt-layer"
|
|
return 1
|
|
fi
|
|
|
|
# Clean up
|
|
chroot "$chroot_dir" apt-get clean
|
|
chroot "$chroot_dir" apt-get autoremove -y
|
|
|
|
log_success "Packages installed successfully in chroot" "apt-layer"
|
|
return 0
|
|
}
|
|
|
|
# Validate chroot environment
|
|
validate_chroot_environment() {
|
|
local chroot_dir="$1"
|
|
|
|
log_debug "Validating chroot environment: $chroot_dir" "apt-layer"
|
|
|
|
# Check if chroot directory exists
|
|
if [[ ! -d "$chroot_dir" ]]; then
|
|
log_error "Chroot directory does not exist: $chroot_dir" "apt-layer"
|
|
return 1
|
|
fi
|
|
|
|
# Check if essential directories exist
|
|
for dir in bin lib usr etc; do
|
|
if [[ ! -d "$chroot_dir/$dir" ]]; then
|
|
log_error "Essential directory missing in chroot: $dir" "apt-layer"
|
|
return 1
|
|
fi
|
|
done
|
|
|
|
# Check if apt is available
|
|
if [[ ! -x "$chroot_dir/usr/bin/apt-get" ]]; then
|
|
log_error "apt-get not found in chroot environment" "apt-layer"
|
|
return 1
|
|
fi
|
|
|
|
log_debug "Chroot environment validation passed" "apt-layer"
|
|
return 0
|
|
}
|