mirror of
https://github.com/Sagit-chu/flvx.git
synced 2026-10-06 01:56:37 +08:00
2.0版本测试
This commit is contained in:
+5
-774
@@ -8,16 +8,14 @@ export LC_ALL=C
|
||||
|
||||
|
||||
# 全局下载地址配置
|
||||
DOCKER_COMPOSEV4_URL="https://github.com/bqlpfy/flux-panel/releases/download/1.4.2/docker-compose-v4.yml"
|
||||
DOCKER_COMPOSEV6_URL="https://github.com/bqlpfy/flux-panel/releases/download/1.4.2/docker-compose-v6.yml"
|
||||
GOST_SQL_URL="https://github.com/bqlpfy/flux-panel/releases/download/1.4.2/gost.sql"
|
||||
DOCKER_COMPOSEV4_URL="https://github.com/bqlpfy/flux-panel/releases/download/2.0.0-beta/docker-compose-v4.yml"
|
||||
DOCKER_COMPOSEV6_URL="https://github.com/bqlpfy/flux-panel/releases/download/2.0.0-beta/docker-compose-v6.yml"
|
||||
|
||||
COUNTRY=$(curl -s https://ipinfo.io/country)
|
||||
if [ "$COUNTRY" = "CN" ]; then
|
||||
# 拼接 URL
|
||||
DOCKER_COMPOSEV4_URL="https://ghfast.top/${DOCKER_COMPOSEV4_URL}"
|
||||
DOCKER_COMPOSEV6_URL="https://ghfast.top/${DOCKER_COMPOSEV6_URL}"
|
||||
GOST_SQL_URL="https://ghfast.top/${GOST_SQL_URL}"
|
||||
fi
|
||||
|
||||
|
||||
@@ -149,8 +147,7 @@ show_menu() {
|
||||
echo "1. 安装面板"
|
||||
echo "2. 更新面板"
|
||||
echo "3. 卸载面板"
|
||||
echo "4. 导出备份"
|
||||
echo "5. 退出"
|
||||
echo "4. 退出"
|
||||
echo "==============================================="
|
||||
}
|
||||
|
||||
@@ -173,17 +170,13 @@ delete_self() {
|
||||
get_config_params() {
|
||||
echo "🔧 请输入配置参数:"
|
||||
|
||||
|
||||
|
||||
read -p "前端端口(默认 6366): " FRONTEND_PORT
|
||||
FRONTEND_PORT=${FRONTEND_PORT:-6366}
|
||||
|
||||
read -p "后端端口(默认 6365): " BACKEND_PORT
|
||||
BACKEND_PORT=${BACKEND_PORT:-6365}
|
||||
|
||||
DB_NAME=$(generate_random)
|
||||
DB_USER=$(generate_random)
|
||||
DB_PASSWORD=$(generate_random)
|
||||
# 生成JWT密钥
|
||||
JWT_SECRET=$(generate_random)
|
||||
}
|
||||
|
||||
@@ -197,14 +190,6 @@ install_panel() {
|
||||
DOCKER_COMPOSE_URL=$(get_docker_compose_url)
|
||||
echo "📡 选择配置文件:$(basename "$DOCKER_COMPOSE_URL")"
|
||||
curl -L -o docker-compose.yml "$DOCKER_COMPOSE_URL"
|
||||
|
||||
# 检查 gost.sql 是否已存在
|
||||
if [[ -f "gost.sql" ]]; then
|
||||
echo "⏭️ 跳过下载: gost.sql (使用当前位置的文件)"
|
||||
else
|
||||
echo "📡 下载数据库初始化文件..."
|
||||
curl -L -o gost.sql "$GOST_SQL_URL"
|
||||
fi
|
||||
echo "✅ 文件准备完成"
|
||||
|
||||
# 自动检测并配置 IPv6 支持
|
||||
@@ -214,9 +199,6 @@ install_panel() {
|
||||
fi
|
||||
|
||||
cat > .env <<EOF
|
||||
DB_NAME=$DB_NAME
|
||||
DB_USER=$DB_USER
|
||||
DB_PASSWORD=$DB_PASSWORD
|
||||
JWT_SECRET=$JWT_SECRET
|
||||
FRONTEND_PORT=$FRONTEND_PORT
|
||||
BACKEND_PORT=$BACKEND_PORT
|
||||
@@ -295,755 +277,9 @@ update_panel() {
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# 检查数据库容器健康状态
|
||||
echo "🔍 检查数据库服务状态..."
|
||||
for i in {1..60}; do
|
||||
if docker ps --format "{{.Names}}" | grep -q "^gost-mysql$"; then
|
||||
DB_HEALTH=$(docker inspect -f '{{.State.Health.Status}}' gost-mysql 2>/dev/null || echo "unknown")
|
||||
if [[ "$DB_HEALTH" == "healthy" ]]; then
|
||||
echo "✅ 数据库服务健康检查通过"
|
||||
break
|
||||
elif [[ "$DB_HEALTH" == "starting" ]]; then
|
||||
# 继续等待
|
||||
:
|
||||
elif [[ "$DB_HEALTH" == "unhealthy" ]]; then
|
||||
echo "⚠️ 数据库健康状态:$DB_HEALTH"
|
||||
fi
|
||||
else
|
||||
echo "⚠️ 数据库容器未找到或未运行"
|
||||
DB_HEALTH="not_running"
|
||||
fi
|
||||
if [ $i -eq 60 ]; then
|
||||
echo "❌ 数据库服务启动超时(60秒)"
|
||||
echo "🔍 当前状态:$(docker inspect -f '{{.State.Health.Status}}' gost-mysql 2>/dev/null || echo '容器不存在')"
|
||||
echo "🛑 更新终止"
|
||||
return 1
|
||||
fi
|
||||
# 每10秒显示一次进度
|
||||
if [ $((i % 10)) -eq 1 ]; then
|
||||
echo "⏳ 等待数据库服务启动... ($i/60) 状态:${DB_HEALTH:-unknown}"
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# 从容器环境变量获取数据库信息
|
||||
echo "🔍 获取数据库配置信息..."
|
||||
|
||||
# 等待一下让服务完全就绪
|
||||
echo "⏳ 等待服务完全就绪..."
|
||||
sleep 5
|
||||
|
||||
# 先检查后端容器是否在运行
|
||||
if ! docker ps --format "{{.Names}}" | grep -q "^springboot-backend$"; then
|
||||
echo "❌ 后端容器未运行,无法获取数据库配置"
|
||||
echo "🔍 当前运行的容器:"
|
||||
docker ps --format "table {{.Names}}\t{{.Status}}"
|
||||
echo "🛑 更新终止"
|
||||
return 1
|
||||
fi
|
||||
|
||||
DB_INFO=$(docker exec springboot-backend env | grep "^DB_" 2>/dev/null || echo "")
|
||||
|
||||
if [[ -n "$DB_INFO" ]]; then
|
||||
DB_NAME=$(echo "$DB_INFO" | grep "^DB_NAME=" | cut -d'=' -f2)
|
||||
DB_PASSWORD=$(echo "$DB_INFO" | grep "^DB_PASSWORD=" | cut -d'=' -f2)
|
||||
DB_USER=$(echo "$DB_INFO" | grep "^DB_USER=" | cut -d'=' -f2)
|
||||
DB_HOST=$(echo "$DB_INFO" | grep "^DB_HOST=" | cut -d'=' -f2)
|
||||
|
||||
echo "📋 数据库配置:"
|
||||
echo " 数据库名: $DB_NAME"
|
||||
echo " 用户名: $DB_USER"
|
||||
echo " 主机: $DB_HOST"
|
||||
else
|
||||
echo "❌ 无法获取数据库配置信息"
|
||||
echo "🔍 尝试诊断问题:"
|
||||
echo " 容器状态: $(docker inspect -f '{{.State.Status}}' springboot-backend 2>/dev/null || echo '容器不存在')"
|
||||
echo " 健康状态: $(docker inspect -f '{{.State.Health.Status}}' springboot-backend 2>/dev/null || echo '无健康检查')"
|
||||
|
||||
# 尝试从 .env 文件读取配置
|
||||
if [[ -f ".env" ]]; then
|
||||
echo "🔄 尝试从 .env 文件读取配置..."
|
||||
DB_NAME=$(grep "^DB_NAME=" .env | cut -d'=' -f2 2>/dev/null)
|
||||
DB_PASSWORD=$(grep "^DB_PASSWORD=" .env | cut -d'=' -f2 2>/dev/null)
|
||||
DB_USER=$(grep "^DB_USER=" .env | cut -d'=' -f2 2>/dev/null)
|
||||
|
||||
if [[ -n "$DB_NAME" && -n "$DB_PASSWORD" && -n "$DB_USER" ]]; then
|
||||
echo "✅ 从 .env 文件成功读取数据库配置"
|
||||
echo "📋 数据库配置:"
|
||||
echo " 数据库名: $DB_NAME"
|
||||
echo " 用户名: $DB_USER"
|
||||
else
|
||||
echo "❌ .env 文件中的数据库配置不完整"
|
||||
echo "🛑 更新终止"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
echo "❌ 未找到 .env 文件"
|
||||
echo "🛑 更新终止"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# 检查必要的数据库配置
|
||||
if [[ -z "$DB_PASSWORD" || -z "$DB_USER" || -z "$DB_NAME" ]]; then
|
||||
echo "❌ 数据库配置不完整(缺少必要参数)"
|
||||
echo "🛑 更新终止"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 执行数据库字段变更
|
||||
echo "🔄 执行数据库结构更新..."
|
||||
|
||||
# 创建临时迁移文件(现在有了数据库信息)
|
||||
cat > temp_migration.sql <<EOF
|
||||
-- 数据库结构更新
|
||||
USE \`$DB_NAME\`;
|
||||
|
||||
-- user 表:删除 name 字段(如果存在)
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'user'
|
||||
AND column_name = 'name'
|
||||
),
|
||||
'ALTER TABLE \`user\` DROP COLUMN \`name\`;',
|
||||
'SELECT "Column \`name\` not exists in \`user\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- node 表:删除 port 字段、添加 server_ip 字段(如果不存在)
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'node'
|
||||
AND column_name = 'port'
|
||||
),
|
||||
'ALTER TABLE \`node\` DROP COLUMN \`port\`;',
|
||||
'SELECT "Column \`port\` not exists in \`node\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'node'
|
||||
AND column_name = 'server_ip'
|
||||
),
|
||||
'ALTER TABLE \`node\` ADD COLUMN \`server_ip\` VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;',
|
||||
'SELECT "Column \`server_ip\` already exists in \`node\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- 将 ip 赋值给 server_ip(如果字段都存在)
|
||||
UPDATE \`node\`
|
||||
SET \`server_ip\` = \`ip\`
|
||||
WHERE \`server_ip\` IS NULL;
|
||||
|
||||
-- node 表:修改 ip 字段类型为 longtext
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'node'
|
||||
AND column_name = 'ip'
|
||||
AND data_type = 'varchar'
|
||||
),
|
||||
'ALTER TABLE \`node\` MODIFY COLUMN \`ip\` LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;',
|
||||
'SELECT "Column \`ip\` not exists or already modified in \`node\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- node 表:添加 version 字段(如果不存在)
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'node'
|
||||
AND column_name = 'version'
|
||||
),
|
||||
'ALTER TABLE \`node\` ADD COLUMN \`version\` VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL;',
|
||||
'SELECT "Column \`version\` already exists in \`node\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- node 表:添加 port_sta 字段(如果不存在)
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'node'
|
||||
AND column_name = 'port_sta'
|
||||
),
|
||||
'ALTER TABLE \`node\` ADD COLUMN \`port_sta\` INT(10) DEFAULT 1000 COMMENT "端口起始范围";',
|
||||
'SELECT "Column \`port_sta\` already exists in \`node\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- node 表:添加 port_end 字段(如果不存在)
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'node'
|
||||
AND column_name = 'port_end'
|
||||
),
|
||||
'ALTER TABLE \`node\` ADD COLUMN \`port_end\` INT(10) DEFAULT 65535 COMMENT "端口结束范围";',
|
||||
'SELECT "Column \`port_end\` already exists in \`node\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- 为现有节点设置默认端口范围
|
||||
UPDATE \`node\`
|
||||
SET \`port_sta\` = 1000, \`port_end\` = 65535
|
||||
WHERE \`port_sta\` IS NULL OR \`port_end\` IS NULL;
|
||||
|
||||
-- node 表:添加 http、tls、socks 字段(如果不存在)
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'node'
|
||||
AND column_name = 'http'
|
||||
),
|
||||
'ALTER TABLE \`node\` ADD COLUMN \`http\` INT(10) DEFAULT 0 COMMENT "HTTP 服务端口";',
|
||||
'SELECT "Column \`http\` already exists in \`node\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'node'
|
||||
AND column_name = 'tls'
|
||||
),
|
||||
'ALTER TABLE \`node\` ADD COLUMN \`tls\` INT(10) DEFAULT 0 COMMENT "TLS 服务端口";',
|
||||
'SELECT "Column \`tls\` already exists in \`node\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'node'
|
||||
AND column_name = 'socks'
|
||||
),
|
||||
'ALTER TABLE \`node\` ADD COLUMN \`socks\` INT(10) DEFAULT 0 COMMENT "SOCKS 服务端口";',
|
||||
'SELECT "Column \`socks\` already exists in \`node\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- 为现有节点设置 http、tls、socks 默认值
|
||||
UPDATE \`node\`
|
||||
SET \`http\` = IFNULL(\`http\`, 0),
|
||||
\`tls\` = IFNULL(\`tls\`, 0),
|
||||
\`socks\` = IFNULL(\`socks\`, 0);
|
||||
|
||||
-- tunnel 表:删除废弃字段(如果存在)
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'tunnel'
|
||||
AND column_name = 'in_port_sta'
|
||||
),
|
||||
'ALTER TABLE \`tunnel\` DROP COLUMN \`in_port_sta\`;',
|
||||
'SELECT "Column \`in_port_sta\` not exists in \`tunnel\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'tunnel'
|
||||
AND column_name = 'in_port_end'
|
||||
),
|
||||
'ALTER TABLE \`tunnel\` DROP COLUMN \`in_port_end\`;',
|
||||
'SELECT "Column \`in_port_end\` not exists in \`tunnel\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'tunnel'
|
||||
AND column_name = 'out_ip_sta'
|
||||
),
|
||||
'ALTER TABLE \`tunnel\` DROP COLUMN \`out_ip_sta\`;',
|
||||
'SELECT "Column \`out_ip_sta\` not exists in \`tunnel\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'tunnel'
|
||||
AND column_name = 'out_ip_end'
|
||||
),
|
||||
'ALTER TABLE \`tunnel\` DROP COLUMN \`out_ip_end\`;',
|
||||
'SELECT "Column \`out_ip_end\` not exists in \`tunnel\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- tunnel 表:添加 tcp_listen_addr、udp_listen_addr、protocol(如果不存在)
|
||||
|
||||
-- tcp_listen_addr
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'tunnel'
|
||||
AND column_name = 'tcp_listen_addr'
|
||||
),
|
||||
'ALTER TABLE \`tunnel\` ADD COLUMN \`tcp_listen_addr\` VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT "0.0.0.0";',
|
||||
'SELECT "Column \`tcp_listen_addr\` already exists in \`tunnel\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- udp_listen_addr
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'tunnel'
|
||||
AND column_name = 'udp_listen_addr'
|
||||
),
|
||||
'ALTER TABLE \`tunnel\` ADD COLUMN \`udp_listen_addr\` VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT "0.0.0.0";',
|
||||
'SELECT "Column \`udp_listen_addr\` already exists in \`tunnel\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- protocol
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'tunnel'
|
||||
AND column_name = 'protocol'
|
||||
),
|
||||
'ALTER TABLE \`tunnel\` ADD COLUMN \`protocol\` VARCHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT "tls";',
|
||||
'SELECT "Column \`protocol\` already exists in \`tunnel\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- traffic_ratio (流量倍率)
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'tunnel'
|
||||
AND column_name = 'traffic_ratio'
|
||||
),
|
||||
'ALTER TABLE \`tunnel\` ADD COLUMN \`traffic_ratio\` DECIMAL(5,1) DEFAULT 1.0 COMMENT "流量倍率";',
|
||||
'SELECT "Column \`traffic_ratio\` already exists in \`tunnel\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- 为现有数据设置默认流量倍率
|
||||
UPDATE \`tunnel\`
|
||||
SET \`traffic_ratio\` = 1.0
|
||||
WHERE \`traffic_ratio\` IS NULL;
|
||||
|
||||
-- forward 表:删除 proxy_protocol 字段(如果存在)
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'forward'
|
||||
AND column_name = 'proxy_protocol'
|
||||
),
|
||||
'ALTER TABLE \`forward\` DROP COLUMN \`proxy_protocol\`;',
|
||||
'SELECT "Column \`proxy_protocol\` not exists in \`forward\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- forward 表:修改 remote_addr 字段类型为 longtext
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'forward'
|
||||
AND column_name = 'remote_addr'
|
||||
AND data_type = 'varchar'
|
||||
),
|
||||
'ALTER TABLE \`forward\` MODIFY COLUMN \`remote_addr\` LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;',
|
||||
'SELECT "Column \`remote_addr\` not exists or already modified in \`forward\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- forward 表:添加 strategy 字段(负载均衡策略)
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'forward'
|
||||
AND column_name = 'strategy'
|
||||
),
|
||||
'ALTER TABLE \`forward\` ADD COLUMN \`strategy\` VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT "fifo" COMMENT "负载均衡策略";',
|
||||
'SELECT "Column \`strategy\` already exists in \`forward\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- 为现有数据设置默认负载均衡策略
|
||||
UPDATE \`forward\`
|
||||
SET \`strategy\` = 'fifo'
|
||||
WHERE \`strategy\` IS NULL;
|
||||
|
||||
-- forward 表:添加 inx 字段(排序索引)
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'forward'
|
||||
AND column_name = 'inx'
|
||||
),
|
||||
'ALTER TABLE \`forward\` ADD COLUMN \`inx\` INT(10) DEFAULT 0 COMMENT "排序索引";',
|
||||
'SELECT "Column \`inx\` already exists in \`forward\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- 为现有数据设置默认排序索引
|
||||
UPDATE \`forward\`
|
||||
SET \`inx\` = 0
|
||||
WHERE \`inx\` IS NULL;
|
||||
|
||||
-- tunnel 表:添加 interface_name 字段(如果不存在)
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'tunnel'
|
||||
AND column_name = 'interface_name'
|
||||
),
|
||||
'ALTER TABLE \`tunnel\` ADD COLUMN \`interface_name\` VARCHAR(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL;',
|
||||
'SELECT "Column \`interface_name\` already exists in \`tunnel\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- forward 表:添加 interface_name 字段(如果不存在)
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'forward'
|
||||
AND column_name = 'interface_name'
|
||||
),
|
||||
'ALTER TABLE \`forward\` ADD COLUMN \`interface_name\` VARCHAR(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL;',
|
||||
'SELECT "Column \`interface_name\` already exists in \`forward\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- 创建 vite_config 表(如果不存在)
|
||||
CREATE TABLE IF NOT EXISTS \`vite_config\` (
|
||||
\`id\` int(10) NOT NULL AUTO_INCREMENT,
|
||||
\`name\` varchar(200) NOT NULL,
|
||||
\`value\` varchar(200) NOT NULL,
|
||||
\`time\` bigint(20) NOT NULL,
|
||||
PRIMARY KEY (\`id\`),
|
||||
UNIQUE KEY \`unique_name\` (\`name\`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- 创建 statistics_flow 表(如果不存在)
|
||||
CREATE TABLE IF NOT EXISTS \`statistics_flow\` (
|
||||
\`id\` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
\`user_id\` int(10) NOT NULL,
|
||||
\`flow\` bigint(20) NOT NULL,
|
||||
\`total_flow\` bigint(20) NOT NULL,
|
||||
\`time\` varchar(100) NOT NULL,
|
||||
\`created_time\` bigint(20) NOT NULL,
|
||||
PRIMARY KEY (\`id\`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- statistics_flow 表:添加 created_time 字段(如果不存在)
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'statistics_flow'
|
||||
AND column_name = 'created_time'
|
||||
),
|
||||
'ALTER TABLE \`statistics_flow\` ADD COLUMN \`created_time\` BIGINT(20) NOT NULL DEFAULT 0 COMMENT "创建时间毫秒时间戳";',
|
||||
'SELECT "Column \`created_time\` already exists in \`statistics_flow\`";'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- 为现有记录设置当前毫秒时间戳(仅当 created_time 为 0 或 NULL 时)
|
||||
UPDATE \`statistics_flow\`
|
||||
SET \`created_time\` = UNIX_TIMESTAMP() * 1000
|
||||
WHERE \`created_time\` = 0 OR \`created_time\` IS NULL;
|
||||
|
||||
EOF
|
||||
|
||||
# 检查数据库容器
|
||||
if ! docker ps --format "{{.Names}}" | grep -q "^gost-mysql$"; then
|
||||
echo "❌ 数据库容器 gost-mysql 未运行"
|
||||
echo "🔍 当前运行的容器:"
|
||||
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"
|
||||
echo "❌ 数据库结构更新失败,请手动执行 temp_migration.sql"
|
||||
echo "📁 迁移文件已保存为 temp_migration.sql"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 执行数据库迁移
|
||||
if docker exec -i gost-mysql mysql -u "$DB_USER" -p"$DB_PASSWORD" < temp_migration.sql 2>/dev/null; then
|
||||
echo "✅ 数据库结构更新完成"
|
||||
else
|
||||
echo "⚠️ 使用用户密码失败,尝试root密码..."
|
||||
if docker exec -i gost-mysql mysql -u root -p"$DB_PASSWORD" < temp_migration.sql 2>/dev/null; then
|
||||
echo "✅ 数据库结构更新完成"
|
||||
else
|
||||
echo "❌ 数据库结构更新失败,请手动执行 temp_migration.sql"
|
||||
echo "📁 迁移文件已保存为 temp_migration.sql"
|
||||
echo "🔍 数据库容器状态: $(docker inspect -f '{{.State.Status}}' gost-mysql 2>/dev/null || echo '容器不存在')"
|
||||
echo "🛑 更新终止"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# 清理临时文件
|
||||
rm -f temp_migration.sql
|
||||
|
||||
echo "✅ 更新完成"
|
||||
}
|
||||
|
||||
# 导出数据库备份
|
||||
export_migration_sql() {
|
||||
echo "📄 开始导出数据库备份..."
|
||||
|
||||
# 获取数据库配置信息
|
||||
echo "🔍 获取数据库配置信息..."
|
||||
|
||||
# 先检查后端容器是否在运行
|
||||
if ! docker ps --format "{{.Names}}" | grep -q "^springboot-backend$"; then
|
||||
echo "❌ 后端容器未运行,尝试从 .env 文件读取配置..."
|
||||
|
||||
# 从 .env 文件读取配置
|
||||
if [[ -f ".env" ]]; then
|
||||
DB_NAME=$(grep "^DB_NAME=" .env | cut -d'=' -f2 2>/dev/null)
|
||||
DB_PASSWORD=$(grep "^DB_PASSWORD=" .env | cut -d'=' -f2 2>/dev/null)
|
||||
DB_USER=$(grep "^DB_USER=" .env | cut -d'=' -f2 2>/dev/null)
|
||||
|
||||
if [[ -n "$DB_NAME" && -n "$DB_PASSWORD" && -n "$DB_USER" ]]; then
|
||||
echo "✅ 从 .env 文件读取数据库配置成功"
|
||||
else
|
||||
echo "❌ .env 文件中的数据库配置不完整"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
echo "❌ 未找到 .env 文件"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
# 从容器环境变量获取数据库信息
|
||||
DB_INFO=$(docker exec springboot-backend env | grep "^DB_" 2>/dev/null || echo "")
|
||||
|
||||
if [[ -n "$DB_INFO" ]]; then
|
||||
DB_NAME=$(echo "$DB_INFO" | grep "^DB_NAME=" | cut -d'=' -f2)
|
||||
DB_PASSWORD=$(echo "$DB_INFO" | grep "^DB_PASSWORD=" | cut -d'=' -f2)
|
||||
DB_USER=$(echo "$DB_INFO" | grep "^DB_USER=" | cut -d'=' -f2)
|
||||
|
||||
echo "✅ 从容器环境变量读取数据库配置成功"
|
||||
else
|
||||
echo "❌ 无法从容器获取数据库配置,尝试从 .env 文件读取..."
|
||||
|
||||
if [[ -f ".env" ]]; then
|
||||
DB_NAME=$(grep "^DB_NAME=" .env | cut -d'=' -f2 2>/dev/null)
|
||||
DB_PASSWORD=$(grep "^DB_PASSWORD=" .env | cut -d'=' -f2 2>/dev/null)
|
||||
DB_USER=$(grep "^DB_USER=" .env | cut -d'=' -f2 2>/dev/null)
|
||||
|
||||
if [[ -n "$DB_NAME" && -n "$DB_PASSWORD" && -n "$DB_USER" ]]; then
|
||||
echo "✅ 从 .env 文件读取数据库配置成功"
|
||||
else
|
||||
echo "❌ .env 文件中的数据库配置不完整"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
echo "❌ 未找到 .env 文件"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# 检查必要的数据库配置
|
||||
if [[ -z "$DB_PASSWORD" || -z "$DB_USER" || -z "$DB_NAME" ]]; then
|
||||
echo "❌ 数据库配置不完整(缺少必要参数)"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "📋 数据库配置:"
|
||||
echo " 数据库名: $DB_NAME"
|
||||
echo " 用户名: $DB_USER"
|
||||
|
||||
# 检查数据库容器是否运行
|
||||
if ! docker ps --format "{{.Names}}" | grep -q "^gost-mysql$"; then
|
||||
echo "❌ 数据库容器未运行,无法导出数据"
|
||||
echo "🔍 当前运行的容器:"
|
||||
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 生成数据库备份文件
|
||||
SQL_FILE="database_backup_$(date +%Y%m%d_%H%M%S).sql"
|
||||
echo "📝 导出数据库备份: $SQL_FILE"
|
||||
|
||||
# 使用 mysqldump 导出数据库
|
||||
echo "⏳ 正在导出数据库..."
|
||||
if docker exec gost-mysql mysqldump -u "$DB_USER" -p"$DB_PASSWORD" --single-transaction --routines --triggers "$DB_NAME" > "$SQL_FILE" 2>/dev/null; then
|
||||
echo "✅ 数据库导出成功"
|
||||
else
|
||||
echo "⚠️ 使用用户密码失败,尝试root密码..."
|
||||
if docker exec gost-mysql mysqldump -u root -p"$DB_PASSWORD" --single-transaction --routines --triggers "$DB_NAME" > "$SQL_FILE" 2>/dev/null; then
|
||||
echo "✅ 数据库导出成功"
|
||||
else
|
||||
echo "❌ 数据库导出失败"
|
||||
rm -f "$SQL_FILE"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# 检查文件大小
|
||||
if [[ -f "$SQL_FILE" ]] && [[ -s "$SQL_FILE" ]]; then
|
||||
FILE_SIZE=$(du -h "$SQL_FILE" | cut -f1)
|
||||
echo "📁 文件位置: $(pwd)/$SQL_FILE"
|
||||
echo "📊 文件大小: $FILE_SIZE"
|
||||
else
|
||||
echo "❌ 导出的文件为空或不存在"
|
||||
rm -f "$SQL_FILE"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# 卸载功能
|
||||
@@ -1068,7 +304,7 @@ uninstall_panel() {
|
||||
echo "🛑 停止并删除容器、镜像、卷..."
|
||||
$DOCKER_CMD down --rmi all --volumes --remove-orphans
|
||||
echo "🧹 删除配置文件..."
|
||||
rm -f docker-compose.yml gost.sql .env
|
||||
rm -f docker-compose.yml .env
|
||||
echo "✅ 卸载完成"
|
||||
}
|
||||
|
||||
@@ -1097,11 +333,6 @@ main() {
|
||||
exit 0
|
||||
;;
|
||||
4)
|
||||
export_migration_sql
|
||||
delete_self
|
||||
exit 0
|
||||
;;
|
||||
5)
|
||||
echo "👋 退出脚本"
|
||||
delete_self
|
||||
exit 0
|
||||
|
||||
Reference in New Issue
Block a user