Files
linkmaster-node/start-systemd.sh
2025-12-03 21:57:18 +08:00

145 lines
4.4 KiB
Bash
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
# ============================================
# LinkMaster 节点端 systemd 启动脚本
# 用于 systemd 服务,直接运行二进制文件
# ============================================
set -e
# 脚本目录
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
# 配置
BINARY_NAME="agent"
BACKEND_URL="${BACKEND_URL:-http://localhost:8080}"
# 检查二进制文件是否存在且有效
check_binary() {
if [ -f "$BINARY_NAME" ] && [ -x "$BINARY_NAME" ] && [ -s "$BINARY_NAME" ]; then
# 验证二进制文件类型Linux 应该是 ELF 文件)
if command -v file > /dev/null 2>&1; then
local file_type=$(file "$BINARY_NAME" 2>/dev/null || echo "")
if [ -n "$file_type" ] && echo "$file_type" | grep -qi "ELF"; then
return 0
fi
else
# 如果没有 file 命令,至少检查文件大小(应该大于 1MB
local file_size=$(stat -c%s "$BINARY_NAME" 2>/dev/null || stat -f%z "$BINARY_NAME" 2>/dev/null || echo "0")
if [ "$file_size" -gt 1048576 ]; then
return 0
fi
fi
fi
return 1
}
# 拉取最新源码并编译
update_and_build() {
# 如果二进制文件已存在且有效,跳过编译
if check_binary; then
echo "二进制文件已存在,跳过编译步骤"
return 0
fi
# 检查是否在 Git 仓库中
if [ ! -d ".git" ]; then
echo "错误: 不在 Git 仓库中,无法更新代码" >&2
return 1
fi
# 配置 Git safe.directory解决所有权问题
CURRENT_DIR=$(pwd)
git config --global --add safe.directory "$CURRENT_DIR" 2>/dev/null || true
# 拉取最新代码
if git pull 2>&1 > /dev/null; then
echo "代码更新完成"
fi
# 确保 Go 在 PATH 中systemd 可能没有设置 PATH
if [ -d "/usr/local/go/bin" ] && ! echo "$PATH" | grep -q "/usr/local/go/bin"; then
export PATH="/usr/local/go/bin:$PATH"
fi
# 检查 Go 环境
if ! command -v go > /dev/null 2>&1; then
echo "错误: 未找到 Go 环境,无法编译" >&2
echo "PATH: $PATH" >&2
echo "请确保 Go 已安装: /usr/local/go/bin 或系统 PATH 中包含 go 命令" >&2
exit 1
fi
# 检查是否有 vendor 目录
local use_vendor=false
if [ -d "./vendor" ] && [ -f "./vendor/modules.txt" ]; then
use_vendor=true
echo "使用 vendor 目录编译(无需网络连接)"
fi
# 更新依赖(仅在非 vendor 模式下,并设置超时避免卡住)
if [ "$use_vendor" != "true" ]; then
echo "更新 Go 依赖..."
# 使用 timeout 命令设置超时30秒如果系统没有 timeout 命令则直接执行
if command -v timeout > /dev/null 2>&1; then
timeout 30 go mod download 2>&1 > /dev/null || {
echo "警告: 依赖更新失败或超时,尝试继续编译" >&2
}
else
# 如果没有 timeout 命令,直接执行(可能卡住,但至少能工作)
go mod download 2>&1 > /dev/null || {
echo "警告: 依赖更新失败,尝试继续编译" >&2
}
fi
fi
# 编译
ARCH=$(uname -m)
case $ARCH in
x86_64)
ARCH="amd64"
;;
aarch64|arm64)
ARCH="arm64"
;;
*)
ARCH="amd64"
;;
esac
# 构建编译命令
local build_cmd="GOOS=linux GOARCH=${ARCH} CGO_ENABLED=0 go build -buildvcs=false -ldflags=\"-w -s\""
if [ "$use_vendor" = "true" ]; then
build_cmd="$build_cmd -mod=vendor"
fi
build_cmd="$build_cmd -o \"$BINARY_NAME\" ./cmd/agent"
echo "开始编译(架构: ${ARCH}..."
if eval "$build_cmd" 2>&1; then
if [ -f "$BINARY_NAME" ] && [ -s "$BINARY_NAME" ]; then
chmod +x "$BINARY_NAME"
echo "编译成功"
return 0
else
echo "错误: 编译失败,未生成二进制文件" >&2
return 1
fi
else
echo "错误: 编译失败" >&2
return 1
fi
}
# 检查并更新/编译
if ! check_binary; then
update_and_build
fi
# 设置环境变量
export BACKEND_URL="$BACKEND_URL"
# 直接运行二进制文件systemd 会管理进程)
exec ./"$BINARY_NAME"