修复Action history 为空的问题
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
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
This commit is contained in:
407
hawkbit-compose/start-hawkbit.sh
Executable file
407
hawkbit-compose/start-hawkbit.sh
Executable file
@@ -0,0 +1,407 @@
|
||||
#!/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
|
||||
Reference in New Issue
Block a user