forked from tfgrid/zosbuilder
feat: Implement complete Zero OS Alpine Initramfs Builder
- Complete bash framework with strict error handling - Modular library system (docker, alpine, components, initramfs, kernel, testing) - Rust component integration (zinit, rfs, mycelium) with musl targeting - Rootless Docker/Podman support for GitHub Actions - Centralized configuration in config/build.conf - 2-stage module loading system - Strip + UPX optimization for minimal size - Complete zinit integration replacing OpenRC - GitHub Actions CI/CD pipeline - Comprehensive documentation and usage guides Components: - Latest stable kernel 6.12.44 - Alpine Linux 3.22 base - ThreeFold components: zinit, mycelium, rfs, corex - Target: ~8-12MB final initramfs.cpio.xz
This commit is contained in:
314
scripts/build.sh
Executable file
314
scripts/build.sh
Executable file
@@ -0,0 +1,314 @@
|
||||
#!/bin/bash
|
||||
# Main orchestrator script for Zero OS Alpine Initramfs Builder
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Script directory and project root detection
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||
|
||||
# Source all libraries
|
||||
source "${SCRIPT_DIR}/lib/common.sh"
|
||||
source "${SCRIPT_DIR}/lib/docker.sh"
|
||||
source "${SCRIPT_DIR}/lib/alpine.sh"
|
||||
source "${SCRIPT_DIR}/lib/components.sh"
|
||||
source "${SCRIPT_DIR}/lib/initramfs.sh"
|
||||
source "${SCRIPT_DIR}/lib/kernel.sh"
|
||||
source "${SCRIPT_DIR}/lib/testing.sh"
|
||||
|
||||
# Build configuration loaded from config/build.conf via common.sh
|
||||
# Environment variables can override config file values
|
||||
ALPINE_VERSION="${ALPINE_VERSION:-3.22}"
|
||||
KERNEL_VERSION="${KERNEL_VERSION:-6.12.44}"
|
||||
RUST_TARGET="${RUST_TARGET:-x86_64-unknown-linux-musl}"
|
||||
OPTIMIZATION_LEVEL="${OPTIMIZATION_LEVEL:-max}"
|
||||
|
||||
# Directory configuration
|
||||
export INSTALL_DIR="${PROJECT_ROOT}/initramfs"
|
||||
export COMPONENTS_DIR="${PROJECT_ROOT}/components"
|
||||
export KERNEL_DIR="${PROJECT_ROOT}/kernel"
|
||||
export DIST_DIR="${PROJECT_ROOT}/dist"
|
||||
|
||||
# Configuration files
|
||||
CONFIG_DIR="${PROJECT_ROOT}/config"
|
||||
PACKAGES_LIST="${CONFIG_DIR}/packages.list"
|
||||
SOURCES_CONF="${CONFIG_DIR}/sources.conf"
|
||||
MODULES_CONF="${CONFIG_DIR}/modules.conf"
|
||||
KERNEL_CONFIG="${CONFIG_DIR}/kernel.config"
|
||||
ZINIT_CONFIG_DIR="${CONFIG_DIR}/zinit"
|
||||
|
||||
# Build options
|
||||
USE_CONTAINER="${USE_CONTAINER:-auto}"
|
||||
CLEAN_BUILD="${CLEAN_BUILD:-false}"
|
||||
SKIP_TESTS="${SKIP_TESTS:-false}"
|
||||
KEEP_ARTIFACTS="${KEEP_ARTIFACTS:-false}"
|
||||
|
||||
# Display usage information
|
||||
function show_usage() {
|
||||
cat << EOF
|
||||
Zero OS Alpine Initramfs Builder
|
||||
|
||||
Usage: $0 [OPTIONS]
|
||||
|
||||
Options:
|
||||
--container Force container build
|
||||
--no-container Force native build
|
||||
--clean Clean build (remove all artifacts first)
|
||||
--skip-tests Skip boot tests
|
||||
--keep-artifacts Keep build artifacts after completion
|
||||
--help Show this help message
|
||||
|
||||
Environment Variables:
|
||||
ALPINE_VERSION Alpine Linux version (default: 3.22)
|
||||
KERNEL_VERSION Linux kernel version (default: 6.8.8)
|
||||
RUST_TARGET Rust compilation target (default: x86_64-unknown-linux-musl)
|
||||
OPTIMIZATION_LEVEL Optimization level: max|size|speed (default: max)
|
||||
DEBUG Enable debug output (default: 0)
|
||||
|
||||
Examples:
|
||||
$0 # Basic build
|
||||
$0 --clean # Clean build
|
||||
$0 --container # Force container build
|
||||
DEBUG=1 $0 # Build with debug output
|
||||
EOF
|
||||
}
|
||||
|
||||
# Parse command line arguments
|
||||
function parse_arguments() {
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--container)
|
||||
USE_CONTAINER="true"
|
||||
shift
|
||||
;;
|
||||
--no-container)
|
||||
USE_CONTAINER="false"
|
||||
shift
|
||||
;;
|
||||
--clean)
|
||||
CLEAN_BUILD="true"
|
||||
shift
|
||||
;;
|
||||
--skip-tests)
|
||||
SKIP_TESTS="true"
|
||||
shift
|
||||
;;
|
||||
--keep-artifacts)
|
||||
KEEP_ARTIFACTS="true"
|
||||
shift
|
||||
;;
|
||||
--help|-h)
|
||||
show_usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
log_error "Unknown option: $1"
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# Setup build environment
|
||||
function setup_build_environment() {
|
||||
section_header "Setting up build environment"
|
||||
|
||||
log_info "Project root: ${PROJECT_ROOT}"
|
||||
log_info "Alpine version: ${ALPINE_VERSION}"
|
||||
log_info "Kernel version: ${KERNEL_VERSION}"
|
||||
log_info "Rust target: ${RUST_TARGET}"
|
||||
log_info "Optimization level: ${OPTIMIZATION_LEVEL}"
|
||||
|
||||
# Create build directories
|
||||
safe_mkdir "$INSTALL_DIR"
|
||||
safe_mkdir "$COMPONENTS_DIR"
|
||||
safe_mkdir "$KERNEL_DIR"
|
||||
safe_mkdir "$DIST_DIR"
|
||||
|
||||
# Check dependencies
|
||||
if ! check_dependencies; then
|
||||
log_error "Dependency check failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verify configuration files exist
|
||||
verify_configuration_files
|
||||
|
||||
log_info "Build environment setup complete"
|
||||
}
|
||||
|
||||
# Verify all required configuration files exist
|
||||
function verify_configuration_files() {
|
||||
section_header "Verifying Configuration Files"
|
||||
|
||||
local required_configs=(
|
||||
"$PACKAGES_LIST"
|
||||
"$SOURCES_CONF"
|
||||
"$MODULES_CONF"
|
||||
"$KERNEL_CONFIG"
|
||||
)
|
||||
|
||||
local missing_configs=()
|
||||
|
||||
for config in "${required_configs[@]}"; do
|
||||
if [[ ! -f "$config" ]]; then
|
||||
missing_configs+=("$config")
|
||||
else
|
||||
log_info "✓ Configuration found: $(basename "$config")"
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ${#missing_configs[@]} -gt 0 ]]; then
|
||||
log_error "Missing configuration files:"
|
||||
for config in "${missing_configs[@]}"; do
|
||||
log_error " - $config"
|
||||
done
|
||||
log_error "Run the setup script or create configuration files manually"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check zinit configuration directory
|
||||
if [[ ! -d "$ZINIT_CONFIG_DIR" ]]; then
|
||||
log_error "zinit configuration directory not found: ${ZINIT_CONFIG_DIR}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "All configuration files verified"
|
||||
}
|
||||
|
||||
# Main build process
|
||||
function main_build_process() {
|
||||
section_header "Starting Zero OS Alpine Initramfs Build"
|
||||
|
||||
local start_time=$(date +%s)
|
||||
|
||||
# Phase 1: Extract Alpine miniroot
|
||||
alpine_extract_miniroot "$INSTALL_DIR" "$ALPINE_VERSION"
|
||||
|
||||
# Phase 2: Configure Alpine system
|
||||
alpine_configure_repos "$INSTALL_DIR" "$ALPINE_VERSION"
|
||||
alpine_configure_system "$INSTALL_DIR"
|
||||
|
||||
# Phase 3: Install Alpine packages (NO OpenRC)
|
||||
alpine_install_packages "$INSTALL_DIR" "$PACKAGES_LIST"
|
||||
|
||||
# Phase 4: Build and install ThreeFold components
|
||||
components_parse_sources_conf "$SOURCES_CONF" "$COMPONENTS_DIR"
|
||||
|
||||
# Phase 5: Verify component installation
|
||||
components_verify_installation
|
||||
|
||||
# Phase 6: Setup zinit as init system
|
||||
initramfs_setup_zinit "$INSTALL_DIR" "$ZINIT_CONFIG_DIR"
|
||||
|
||||
# Phase 7: Setup 2-stage module loading
|
||||
initramfs_setup_modules "$INSTALL_DIR" "$MODULES_CONF" "$KERNEL_VERSION"
|
||||
|
||||
# Phase 8: Aggressive cleanup for size optimization
|
||||
alpine_aggressive_cleanup "$INSTALL_DIR"
|
||||
|
||||
# Phase 9: Strip and UPX all binaries
|
||||
initramfs_strip_and_upx "$INSTALL_DIR"
|
||||
|
||||
# Phase 10: Validate initramfs
|
||||
initramfs_validate "$INSTALL_DIR"
|
||||
|
||||
# Phase 11: Create initramfs archive
|
||||
local initramfs_archive="${DIST_DIR}/initramfs.cpio.xz"
|
||||
initramfs_create_cpio "$INSTALL_DIR" "$initramfs_archive"
|
||||
|
||||
# Phase 12: Test archive integrity
|
||||
initramfs_test_archive "$initramfs_archive"
|
||||
|
||||
# Phase 13: Build kernel with embedded initramfs
|
||||
local kernel_output="${DIST_DIR}/vmlinuz.efi"
|
||||
kernel_build_with_initramfs "$KERNEL_CONFIG" "$initramfs_archive" "$kernel_output"
|
||||
|
||||
# Phase 14: Run boot tests (unless skipped)
|
||||
if [[ "$SKIP_TESTS" != "true" ]]; then
|
||||
testing_run_all "$kernel_output"
|
||||
else
|
||||
log_info "Skipping boot tests as requested"
|
||||
fi
|
||||
|
||||
# Calculate build time
|
||||
local end_time=$(date +%s)
|
||||
local build_time=$((end_time - start_time))
|
||||
local build_minutes=$((build_time / 60))
|
||||
local build_seconds=$((build_time % 60))
|
||||
|
||||
section_header "Build Complete"
|
||||
log_info "Build time: ${build_minutes}m ${build_seconds}s"
|
||||
log_info "Output files:"
|
||||
log_info " Kernel: ${kernel_output} ($(get_file_size "$kernel_output"))"
|
||||
log_info " Initramfs: ${initramfs_archive} ($(get_file_size "$initramfs_archive"))"
|
||||
}
|
||||
|
||||
# Cleanup build artifacts
|
||||
function cleanup_build_artifacts() {
|
||||
if [[ "$KEEP_ARTIFACTS" != "true" ]]; then
|
||||
section_header "Cleaning Build Artifacts"
|
||||
|
||||
components_cleanup "$COMPONENTS_DIR" "false"
|
||||
kernel_cleanup "$KERNEL_DIR" "false"
|
||||
|
||||
log_info "Build artifacts cleaned"
|
||||
else
|
||||
log_info "Keeping build artifacts as requested"
|
||||
fi
|
||||
}
|
||||
|
||||
# Main function
|
||||
function main() {
|
||||
# Parse command line arguments
|
||||
parse_arguments "$@"
|
||||
|
||||
# Show banner
|
||||
echo ""
|
||||
echo "=================================================="
|
||||
echo "== ZERO-OS ALPINE INITRAMFS BUILDER =="
|
||||
echo "== ThreeFold Edition =="
|
||||
echo "=================================================="
|
||||
echo ""
|
||||
|
||||
# Clean build if requested
|
||||
if [[ "$CLEAN_BUILD" == "true" ]]; then
|
||||
section_header "Clean Build Requested"
|
||||
"$SCRIPT_DIR/clean.sh"
|
||||
fi
|
||||
|
||||
# Setup environment
|
||||
setup_build_environment
|
||||
|
||||
# Determine build method
|
||||
if [[ "$USE_CONTAINER" == "auto" ]]; then
|
||||
if in_container; then
|
||||
log_info "Already in container, using native build"
|
||||
main_build_process
|
||||
elif command_exists "podman" || command_exists "docker"; then
|
||||
log_info "Container runtime available, using container build"
|
||||
docker_detect_runtime
|
||||
docker_build_container
|
||||
docker_run_build "./scripts/build.sh --no-container"
|
||||
else
|
||||
log_info "No container runtime, using native build"
|
||||
main_build_process
|
||||
fi
|
||||
elif [[ "$USE_CONTAINER" == "true" ]]; then
|
||||
docker_detect_runtime
|
||||
docker_build_container
|
||||
docker_run_build "./scripts/build.sh --no-container"
|
||||
else
|
||||
main_build_process
|
||||
fi
|
||||
|
||||
# Cleanup if requested
|
||||
cleanup_build_artifacts
|
||||
|
||||
section_header "Zero OS Build Complete"
|
||||
log_info "Ready to deploy Zero OS with Alpine Linux and zinit"
|
||||
}
|
||||
|
||||
# Run main function with all arguments
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user