diff --git a/install.sh b/install.sh index 2987b74..f15dfcf 100755 --- a/install.sh +++ b/install.sh @@ -8,6 +8,30 @@ set -e +# 错误处理函数 +error_handler() { + local line_number=$1 + local command=$2 + echo "" + echo -e "${RED}========================================${NC}" + echo -e "${RED} 脚本执行出错!${NC}" + echo -e "${RED}========================================${NC}" + echo -e "${YELLOW}错误位置: 第 ${line_number} 行${NC}" + echo -e "${YELLOW}失败命令: ${command}${NC}" + echo "" + echo -e "${YELLOW}故障排查建议:${NC}" + echo " 1. 检查网络连接是否正常" + echo " 2. 检查后端地址是否正确: ${BACKEND_URL:-未设置}" + echo " 3. 检查是否有足够的磁盘空间和权限" + echo " 4. 查看上面的详细错误信息" + echo "" + echo -e "${YELLOW}查看服务日志: sudo journalctl -u ${SERVICE_NAME:-linkmaster-node} -n 50${NC}" + exit 1 +} + +# 设置错误陷阱 +trap 'error_handler ${LINENO} "${BASH_COMMAND}"' ERR + # 颜色输出 RED='\033[0;31m' GREEN='\033[0;32m' @@ -1262,11 +1286,18 @@ EOF # 调用心跳API获取节点信息 echo -e "${BLUE}发送心跳请求获取节点信息...${NC}" - RESPONSE=$(curl -s -X POST "${BACKEND_URL}/api/node/heartbeat" \ + echo -e "${BLUE}后端地址: ${BACKEND_URL}${NC}" + + # 添加超时设置,避免长时间卡住 + # 使用 set +e 临时禁用错误退出,因为心跳失败不应该阻止安装 + set +e + RESPONSE=$(curl -s --connect-timeout 10 --max-time 30 -X POST "${BACKEND_URL}/api/node/heartbeat" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "type=pingServer" 2>&1) + CURL_EXIT_CODE=$? + set -e # 重新启用错误退出 - if [ $? -eq 0 ]; then + if [ $CURL_EXIT_CODE -eq 0 ]; then # 尝试解析JSON响应 NODE_ID=$(echo "$RESPONSE" | grep -o '"node_id":[0-9]*' | grep -o '[0-9]*' | head -1) NODE_IP=$(echo "$RESPONSE" | grep -o '"node_ip":"[^"]*"' | cut -d'"' -f4 | head -1) @@ -1304,8 +1335,10 @@ EOF echo -e "${YELLOW} 响应: ${RESPONSE}${NC}" fi else - echo -e "${YELLOW}⚠ 心跳请求失败,将在服务启动时重试${NC}" - echo -e "${YELLOW} 错误: ${RESPONSE}${NC}" + echo -e "${YELLOW}⚠ 心跳请求失败 (退出码: ${CURL_EXIT_CODE}),将在服务启动时重试${NC}" + echo -e "${YELLOW} 错误信息: ${RESPONSE}${NC}" + echo -e "${YELLOW} 提示: 请检查后端地址是否正确: ${BACKEND_URL}${NC}" + echo -e "${YELLOW} 测试连接: curl -v ${BACKEND_URL}/api/public/nodes/online${NC}" fi # 设置配置文件权限 @@ -1316,18 +1349,52 @@ EOF start_service() { echo -e "${BLUE}启动服务...${NC}" - sudo systemctl enable ${SERVICE_NAME} > /dev/null 2>&1 - sudo systemctl restart ${SERVICE_NAME} + # 先检查服务文件是否存在 + if [ ! -f "/etc/systemd/system/${SERVICE_NAME}.service" ]; then + echo -e "${RED}✗ 错误: 服务文件不存在${NC}" + echo -e "${YELLOW} 路径: /etc/systemd/system/${SERVICE_NAME}.service${NC}" + exit 1 + fi + + # 检查二进制文件是否存在 + if [ ! -f "$SOURCE_DIR/agent" ] && [ ! -f "$INSTALL_DIR/$BINARY_NAME" ]; then + echo -e "${RED}✗ 错误: 二进制文件不存在${NC}" + echo -e "${YELLOW} 检查路径: $SOURCE_DIR/agent 或 $INSTALL_DIR/$BINARY_NAME${NC}" + exit 1 + fi + + # 启用服务(显示输出以便调试) + echo -e "${BLUE}启用服务...${NC}" + if ! sudo systemctl enable ${SERVICE_NAME} 2>&1; then + echo -e "${RED}✗ 启用服务失败${NC}" + exit 1 + fi + + # 重新加载 systemd + echo -e "${BLUE}重新加载 systemd...${NC}" + sudo systemctl daemon-reload + + # 启动服务(显示输出以便调试) + echo -e "${BLUE}启动服务...${NC}" + if ! sudo systemctl restart ${SERVICE_NAME} 2>&1; then + echo -e "${RED}✗ 启动服务失败${NC}" + echo -e "${YELLOW}查看详细日志: sudo journalctl -u ${SERVICE_NAME} -n 100 --no-pager${NC}" + echo -e "${YELLOW}查看服务状态: sudo systemctl status ${SERVICE_NAME}${NC}" + exit 1 + fi # 等待服务启动 + echo -e "${BLUE}等待服务启动...${NC}" sleep 3 # 检查服务状态 - if sudo systemctl is-active --quiet ${SERVICE_NAME}; then + if sudo systemctl is-active --quiet ${SERVICE_NAME} 2>/dev/null; then echo -e "${GREEN}✓ 服务启动成功${NC}" else echo -e "${RED}✗ 服务启动失败${NC}" - echo -e "${YELLOW}查看日志: sudo journalctl -u ${SERVICE_NAME} -n 50${NC}" + echo -e "${YELLOW}服务状态:${NC}" + sudo systemctl status ${SERVICE_NAME} --no-pager -l || true + echo -e "${YELLOW}查看详细日志: sudo journalctl -u ${SERVICE_NAME} -n 100 --no-pager${NC}" exit 1 fi } @@ -1385,20 +1452,29 @@ main() { echo -e "${GREEN} LinkMaster 节点端安装程序${NC}" echo -e "${GREEN}========================================${NC}" echo "" + echo -e "${BLUE}后端地址: ${BACKEND_URL}${NC}" + echo "" + echo -e "${BLUE}[1/8] 检测系统类型...${NC}" detect_system # 检查是否已安装,如果已安装则先卸载 if check_installed; then + echo -e "${BLUE}[2/8] 卸载已存在的服务...${NC}" uninstall_service + else + echo -e "${BLUE}[2/8] 检查已安装服务...${NC}" + echo -e "${GREEN}✓ 未检测到已安装的服务${NC}" fi - # 检测并配置最快的镜像源(在安装依赖之前) + echo -e "${BLUE}[3/8] 检测并配置镜像源...${NC}" detect_fastest_mirror + echo -e "${BLUE}[4/8] 安装系统依赖...${NC}" install_dependencies # 优先尝试从 Releases 下载二进制文件 + echo -e "${BLUE}[5/8] 下载或编译二进制文件...${NC}" if ! download_binary_from_releases; then echo -e "${BLUE}从 Releases 下载失败,开始从源码编译...${NC}" build_from_source @@ -1406,10 +1482,19 @@ main() { echo -e "${GREEN}✓ 使用预编译二进制文件,跳过编译步骤${NC}" fi + echo -e "${BLUE}[6/8] 创建 systemd 服务...${NC}" create_service + + echo -e "${BLUE}[7/8] 配置防火墙规则...${NC}" configure_firewall + + echo -e "${BLUE}[8/8] 登记节点到后端服务器...${NC}" register_node + + echo -e "${BLUE}[9/9] 启动服务...${NC}" start_service + + echo -e "${BLUE}[10/10] 验证安装...${NC}" verify_installation echo ""