Files

278 lines
7.3 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.
#!/usr/bin/env bash
set -euo pipefail
# ============================================================================
# DevOps AI Stack - 清理脚本
# 功能:停止和清理所有服务,可选备份数据
# ============================================================================
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
LOG_FILE="${PROJECT_ROOT}/logs/cleanup-dev-$(date +%Y%m%d_%H%M%S).log"
# 创建日志目录
mkdir -p "${PROJECT_ROOT}/logs"
# ============================================================================
# 日志和颜色输出
# ============================================================================
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"
}
log_info() {
echo -e "\033[36ℹ️ INFO\033[0m: $*" | tee -a "$LOG_FILE"
}
log_success() {
echo -e "\033[32✅ SUCCESS\033[0m: $*" | tee -a "$LOG_FILE"
}
log_warning() {
echo -e "\033[33⚠️ WARNING\033[0m: $*" | tee -a "$LOG_FILE"
}
log_error() {
echo -e "\033[31❌ ERROR\033[0m: $*" | tee -a "$LOG_FILE"
}
# ============================================================================
# 备份数据卷
# ============================================================================
backup_volumes() {
log_info "备份关键数据卷..."
local backup_dir="${PROJECT_ROOT}/backups/$(date +%Y%m%d_%H%M%S)"
mkdir -p "$backup_dir"
local volumes=(
"gitea"
"registry"
"postgres"
"redis"
"minio"
"prometheus"
)
for volume in "${volumes[@]}"; do
if docker volume ls | grep -q "$volume"; then
log_info "备份数据卷: $volume"
docker run --rm \
-v "$volume:/source" \
-v "$backup_dir:/backup" \
alpine tar czf "/backup/${volume}.tar.gz" -C /source . || true
fi
done
log_success "数据卷备份完成: $backup_dir"
}
# ============================================================================
# 停止服务
# ============================================================================
stop_services() {
log_info "停止所有服务..."
local services=(
"taskflow"
"ai-visual"
"ai"
"observability"
"dev-cache"
"core"
)
for service in "${services[@]}"; do
local compose_file="${PROJECT_ROOT}/infra/compose/${service}.yml"
if [[ -f "$compose_file" ]]; then
log_info "停止服务: $service"
docker compose -f "$compose_file" down >> "$LOG_FILE" 2>&1 || true
fi
done
log_success "所有服务已停止"
}
# ============================================================================
# 清理选项
# ============================================================================
cleanup_containers() {
log_warning "删除所有容器..."
docker container prune -f >> "$LOG_FILE" 2>&1 || true
log_success "容器清理完成"
}
cleanup_volumes() {
log_warning "删除未使用的数据卷..."
docker volume prune -f >> "$LOG_FILE" 2>&1 || true
log_success "数据卷清理完成"
}
cleanup_networks() {
log_warning "删除未使用的网络..."
docker network prune -f >> "$LOG_FILE" 2>&1 || true
log_success "网络清理完成"
}
cleanup_all() {
log_warning "清理所有 Docker 资源..."
docker system prune -a -f >> "$LOG_FILE" 2>&1 || true
log_success "全部清理完成"
}
# ============================================================================
# 恢复数据卷
# ============================================================================
restore_volumes() {
local backup_dir=$1
if [[ ! -d "$backup_dir" ]]; then
log_error "备份目录不存在: $backup_dir"
return 1
fi
log_info "从备份恢复数据: $backup_dir"
for backup_file in "$backup_dir"/*.tar.gz; do
local volume_name=$(basename "$backup_file" .tar.gz)
log_info "恢复数据卷: $volume_name"
# 创建数据卷
docker volume create "$volume_name" 2>/dev/null || true
# 恢复数据
docker run --rm \
-v "$volume_name:/target" \
-v "$backup_dir:/backup" \
alpine tar xzf "/backup/${volume_name}.tar.gz" -C /target || true
done
log_success "数据恢复完成"
}
# ============================================================================
# 主函数
# ============================================================================
main() {
log "=========================================="
log "🧹 DevOps AI Stack 清理开始"
log "=========================================="
local backup=false
local remove_containers=false
local remove_volumes=false
local remove_networks=false
local remove_all=false
local restore_from=""
# 解析参数
while [[ $# -gt 0 ]]; do
case "$1" in
--backup)
backup=true
shift
;;
--remove-containers)
remove_containers=true
shift
;;
--remove-volumes)
remove_volumes=true
shift
;;
--remove-networks)
remove_networks=true
shift
;;
--remove-all)
remove_all=true
shift
;;
--restore-from)
restore_from="$2"
shift 2
;;
--help)
print_help
exit 0
;;
*)
log_error "未知参数: $1"
print_help
exit 1
;;
esac
done
# 备份数据
if [[ "$backup" == true ]]; then
backup_volumes
fi
# 恢复数据
if [[ -n "$restore_from" ]]; then
if ! restore_volumes "$restore_from"; then
exit 1
fi
fi
# 停止服务
stop_services
# 清理
if [[ "$remove_all" == true ]]; then
cleanup_all
else
[[ "$remove_containers" == true ]] && cleanup_containers
[[ "$remove_volumes" == true ]] && cleanup_volumes
[[ "$remove_networks" == true ]] && cleanup_networks
fi
# 完成
log ""
log "=========================================="
log_success "✅ 清理完成!"
log "=========================================="
log ""
log "📍 下一步:"
log " • 重新启动: ./infra/scripts/init-dev.sh"
log " • 查看备份: ls backups/"
log " • 查看日志: $LOG_FILE"
log ""
}
print_help() {
cat << 'EOF'
用法: cleanup-dev.sh [选项]
选项:
--backup 备份关键数据卷
--remove-containers 删除所有容器
--remove-volumes 删除未使用的数据卷
--remove-networks 删除未使用的网络
--remove-all 删除所有 Docker 资源 (谨慎!)
--restore-from <dir> 从备份恢复数据
--help 显示此帮助信息
示例:
# 停止服务并备份数据
./cleanup-dev.sh --backup
# 完全清理 (删除所有容器和卷)
./cleanup-dev.sh --remove-all
# 从备份恢复
./cleanup-dev.sh --restore-from backups/20240101_120000
EOF
}
main "$@"