Files
ljwx-harbor/brew/brew-manager.sh
T
bruno 435834dc79 feat: Harbor 版本化配置
- 添加 Harbor 快速恢复脚本 (harbor-quick-restore.sh)
- 添加完整恢复指南 (HARBOR-RESTORE-GUIDE.md)
- 添加版本信息文件 (VERSION.md)
- 更新 .gitignore 排除敏感数据
- 配置 harbor git remote
- 修复 Cloudflare Tunnel 配置

系统重装后可通过以下命令快速恢复:
git clone http://192.168.1.83:33000/gao/ljwx-harbor.git
cd ljwx-harbor
./harbor-quick-restore.sh
2026-02-27 08:12:30 +08:00

352 lines
8.5 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# Homebrew 自动化管理脚本
# 用途:管理 Homebrew 自动更新和备份服务
PLIST_NAME="com.ljwx.brew.maintenance.plist"
PLIST_PATH="${HOME}/Library/LaunchAgents/${PLIST_NAME}"
BREW_DIR="${HOME}/ops/brew"
LOG_DIR="${HOME}/ops/logs"
BACKUP_DIR="${HOME}/ops/backups"
# 颜色输出
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m'
log_info() { echo -e "${GREEN}✓${NC} $1"; }
log_warn() { echo -e "${YELLOW}⚠${NC} $1"; }
log_error() { echo -e "${RED}✗${NC} $1"; }
log_section() { echo -e "${BLUE}━━━${NC} $1"; }
# 启动服务
start() {
log_section "启动 Homebrew 自动维护服务"
if [ ! -f "$PLIST_PATH" ]; then
log_error "配置文件不存在: ${PLIST_PATH}"
echo "请先运行: $(dirname "$0")/setup-auto-update.sh"
exit 1
fi
if launchctl load -w "$PLIST_PATH" 2>/dev/null; then
log_info "服务已启动"
status
else
log_warn "服务可能已在运行"
status
fi
}
# 停止服务
stop() {
log_section "停止 Homebrew 自动维护服务"
if launchctl unload "$PLIST_PATH" 2>/dev/null; then
log_info "服务已停止"
else
log_warn "服务可能未运行"
fi
}
# 重启服务
restart() {
log_section "重启 Homebrew 自动维护服务"
stop
sleep 1
start
}
# 查看状态
status() {
log_section "服务状态"
# 检查 launchd 服务
if launchctl list | grep -q "${PLIST_NAME%.plist}"; then
log_info "服务状态: 运行中"
# 显示服务详情
SERVICE_INFO=$(launchctl list | grep "${PLIST_NAME%.plist}")
echo " ${SERVICE_INFO}"
else
log_warn "服务状态: 未运行"
fi
# 检查配置文件
if [ -f "$PLIST_PATH" ]; then
log_info "配置文件: 存在"
# 显示执行时间(使用 plutil 更可靠)
HOUR=$(plutil -extract StartCalendarInterval.Hour raw "$PLIST_PATH" 2>/dev/null || echo "N/A")
MINUTE=$(plutil -extract StartCalendarInterval.Minute raw "$PLIST_PATH" 2>/dev/null || echo "N/A")
if [ "$HOUR" != "N/A" ] && [ "$MINUTE" != "N/A" ]; then
echo " 执行时间: 每天 ${HOUR}:$(printf '%02d' ${MINUTE})"
else
echo " 执行时间: 未配置"
fi
else
log_warn "配置文件: 不存在"
fi
# 检查脚本
echo
log_section "维护脚本"
for script in brew_maintain.sh brew_backup.sh brew_restore.sh; do
if [ -x "${BREW_DIR}/${script}" ]; then
log_info "${script} (可执行)"
elif [ -f "${BREW_DIR}/${script}" ]; then
log_warn "${script} (不可执行)"
else
log_error "${script} (不存在)"
fi
done
# 显示最新日志
echo
log_section "最新日志"
LATEST_LOG="${LOG_DIR}/brew_maintain_$(date +%F).log"
if [ -f "$LATEST_LOG" ]; then
log_info "今日日志: ${LATEST_LOG}"
echo " 最后10行:"
tail -n 10 "$LATEST_LOG" | sed 's/^/ /'
else
log_warn "今日无日志"
# 查找最近的日志
RECENT_LOG=$(find "$LOG_DIR" -name "brew_maintain_*.log" -type f -print0 2>/dev/null | xargs -0 ls -t 2>/dev/null | head -n1)
if [ -n "$RECENT_LOG" ]; then
log_info "最近日志: ${RECENT_LOG}"
echo " 最后10行:"
tail -n 10 "$RECENT_LOG" | sed 's/^/ /'
fi
fi
# 显示备份信息
echo
log_section "备份信息"
if [ -f "${BACKUP_DIR}/Brewfile.latest" ]; then
LATEST_BACKUP=$(ls -lh "${BACKUP_DIR}/Brewfile.latest" 2>/dev/null)
log_info "最新快照: ${LATEST_BACKUP}"
BACKUP_COUNT=$(find "$BACKUP_DIR" -name "Brewfile_*.brew" -type f 2>/dev/null | wc -l | tr -d ' ')
log_info "历史备份: ${BACKUP_COUNT} 个"
else
log_warn "无备份文件"
fi
}
# 查看日志
logs() {
log_section "查看日志"
# 实时日志
if [ "${1:-}" = "-f" ] || [ "${1:-}" = "--follow" ]; then
LATEST_LOG="${LOG_DIR}/brew_maintain_$(date +%F).log"
log_info "实时监控: ${LATEST_LOG}"
touch "$LATEST_LOG"
tail -f "$LATEST_LOG"
else
# 显示最近的日志
RECENT_LOGS=$(find "$LOG_DIR" -name "brew_maintain_*.log" -type f -print0 2>/dev/null | xargs -0 ls -t 2>/dev/null | head -n 5)
if [ -n "$RECENT_LOGS" ]; then
log_info "最近5个日志文件:"
echo "$RECENT_LOGS" | nl -w2 -s'. '
echo
echo "查看完整日志: cat <日志文件>"
echo "实时监控日志: $0 logs -f"
else
log_warn "无日志文件"
fi
fi
}
# 立即运行维护
run() {
log_section "立即运行 Homebrew 维护"
if [ ! -x "${BREW_DIR}/brew_maintain.sh" ]; then
log_error "维护脚本不存在或不可执行: ${BREW_DIR}/brew_maintain.sh"
exit 1
fi
"${BREW_DIR}/brew_maintain.sh"
}
# 手动备份
backup() {
log_section "手动执行 Homebrew 备份"
if [ ! -x "${BREW_DIR}/brew_backup.sh" ]; then
log_error "备份脚本不存在或不可执行: ${BREW_DIR}/brew_backup.sh"
exit 1
fi
"${BREW_DIR}/brew_backup.sh"
}
# 列出备份
list_backups() {
log_section "备份文件列表"
echo
echo "Brewfile 备份:"
find "$BACKUP_DIR" -name "Brewfile_*.brew" -type f -exec ls -lh {} \; 2>/dev/null | sort -r | head -n 10
echo
echo "完整备份:"
find "$BACKUP_DIR" -name "brew_backup_*.tar.gz" -type f -exec ls -lh {} \; 2>/dev/null | sort -r | head -n 10
echo
echo "最新快照:"
ls -lh "${BACKUP_DIR}/Brewfile.latest" 2>/dev/null || echo " (无)"
}
# 统计信息
stats() {
log_section "查看统计信息"
if [ -x "${BREW_DIR}/brew-stats.sh" ]; then
"${BREW_DIR}/brew-stats.sh" summary
else
log_error "统计工具不可用"
fi
}
# 验证备份
verify() {
log_section "验证备份"
if [ -x "${BREW_DIR}/brew-verify.sh" ]; then
"${BREW_DIR}/brew-verify.sh" health
else
log_error "验证工具不可用"
fi
}
# 自动修复
fix() {
log_section "自动修复 Homebrew 问题"
if [ -x "${BREW_DIR}/brew-doctor-fix.sh" ]; then
"${BREW_DIR}/brew-doctor-fix.sh" --auto
else
log_error "修复工具不可用"
fi
}
# 显示帮助
show_help() {
cat << 'EOF'
Homebrew 自动化管理工具
用法: brew-manager.sh <命令>
命令:
start 启动自动维护服务
stop 停止自动维护服务
restart 重启自动维护服务
status 查看服务状态和最近日志
logs 查看日志文件列表
logs -f 实时监控今日日志
run 立即运行维护任务
backup 手动执行备份
list 列出所有备份文件
stats 查看统计信息
verify 验证备份和健康检查
fix 自动修复 Homebrew 问题
help 显示此帮助信息
示例:
# 启动自动维护服务
./brew-manager.sh start
# 查看服务状态
./brew-manager.sh status
# 实时查看日志
./brew-manager.sh logs -f
# 立即运行维护
./brew-manager.sh run
# 手动备份
./brew-manager.sh backup
# 查看统计信息
./brew-manager.sh stats
# 验证备份
./brew-manager.sh verify
# 自动修复问题
./brew-manager.sh fix
服务配置:
• 配置文件: ~/Library/LaunchAgents/com.ljwx.brew.maintenance.plist
• 脚本目录: ~/ops/brew
• 日志目录: ~/ops/logs
• 备份目录: ~/ops/backups
高级工具:
• brew-stats.sh - 统计和报告工具
• brew-verify.sh - 备份验证工具
• brew-notify.sh - 通知工具库
EOF
}
# 主函数
main() {
case "${1:-}" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
status
;;
logs)
logs "${2:-}"
;;
run)
run
;;
backup)
backup
;;
list)
list_backups
;;
stats)
stats
;;
verify)
verify
;;
fix)
fix
;;
help|--help|-h)
show_help
;;
*)
echo "错误: 未知命令 '${1:-}'"
echo
show_help
exit 1
;;
esac
}
main "$@"