Files
NebulaShell/start.sh
Falck 76147bae94 初始提交 - FutureOSS v1.0 插件化运行时框架
一切皆为插件的开发者工具运行时框架

🧩 核心特性:
  - 插件热插拔 (importlib 动态加载)
  - 依赖自动解析 (拓扑排序 + 循环检测)
  - 企业级稳定 (熔断/降级/重试/隔离)
  - 事件驱动 (发布/订阅事件总线)
  - 完整配置 (YAML 配置 + 热重载)
2026-04-06 09:57:10 +08:00

181 lines
6.9 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# ═══════════════════════════════════════════════════════════
# FutureOSS 启动脚本 — Linux / macOS
# 自动检测 Python / 依赖 / 守护 / 崩溃重启
# ═══════════════════════════════════════════════════════════
set -e
# ── 颜色 ──
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
CYAN='\033[0;36m'; WHITE='\033[1;37m'; BOLD='\033[1m'; NC='\033[0m'
LOGO="
███████╗ ██████╗ ██████╗ ██████╗ ██████╗ ██████╗
██╔════╝ ██╔══██╗ ██╔══██╗ ██╔══██╗ ██╔══██╗██╔════╝
█████╗ ██████╔╝ ██████╔╝ ██████╔╝ ██║ ██║██║ ███╗
██╔══╝ ██╔══██╗ ██╔══██╗ ██╔══██╗ ██║ ██║██║ ██║
██║ ██║ ██║ ██║ ██║ ██║ ██║ ██████╔╝╚██████╔╝
╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝"
info() { echo -e "${CYAN} $1${NC}"; }
ok() { echo -e "${GREEN}$1${NC}"; }
warn() { echo -e "${YELLOW}$1${NC}"; }
err() { echo -e "${RED}$1${NC}"; }
title() { echo -e "\n${BOLD}$1${NC}"; }
# ── 守护参数 ──
DAEMON=false
if [[ "$1" == "--daemon" || "$1" == "-d" ]]; then
DAEMON=true
fi
title "$LOGO"
echo -e "${WHITE} 一切皆为插件 · 零编译热插拔${NC}"
echo -e "${WHITE} https://gitee.com/starlight-apk/feature-oss${NC}"
echo ""
# ── 目录 ──
PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
cd "$PROJECT_DIR"
# ═══════════════════════════════════════════════════════════
# 1. 检查 Python
# ═══════════════════════════════════════════════════════════
title "📦 环境检测"
find_python() {
for cmd in python3 python python3.12 python3.11 python3.10; do
if command -v "$cmd" &>/dev/null; then
echo "$cmd"
return
fi
done
return 1
}
PYTHON_CMD=$(find_python || true)
if [[ -z "$PYTHON_CMD" ]]; then
warn "未检测到 Python正在自动安装..."
if command -v apt-get &>/dev/null; then
sudo apt-get update -qq && sudo apt-get install -y -qq python3 python3-pip python3-venv
elif command -v yum &>/dev/null; then
sudo yum install -y python3 python3-pip
elif command -v pacman &>/dev/null; then
sudo pacman -Sy --noconfirm python python-pip
elif command -v brew &>/dev/null; then
brew install python
elif command -v apk &>/dev/null; then
apk add python3 py3-pip
else
err "无法自动安装 Python请手动安装 Python 3.10+"
exit 1
fi
PYTHON_CMD=$(find_python || true)
[[ -z "$PYTHON_CMD" ]] && { err "Python 安装失败"; exit 1; }
fi
PY_VER=$($PYTHON_CMD --version 2>&1)
ok "Python: $PY_VER ($PYTHON_CMD)"
# ═══════════════════════════════════════════════════════════
# 2. 虚拟环境 & 依赖
# ═══════════════════════════════════════════════════════════
title "📚 依赖安装"
VENV_DIR=".venv"
if [[ ! -d "$VENV_DIR" ]]; then
info "创建虚拟环境..."
$PYTHON_CMD -m venv "$VENV_DIR"
fi
source "$VENV_DIR/bin/activate"
PIP_CMD="$VENV_DIR/bin/pip"
if [[ -f "pyproject.toml" ]]; then
info "安装项目依赖 (pyproject.toml)..."
$PIP_CMD install -e . -q 2>/dev/null || $PIP_CMD install -e . --break-system-packages -q 2>/dev/null || true
fi
if [[ -f "requirements.txt" ]]; then
info "安装 requirements.txt..."
$PIP_CMD install -r requirements.txt -q 2>/dev/null || true
fi
# 核心依赖兜底
for pkg in click pyyaml websockets; do
$PYTHON_CMD -c "import $pkg" 2>/dev/null || {
info "安装 $pkg ..."
$PIP_CMD install "$pkg" -q 2>/dev/null || $PIP_CMD install "$pkg" --break-system-packages -q 2>/dev/null || true
}
done
ok "依赖就绪"
# ═══════════════════════════════════════════════════════════
# 3. 确保 data 目录
# ═══════════════════════════════════════════════════════════
mkdir -p data/html-render data/web-toolkit data/plugin-storage data/DCIM data/pkg
# ═══════════════════════════════════════════════════════════
# 4. 启动
# ═══════════════════════════════════════════════════════════
title "🚀 启动 FutureOSS"
if $DAEMON; then
title "🔒 守护模式"
LOG_FILE="logs/futureoss.log"
mkdir -p logs
PID_FILE="logs/futureoss.pid"
if [[ -f "$PID_FILE" ]]; then
OLD_PID=$(cat "$PID_FILE")
if kill -0 "$OLD_PID" 2>/dev/null; then
warn "已有进程运行 (PID: $OLD_PID),正在停止..."
kill "$OLD_PID" 2>/dev/null || true
sleep 2
fi
fi
nohup $PYTHON_CMD -m oss.cli serve > "$LOG_FILE" 2>&1 &
NEW_PID=$!
echo "$NEW_PID" > "$PID_FILE"
ok "已启动守护进程 (PID: $NEW_PID)"
info "日志: $LOG_FILE"
info "停止: kill $(cat $PID_FILE) 或 bash start.sh stop"
sleep 2
curl -s http://localhost:8080/health &>/dev/null && ok "服务就绪: http://localhost:8080" || warn "服务启动中,请稍候..."
exit 0
fi
# ── 前台模式 + 崩溃自动重启 ──
RESTART_DELAY=3
MAX_RESTARTS=0
RESTART_COUNT=0
run_server() {
$PYTHON_CMD -m oss.cli serve
}
while true; do
run_server
EXIT_CODE=$?
if [[ $EXIT_CODE -eq 0 ]]; then
ok "服务正常退出"
break
fi
RESTART_COUNT=$((RESTART_COUNT + 1))
warn "服务异常退出 (code: $EXIT_CODE)${RESTART_DELAY}s 后重启... (第 $RESTART_COUNT 次)"
sleep $RESTART_DELAY
# 指数退避,最大 30s
if [[ $RESTART_DELAY -lt 30 ]]; then
RESTART_DELAY=$((RESTART_DELAY * 2))
fi
done
deactivate 2>/dev/null || true