Files
sanguo_vnpy/scripts/deployment/nas_auto_deploy.sh
T
2026-04-11 21:18:55 +08:00

335 lines
8.0 KiB
Bash
Executable File

#!/bin/bash
# ============================================
# NAS 全自动部署脚本
# 作者:姜维 伯约
# 日期:2026年3月27日
# ============================================
set -e
# 配置信息
NAS_IP="192.168.2.154"
NAS_USER="cfdaily"
NAS_PASS="Ccf7561523"
NAS_SHARE="stock"
MOUNT_POINT="/Users/chufeng/nas/stock"
LAUNCH_DAEMON_LABEL="com.user.nasmount"
LAUNCH_DAEMON_PATH="/Library/LaunchDaemons/${LAUNCH_DAEMON_LABEL}.plist"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查是否以 root 权限运行
check_root() {
if [ "$EUID" -ne 0 ]; then
log_error "请使用 sudo 运行此脚本"
echo "使用方法: sudo $0"
exit 1
fi
}
# 检查网络连接
check_network() {
log_info "检查网络连接..."
for i in {1..30}; do
if ping -c 1 -W 2 "$NAS_IP" &> /dev/null; then
log_info "网络连接正常: $NAS_IP"
return 0
fi
log_warn "等待网络连接... ($i/30)"
sleep 2
done
log_error "无法连接到 NAS: $NAS_IP"
return 1
}
# 创建挂载点
create_mount_point() {
log_info "创建挂载点..."
mkdir -p "$MOUNT_POINT"
chown chufeng:staff "$MOUNT_POINT"
chmod 755 "$MOUNT_POINT"
log_info "挂载点已创建: $MOUNT_POINT"
}
# 测试挂载
test_mount() {
log_info "测试挂载 NAS..."
# 先卸载(如果已挂载)
if mount | grep -q "$MOUNT_POINT"; then
log_warn "卸载已挂载的卷..."
umount -f "$MOUNT_POINT" 2>/dev/null || true
sleep 2
fi
# 尝试挂载
NAS_URL="smb://${NAS_USER}:${NAS_PASS}@${NAS_IP}/${NAS_SHARE}"
if /sbin/mount_smbfs "$NAS_URL" "$MOUNT_POINT"; then
log_info "NAS 挂载测试成功!"
sleep 2
umount "$MOUNT_POINT"
log_info "测试完成,已卸载"
return 0
else
log_error "NAS 挂载测试失败"
return 1
fi
}
# 创建 Launch Daemon plist 文件
create_launch_daemon() {
log_info "创建 Launch Daemon..."
cat > "$LAUNCH_DAEMON_PATH" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>${LAUNCH_DAEMON_LABEL}</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>/Users/chufeng/.openclaw/workspace-jiangwei/nas_mounter.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StartInterval</key>
<integer>60</integer>
<key>KeepAlive</key>
<dict>
<key>PathState</key>
<dict>
<key>${MOUNT_POINT}/.mounted</key>
<false/>
</dict>
</dict>
<key>StandardOutPath</key>
<string>/Users/chufeng/.openclaw/workspace-jiangwei/logs/nas_mount.log</string>
<key>StandardErrorPath</key>
<string>/Users/chufeng/.openclaw/workspace-jiangwei/logs/nas_mount_error.log</string>
</dict>
</plist>
EOF
# 设置权限
chown root:wheel "$LAUNCH_DAEMON_PATH"
chmod 644 "$LAUNCH_DAEMON_PATH"
log_info "Launch Daemon 已创建: $LAUNCH_DAEMON_PATH"
}
# 创建挂载脚本
create_mounter_script() {
log_info "创建挂载脚本..."
cat > "/Users/chufeng/.openclaw/workspace-jiangwei/nas_mounter.sh" <<'EOF'
#!/bin/bash
# NAS 自动挂载守护脚本
# 由 Launch Daemon 调用
NAS_IP="192.168.2.154"
NAS_USER="cfdaily"
NAS_PASS="Ccf7561523"
NAS_SHARE="stock"
MOUNT_POINT="/Users/chufeng/nas/stock"
MOUNT_MARKER="${MOUNT_POINT}/.mounted"
LOG_FILE="/Users/chufeng/.openclaw/workspace-jiangwei/logs/nas_mount.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
# 检查是否已挂载
check_mounted() {
if mount | grep -q "$MOUNT_POINT"; then
# 更新挂载标记
touch "$MOUNT_MARKER" 2>/dev/null || true
return 0
fi
return 1
}
# 检查网络
check_network() {
ping -c 1 -W 2 "$NAS_IP" &> /dev/null
}
# 执行挂载
do_mount() {
log "开始挂载 NAS..."
# 创建挂载点
mkdir -p "$MOUNT_POINT"
# 尝试挂载
NAS_URL="smb://${NAS_USER}:${NAS_PASS}@${NAS_IP}/${NAS_SHARE}"
if /sbin/mount_smbfs "$NAS_URL" "$MOUNT_POINT"; then
log "NAS 挂载成功: $MOUNT_POINT"
# 创建挂载标记
touch "$MOUNT_MARKER"
chown chufeng:staff "$MOUNT_MARKER" 2>/dev/null || true
# 创建目录结构
create_dir_structure
return 0
else
log "NAS 挂载失败"
return 1
fi
}
# 创建目录结构
create_dir_structure() {
log "创建目录结构..."
cd "$MOUNT_POINT" || return
mkdir -p "A股数据/日线数据" "A股数据/分钟线数据" "A股数据/财务数据"
mkdir -p "回测结果/策略回测" "回测结果/性能报告"
mkdir -p "代码库/策略代码" "代码库/工具脚本"
mkdir -p "临时文件/下载缓存" "临时文件/临时数据"
# 设置权限
chown -R chufeng:staff "$MOUNT_POINT" 2>/dev/null || true
log "目录结构创建完成"
}
# 主逻辑
main() {
# 确保日志目录存在
mkdir -p "$(dirname "$LOG_FILE")"
if check_mounted; then
log "NAS 已挂载,无需操作"
return 0
fi
if ! check_network; then
log "网络不可用,等待下次检查"
return 1
fi
do_mount
}
main
EOF
chmod +x "/Users/chufeng/.openclaw/workspace-jiangwei/nas_mounter.sh"
chown chufeng:staff "/Users/chufeng/.openclaw/workspace-jiangwei/nas_mounter.sh"
log_info "挂载脚本已创建"
}
# 创建 SMB 优化配置
create_smb_config() {
log_info "优化 SMB 配置..."
SMB_CONF="/etc/nsmb.conf"
if [ -f "$SMB_CONF" ]; then
log_warn "SMB 配置文件已存在,备份为 ${SMB_CONF}.backup"
cp "$SMB_CONF" "${SMB_CONF}.backup"
fi
cat > "$SMB_CONF" <<EOF
[default]
signing_required=no
protocol_vers_map=6
dir_cache_max_cnt=65536
dir_cache_max=10485760
file_ids_off=yes
mc_on=no
soft=yes
timeout=30
EOF
log_info "SMB 优化配置已完成"
}
# 卸载旧的 Launch Daemon(如果存在)
unload_old_daemon() {
if [ -f "$LAUNCH_DAEMON_PATH" ]; then
log_info "卸载旧的 Launch Daemon..."
launchctl unload "$LAUNCH_DAEMON_PATH" 2>/dev/null || true
sleep 2
fi
}
# 加载 Launch Daemon
load_launch_daemon() {
log_info "加载 Launch Daemon..."
launchctl load -w "$LAUNCH_DAEMON_PATH"
log_info "Launch Daemon 已加载"
}
# 验证部署
verify_deployment() {
log_info "验证部署..."
# 等待几秒让脚本执行
sleep 10
# 检查挂载状态
if mount | grep -q "$MOUNT_POINT"; then
log_info "✅ NAS 已成功挂载!"
ls -la "$MOUNT_POINT"
else
log_warn "⚠️ NAS 尚未挂载,Launch Daemon 将在后台重试"
log_info "查看日志: tail -f /Users/chufeng/.openclaw/workspace-jiangwei/logs/nas_mount.log"
fi
echo ""
log_info "部署完成!"
log_info "Launch Daemon 将每分钟检查一次挂载状态"
}
# 主函数
main() {
echo "============================================"
echo " NAS 全自动部署脚本"
echo "============================================"
echo ""
check_root
check_network
create_mount_point
test_mount
unload_old_daemon
create_mounter_script
create_launch_daemon
create_smb_config
load_launch_daemon
verify_deployment
echo ""
log_info "🎉 全自动部署完成!"
log_info "📝 常用命令:"
log_info " 查看日志: tail -f /Users/chufeng/.openclaw/workspace-jiangwei/logs/nas_mount.log"
log_info " 查看挂载: ls -la /Users/chufeng/nas/stock"
log_info " 重启守护: sudo launchctl stop ${LAUNCH_DAEMON_LABEL} && sudo launchctl start ${LAUNCH_DAEMON_LABEL}"
}
main