1
This commit is contained in:
@@ -149,7 +149,6 @@ func (s *ServerHandler) executeScript(scriptContent, scriptName string) (string,
|
||||
}
|
||||
}
|
||||
|
||||
// 执行完整的自动化部署流程
|
||||
func (s *ServerHandler) executeFullDeployment() error {
|
||||
s.sendTerminalOutput(s.session.WebSocket, "开始执行完整自动化部署流程...")
|
||||
|
||||
@@ -164,6 +163,9 @@ func (s *ServerHandler) executeFullDeployment() error {
|
||||
remoteExePath := fmt.Sprintf("%s/%s", defaultWorkDir, randomFileName)
|
||||
onlineID := fmt.Sprintf("%d", s.ServerList.OnlineID)
|
||||
|
||||
// 固定Screen会话名称为logic
|
||||
const fixedScreenSession = "logic"
|
||||
|
||||
// 创建完整的部署脚本(不包含#!/bin/bash)
|
||||
deploymentScript := fmt.Sprintf(`
|
||||
|
||||
@@ -188,7 +190,7 @@ else
|
||||
echo "检测到dnf,正在安装screen..."
|
||||
dnf install -y screen > /dev/null 2>&1
|
||||
elif command -v pacman &> /dev/null; then
|
||||
echo "检测到pacman,正在安装screen..."
|
||||
echo "=== 检测到pacman,正在安装screen ==="
|
||||
pacman -S --noconfirm screen > /dev/null 2>&1
|
||||
else
|
||||
echo "=== 不支持的系统包管理器,无法自动安装Screen ==="
|
||||
@@ -203,28 +205,50 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
# ===== 停止旧Screen会话 =====
|
||||
if [ -n "%s" ] && [ "%s" != "" ]; then
|
||||
echo "检查并停止旧会话: %s"
|
||||
if screen -ls | grep -q "%s"; then
|
||||
echo "发现旧会话,正在停止: %s"
|
||||
screen -S %s -X quit 2>/dev/null || true
|
||||
#pkill -f "%s" 2>/dev/null || true
|
||||
# 可选:等待几秒,确认会话是否退出(仅提示,不强制)
|
||||
sleep 5
|
||||
|
||||
# 检查会话是否仍存在(仅告知状态,不做强制操作)
|
||||
if screen -ls | grep -q "$SESSION_NAME"; then
|
||||
echo "⚠️ 警告:旧会话未退出(进程可能正在执行清理逻辑),未执行强制杀死,请手动确认"
|
||||
else
|
||||
echo "=== 旧会话优雅停止成功 ==="
|
||||
fi
|
||||
echo "=== 旧会话已停止 ==="
|
||||
else
|
||||
echo "=== 旧会话不存在,无需停止 ==="
|
||||
fi
|
||||
# ===== 核心逻辑:给logic会话发exit命令 + 循环等待Screen主进程退出 =====
|
||||
echo "开始处理固定名称[logic]的Screen会话..."
|
||||
SCREEN_PID=""
|
||||
# 1. 先查找logic会话是否存在并提取主PID
|
||||
if screen -ls "%s" | grep -q "%s"; then
|
||||
echo "找到[logic]会话,提取主PID..."
|
||||
SCREEN_PID=$(screen -ls "%s" | grep -oE '[0-9]+\.'"$1" | cut -d. -f1)
|
||||
|
||||
# 2. 给Screen会话发送exit命令(核心操作)
|
||||
echo "给[logic]会话发送exit命令,触发会话退出..."
|
||||
screen -x -S "%s" -p 0 -X stuff "exit\n" 2>/dev/null || true
|
||||
else
|
||||
echo "无旧Screen会话,跳过停止"
|
||||
echo "=== 未找到名称为[logic]的Screen会话,跳过终止 ==="
|
||||
fi
|
||||
|
||||
# 3. 循环等待Screen主进程退出(核心:等Screen本身退出)
|
||||
if [ -n "$SCREEN_PID" ] && [ "$SCREEN_PID" != "" ]; then
|
||||
echo "开始循环等待[logic]会话主PID[$SCREEN_PID]退出..."
|
||||
WAIT_COUNT=0
|
||||
MAX_WAIT_SECONDS=30 # 最大等待30秒,避免无限循环
|
||||
while ps -p "$SCREEN_PID" > /dev/null 2>&1; do
|
||||
sleep 0.5 # 每0.5秒检测一次Screen主进程状态
|
||||
WAIT_COUNT=$((WAIT_COUNT + 1))
|
||||
|
||||
# 每2秒输出一次等待状态(可选,方便排查)
|
||||
if [ $((WAIT_COUNT % 4)) -eq 0 ]; then
|
||||
echo "等待中...已等待$((WAIT_COUNT/2))秒(最大$MAX_WAIT_SECONDS秒)"
|
||||
fi
|
||||
|
||||
# 超过最大等待时间则退出循环,避免卡死
|
||||
if [ $WAIT_COUNT -ge $((MAX_WAIT_SECONDS * 2)) ]; then
|
||||
echo "⚠️ 等待超时($MAX_WAIT_SECONDS秒),[logic]会话主PID[$SCREEN_PID]仍未退出"
|
||||
# 兜底:超时后给Screen主进程发kill 15
|
||||
kill -15 "$SCREEN_PID" 2>/dev/null || true
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# 4. 检查Screen主进程最终状态
|
||||
if ps -p "$SCREEN_PID" > /dev/null 2>&1; then
|
||||
echo "❌ [logic]会话主PID[$SCREEN_PID]未退出,建议手动处理"
|
||||
else
|
||||
echo "✅ [logic]会话主PID[$SCREEN_PID]已成功退出"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ===== 下载程序 =====
|
||||
@@ -268,38 +292,36 @@ if [ $? -ne 0 ]; then
|
||||
fi
|
||||
echo "=== 权限设置完成 ==="
|
||||
|
||||
# 启动Screen会话
|
||||
echo "正在启动Screen会话: %s"
|
||||
screen -dmS "%s" bash -c '"%s" -id=%s | tee -a "$HOME/run.log"'
|
||||
# 启动新程序到固定名称[logic]的Screen会话(重建会话)
|
||||
echo "正在启动Screen会话: logic"
|
||||
screen -dmS "logic" bash -c '"%s" -id=%s | tee -a "$HOME/run.log"'
|
||||
|
||||
# 等待一段时间确保会话启动
|
||||
sleep 5
|
||||
# 等待2秒确保会话启动
|
||||
sleep 2
|
||||
|
||||
# 检查会话是否存在
|
||||
if screen -ls | grep -q "%s"; then
|
||||
echo "=== 程序启动成功:Screen会话已创建 ==="
|
||||
echo "=== 会话名称:%s ==="
|
||||
# 检查logic会话是否启动成功
|
||||
if screen -ls | grep -q "logic"; then
|
||||
echo "=== 程序启动成功:Screen会话[logic]已创建 ==="
|
||||
echo "=== 会话名称:logic ==="
|
||||
screen -ls
|
||||
echo "程序已在后台Screen会话中运行"
|
||||
echo "程序已在后台Screen会话[logic]中运行"
|
||||
else
|
||||
echo "=== 程序启动失败:Screen会话未创建 ==="
|
||||
echo "=== 程序启动失败:Screen会话[logic]未创建 ==="
|
||||
screen -ls
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "#SCRIPT_EXECUTION_COMPLETE#"
|
||||
`,
|
||||
s.ServerList.OldScreen, s.ServerList.OldScreen, s.ServerList.OldScreen,
|
||||
s.ServerList.OldScreen, s.ServerList.OldScreen, s.ServerList.OldScreen,
|
||||
s.ServerList.OldScreen,
|
||||
remoteExePath,
|
||||
remoteExePath, remoteExePath,
|
||||
remoteExePath, fileURL,
|
||||
remoteExePath, fileURL,
|
||||
remoteExePath, remoteExePath, remoteExePath,
|
||||
remoteExePath,
|
||||
randomFileName, randomFileName, remoteExePath, onlineID,
|
||||
randomFileName, randomFileName)
|
||||
fixedScreenSession, fixedScreenSession, fixedScreenSession, fixedScreenSession, // logic会话参数
|
||||
remoteExePath, // 下载路径
|
||||
remoteExePath, remoteExePath, // 删除旧文件
|
||||
remoteExePath, fileURL, // wget下载
|
||||
remoteExePath, fileURL, // curl下载
|
||||
remoteExePath, remoteExePath, remoteExePath, // 文件验证
|
||||
remoteExePath, // 执行权限
|
||||
remoteExePath, onlineID, // 启动logic会话,
|
||||
)
|
||||
|
||||
// 执行完整的部署脚本
|
||||
_, err := s.executeScript(deploymentScript, "full_deployment_"+grand.S(10))
|
||||
@@ -307,8 +329,8 @@ echo "#SCRIPT_EXECUTION_COMPLETE#"
|
||||
return err
|
||||
}
|
||||
|
||||
// 保存会话名称
|
||||
config.NewServerService().SetServerScreen(s.ServerList.OnlineID, randomFileName)
|
||||
// 保存固定的logic会话名称
|
||||
config.NewServerService().SetServerScreen(s.ServerList.OnlineID, fixedScreenSession)
|
||||
|
||||
s.sendTerminalOutput(s.session.WebSocket, "自动化部署完成")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user