#!/bin/bash set -euo pipefail # HCFS Docker Images Build Script # Builds all HCFS-enabled development environment containers SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Configuration REGISTRY="${DOCKER_REGISTRY:-registry.home.deepblack.cloud}" NAMESPACE="${DOCKER_NAMESPACE:-tony}" VERSION="${VERSION:-latest}" BUILD_PARALLEL="${BUILD_PARALLEL:-false}" # Logging functions log() { echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1" } success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } error() { echo -e "${RED}[ERROR]${NC} $1" >&2 } # Function to build a single image build_image() { local image_name="$1" local dockerfile_dir="$2" local build_args="$3" log "Building image: $image_name" local full_image_name="$REGISTRY/$NAMESPACE/$image_name:$VERSION" local build_cmd="docker build" # Add build arguments if provided if [ -n "$build_args" ]; then build_cmd="$build_cmd $build_args" fi # Add tags build_cmd="$build_cmd -t $image_name:$VERSION -t $image_name:latest" build_cmd="$build_cmd -t $full_image_name" # Add dockerfile directory build_cmd="$build_cmd $dockerfile_dir" if eval $build_cmd; then success "Built image: $image_name" return 0 else error "Failed to build image: $image_name" return 1 fi } # Function to prepare HCFS SDK files prepare_hcfs_sdks() { log "Preparing HCFS SDK files..." local sdk_dir="$SCRIPT_DIR/sdks" mkdir -p "$sdk_dir" # Copy Python SDK if [ -d "$PROJECT_ROOT/../HCFS/hcfs-python" ]; then cp -r "$PROJECT_ROOT/../HCFS/hcfs-python" "$sdk_dir/hcfs-python-sdk" success "Copied Python HCFS SDK" else warning "Python HCFS SDK not found, creating minimal version" mkdir -p "$sdk_dir/hcfs-python-sdk" cat > "$sdk_dir/hcfs-python-sdk/setup.py" << 'EOF' from setuptools import setup, find_packages setup( name="hcfs-sdk", version="1.0.0", packages=find_packages(), install_requires=["httpx", "pydantic"], ) EOF mkdir -p "$sdk_dir/hcfs-python-sdk/hcfs" echo "# HCFS Python SDK Placeholder" > "$sdk_dir/hcfs-python-sdk/hcfs/__init__.py" fi # Create Node.js SDK mkdir -p "$sdk_dir/hcfs-nodejs-sdk" cat > "$sdk_dir/hcfs-nodejs-sdk/package.json" << 'EOF' { "name": "@hcfs/sdk", "version": "1.0.0", "description": "HCFS Node.js SDK", "main": "index.js", "dependencies": { "axios": "^1.0.0" } } EOF echo "module.exports = { HCFSClient: class HCFSClient {} };" > "$sdk_dir/hcfs-nodejs-sdk/index.js" # Create Go SDK mkdir -p "$sdk_dir/hcfs-go-sdk" cat > "$sdk_dir/hcfs-go-sdk/go.mod" << 'EOF' module github.com/hcfs/go-sdk go 1.21 require ( github.com/go-resty/resty/v2 v2.7.0 ) EOF cat > "$sdk_dir/hcfs-go-sdk/client.go" << 'EOF' package client import "github.com/go-resty/resty/v2" type HCFSClient struct { client *resty.Client baseURL string } func NewHCFSClient(baseURL string) (*HCFSClient, error) { return &HCFSClient{ client: resty.New(), baseURL: baseURL, }, nil } EOF success "HCFS SDKs prepared" } # Function to copy scripts prepare_scripts() { log "Preparing build scripts..." # Copy scripts to each image directory for image_dir in "$SCRIPT_DIR"/hcfs-*; do if [ -d "$image_dir" ]; then mkdir -p "$image_dir/scripts" mkdir -p "$image_dir/config" mkdir -p "$image_dir/hcfs-client" # Copy common scripts cp "$SCRIPT_DIR/hcfs-base/scripts/"* "$image_dir/scripts/" 2>/dev/null || true cp "$SCRIPT_DIR/hcfs-base/config/"* "$image_dir/config/" 2>/dev/null || true # Copy HCFS client cp -r "$SCRIPT_DIR/sdks/hcfs-python-sdk/"* "$image_dir/hcfs-client/" 2>/dev/null || true fi done success "Scripts prepared" } # Function to validate prerequisites validate_prerequisites() { log "Validating prerequisites..." # Check if Docker is available if ! command -v docker &> /dev/null; then error "Docker is not installed or not in PATH" exit 1 fi # Check if Docker daemon is running if ! docker info &> /dev/null; then error "Docker daemon is not running" exit 1 fi # Check if required directories exist if [ ! -d "$SCRIPT_DIR/hcfs-base" ]; then error "Base image directory not found: $SCRIPT_DIR/hcfs-base" exit 1 fi success "Prerequisites validated" } # Function to build all images build_all_images() { log "Building HCFS development environment images..." local images=( "bzzz-hcfs-base:$SCRIPT_DIR/hcfs-base:" "bzzz-hcfs-python:$SCRIPT_DIR/hcfs-python:" "bzzz-hcfs-nodejs:$SCRIPT_DIR/hcfs-nodejs:" "bzzz-hcfs-go:$SCRIPT_DIR/hcfs-go:" ) local failed_builds=() if [ "$BUILD_PARALLEL" = "true" ]; then log "Building images in parallel..." local pids=() for image_spec in "${images[@]}"; do IFS=':' read -r image_name dockerfile_dir build_args <<< "$image_spec" (build_image "$image_name" "$dockerfile_dir" "$build_args") & pids+=($!) done # Wait for all builds to complete for pid in "${pids[@]}"; do if ! wait $pid; then failed_builds+=("PID:$pid") fi done else log "Building images sequentially..." for image_spec in "${images[@]}"; do IFS=':' read -r image_name dockerfile_dir build_args <<< "$image_spec" if ! build_image "$image_name" "$dockerfile_dir" "$build_args"; then failed_builds+=("$image_name") fi done fi # Report results if [ ${#failed_builds[@]} -eq 0 ]; then success "All images built successfully!" else error "Failed to build images: ${failed_builds[*]}" return 1 fi } # Function to push images to registry push_images() { log "Pushing images to registry: $REGISTRY" local images=( "bzzz-hcfs-base" "bzzz-hcfs-python" "bzzz-hcfs-nodejs" "bzzz-hcfs-go" ) for image in "${images[@]}"; do local full_name="$REGISTRY/$NAMESPACE/$image:$VERSION" log "Pushing $full_name..." if docker push "$full_name"; then success "Pushed $full_name" else warning "Failed to push $full_name" fi done } # Function to run tests test_images() { log "Testing built images..." local images=( "bzzz-hcfs-base" "bzzz-hcfs-python" "bzzz-hcfs-nodejs" "bzzz-hcfs-go" ) for image in "${images[@]}"; do log "Testing $image..." # Basic smoke test if docker run --rm "$image:$VERSION" /bin/echo "Image $image test successful"; then success "Test passed: $image" else warning "Test failed: $image" fi done } # Function to clean up cleanup() { log "Cleaning up temporary files..." # Remove copied SDK files rm -rf "$SCRIPT_DIR/sdks" # Clean up dangling images docker image prune -f &> /dev/null || true success "Cleanup completed" } # Main execution main() { local command="${1:-build}" case $command in "build") validate_prerequisites prepare_hcfs_sdks prepare_scripts build_all_images ;; "push") push_images ;; "test") test_images ;; "all") validate_prerequisites prepare_hcfs_sdks prepare_scripts build_all_images test_images push_images ;; "clean") cleanup ;; "help"|*) echo "HCFS Docker Images Build Script" echo "" echo "Usage: $0 {build|push|test|all|clean|help}" echo "" echo "Commands:" echo " build - Build all HCFS development images" echo " push - Push images to registry" echo " test - Run smoke tests on built images" echo " all - Build, test, and push images" echo " clean - Clean up temporary files" echo " help - Show this help message" echo "" echo "Environment Variables:" echo " DOCKER_REGISTRY - Docker registry URL (default: registry.home.deepblack.cloud)" echo " DOCKER_NAMESPACE - Docker namespace (default: tony)" echo " VERSION - Image version tag (default: latest)" echo " BUILD_PARALLEL - Build images in parallel (default: false)" exit 0 ;; esac } # Set up signal handlers for cleanup trap cleanup EXIT INT TERM # Execute main function main "$@"