#!/bin/bash # Cloudron Application Packager - Automated packaging system set -e # Configuration WORKSPACE_DIR="/home/localuser/TSYSDevStack/Cloudron/CloudronPackages-Workspace" ARTIFACTS_DIR="/home/localuser/TSYSDevStack/Cloudron/CloudronPackages-Artifacts" APPS_FILE="/home/localuser/TSYSDevStack/Cloudron/GitUrlList.txt" # Create directories mkdir -p "$WORKSPACE_DIR" "$ARTIFACTS_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 # Logging log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } # Status tracking update_status() { local app="$1" local status="$2" local details="$3" echo "$(date '+%Y-%m-%d %H:%M:%S')|$app|$status|$details" >> "$ARTIFACTS_DIR/packaging_status.log" } # Clone or update application clone_app() { local url="$1" local app_name=$(basename "$url" .git) local app_dir="$WORKSPACE_DIR/$app_name" log_info "Processing $app_name from $url" update_status "$app_name" "started" "Cloning repository" if [ -d "$app_dir" ]; then log_info "Updating existing $app_name repository" cd "$app_dir" git fetch origin git reset --hard origin/HEAD update_status "$app_name" "updated" "Repository updated" else log_info "Cloning $app_name repository" git clone "$url" "$app_dir" update_status "$app_name" "cloned" "Repository cloned" fi echo "$app_dir" } # Detect application type and language detect_app_type() { local app_dir="$1" local app_name=$(basename "$app_dir") log_info "Detecting application type for $app_name" # Check for common indicators if [ -f "$app_dir/package.json" ]; then echo "nodejs" elif [ -f "$app_dir/go.mod" ]; then echo "golang" elif [ -f "$app_dir/requirements.txt" ] || [ -f "$app_dir/setup.py" ] || [ -f "$app_dir/pyproject.toml" ]; then echo "python" elif [ -f "$app_dir/Cargo.toml" ]; then echo "rust" elif [ -f "$app_dir/pom.xml" ] || [ -f "$app_dir/build.gradle" ]; then echo "java" elif [ -f "$app_dir/Gemfile" ] || [ -f "$app_dir/Gemfile.lock" ]; then echo "ruby" elif [ -f "$app_dir/composer.json" ]; then echo "php" else echo "unknown" fi } # Create Cloudron package structure create_cloudron_package() { local app_dir="$1" local app_type="$2" local app_name=$(basename "$app_dir") log_info "Creating Cloudron package for $app_name ($app_type)" update_status "$app_name" "packaging" "Creating Cloudron package structure" # Create app directory structure mkdir -p "$app_dir/app" # Create basic Cloudron manifest cat > "$app_dir/app/manifest.json" << EOF { "id": "com.$app_name.cloudron", "title": "$app_name", "version": "1.0.0", "description": "Auto-generated Cloudron package for $app_name", "developer": { "name": "TSYSDevStack Team", "email": "support@tsysdevstack.com" }, "tags": ["productivity", "web-app"], "httpPort": 8080, "manifestVersion": 2, "healthCheck": { "path": "/", "port": 8080 } } EOF # Create basic Dockerfile based on application type case "$app_type" in "nodejs") cat > "$app_dir/app/Dockerfile" << 'EOF' FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY . . EXPOSE 8080 CMD ["npm", "start"] EOF ;; "golang") cat > "$app_dir/app/Dockerfile" << 'EOF' FROM golang:1.21-alpine AS builder WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY . . RUN CGO_ENABLED=0 go build -o main . FROM alpine:latest RUN apk --no-cache add ca-certificates WORKDIR /root/ COPY --from=builder /app/main . EXPOSE 8080 CMD ["./main"] EOF ;; "python") cat > "$app_dir/app/Dockerfile" << 'EOF' FROM python:3.11-alpine WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . EXPOSE 8080 CMD ["python", "app.py"] EOF ;; *) cat > "$app_dir/app/Dockerfile" << 'EOF' FROM alpine:latest RUN apk --no-cache add ca-certificates WORKDIR /app COPY . . EXPOSE 8080 CMD ["./start.sh"] EOF ;; esac update_status "$app_name" "packaged" "Cloudron package structure created" log_success "Cloudron package created for $app_name" } # Main processing function process_app() { local url="$1" local app_name=$(basename "$url" .git) log_info "Starting processing for $app_name" # Clone/update repository local app_dir=$(clone_app "$url") # Detect application type local app_type=$(detect_app_type "$app_dir") log_info "Detected $app_name as $app_type application" # Create Cloudron package create_cloudron_package "$app_dir" "$app_type" # Commit the package files cd "$app_dir" git add app/ 2>/dev/null || true if git diff --staged --quiet; then log_info "No changes to commit for $app_name" else git commit -m "Add Cloudron package structure for $app_name Auto-generated Cloudron package: - Application type: $app_type - Manifest: app/manifest.json - Dockerfile: app/Dockerfile - Generated: $(date) " log_success "Committed Cloudron package for $app_name" fi update_status "$app_name" "completed" "Cloudron package ready" log_success "Completed processing for $app_name" } # Batch processing process_all_apps() { log_info "Starting batch processing of applications" if [ ! -f "$APPS_FILE" ]; then log_error "Applications file not found: $APPS_FILE" exit 1 fi local total=0 local processed=0 while IFS= read -r url; do # Skip empty lines and comments [[ -z "$url" || "$url" == \#* ]] && continue ((total++)) log_info "Processing application $total: $url" if process_app "$url"; then ((processed++)) log_success "Successfully processed $app_name" else log_error "Failed to process $url" update_status "$app_name" "failed" "Processing error" fi echo "----------------------------------------" done < "$APPS_FILE" log_info "Processing complete: $processed/$total applications processed successfully" } # Status reporting show_status() { log_info "Current packaging status:" if [ -f "$ARTIFACTS_DIR/packaging_status.log" ]; then cat "$ARTIFACTS_DIR/packaging_status.log" else log_warning "No status log found" fi } # Main script logic case "${1:-process}" in "process") process_all_apps ;; "status") show_status ;; "help") echo "Usage: $0 [process|status|help]" echo " process - Process all applications (default)" echo " status - Show current status" echo " help - Show this help" ;; *) log_error "Unknown command: $1" exit 1 ;; esac