7cbb7a9ac8
ci/woodpecker/push/woodpecker Pipeline failed
1. jest.setup.js: - 添加 Request/Response/Headers 全局对象 mock - 解决 'Request is not defined' 错误 2. .eslintrc.json: - 将 jest.setup.js 添加到忽略列表 3. shared-mocks.tsx: - 添加 ArrowUp 图标 mock 4. back-to-top.test.tsx: - 重写测试使用 import 语法 - 使用 fireEvent.scroll 触发滚动事件 - 修复组件渲染测试
333 lines
7.9 KiB
Bash
Executable File
333 lines
7.9 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Docker镜像清理脚本
|
|
# 用途:检查生产环境Docker镜像使用情况并清理未使用的镜像
|
|
|
|
set -e
|
|
|
|
# 颜色定义
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# 日志函数
|
|
log_info() {
|
|
echo -e "${BLUE}[INFO]${NC} $1"
|
|
}
|
|
|
|
log_success() {
|
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
|
}
|
|
|
|
log_warning() {
|
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
}
|
|
|
|
log_error() {
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
|
}
|
|
|
|
# 分隔线
|
|
separator() {
|
|
echo "======================================================================"
|
|
}
|
|
|
|
# 检查Docker是否运行
|
|
check_docker() {
|
|
if ! docker info > /dev/null 2>&1; then
|
|
log_error "Docker未运行,请先启动Docker"
|
|
exit 1
|
|
fi
|
|
log_success "Docker运行正常"
|
|
}
|
|
|
|
# 显示磁盘使用情况
|
|
show_disk_usage() {
|
|
separator
|
|
log_info "磁盘使用情况"
|
|
separator
|
|
|
|
echo ""
|
|
log_info "系统磁盘使用:"
|
|
df -h | grep -E "Filesystem|/$|/home|/var"
|
|
|
|
echo ""
|
|
log_info "Docker数据目录使用:"
|
|
docker system df
|
|
|
|
echo ""
|
|
log_info "Docker镜像详情:"
|
|
docker system df -v | grep -A 100 "Images space usage"
|
|
}
|
|
|
|
# 列出所有镜像
|
|
list_images() {
|
|
separator
|
|
log_info "Docker镜像列表"
|
|
separator
|
|
|
|
echo ""
|
|
log_info "所有镜像(按大小排序):"
|
|
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}\t{{.CreatedSince}}" | head -20
|
|
|
|
echo ""
|
|
log_info "悬空镜像(<none>):"
|
|
docker images -f "dangling=true" --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}\t{{.CreatedSince}}"
|
|
|
|
echo ""
|
|
log_info "未使用的镜像(没有被任何容器使用):"
|
|
docker images --format "{{.Repository}}:{{.Tag}} {{.ID}}" | while read image id; do
|
|
if ! docker ps -a --format "{{.Image}}" | grep -q "$id"; then
|
|
echo "$image (ID: $id)"
|
|
fi
|
|
done
|
|
}
|
|
|
|
# 列出所有容器
|
|
list_containers() {
|
|
separator
|
|
log_info "Docker容器列表"
|
|
separator
|
|
|
|
echo ""
|
|
log_info "运行中的容器:"
|
|
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Size}}"
|
|
|
|
echo ""
|
|
log_info "已停止的容器:"
|
|
docker ps -f "status=exited" --format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Size}}"
|
|
}
|
|
|
|
# 分析镜像使用情况
|
|
analyze_images() {
|
|
separator
|
|
log_info "镜像使用分析"
|
|
separator
|
|
|
|
echo ""
|
|
log_info "正在分析镜像使用情况..."
|
|
|
|
# 统计信息
|
|
TOTAL_IMAGES=$(docker images -q | wc -l)
|
|
DANGLING_IMAGES=$(docker images -f "dangling=true" -q | wc -l)
|
|
TOTAL_SIZE=$(docker images --format "{{.Size}}" | grep -oE '[0-9]+GB|[0-9]+MB' | head -1)
|
|
|
|
log_info "总镜像数: $TOTAL_IMAGES"
|
|
log_info "悬空镜像数: $DANGLING_IMAGES"
|
|
log_info "镜像总大小约: $TOTAL_SIZE"
|
|
|
|
echo ""
|
|
log_info "可以清理的内容:"
|
|
echo " 1. 悬空镜像(<none>标签): $DANGLING_IMAGES 个"
|
|
echo " 2. 已停止的容器"
|
|
echo " 3. 未使用的网络"
|
|
echo " 4. 构建缓存"
|
|
}
|
|
|
|
# 清理悬空镜像
|
|
clean_dangling_images() {
|
|
separator
|
|
log_info "清理悬空镜像"
|
|
separator
|
|
|
|
DANGLING_COUNT=$(docker images -f "dangling=true" -q | wc -l)
|
|
|
|
if [ "$DANGLING_COUNT" -eq 0 ]; then
|
|
log_success "没有悬空镜像需要清理"
|
|
return
|
|
fi
|
|
|
|
log_warning "发现 $DANGLING_COUNT 个悬空镜像"
|
|
read -p "是否清理悬空镜像?(y/n): " -n 1 -r
|
|
echo
|
|
|
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
log_info "正在清理悬空镜像..."
|
|
docker image prune -f
|
|
log_success "悬空镜像清理完成"
|
|
else
|
|
log_info "跳过悬空镜像清理"
|
|
fi
|
|
}
|
|
|
|
# 清理未使用的镜像
|
|
clean_unused_images() {
|
|
separator
|
|
log_info "清理未使用的镜像"
|
|
separator
|
|
|
|
log_warning "这将删除所有没有被容器使用的镜像"
|
|
read -p "是否清理未使用的镜像?(y/n): " -n 1 -r
|
|
echo
|
|
|
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
log_info "正在清理未使用的镜像..."
|
|
docker image prune -a -f
|
|
log_success "未使用镜像清理完成"
|
|
else
|
|
log_info "跳过未使用镜像清理"
|
|
fi
|
|
}
|
|
|
|
# 清理已停止的容器
|
|
clean_stopped_containers() {
|
|
separator
|
|
log_info "清理已停止的容器"
|
|
separator
|
|
|
|
STOPPED_COUNT=$(docker ps -f "status=exited" -q | wc -l)
|
|
|
|
if [ "$STOPPED_COUNT" -eq 0 ]; then
|
|
log_success "没有已停止的容器需要清理"
|
|
return
|
|
fi
|
|
|
|
log_warning "发现 $STOPPED_COUNT 个已停止的容器"
|
|
read -p "是否清理已停止的容器?(y/n): " -n 1 -r
|
|
echo
|
|
|
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
log_info "正在清理已停止的容器..."
|
|
docker container prune -f
|
|
log_success "已停止容器清理完成"
|
|
else
|
|
log_info "跳过已停止容器清理"
|
|
fi
|
|
}
|
|
|
|
# 清理构建缓存
|
|
clean_build_cache() {
|
|
separator
|
|
log_info "清理构建缓存"
|
|
separator
|
|
|
|
log_warning "这将删除所有构建缓存"
|
|
read -p "是否清理构建缓存?(y/n): " -n 1 -r
|
|
echo
|
|
|
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
log_info "正在清理构建缓存..."
|
|
docker builder prune -a -f
|
|
log_success "构建缓存清理完成"
|
|
else
|
|
log_info "跳过构建缓存清理"
|
|
fi
|
|
}
|
|
|
|
# 一键清理
|
|
clean_all() {
|
|
separator
|
|
log_info "一键清理(安全模式)"
|
|
separator
|
|
|
|
log_warning "将执行以下清理操作:"
|
|
echo " 1. 清理悬空镜像"
|
|
echo " 2. 清理已停止的容器"
|
|
echo " 3. 清理未使用的网络"
|
|
echo " 4. 清理构建缓存"
|
|
echo ""
|
|
log_warning "不会删除正在使用的镜像"
|
|
|
|
read -p "是否继续?(y/n): " -n 1 -r
|
|
echo
|
|
|
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
log_info "开始一键清理..."
|
|
|
|
log_info "清理悬空镜像..."
|
|
docker image prune -f
|
|
|
|
log_info "清理已停止的容器..."
|
|
docker container prune -f
|
|
|
|
log_info "清理未使用的网络..."
|
|
docker network prune -f
|
|
|
|
log_info "清理构建缓存..."
|
|
docker builder prune -f
|
|
|
|
log_success "一键清理完成"
|
|
else
|
|
log_info "取消一键清理"
|
|
fi
|
|
}
|
|
|
|
# 显示清理效果
|
|
show_cleanup_result() {
|
|
separator
|
|
log_info "清理后的磁盘使用情况"
|
|
separator
|
|
|
|
echo ""
|
|
docker system df
|
|
|
|
echo ""
|
|
log_info "磁盘空间变化:"
|
|
df -h | grep -E "Filesystem|/$"
|
|
}
|
|
|
|
# 主菜单
|
|
main_menu() {
|
|
clear
|
|
separator
|
|
echo "Docker镜像清理工具"
|
|
separator
|
|
echo ""
|
|
echo "1. 查看磁盘使用情况"
|
|
echo "2. 列出所有镜像"
|
|
echo "3. 列出所有容器"
|
|
echo "4. 分析镜像使用情况"
|
|
echo "5. 清理悬空镜像(安全)"
|
|
echo "6. 清理未使用的镜像(谨慎)"
|
|
echo "7. 清理已停止的容器"
|
|
echo "8. 清理构建缓存"
|
|
echo "9. 一键清理(安全模式)"
|
|
echo "0. 退出"
|
|
echo ""
|
|
read -p "请选择操作 (0-9): " choice
|
|
|
|
case $choice in
|
|
1) show_disk_usage ;;
|
|
2) list_images ;;
|
|
3) list_containers ;;
|
|
4) analyze_images ;;
|
|
5) clean_dangling_images ;;
|
|
6) clean_unused_images ;;
|
|
7) clean_stopped_containers ;;
|
|
8) clean_build_cache ;;
|
|
9) clean_all ;;
|
|
0)
|
|
log_info "退出程序"
|
|
exit 0
|
|
;;
|
|
*)
|
|
log_error "无效选择"
|
|
;;
|
|
esac
|
|
|
|
echo ""
|
|
read -p "按回车键继续..."
|
|
main_menu
|
|
}
|
|
|
|
# 主函数
|
|
main() {
|
|
log_info "Docker镜像清理工具启动"
|
|
check_docker
|
|
|
|
if [ "$1" = "--auto" ]; then
|
|
log_info "自动模式:执行安全清理"
|
|
clean_dangling_images
|
|
clean_stopped_containers
|
|
clean_build_cache
|
|
show_cleanup_result
|
|
else
|
|
main_menu
|
|
fi
|
|
}
|
|
|
|
# 执行主函数
|
|
main "$@"
|