Fixed WSL / Linux installation
This commit is contained in:
426
run-server.sh
426
run-server.sh
@@ -213,10 +213,183 @@ find_python() {
|
||||
return 1
|
||||
}
|
||||
|
||||
# Detect Linux distribution
|
||||
detect_linux_distro() {
|
||||
if [[ -f /etc/os-release ]]; then
|
||||
. /etc/os-release
|
||||
echo "${ID:-unknown}"
|
||||
elif [[ -f /etc/debian_version ]]; then
|
||||
echo "debian"
|
||||
elif [[ -f /etc/redhat-release ]]; then
|
||||
echo "rhel"
|
||||
elif [[ -f /etc/arch-release ]]; then
|
||||
echo "arch"
|
||||
else
|
||||
echo "unknown"
|
||||
fi
|
||||
}
|
||||
|
||||
# Get package manager and install command for the distro
|
||||
get_install_command() {
|
||||
local distro="$1"
|
||||
local python_version="${2:-}"
|
||||
|
||||
# Extract major.minor version if provided
|
||||
local version_suffix=""
|
||||
if [[ -n "$python_version" ]] && [[ "$python_version" =~ ([0-9]+\.[0-9]+) ]]; then
|
||||
version_suffix="${BASH_REMATCH[1]}"
|
||||
fi
|
||||
|
||||
case "$distro" in
|
||||
ubuntu|debian|raspbian|pop|linuxmint|elementary)
|
||||
if [[ -n "$version_suffix" ]]; then
|
||||
# Try version-specific packages first, then fall back to generic
|
||||
echo "sudo apt update && (sudo apt install -y python${version_suffix}-venv python${version_suffix}-dev || sudo apt install -y python3-venv python3-pip)"
|
||||
else
|
||||
echo "sudo apt update && sudo apt install -y python3-venv python3-pip"
|
||||
fi
|
||||
;;
|
||||
fedora)
|
||||
echo "sudo dnf install -y python3-venv python3-pip"
|
||||
;;
|
||||
rhel|centos|rocky|almalinux|oracle)
|
||||
echo "sudo dnf install -y python3-venv python3-pip || sudo yum install -y python3-venv python3-pip"
|
||||
;;
|
||||
arch|manjaro|endeavouros)
|
||||
echo "sudo pacman -Syu --noconfirm python-pip python-virtualenv"
|
||||
;;
|
||||
opensuse|suse)
|
||||
echo "sudo zypper install -y python3-venv python3-pip"
|
||||
;;
|
||||
alpine)
|
||||
echo "sudo apk add --no-cache python3-dev py3-pip py3-virtualenv"
|
||||
;;
|
||||
*)
|
||||
echo ""
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Check if we can use sudo
|
||||
can_use_sudo() {
|
||||
# Check if sudo exists and user can use it
|
||||
if command -v sudo &> /dev/null; then
|
||||
# Test sudo with a harmless command
|
||||
if sudo -n true 2>/dev/null; then
|
||||
return 0
|
||||
elif [[ -t 0 ]]; then
|
||||
# Terminal is interactive, test if sudo works with password
|
||||
if sudo true 2>/dev/null; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Try to install system packages automatically
|
||||
try_install_system_packages() {
|
||||
local python_cmd="${1:-python3}"
|
||||
local os_type=$(detect_os)
|
||||
|
||||
# Skip on macOS as it works fine
|
||||
if [[ "$os_type" == "macos" ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Only try on Linux systems
|
||||
if [[ "$os_type" != "linux" && "$os_type" != "wsl" ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Get Python version
|
||||
local python_version=""
|
||||
if command -v "$python_cmd" &> /dev/null; then
|
||||
python_version=$($python_cmd --version 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "")
|
||||
fi
|
||||
|
||||
local distro=$(detect_linux_distro)
|
||||
local install_cmd=$(get_install_command "$distro" "$python_version")
|
||||
|
||||
if [[ -z "$install_cmd" ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
print_info "Attempting to install required Python packages..."
|
||||
|
||||
# Check if we can use sudo
|
||||
if can_use_sudo; then
|
||||
print_info "Installing system packages (this may ask for your password)..."
|
||||
if eval "$install_cmd" >/dev/null 2>&1; then
|
||||
print_success "System packages installed successfully"
|
||||
return 0
|
||||
else
|
||||
print_warning "Failed to install system packages automatically"
|
||||
fi
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# Bootstrap pip in virtual environment
|
||||
bootstrap_pip() {
|
||||
local venv_python="$1"
|
||||
local python_cmd="$2"
|
||||
|
||||
print_info "Bootstrapping pip in virtual environment..."
|
||||
|
||||
# Try ensurepip first
|
||||
if $venv_python -m ensurepip --default-pip 2>/dev/null; then
|
||||
print_success "Successfully bootstrapped pip using ensurepip"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Try to download get-pip.py
|
||||
print_info "Downloading pip installer..."
|
||||
local get_pip_url="https://bootstrap.pypa.io/get-pip.py"
|
||||
local temp_pip=$(mktemp)
|
||||
local download_success=false
|
||||
|
||||
# Try curl first
|
||||
if command -v curl &> /dev/null; then
|
||||
if curl -sSL "$get_pip_url" -o "$temp_pip" 2>/dev/null; then
|
||||
download_success=true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Try wget if curl failed
|
||||
if [[ "$download_success" == false ]] && command -v wget &> /dev/null; then
|
||||
if wget -qO "$temp_pip" "$get_pip_url" 2>/dev/null; then
|
||||
download_success=true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Try python urllib as last resort
|
||||
if [[ "$download_success" == false ]]; then
|
||||
print_info "Using Python to download pip installer..."
|
||||
if $python_cmd -c "import urllib.request; urllib.request.urlretrieve('$get_pip_url', '$temp_pip')" 2>/dev/null; then
|
||||
download_success=true
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$download_success" == true ]] && [[ -f "$temp_pip" ]] && [[ -s "$temp_pip" ]]; then
|
||||
print_info "Installing pip..."
|
||||
if $venv_python "$temp_pip" --no-warn-script-location >/dev/null 2>&1; then
|
||||
rm -f "$temp_pip"
|
||||
print_success "Successfully installed pip"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -f "$temp_pip" 2>/dev/null
|
||||
return 1
|
||||
}
|
||||
|
||||
# Setup virtual environment
|
||||
setup_venv() {
|
||||
local python_cmd="$1"
|
||||
local venv_python=""
|
||||
local venv_pip=""
|
||||
|
||||
# Create venv if it doesn't exist
|
||||
if [[ ! -d "$VENV_PATH" ]]; then
|
||||
@@ -227,68 +400,92 @@ setup_venv() {
|
||||
if venv_error=$($python_cmd -m venv "$VENV_PATH" 2>&1); then
|
||||
print_success "Created isolated environment"
|
||||
else
|
||||
print_error "Failed to create virtual environment"
|
||||
echo ""
|
||||
echo "Error details:"
|
||||
echo "$venv_error"
|
||||
echo ""
|
||||
|
||||
# Check for common Linux issues and try fallbacks
|
||||
local os_type=$(detect_os)
|
||||
if [[ "$os_type" == "linux" || "$os_type" == "wsl" ]]; then
|
||||
if echo "$venv_error" | grep -E -q "No module named venv|venv.*not found"; then
|
||||
print_warning "Python venv module not available, trying fallback methods..."
|
||||
|
||||
# Try virtualenv as fallback
|
||||
if command -v virtualenv &> /dev/null; then
|
||||
print_info "Attempting to create environment with virtualenv..."
|
||||
local fallback_error
|
||||
if fallback_error=$(virtualenv -p "$python_cmd" "$VENV_PATH" 2>&1); then
|
||||
print_success "Created environment using virtualenv fallback"
|
||||
# Continue to path setup below instead of early return
|
||||
if echo "$venv_error" | grep -E -q "No module named venv|venv.*not found|ensurepip is not|python3.*-venv"; then
|
||||
# Try to install system packages automatically first
|
||||
if try_install_system_packages "$python_cmd"; then
|
||||
print_info "Retrying virtual environment creation..."
|
||||
if venv_error=$($python_cmd -m venv "$VENV_PATH" 2>&1); then
|
||||
print_success "Created isolated environment"
|
||||
else
|
||||
echo "virtualenv fallback failed: $fallback_error"
|
||||
# Continue to fallback methods below
|
||||
print_warning "Still unable to create venv, trying fallback methods..."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Try python -m virtualenv if directory wasn't created
|
||||
# If venv still doesn't exist, try fallback methods
|
||||
if [[ ! -d "$VENV_PATH" ]]; then
|
||||
local fallback_error
|
||||
if fallback_error=$($python_cmd -m virtualenv "$VENV_PATH" 2>&1); then
|
||||
print_success "Created environment using python -m virtualenv fallback"
|
||||
# Continue to path setup below instead of early return
|
||||
else
|
||||
echo "python -m virtualenv fallback failed: $fallback_error"
|
||||
# Try virtualenv as fallback
|
||||
if command -v virtualenv &> /dev/null; then
|
||||
print_info "Attempting to create environment with virtualenv..."
|
||||
if virtualenv -p "$python_cmd" "$VENV_PATH" &>/dev/null 2>&1; then
|
||||
print_success "Created environment using virtualenv fallback"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Try python -m virtualenv if directory wasn't created
|
||||
if [[ ! -d "$VENV_PATH" ]]; then
|
||||
if $python_cmd -m virtualenv "$VENV_PATH" &>/dev/null 2>&1; then
|
||||
print_success "Created environment using python -m virtualenv fallback"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Last resort: try to install virtualenv via pip and use it
|
||||
if [[ ! -d "$VENV_PATH" ]] && command -v pip3 &> /dev/null; then
|
||||
print_info "Installing virtualenv via pip..."
|
||||
if pip3 install --user virtualenv &>/dev/null 2>&1; then
|
||||
local user_bin="$HOME/.local/bin"
|
||||
if [[ -f "$user_bin/virtualenv" ]]; then
|
||||
if "$user_bin/virtualenv" -p "$python_cmd" "$VENV_PATH" &>/dev/null 2>&1; then
|
||||
print_success "Created environment using pip-installed virtualenv"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if any fallback succeeded
|
||||
# Check if any method succeeded
|
||||
if [[ ! -d "$VENV_PATH" ]]; then
|
||||
print_error "All virtual environment creation methods failed!"
|
||||
print_error "Unable to create virtual environment"
|
||||
echo ""
|
||||
echo "Please install the venv or virtualenv package:"
|
||||
echo " Ubuntu/Debian: sudo apt install python3-venv python3-virtualenv"
|
||||
echo " RHEL/CentOS: sudo dnf install python3-venv python3-virtualenv"
|
||||
echo " Fedora: sudo dnf install python3-venv python3-virtualenv"
|
||||
echo " Arch: sudo pacman -S python-virtualenv"
|
||||
echo "Your system is missing Python development packages."
|
||||
echo ""
|
||||
echo "Or install via pip:"
|
||||
echo " $python_cmd -m pip install --user virtualenv"
|
||||
|
||||
local distro=$(detect_linux_distro)
|
||||
local python_version=$($python_cmd --version 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "")
|
||||
local install_cmd=$(get_install_command "$distro" "$python_version")
|
||||
|
||||
if [[ -n "$install_cmd" ]]; then
|
||||
echo "Please run this command to install them:"
|
||||
echo " $install_cmd"
|
||||
else
|
||||
echo "Please install Python venv support for your system:"
|
||||
echo " Ubuntu/Debian: sudo apt install python3-venv python3-pip"
|
||||
echo " RHEL/CentOS: sudo dnf install python3-venv python3-pip"
|
||||
echo " Arch: sudo pacman -S python-pip python-virtualenv"
|
||||
fi
|
||||
echo ""
|
||||
echo "Then run this script again."
|
||||
exit 1
|
||||
fi
|
||||
elif echo "$venv_error" | grep -q "Permission denied"; then
|
||||
print_error "Permission denied creating virtual environment"
|
||||
echo ""
|
||||
echo "Try running with different permissions or in a different directory:"
|
||||
echo " mkdir -p ~/zen-mcp-temp && cd ~/zen-mcp-temp"
|
||||
echo " git clone <repository-url> && cd zen-mcp-server && ./run-server.sh"
|
||||
echo "Try running in a different directory:"
|
||||
echo " cd ~ && git clone <repository-url> && cd zen-mcp-server && ./run-server.sh"
|
||||
echo ""
|
||||
exit 1
|
||||
else
|
||||
print_error "Failed to create virtual environment"
|
||||
echo "Error: $venv_error"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# For non-Linux systems, show the error and exit
|
||||
print_error "Failed to create virtual environment"
|
||||
echo "Error: $venv_error"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
@@ -299,25 +496,89 @@ setup_venv() {
|
||||
case "$os_type" in
|
||||
windows)
|
||||
venv_python="$VENV_PATH/Scripts/python.exe"
|
||||
venv_pip="$VENV_PATH/Scripts/pip.exe"
|
||||
;;
|
||||
*)
|
||||
venv_python="$VENV_PATH/bin/python"
|
||||
venv_pip="$VENV_PATH/bin/pip"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Always use venv Python
|
||||
if [[ -f "$venv_python" ]]; then
|
||||
if [[ -n "${VIRTUAL_ENV:-}" ]]; then
|
||||
print_success "Using activated virtual environment"
|
||||
fi
|
||||
# Convert to absolute path for MCP registration
|
||||
local abs_venv_python=$(cd "$(dirname "$venv_python")" && pwd)/$(basename "$venv_python")
|
||||
echo "$abs_venv_python"
|
||||
return 0
|
||||
else
|
||||
# Check if venv Python exists
|
||||
if [[ ! -f "$venv_python" ]]; then
|
||||
print_error "Virtual environment Python not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if pip exists in the virtual environment
|
||||
if [[ ! -f "$venv_pip" ]] && ! $venv_python -m pip --version &>/dev/null 2>&1; then
|
||||
# On Linux, try to install system packages if pip is missing
|
||||
local os_type=$(detect_os)
|
||||
if [[ "$os_type" == "linux" || "$os_type" == "wsl" ]]; then
|
||||
if try_install_system_packages "$python_cmd"; then
|
||||
# Check if pip is now available after system package install
|
||||
if $venv_python -m pip --version &>/dev/null 2>&1; then
|
||||
print_success "pip is now available"
|
||||
else
|
||||
# Still need to bootstrap pip
|
||||
bootstrap_pip "$venv_python" "$python_cmd" || true
|
||||
fi
|
||||
else
|
||||
# Try to bootstrap pip without system packages
|
||||
bootstrap_pip "$venv_python" "$python_cmd" || true
|
||||
fi
|
||||
else
|
||||
# For non-Linux systems, just try to bootstrap pip
|
||||
bootstrap_pip "$venv_python" "$python_cmd" || true
|
||||
fi
|
||||
|
||||
# Final check after all attempts
|
||||
if ! $venv_python -m pip --version &>/dev/null 2>&1; then
|
||||
print_error "Failed to install pip in virtual environment"
|
||||
echo ""
|
||||
echo "Your Python installation appears to be incomplete."
|
||||
echo ""
|
||||
|
||||
local distro=$(detect_linux_distro)
|
||||
local python_version=$($python_cmd --version 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "")
|
||||
local install_cmd=$(get_install_command "$distro" "$python_version")
|
||||
|
||||
if [[ -n "$install_cmd" ]]; then
|
||||
echo "Please run this command to install Python packages:"
|
||||
echo " $install_cmd"
|
||||
else
|
||||
echo "Please install Python pip support for your system."
|
||||
fi
|
||||
echo ""
|
||||
echo "Then delete the virtual environment and run this script again:"
|
||||
echo " rm -rf $VENV_PATH"
|
||||
echo " ./run-server.sh"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Verify pip is working
|
||||
if ! $venv_python -m pip --version &>/dev/null 2>&1; then
|
||||
print_error "pip is not working correctly in the virtual environment"
|
||||
echo ""
|
||||
echo "Try deleting the virtual environment and running again:"
|
||||
echo " rm -rf $VENV_PATH"
|
||||
echo " ./run-server.sh"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -n "${VIRTUAL_ENV:-}" ]]; then
|
||||
print_success "Using activated virtual environment with pip"
|
||||
else
|
||||
print_success "Virtual environment ready with pip"
|
||||
fi
|
||||
|
||||
# Convert to absolute path for MCP registration
|
||||
local abs_venv_python=$(cd "$(dirname "$venv_python")" && pwd)/$(basename "$venv_python")
|
||||
echo "$abs_venv_python"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Check if package is installed
|
||||
@@ -332,8 +593,17 @@ install_dependencies() {
|
||||
local python_cmd="$1"
|
||||
local deps_needed=false
|
||||
|
||||
# First verify pip is available
|
||||
if ! $python_cmd -m pip --version &>/dev/null 2>&1; then
|
||||
print_error "pip is not available in the Python environment"
|
||||
echo ""
|
||||
echo "This indicates an incomplete Python installation."
|
||||
echo "Please see the instructions above for installing the required packages."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check required packages
|
||||
local packages=("mcp" "google.generativeai" "openai" "pydantic")
|
||||
local packages=("mcp" "google.generativeai" "openai" "pydantic" "dotenv")
|
||||
for package in "${packages[@]}"; do
|
||||
local import_name=${package%%.*} # Get first part before dot
|
||||
if ! check_package "$python_cmd" "$import_name"; then
|
||||
@@ -353,6 +623,7 @@ install_dependencies() {
|
||||
echo " • MCP protocol library"
|
||||
echo " • AI model connectors"
|
||||
echo " • Data validation tools"
|
||||
echo " • Environment configuration"
|
||||
echo ""
|
||||
|
||||
# Determine if we're in a venv
|
||||
@@ -363,16 +634,69 @@ install_dependencies() {
|
||||
install_cmd="$python_cmd -m pip install -q --user -r requirements.txt"
|
||||
fi
|
||||
|
||||
# Install packages
|
||||
# Install packages with better error handling
|
||||
echo -n "Downloading packages..."
|
||||
if $install_cmd 2>&1 | grep -i error | grep -v warning; then
|
||||
local install_output
|
||||
local install_error
|
||||
|
||||
# Capture both stdout and stderr
|
||||
install_output=$($install_cmd 2>&1)
|
||||
local exit_code=$?
|
||||
|
||||
if [[ $exit_code -ne 0 ]]; then
|
||||
echo -e "\r${RED}✗ Setup failed${NC} "
|
||||
echo ""
|
||||
echo "Try running manually:"
|
||||
echo " $python_cmd -m pip install mcp google-genai openai pydantic"
|
||||
echo "Installation error:"
|
||||
echo "$install_output" | head -20
|
||||
echo ""
|
||||
|
||||
# Check for common issues
|
||||
if echo "$install_output" | grep -q "No module named pip"; then
|
||||
print_error "pip module not found"
|
||||
echo ""
|
||||
echo "Your Python installation is incomplete. Please install pip:"
|
||||
|
||||
local distro=$(detect_linux_distro)
|
||||
local python_version=$($python_cmd --version 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "")
|
||||
local install_cmd=$(get_install_command "$distro" "$python_version")
|
||||
|
||||
if [[ -n "$install_cmd" ]]; then
|
||||
echo ""
|
||||
echo "For your system ($distro), run:"
|
||||
echo " $install_cmd"
|
||||
else
|
||||
echo ""
|
||||
echo " Ubuntu/Debian: sudo apt install python3-pip"
|
||||
echo " RHEL/CentOS: sudo dnf install python3-pip"
|
||||
echo " Arch: sudo pacman -S python-pip"
|
||||
fi
|
||||
elif echo "$install_output" | grep -q "Permission denied"; then
|
||||
print_error "Permission denied during installation"
|
||||
echo ""
|
||||
echo "Try using a virtual environment or install with --user flag:"
|
||||
echo " $python_cmd -m pip install --user -r requirements.txt"
|
||||
else
|
||||
echo "Try running manually:"
|
||||
echo " $python_cmd -m pip install -r requirements.txt"
|
||||
echo ""
|
||||
echo "Or install individual packages:"
|
||||
echo " $python_cmd -m pip install mcp google-genai openai pydantic python-dotenv"
|
||||
fi
|
||||
return 1
|
||||
else
|
||||
echo -e "\r${GREEN}✓ Setup complete!${NC} "
|
||||
|
||||
# Verify critical imports work
|
||||
if ! check_package "$python_cmd" "dotenv"; then
|
||||
print_warning "python-dotenv not imported correctly, installing explicitly..."
|
||||
if $python_cmd -m pip install python-dotenv &>/dev/null 2>&1; then
|
||||
print_success "python-dotenv installed successfully"
|
||||
else
|
||||
print_error "Failed to install python-dotenv"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user