235 lines
6.2 KiB
Bash
Executable File
235 lines
6.2 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Exit on error
|
|
set -e
|
|
|
|
# Function to print error messages
|
|
error() {
|
|
echo -e "\e[31mERROR:\e[0m $1" >&2
|
|
exit 1
|
|
}
|
|
|
|
# Function to print success messages
|
|
success() {
|
|
echo -e "\e[32mSUCCESS:\e[0m $1"
|
|
}
|
|
|
|
# Function to print info messages
|
|
info() {
|
|
echo -e "\e[34mINFO:\e[0m $1"
|
|
}
|
|
|
|
# Function to check if a command exists
|
|
check_command() {
|
|
if ! command -v "$1" &> /dev/null; then
|
|
error "Required command '$1' not found. Please install it first."
|
|
fi
|
|
}
|
|
|
|
# Function to compare version numbers
|
|
version_compare() {
|
|
if [[ "$1" == "$2" ]]; then
|
|
echo 0
|
|
return
|
|
fi
|
|
local IFS=.
|
|
local i ver1=($1) ver2=($2)
|
|
# Fill empty positions in ver1 with zeros
|
|
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)); do
|
|
ver1[i]=0
|
|
done
|
|
for ((i=0; i<${#ver1[@]}; i++)); do
|
|
# Fill empty positions in ver2 with zeros
|
|
if [[ -z ${ver2[i]} ]]; then
|
|
ver2[i]=0
|
|
fi
|
|
if ((10#${ver1[i]} > 10#${ver2[i]})); then
|
|
echo 1
|
|
return
|
|
fi
|
|
if ((10#${ver1[i]} < 10#${ver2[i]})); then
|
|
echo -1
|
|
return
|
|
fi
|
|
done
|
|
echo 0
|
|
}
|
|
|
|
# Check for required system commands
|
|
check_command python3
|
|
check_command pip3
|
|
|
|
# Check Python version
|
|
PYTHON_VERSION=$(python3 -c 'import sys; print(".".join(map(str, sys.version_info[:2])))')
|
|
MIN_VERSION="3.8"
|
|
if [ $(version_compare "$PYTHON_VERSION" "$MIN_VERSION") -lt 0 ]; then
|
|
error "Python version must be $MIN_VERSION or higher (found $PYTHON_VERSION)"
|
|
fi
|
|
success "Python version check passed (found $PYTHON_VERSION)"
|
|
|
|
# Function to install packages on Fedora
|
|
install_fedora_deps() {
|
|
info "Installing Fedora dependencies..."
|
|
# Check which packages need to be installed
|
|
local packages=()
|
|
local check_packages=(
|
|
"python3-devel"
|
|
"gcc"
|
|
"python3-pip"
|
|
"python3-setuptools"
|
|
"python3-numpy"
|
|
"python3-opencv"
|
|
"python3-flask"
|
|
"python3-gunicorn"
|
|
"bc"
|
|
"lsof"
|
|
)
|
|
|
|
for pkg in "${check_packages[@]}"; do
|
|
if ! rpm -q "$pkg" &>/dev/null; then
|
|
packages+=("$pkg")
|
|
fi
|
|
done
|
|
|
|
# Only run dnf if there are packages to install
|
|
if [ ${#packages[@]} -gt 0 ]; then
|
|
info "Installing missing packages: ${packages[*]}"
|
|
sudo dnf install -y "${packages[@]}" || error "Failed to install required packages"
|
|
else
|
|
info "All required system packages are already installed"
|
|
fi
|
|
}
|
|
|
|
# Function to install packages on Ubuntu/Debian
|
|
install_ubuntu_deps() {
|
|
info "Installing Ubuntu/Debian dependencies..."
|
|
sudo apt-get update || error "Failed to update package lists"
|
|
sudo apt-get install -y \
|
|
python3-dev \
|
|
python3-pip \
|
|
python3-venv \
|
|
python3-numpy \
|
|
python3-opencv \
|
|
python3-flask \
|
|
python3-gunicorn \
|
|
bc \
|
|
lsof \
|
|
|| error "Failed to install required packages"
|
|
}
|
|
|
|
# Check and install system dependencies based on distribution
|
|
install_system_deps() {
|
|
if [ -f /etc/os-release ]; then
|
|
. /etc/os-release
|
|
case $ID in
|
|
fedora)
|
|
install_fedora_deps
|
|
;;
|
|
ubuntu|debian)
|
|
install_ubuntu_deps
|
|
;;
|
|
*)
|
|
info "Unknown distribution. Please ensure you have the following packages installed:"
|
|
echo "- Python development package (python3-devel/python3-dev)"
|
|
echo "- GCC compiler"
|
|
echo "- Python pip"
|
|
echo "- Python venv"
|
|
echo "- Python numpy"
|
|
echo "- Python OpenCV"
|
|
echo "- Python Flask"
|
|
echo "- Python Gunicorn"
|
|
echo "- bc"
|
|
echo "- lsof"
|
|
;;
|
|
esac
|
|
fi
|
|
}
|
|
|
|
# Install system dependencies
|
|
install_system_deps
|
|
|
|
# Create and activate virtual environment
|
|
if [ ! -d "venv" ]; then
|
|
info "Creating virtual environment..."
|
|
# Create venv with system packages to use system numpy and opencv
|
|
python3 -m venv venv --system-site-packages || error "Failed to create virtual environment"
|
|
success "Virtual environment created successfully"
|
|
fi
|
|
|
|
# Ensure virtual environment is activated
|
|
if [ -z "$VIRTUAL_ENV" ]; then
|
|
info "Activating virtual environment..."
|
|
source venv/bin/activate || error "Failed to activate virtual environment"
|
|
fi
|
|
|
|
# Upgrade pip to latest version
|
|
info "Upgrading pip..."
|
|
python3 -m pip install --upgrade pip setuptools wheel || error "Failed to upgrade pip and setuptools"
|
|
|
|
# Create or update requirements.txt with compatible package versions
|
|
if [ ! -f "requirements.txt" ]; then
|
|
info "Creating requirements.txt..."
|
|
cat > requirements.txt << EOF
|
|
# Web framework and extensions
|
|
Flask>=3.0.0
|
|
Flask-Cors>=4.0.0
|
|
Werkzeug>=3.0.0
|
|
gunicorn>=21.2.0
|
|
|
|
# Core dependencies
|
|
opencv-python-headless>=4.8.0
|
|
|
|
# Flask dependencies
|
|
click>=8.1.7
|
|
itsdangerous>=2.1.2
|
|
Jinja2>=3.1.2
|
|
MarkupSafe>=2.1.3
|
|
EOF
|
|
success "Created requirements.txt"
|
|
fi
|
|
|
|
# Install requirements with better error handling
|
|
info "Installing/updating requirements..."
|
|
# First ensure pip is up to date
|
|
pip install --upgrade pip
|
|
|
|
# Install packages with specific options for better compatibility
|
|
PYTHONWARNINGS="ignore" pip install \
|
|
--no-cache-dir \
|
|
--prefer-binary \
|
|
--only-binary :all: \
|
|
-r requirements.txt || error "Failed to install requirements"
|
|
|
|
success "Requirements installed successfully"
|
|
|
|
# Create necessary directories
|
|
info "Creating required directories..."
|
|
mkdir -p logs || error "Failed to create logs directory"
|
|
success "Created required directories"
|
|
|
|
# Function to check if port is available
|
|
check_port() {
|
|
if lsof -Pi :5000 -sTCP:LISTEN -t >/dev/null ; then
|
|
error "Port 5000 is already in use. Please stop the other process first."
|
|
fi
|
|
}
|
|
|
|
# Check if port is available
|
|
check_port
|
|
|
|
# Start Gunicorn with modern settings
|
|
info "Starting server with Gunicorn..."
|
|
exec gunicorn web_server:app \
|
|
--bind 0.0.0.0:5000 \
|
|
--workers $(nproc) \
|
|
--worker-class gthread \
|
|
--threads 2 \
|
|
--timeout 120 \
|
|
--access-logfile logs/access.log \
|
|
--error-logfile logs/error.log \
|
|
--capture-output \
|
|
--log-level info \
|
|
--reload \
|
|
--max-requests 1000 \
|
|
--max-requests-jitter 50 \
|
|
|| error "Failed to start Gunicorn server" |