Files
hawkbit/hawkbit-compose/start-hawkbit.sh
lingwei.kong a3eb952931
Some checks failed
Mark & close stale issues / stale (push) Has been cancelled
Vulnerability Scan / trivy-scan (1.0) (push) Has been cancelled
Vulnerability Scan / trivy-scan (master) (push) Has been cancelled
CodeQL Advanced / Analyze (java-kotlin) (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
修复Action history 为空的问题
2026-06-22 16:06:08 +08:00

408 lines
18 KiB
Bash
Executable File
Raw Permalink 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.
#!/bin/bash
# ═══════════════════════════════════════════════════════════════════════════════
# Hawkbit Monolith + UI 本地启动脚本(替代 docker-compose
# ═══════════════════════════════════════════════════════════════════════════════
#
# 两种模式:
# h2 H2 内嵌数据库(零依赖,开发测试用)
# postgres PostgreSQL + RabbitMQ模拟生产环境
#
# 用法:
# ./start-hawkbit.sh h2 # H2 模式,端口 9090/9091
# ./start-hawkbit.sh postgres # PostgreSQL 模式,端口 9090/9091
# ./start-hawkbit.sh stop # 停止所有
# ./start-hawkbit.sh status # 查看状态
# ./start-hawkbit.sh dbinit # 仅执行数据库初始化postgres 模式)
# ./start-hawkbit.sh help # 帮助
#
# 对应 docker-compose 文件:
# h2 → docker-compose-monolith-with-ui-postgres.yml (但用 H2)
# postgres → docker-compose-monolith-dbinit-with-ui-postgres.yml
# ═══════════════════════════════════════════════════════════════════════════════
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
HAWKBIT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
LOG_DIR="$SCRIPT_DIR/logs"
PID_DIR="$SCRIPT_DIR/pid"
# ── 配置 ─────────────────────────────────────────────────────────────────────
MONOLITH_JAR="$HAWKBIT_ROOT/hawkbit-monolith/hawkbit-update-server/target/hawkbit-update-server-0-SNAPSHOT.jar"
UI_JAR="$HAWKBIT_ROOT/hawkbit-ui/target/hawkbit-ui.jar"
DBINIT_JAR="$HOME/.m2/repository/org/eclipse/hawkbit/hawkbit-repository-jpa-init/0-SNAPSHOT/hawkbit-repository-jpa-init-0-SNAPSHOT.jar"
# 端口
MONOLITH_PORT=9090
UI_PORT=9091
# PostgreSQL 配置postgres 模式)
PG_HOST=localhost
PG_PORT=5432
PG_DB=hawkbit
PG_USER=postgres
PG_PASSWORD=hawkbit
# RabbitMQ 配置postgres 模式)
RABBIT_HOST=localhost
RABBIT_PORT=5672
# H2 配置
H2_DB_DIR="$SCRIPT_DIR/h2data"
# JVM 参数
MONOLITH_XMS=512m
MONOLITH_XMX=1024m
UI_XMS=256m
UI_XMX=512m
# ── 颜色 ─────────────────────────────────────────────────────────────────────
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'
info() { echo -e "${GREEN}[INFO]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*"; }
step() { echo -e "\n${BLUE}═══ $* ═══${NC}"; }
# ── 初始化 ───────────────────────────────────────────────────────────────────
init() {
mkdir -p "$LOG_DIR" "$PID_DIR"
}
# ── 清理 ─────────────────────────────────────────────────────────────────────
cleanup_pid() {
local pid_file="$1"
local name="$2"
if [ -f "$pid_file" ]; then
local pid=$(cat "$pid_file")
if kill -0 "$pid" 2>/dev/null; then
info "停止 $name (PID: $pid)"
kill "$pid" 2>/dev/null || true
sleep 2
kill -9 "$pid" 2>/dev/null || true
fi
rm -f "$pid_file"
fi
}
# ── 停止 ─────────────────────────────────────────────────────────────────────
do_stop() {
step "停止 Hawkbit 服务"
cleanup_pid "$PID_DIR/hawkbit-monolith.pid" "hawkbit-monolith"
cleanup_pid "$PID_DIR/hawkbit-ui.pid" "hawkbit-ui"
if [ -f "$PID_DIR/postgres.pid" ]; then
local pg_pid=$(cat "$PID_DIR/postgres.pid")
if kill -0 "$pg_pid" 2>/dev/null; then
info "停止 PostgreSQL (PID: $pg_pid)"
pg_ctl -D "$SCRIPT_DIR/pgdata" stop 2>/dev/null || kill "$pg_pid"
fi
rm -f "$PID_DIR/postgres.pid"
fi
if [ -f "$PID_DIR/rabbitmq.pid" ]; then
local rb_pid=$(cat "$PID_DIR/rabbitmq.pid")
if kill -0 "$rb_pid" 2>/dev/null; then
info "停止 RabbitMQ (PID: $rb_pid)"
kill "$rb_pid" 2>/dev/null || true
fi
rm -f "$PID_DIR/rabbitmq.pid"
fi
info "全部已停止"
}
# ── 状态 ─────────────────────────────────────────────────────────────────────
do_status() {
echo "Hawkbit 服务状态:"
echo "─────────────────"
for svc in "hawkbit-monolith:${MONOLITH_PORT}:$PID_DIR/hawkbit-monolith.pid" \
"hawkbit-ui:${UI_PORT}:$PID_DIR/hawkbit-ui.pid"; do
IFS=':' read -r name port pid_file <<< "$svc"
if [ -f "$pid_file" ] && kill -0 "$(cat "$pid_file")" 2>/dev/null; then
echo -e " ${GREEN}${NC} $name (port $port, PID $(cat "$pid_file"))"
else
echo -e " ${RED}${NC} $name (port $port)"
fi
done
echo ""
if [ -f "$PID_DIR/postgres.pid" ] && kill -0 "$(cat "$PID_DIR/postgres.pid")" 2>/dev/null; then
echo -e " ${GREEN}${NC} PostgreSQL (port $PG_PORT)"
else
echo -e " ${YELLOW}${NC} PostgreSQL (not managed by this script)"
fi
}
# ── 等待端口 ─────────────────────────────────────────────────────────────────
wait_for_port() {
local host=$1 port=$2 timeout=${3:-30} label=${4:-"$host:$port"}
local waited=0
while ! (echo >"/dev/tcp/$host/$port") 2>/dev/null; do
sleep 1
waited=$((waited + 1))
if [ $waited -ge $timeout ]; then
error "$label 启动超时(${timeout}s"
return 1
fi
done
info "$label 就绪"
}
# ── H2 模式 ──────────────────────────────────────────────────────────────────
start_h2() {
step "H2 模式启动"
if [ -f "$PID_DIR/hawkbit-monolith.pid" ] && kill -0 "$(cat "$PID_DIR/hawkbit-monolith.pid")" 2>/dev/null; then
warn "hawkbit-monolith 已在运行"
else
mkdir -p "$H2_DB_DIR"
info "启动 hawkbit-update-server (H2, 端口 $MONOLITH_PORT)..."
nohup java \
-Xms${MONOLITH_XMS} -Xmx${MONOLITH_XMX} \
-jar "$MONOLITH_JAR" \
--server.port=$MONOLITH_PORT \
--hawkbit.dmf.rabbitmq.enabled=false \
--hawkbit.server.ddi.security.authentication.anonymous.enabled=true \
--hawkbit.server.ui.demo.user=admin \
--hawkbit.server.ui.demo.password=admin \
--spring.datasource.url="jdbc:h2:file:$H2_DB_DIR/hawkbit;DB_CLOSE_DELAY=-1" \
>> "$LOG_DIR/hawkbit-monolith.log" 2>&1 &
echo $! > "$PID_DIR/hawkbit-monolith.pid"
fi
start_ui
}
# ── PostgreSQL 模式 ──────────────────────────────────────────────────────────
start_postgres() {
step "PostgreSQL 模式启动"
# ── 检查 PostgreSQL ────────────────────────────────────────────────
if ! command -v pg_isready &>/dev/null; then
error "PostgreSQL 未安装。请先执行: sudo apt install postgresql-16 rabbitmq-server"
echo ""
echo "或者用 H2 模式: $0 h2"
exit 1
fi
# 确保 PostgreSQL 运行
if ! pg_isready -h $PG_HOST -p $PG_PORT &>/dev/null; then
info "启动 PostgreSQL..."
sudo pg_ctlcluster 16 main start 2>/dev/null || \
sudo service postgresql start 2>/dev/null || {
error "无法启动 PostgreSQL"
exit 1
}
fi
info "PostgreSQL 已就绪"
# ── 创建数据库和用户 ──────────────────────────────────────────────
sudo -u postgres psql -tc "SELECT 1 FROM pg_roles WHERE rolname='$PG_USER'" 2>/dev/null | grep -q 1 || {
info "创建数据库用户 $PG_USER"
sudo -u postgres psql -c "CREATE USER $PG_USER WITH PASSWORD '$PG_PASSWORD';" 2>/dev/null
sudo -u postgres psql -c "ALTER USER $PG_USER CREATEDB;" 2>/dev/null
}
sudo -u postgres psql -tc "SELECT 1 FROM pg_database WHERE datname='$PG_DB'" 2>/dev/null | grep -q 1 || {
info "创建数据库 $PG_DB"
sudo -u postgres psql -c "CREATE DATABASE $PG_DB OWNER $PG_USER;" 2>/dev/null
}
# ── RabbitMQ ───────────────────────────────────────────────────────
if ! rabbitmqctl status &>/dev/null 2>&1; then
info "启动 RabbitMQ..."
sudo service rabbitmq-server start 2>/dev/null || {
warn "RabbitMQ 启动失败,禁用 DMF"
RABBIT_DISABLED=true
}
fi
[ -z "$RABBIT_DISABLED" ] && info "RabbitMQ 已就绪"
# ── DB Init (Flyway 迁移) ──────────────────────────────────────────
if [ -f "$DBINIT_JAR" ]; then
step "数据库初始化 (Flyway 迁移)"
info "执行 Hawkbit DB Init..."
java \
-Xms256m -Xmx512m \
-classpath "$DBINIT_JAR" \
-Dspring.datasource.url="jdbc:postgresql://${PG_HOST}:${PG_PORT}/${PG_DB}" \
-Dspring.datasource.username="$PG_USER" \
-Dspring.datasource.password="$PG_PASSWORD" \
org.eclipse.hawkbit.repository.jpa.init.HawkbitFlywayDbInit \
migrate 2>&1 | tee "$LOG_DIR/dbinit.log"
if [ ${PIPESTATUS[0]} -ne 0 ]; then
error "DB 初始化失败,查看日志: $LOG_DIR/dbinit.log"
exit 1
fi
info "DB 初始化完成"
else
warn "DB Init JAR 未找到: $DBINIT_JAR"
warn "跳过 DB 初始化,由 Monolith 内嵌 Flyway 执行"
fi
# ── 启动 Monolith ─────────────────────────────────────────────────
info "启动 hawkbit-update-server (PostgreSQL, 端口 $MONOLITH_PORT)..."
local rabbit_args=""
if [ "$RABBIT_DISABLED" = true ]; then
rabbit_args="--hawkbit.dmf.rabbitmq.enabled=false"
else
rabbit_args="--spring.rabbitmq.host=$RABBIT_HOST"
fi
nohup java \
-Xms${MONOLITH_XMS} -Xmx${MONOLITH_XMX} \
-Dspring.profiles.active=postgresql \
-jar "$MONOLITH_JAR" \
--server.port=$MONOLITH_PORT \
--spring.datasource.url="jdbc:postgresql://${PG_HOST}:${PG_PORT}/${PG_DB}" \
--spring.datasource.username="$PG_USER" \
--spring.datasource.password="$PG_PASSWORD" \
$rabbit_args \
--hawkbit.server.ddi.security.authentication.anonymous.enabled=true \
--hawkbit.server.ui.demo.user=admin \
--hawkbit.server.ui.demo.password=admin \
>> "$LOG_DIR/hawkbit-monolith.log" 2>&1 &
echo $! > "$PID_DIR/hawkbit-monolith.pid"
wait_for_port localhost $MONOLITH_PORT 60 "hawkbit-monolith"
start_ui
}
# ── 启动 UI ──────────────────────────────────────────────────────────────────
start_ui() {
if [ -f "$PID_DIR/hawkbit-ui.pid" ] && kill -0 "$(cat "$PID_DIR/hawkbit-ui.pid")" 2>/dev/null; then
warn "hawkbit-ui 已在运行"
else
info "启动 hawkbit-ui (端口 $UI_PORT)..."
nohup java \
-Xms${UI_XMS} -Xmx${UI_XMX} \
-jar "$UI_JAR" \
--server.port=$UI_PORT \
--hawkbit.server.mgmturl="http://127.0.0.1:${MONOLITH_PORT}" \
>> "$LOG_DIR/hawkbit-ui.log" 2>&1 &
echo $! > "$PID_DIR/hawkbit-ui.pid"
fi
wait_for_port localhost $UI_PORT 30 "hawkbit-ui"
step "启动完成"
echo ""
echo " ┌─────────────────────────────────────────────────────┐"
echo " │ Hawkbit Management API : http://localhost:${MONOLITH_PORT}/rest/v1 │"
echo " │ Hawkbit DDI API : http://localhost:${MONOLITH_PORT}/DEFAULT/controller/v1 │"
echo " │ Hawkbit UI : http://localhost:${UI_PORT}"
echo " │ Admin 账号 : admin / admin │"
echo " ├─────────────────────────────────────────────────────┤"
echo " │ 日志目录 : $LOG_DIR"
echo " │ PID 目录 : $PID_DIR"
echo " │ 停止 : $0 stop"
echo " │ 状态 : $0 status"
echo " └─────────────────────────────────────────────────────┘"
}
# ── 仅 DB 初始化 ─────────────────────────────────────────────────────────────
do_dbinit() {
step "数据库初始化"
if ! pg_isready -h $PG_HOST -p $PG_PORT &>/dev/null; then
error "PostgreSQL 未运行"
exit 1
fi
if [ ! -f "$DBINIT_JAR" ]; then
error "DB Init JAR 未找到: $DBINIT_JAR"
exit 1
fi
java \
-Xms256m -Xmx512m \
-classpath "$DBINIT_JAR" \
-Dspring.datasource.url="jdbc:postgresql://${PG_HOST}:${PG_PORT}/${PG_DB}" \
-Dspring.datasource.username="$PG_USER" \
-Dspring.datasource.password="$PG_PASSWORD" \
org.eclipse.hawkbit.repository.jpa.init.HawkbitFlywayDbInit \
migrate
info "DB 初始化完成"
}
# ── 帮助 ─────────────────────────────────────────────────────────────────────
do_help() {
cat << 'EOF'
╔══════════════════════════════════════════════════════════════════╗
║ Hawkbit Monolith + UI 本地启动脚本 ║
╚══════════════════════════════════════════════════════════════════╝
用法: start-hawkbit.sh <command>
命令:
h2 H2 内嵌数据库模式(零依赖,开发测试推荐)
postgres PostgreSQL 模式(需先: sudo apt install postgresql-16 rabbitmq-server
stop 停止所有服务
status 查看服务状态
dbinit 仅执行 DB 初始化postgres 模式)
help 显示此帮助
示例:
./start-hawkbit.sh h2 # 快速启动,用 H2 数据库
./start-hawkbit.sh postgres # 生产模式,用 PostgreSQL
./start-hawkbit.sh stop # 停止
./start-hawkbit.sh status # 查看
对应 Docker Compose:
h2 ≈ docker-compose-monolith-with-ui-postgres.yml (但用 H2)
postgres ≈ docker-compose-monolith-dbinit-with-ui-postgres.yml
区别:
H2 PostgreSQL
DB 文件存储 独立服务
安装 零依赖 sudo apt install postgresql-16
数据路径 h2data/ PostgreSQL pgdata/
适用场景 开发/测试 生产模拟
数据持久化 是 是
H2 模式启动后:
MGMT API: http://localhost:9090/rest/v1
DDI API: http://localhost:9090/DEFAULT/controller/v1
UI: http://localhost:9091
Admin: admin / admin
EOF
}
# ═══════════════════════════════════════════════════════════════════════════════
# Main
# ═══════════════════════════════════════════════════════════════════════════════
init
case "${1:-help}" in
h2)
start_h2
;;
postgres)
start_postgres
;;
stop)
do_stop
;;
status)
do_status
;;
dbinit)
do_dbinit
;;
help|--help|-h)
do_help
;;
*)
error "未知命令: $1"
do_help
exit 1
;;
esac