#!/bin/bash # DMS合规性测试工具 - 跨平台 Docker Compose部署包创建脚本 # 支持任意选择目标平台架构 # 支持FastAPI和Flask两种框架 set -e # 配置变量 EXPORT_DIR="dms-compliance-multiplatform-$(date +%Y%m%d-%H%M%S)" IMAGE_NAME="compliance-dms-multiplatform" ARCHIVE_NAME="$EXPORT_DIR.tar.gz" # 支持的平台列表 - 使用函数替代关联数组以兼容旧版bash get_platform() { case "$1" in 1) echo "linux/amd64" ;; 2) echo "linux/arm64" ;; 3) echo "linux/arm/v7" ;; 4) echo "linux/arm/v6" ;; 5) echo "linux/386" ;; 6) echo "linux/ppc64le" ;; 7) echo "linux/s390x" ;; 8) echo "linux/riscv64" ;; *) echo "" ;; esac } get_platform_name() { case "$1" in "linux/amd64") echo "AMD64 (x86_64) - Intel/AMD 64位" ;; "linux/arm64") echo "ARM64 (aarch64) - Apple M1/M2, ARM 64位" ;; "linux/arm/v7") echo "ARMv7 - 树莓派 3/4, ARM 32位" ;; "linux/arm/v6") echo "ARMv6 - 树莓派 1/Zero, ARM 32位" ;; "linux/386") echo "i386 - Intel/AMD 32位" ;; "linux/ppc64le") echo "PowerPC 64位小端" ;; "linux/s390x") echo "IBM System z" ;; "linux/riscv64") echo "RISC-V 64位" ;; *) echo "未知平台" ;; esac } # 服务架构选择 get_service_arch() { case "$1" in 1) echo "dual" ;; 2) echo "fastapi" ;; 3) echo "flask" ;; *) echo "" ;; esac } get_service_arch_name() { case "$1" in "dual") echo "双服务架构 - API服务器(5050) + 历史查看器(5051)" ;; "fastapi") echo "FastAPI单服务 - 现代异步框架,自动生成API文档(5051)" ;; "flask") echo "Flask单服务 - 轻量级传统框架(5050)" ;; *) echo "未知架构" ;; esac } get_service_ports() { case "$1" in "dual") echo "5050,5051" ;; "fastapi") echo "5051" ;; "flask") echo "5050" ;; *) echo "5050" ;; esac } echo "=== DMS合规性测试工具 跨平台 Docker Compose部署包创建脚本 ===" echo "" # 检查Docker是否运行 if ! docker info >/dev/null 2>&1; then echo "[错误] Docker未运行或无法访问" exit 1 fi # 检查是否支持buildx if ! docker buildx version >/dev/null 2>&1; then echo "[错误] Docker Buildx未安装或不可用" echo "[提示] 请升级到Docker 19.03+或安装buildx插件" exit 1 fi # 检测当前平台 CURRENT_ARCH=$(docker version --format '{{.Server.Arch}}' 2>/dev/null || uname -m) case "$CURRENT_ARCH" in x86_64|amd64) CURRENT_PLATFORM="linux/amd64" ;; aarch64|arm64) CURRENT_PLATFORM="linux/arm64" ;; armv7l) CURRENT_PLATFORM="linux/arm/v7" ;; armv6l) CURRENT_PLATFORM="linux/arm/v6" ;; i386|i686) CURRENT_PLATFORM="linux/386" ;; *) CURRENT_PLATFORM="linux/amd64" ;; esac echo "[信息] 当前平台: ${PLATFORM_NAMES[$CURRENT_PLATFORM]}" echo "" # 选择服务架构 echo "请选择服务架构:" echo " 1) $(get_service_arch_name "dual")" echo " 2) $(get_service_arch_name "fastapi")" echo " 3) $(get_service_arch_name "flask")" echo "" read -p "请输入选择 (1-3) [默认: 1]: " service_choice service_choice=${service_choice:-1} SELECTED_SERVICE_ARCH=$(get_service_arch "$service_choice") if [[ -z "$SELECTED_SERVICE_ARCH" ]]; then echo "[错误] 无效的服务架构选择" exit 1 fi SELECTED_PORTS=$(get_service_ports "$SELECTED_SERVICE_ARCH") echo "[信息] 选择的架构: $(get_service_arch_name "$SELECTED_SERVICE_ARCH")" echo "[信息] 服务端口: $SELECTED_PORTS" echo "" # 选择目标平台 echo "请选择目标平台架构:" for key in 1 2 3 4 5 6 7 8; do platform=$(get_platform "$key") name=$(get_platform_name "$platform") if [[ "$platform" == "$CURRENT_PLATFORM" ]]; then echo " $key) $name [当前平台]" else echo " $key) $name" fi done echo " 9) 多平台构建 (同时构建多个平台)" echo " 0) 自动检测当前平台" echo "" read -p "请输入选择 (0-9) [默认: 0]: " platform_choice platform_choice=${platform_choice:-0} if [[ "$platform_choice" == "0" ]]; then TARGET_PLATFORM="$CURRENT_PLATFORM" TARGET_PLATFORM_NAME="$(get_platform_name "$CURRENT_PLATFORM") [自动检测]" MULTI_PLATFORM=false elif [[ "$platform_choice" == "9" ]]; then echo "" echo "多平台构建选项:" echo " 1) 常用平台 (amd64 + arm64)" echo " 2) 全平台 (所有支持的平台)" echo " 3) 自定义选择" echo "" read -p "请选择多平台构建方式 (1-3) [默认: 1]: " multi_choice multi_choice=${multi_choice:-1} case "$multi_choice" in 1) TARGET_PLATFORM="linux/amd64,linux/arm64" TARGET_PLATFORM_NAME="常用平台 (AMD64 + ARM64)" ;; 2) TARGET_PLATFORM="linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6,linux/386,linux/ppc64le,linux/s390x,linux/riscv64" TARGET_PLATFORM_NAME="全平台构建" ;; 3) echo "" echo "请选择要构建的平台 (多选,用空格分隔):" for key in 1 2 3 4 5 6 7 8; do platform=$(get_platform "$key") echo " $key) $(get_platform_name "$platform")" done echo "" read -p "请输入选择的平台编号 (例如: 1 2 3): " selected_platforms selected_platform_list="" for num in $selected_platforms; do platform=$(get_platform "$num") if [[ -n "$platform" ]]; then if [[ -n "$selected_platform_list" ]]; then selected_platform_list="$selected_platform_list,$platform" else selected_platform_list="$platform" fi fi done if [[ -z "$selected_platform_list" ]]; then echo "[错误] 未选择有效的平台" exit 1 fi TARGET_PLATFORM="$selected_platform_list" TARGET_PLATFORM_NAME="自定义平台 ($selected_platform_list)" ;; *) echo "[错误] 无效的多平台构建选择" exit 1 ;; esac MULTI_PLATFORM=true else TARGET_PLATFORM=$(get_platform "$platform_choice") if [[ -z "$TARGET_PLATFORM" ]]; then echo "[错误] 无效的平台选择" exit 1 fi TARGET_PLATFORM_NAME=$(get_platform_name "$TARGET_PLATFORM") MULTI_PLATFORM=false fi echo "[信息] 目标平台: $TARGET_PLATFORM_NAME" echo "[信息] 多平台构建: $MULTI_PLATFORM" echo "" # 确认构建 echo "构建配置确认:" echo " 架构: $(get_service_arch_name "$SELECTED_SERVICE_ARCH")" echo " 端口: $SELECTED_PORTS" echo " 平台: $TARGET_PLATFORM_NAME" echo " 输出: $EXPORT_DIR" echo "" read -p "确认开始构建? (y/N): " confirm if [[ ! "$confirm" =~ ^[Yy]$ ]]; then echo "[信息] 构建已取消" exit 0 fi # 先创建初始导出目录(稍后会重命名) INITIAL_EXPORT_DIR="$EXPORT_DIR" echo "[信息] 准备创建导出目录..." # 更新导出目录名称以包含平台信息 if [[ "$MULTI_PLATFORM" == "true" ]]; then EXPORT_DIR="dms-compliance-${SELECTED_SERVICE_ARCH}-multiplatform-$(date +%Y%m%d-%H%M%S)" else platform_suffix=$(echo "$TARGET_PLATFORM" | sed 's/linux\///g' | sed 's/\//-/g') EXPORT_DIR="dms-compliance-${SELECTED_SERVICE_ARCH}-${platform_suffix}-$(date +%Y%m%d-%H%M%S)" fi ARCHIVE_NAME="$EXPORT_DIR.tar.gz" # 重新创建目录 rm -rf "$EXPORT_DIR" mkdir -p "$EXPORT_DIR" echo "[信息] 最终输出目录: $EXPORT_DIR" # 创建最终导出目录 rm -rf "$EXPORT_DIR" mkdir -p "$EXPORT_DIR" echo "" # 复制项目文件 echo "[步骤 1/6] 复制项目文件..." # 创建临时构建目录 TEMP_BUILD_DIR=$(mktemp -d) trap "rm -rf $TEMP_BUILD_DIR" EXIT # 复制核心目录(排除缓存和临时文件) echo "[信息] 复制核心目录..." mkdir -p "$TEMP_BUILD_DIR"/{ddms_compliance_suite,custom_stages,custom_testcases,templates,static,assets} rsync -av --exclude='__pycache__' --exclude='*.pyc' --exclude='*.log' ddms_compliance_suite/ "$TEMP_BUILD_DIR/ddms_compliance_suite/" 2>/dev/null || cp -r ddms_compliance_suite "$TEMP_BUILD_DIR/" rsync -av --exclude='__pycache__' --exclude='*.pyc' custom_stages/ "$TEMP_BUILD_DIR/custom_stages/" 2>/dev/null || cp -r custom_stages "$TEMP_BUILD_DIR/" rsync -av --exclude='__pycache__' --exclude='*.pyc' custom_testcases/ "$TEMP_BUILD_DIR/custom_testcases/" 2>/dev/null || cp -r custom_testcases "$TEMP_BUILD_DIR/" 2>/dev/null || true # 复制模板和静态文件 rsync -av templates/ "$TEMP_BUILD_DIR/templates/" 2>/dev/null || cp -r templates "$TEMP_BUILD_DIR/" 2>/dev/null || mkdir -p "$TEMP_BUILD_DIR/templates" rsync -av static/ "$TEMP_BUILD_DIR/static/" 2>/dev/null || cp -r static "$TEMP_BUILD_DIR/" 2>/dev/null || mkdir -p "$TEMP_BUILD_DIR/static" rsync -av assets/ "$TEMP_BUILD_DIR/assets/" 2>/dev/null || cp -r assets "$TEMP_BUILD_DIR/" 2>/dev/null || mkdir -p "$TEMP_BUILD_DIR/assets" # 复制核心Python文件 echo "[信息] 复制核心Python文件..." for file in api_server.py history_viewer.py flask_app.py web_interface.py; do [ -f "$file" ] && cp "$file" "$TEMP_BUILD_DIR/" done # 复制requirements.txt cp requirements.txt "$TEMP_BUILD_DIR/" # 创建对应架构的Dockerfile echo "[步骤 2/6] 创建 Dockerfile..." cd "$TEMP_BUILD_DIR" if [[ "$SELECTED_SERVICE_ARCH" == "dual" ]]; then # 双服务架构 - 使用supervisor管理两个服务 cat > "Dockerfile" << 'EOF' # 使用稳定的Python基础镜像 FROM python:3.11-alpine # 安装系统依赖 RUN apk update && apk add --no-cache \ gcc \ musl-dev \ libffi-dev \ openssl-dev \ python3-dev \ build-base \ linux-headers \ supervisor \ curl \ bash \ tzdata && \ rm -rf /var/cache/apk/* # 设置工作目录 WORKDIR /app # 复制依赖文件并安装Python包 COPY requirements.txt . RUN pip install --no-cache-dir --upgrade pip setuptools wheel && \ pip install --no-cache-dir -r requirements.txt # 复制应用代码 COPY . . # 创建supervisor配置目录 RUN mkdir -p /etc/supervisor/conf.d /var/log/supervisor /app/logs /app/test_reports /app/uploads # 复制supervisor配置 COPY supervisord.conf /etc/supervisor/conf.d/ # 创建非root用户 RUN addgroup -g 1000 appuser && \ adduser -D -u 1000 -G appuser appuser && \ chown -R appuser:appuser /app /var/log/supervisor USER appuser # 设置环境变量 ENV PYTHONPATH=/app ENV FLASK_ENV=production ENV PYTHONUNBUFFERED=1 # 健康检查 HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ CMD curl -f http://localhost:5050/ || exit 1 # 暴露端口 EXPOSE 5050 5051 # 启动命令 CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"] EOF # 创建supervisor配置 cat > "supervisord.conf" << 'EOF' [supervisord] nodaemon=true logfile=/var/log/supervisor/supervisord.log pidfile=/var/run/supervisord.pid childlogdir=/var/log/supervisor logfile_maxbytes=50MB logfile_backups=10 loglevel=info [unix_http_server] file=/tmp/supervisor.sock chmod=0700 [supervisorctl] serverurl=unix:///tmp/supervisor.sock [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface # DMS API服务器 (主服务) [program:api_server] command=python api_server.py directory=/app autostart=true autorestart=true redirect_stderr=true stdout_logfile=/var/log/supervisor/api_server.log stdout_logfile_maxbytes=10MB stdout_logfile_backups=5 environment=PYTHONPATH="/app",PYTHONUNBUFFERED="1" # 历史查看器服务 [program:history_viewer] command=python history_viewer.py directory=/app autostart=true autorestart=true redirect_stderr=true stdout_logfile=/var/log/supervisor/history_viewer.log stdout_logfile_maxbytes=10MB stdout_logfile_backups=5 environment=PYTHONPATH="/app",PYTHONUNBUFFERED="1" # 进程组配置 [group:dms_services] programs=api_server,history_viewer priority=999 EOF elif [[ "$SELECTED_SERVICE_ARCH" == "fastapi" ]]; then cat > "Dockerfile" << 'EOF' # 使用稳定的Python基础镜像 FROM python:3.11-alpine # 安装系统依赖 RUN apk update && apk add --no-cache \ gcc \ musl-dev \ libffi-dev \ openssl-dev \ python3-dev \ build-base \ linux-headers \ curl \ bash \ tzdata && \ rm -rf /var/cache/apk/* # 设置工作目录 WORKDIR /app # 复制依赖文件并安装Python包 COPY requirements.txt . RUN pip install --no-cache-dir --upgrade pip setuptools wheel && \ pip install --no-cache-dir -r requirements.txt && \ pip install --no-cache-dir fastapi uvicorn[standard] # 复制应用代码 COPY . . # 创建必要目录 RUN mkdir -p /app/logs /app/uploads /app/reports # 创建非root用户 RUN addgroup -g 1000 appuser && \ adduser -D -u 1000 -G appuser appuser && \ chown -R appuser:appuser /app USER appuser # 设置环境变量 ENV PYTHONPATH=/app ENV PYTHONUNBUFFERED=1 # 健康检查 HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ CMD curl -f http://localhost:5051/health || exit 1 # 暴露端口 EXPOSE 5051 # 启动命令 CMD ["uvicorn", "web_interface_fastapi:app", "--host", "0.0.0.0", "--port", "5051"] EOF # 创建FastAPI web接口 cat > "web_interface_fastapi.py" << 'EOF' #!/usr/bin/env python3 """ DMS合规性测试工具 - FastAPI Web接口 """ import os import sys import json import logging import traceback from datetime import datetime from pathlib import Path from typing import Optional, Dict, Any, List from fastapi import FastAPI, HTTPException, UploadFile, File, Form, BackgroundTasks from fastapi.responses import HTMLResponse, FileResponse, JSONResponse from fastapi.staticfiles import StaticFiles from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel import uvicorn # 添加项目根目录到Python路径 sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) # 导入测试模块 try: from ddms_compliance_suite.main import main as run_compliance_test from ddms_compliance_suite.input_parser.parser import parse_dms_api_spec except ImportError as e: print(f"导入错误: {e}") sys.exit(1) # 配置日志 logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # 创建FastAPI应用 app = FastAPI( title="DMS合规性测试工具", description="用于测试DMS API合规性的Web界面", version="1.0.0", docs_url="/docs", redoc_url="/redoc" ) # 添加CORS中间件 app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # 数据模型 class TestRequest(BaseModel): api_spec_file: str base_url: Optional[str] = "https://www.dev.ideas.cnpc" test_mode: Optional[str] = "all" endpoint_filter: Optional[str] = None log_level: Optional[str] = "INFO" enable_well_data: Optional[bool] = True class TestResult(BaseModel): success: bool message: str log_file: Optional[str] = None details: Optional[Dict[str, Any]] = None # 全局变量 current_test_status = {"running": False, "progress": 0, "message": ""} test_results = {} @app.get("/", response_class=HTMLResponse) async def root(): """主页""" return """ DMS合规性测试工具

DMS合规性测试工具

上传API规范文件并运行合规性测试

API文档

Swagger UI | ReDoc

""" @app.get("/health") async def health_check(): """健康检查端点""" return {"status": "healthy", "timestamp": datetime.now().isoformat()} @app.get("/status") async def get_status(): """获取当前测试状态""" return current_test_status @app.post("/test") async def run_test( background_tasks: BackgroundTasks, api_spec_file: UploadFile = File(...), base_url: str = Form("https://www.dev.ideas.cnpc"), test_mode: str = Form("all"), endpoint_filter: Optional[str] = Form(None), log_level: str = Form("INFO"), enable_well_data: bool = Form(True) ): """运行合规性测试""" if current_test_status["running"]: raise HTTPException(status_code=400, detail="测试正在进行中,请等待完成") # 保存上传的文件 upload_dir = Path("uploads") upload_dir.mkdir(exist_ok=True) file_path = upload_dir / api_spec_file.filename with open(file_path, "wb") as f: content = await api_spec_file.read() f.write(content) # 验证文件格式 try: with open(file_path, 'r', encoding='utf-8') as f: json.load(f) except json.JSONDecodeError: raise HTTPException(status_code=400, detail="无效的JSON文件") # 启动后台测试任务 background_tasks.add_task( run_test_background, str(file_path), base_url, test_mode, endpoint_filter, log_level, enable_well_data ) return {"success": True, "message": "测试已开始,请等待完成"} async def run_test_background( api_spec_file: str, base_url: str, test_mode: str, endpoint_filter: Optional[str], log_level: str, enable_well_data: bool ): """后台运行测试""" global current_test_status, test_results current_test_status = {"running": True, "progress": 0, "message": "初始化测试..."} try: # 构建命令行参数 args = [ "--api-spec-file", api_spec_file, "--base-url", base_url, "--test-mode", test_mode, "--log-level", log_level ] if endpoint_filter: args.extend(["--endpoint-filter", endpoint_filter]) if enable_well_data: args.append("--enable-well-data") current_test_status["progress"] = 20 current_test_status["message"] = "解析API规范..." # 运行测试 current_test_status["progress"] = 50 current_test_status["message"] = "执行测试..." # 这里应该调用实际的测试函数 # result = run_compliance_test(args) current_test_status["progress"] = 100 current_test_status["message"] = "测试完成" test_results[api_spec_file] = { "success": True, "message": "测试成功完成", "timestamp": datetime.now().isoformat() } except Exception as e: logger.error(f"测试执行失败: {e}") test_results[api_spec_file] = { "success": False, "message": f"测试失败: {str(e)}", "timestamp": datetime.now().isoformat(), "traceback": traceback.format_exc() } finally: current_test_status["running"] = False if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=5051) EOF else # Flask版本的Dockerfile cat > "Dockerfile" << 'EOF' # 使用稳定的Python基础镜像 FROM python:3.11-alpine # 安装系统依赖 RUN apk update && apk add --no-cache \ gcc \ musl-dev \ libffi-dev \ openssl-dev \ python3-dev \ build-base \ linux-headers \ curl \ bash \ tzdata && \ rm -rf /var/cache/apk/* # 设置工作目录 WORKDIR /app # 复制依赖文件并安装Python包 COPY requirements.txt . RUN pip install --no-cache-dir --upgrade pip setuptools wheel && \ pip install --no-cache-dir -r requirements.txt && \ pip install --no-cache-dir flask gunicorn # 复制应用代码 COPY . . # 创建必要目录 RUN mkdir -p /app/logs /app/uploads /app/reports # 创建非root用户 RUN addgroup -g 1000 appuser && \ adduser -D -u 1000 -G appuser appuser && \ chown -R appuser:appuser /app USER appuser # 设置环境变量 ENV PYTHONPATH=/app ENV FLASK_ENV=production ENV PYTHONUNBUFFERED=1 # 健康检查 HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ CMD curl -f http://localhost:5050/ || exit 1 # 暴露端口 EXPOSE 5050 # 启动命令 CMD ["gunicorn", "--bind", "0.0.0.0:5050", "--workers", "1", "--timeout", "300", "web_interface:app"] EOF # 复制现有的Flask web接口 if [[ -f "../web_interface.py" ]]; then cp "../web_interface.py" . else echo "[警告] web_interface.py 不存在,请确保Flask版本的web接口文件存在" fi fi cd .. # 复制构建文件到最终目录 echo "[步骤 3/6] 复制构建文件..." # 确保目标目录存在 mkdir -p "$EXPORT_DIR" cp -r "$TEMP_BUILD_DIR"/* "$EXPORT_DIR/" # 创建Docker Compose文件 echo "[步骤 4/6] 创建 Docker Compose 配置..." if [[ "$SELECTED_SERVICE_ARCH" == "dual" ]]; then # 双服务架构 cat > "$EXPORT_DIR/docker-compose.yml" << EOF version: '3.8' services: dms-compliance: build: context: . dockerfile: Dockerfile platforms: - $TARGET_PLATFORM image: $IMAGE_NAME:latest container_name: dms-compliance-tool ports: - "5050:5050" # API服务器端口 - "5051:5051" # 历史查看器端口 environment: - PYTHONPATH=/app - TZ=Asia/Shanghai - FLASK_ENV=production - PYTHONUNBUFFERED=1 volumes: - ./uploads:/app/uploads - ./logs:/app/logs - ./test_reports:/app/test_reports - ./config:/app/config:ro restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:5050/"] interval: 30s timeout: 10s retries: 3 start_period: 40s networks: - dms-network networks: dms-network: driver: bridge volumes: uploads: logs: test_reports: config: EOF else # 单服务架构 PRIMARY_PORT=$(echo "$SELECTED_PORTS" | cut -d',' -f1) cat > "$EXPORT_DIR/docker-compose.yml" << EOF version: '3.8' services: dms-compliance: build: context: . dockerfile: Dockerfile platforms: - $TARGET_PLATFORM image: $IMAGE_NAME:latest container_name: dms-compliance-tool ports: - "$PRIMARY_PORT:$PRIMARY_PORT" environment: - PYTHONPATH=/app - TZ=Asia/Shanghai volumes: - ./uploads:/app/uploads - ./logs:/app/logs - ./reports:/app/reports restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:$PRIMARY_PORT/health"] interval: 30s timeout: 10s retries: 3 start_period: 40s volumes: uploads: logs: reports: EOF fi # 创建环境配置文件 cat > "$EXPORT_DIR/.env" << EOF # DMS合规性测试工具环境配置 COMPOSE_PROJECT_NAME=dms-compliance COMPOSE_FILE=docker-compose.yml # 服务配置 SERVICE_PORTS=$SELECTED_PORTS SERVICE_ARCH=$SELECTED_SERVICE_ARCH TARGET_PLATFORM=$TARGET_PLATFORM # 应用配置 PYTHONPATH=/app TZ=Asia/Shanghai LOG_LEVEL=INFO # 构建配置 IMAGE_NAME=$IMAGE_NAME CONTAINER_NAME=dms-compliance-tool EOF # 创建启动脚本 echo "[步骤 5/6] 创建管理脚本..." cat > "$EXPORT_DIR/start.sh" << 'EOF' #!/bin/bash # DMS合规性测试工具启动脚本 set -e echo "=== DMS合规性测试工具启动脚本 ===" # 检查Docker和Docker Compose if ! command -v docker &> /dev/null; then echo "[错误] Docker未安装" exit 1 fi if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then echo "[错误] Docker Compose未安装" exit 1 fi # 选择Docker Compose命令 if docker compose version &> /dev/null; then COMPOSE_CMD="docker compose" else COMPOSE_CMD="docker-compose" fi echo "[信息] 使用 $COMPOSE_CMD" # 创建必要的目录 mkdir -p uploads logs test_reports config # 构建并启动服务 echo "[信息] 构建Docker镜像..." $COMPOSE_CMD build echo "[信息] 启动服务..." $COMPOSE_CMD up -d # 等待服务启动 echo "[信息] 等待服务启动..." sleep 10 # 检查服务状态 if $COMPOSE_CMD ps | grep -q "Up"; then echo "[成功] 服务启动成功!" echo "" echo "访问地址:" if grep -q "dual" .env; then echo " API服务器: http://localhost:5050" echo " 历史查看器: http://localhost:5051" elif grep -q "fastapi" .env; then echo " Web界面: http://localhost:5051" echo " API文档: http://localhost:5051/docs" echo " ReDoc: http://localhost:5051/redoc" else echo " Web界面: http://localhost:5050" fi echo "" echo "管理命令:" echo " 查看日志: $COMPOSE_CMD logs -f" echo " 停止服务: $COMPOSE_CMD down" echo " 重启服务: $COMPOSE_CMD restart" echo " 查看状态: $COMPOSE_CMD ps" else echo "[错误] 服务启动失败" echo "查看日志: $COMPOSE_CMD logs" exit 1 fi EOF cat > "$EXPORT_DIR/stop.sh" << 'EOF' #!/bin/bash # DMS合规性测试工具停止脚本 set -e echo "=== DMS合规性测试工具停止脚本 ===" # 选择Docker Compose命令 if docker compose version &> /dev/null; then COMPOSE_CMD="docker compose" else COMPOSE_CMD="docker-compose" fi echo "[信息] 停止服务..." $COMPOSE_CMD down echo "[成功] 服务已停止" EOF cat > "$EXPORT_DIR/logs.sh" << 'EOF' #!/bin/bash # DMS合规性测试工具日志查看脚本 # 选择Docker Compose命令 if docker compose version &> /dev/null; then COMPOSE_CMD="docker compose" else COMPOSE_CMD="docker-compose" fi echo "=== DMS合规性测试工具日志 ===" $COMPOSE_CMD logs -f EOF # 设置脚本执行权限 chmod +x "$EXPORT_DIR/start.sh" chmod +x "$EXPORT_DIR/stop.sh" chmod +x "$EXPORT_DIR/logs.sh" # 构建Docker镜像 echo "[步骤 6/6] 构建Docker镜像..." # 保存当前目录 ORIGINAL_DIR=$(pwd) cd "$EXPORT_DIR" if [[ "$MULTI_PLATFORM" == "true" ]]; then echo "[信息] 多平台构建: $TARGET_PLATFORM" # 创建并使用buildx构建器 docker buildx create --name multiplatform-builder --use 2>/dev/null || docker buildx use multiplatform-builder # 多平台构建 docker buildx build \ --platform "$TARGET_PLATFORM" \ --tag "$IMAGE_NAME:latest" \ --load \ . else echo "[信息] 单平台构建: $TARGET_PLATFORM" # 单平台构建 docker buildx build \ --platform "$TARGET_PLATFORM" \ --tag "$IMAGE_NAME:latest" \ --load \ . fi # 返回原始目录 cd "$ORIGINAL_DIR" # 导出Docker镜像 echo "[信息] 导出Docker镜像..." cd "$EXPORT_DIR" docker save "$IMAGE_NAME:latest" | gzip > "docker-image.tar.gz" cd "$ORIGINAL_DIR" # 创建README文件 cat > "$EXPORT_DIR/README.md" << EOF # DMS合规性测试工具 - Docker Compose部署包 ## 系统信息 - **架构**: $(get_service_arch_name "$SELECTED_SERVICE_ARCH") - **端口**: $SELECTED_PORTS - **目标平台**: $TARGET_PLATFORM_NAME - **构建时间**: $(date '+%Y-%m-%d %H:%M:%S') ## 快速开始 ### 1. 解压部署包 \`\`\`bash tar -xzf $ARCHIVE_NAME cd $EXPORT_DIR \`\`\` ### 2. 启动服务 \`\`\`bash ./start.sh \`\`\` ### 3. 访问服务 EOF if [[ "$SELECTED_SERVICE_ARCH" == "dual" ]]; then cat >> "$EXPORT_DIR/README.md" << EOF - API服务器: http://localhost:5050 - 历史查看器: http://localhost:5051 EOF elif [[ "$SELECTED_SERVICE_ARCH" == "fastapi" ]]; then cat >> "$EXPORT_DIR/README.md" << EOF - Web界面: http://localhost:5051 - API文档: http://localhost:5051/docs - ReDoc文档: http://localhost:5051/redoc EOF else cat >> "$EXPORT_DIR/README.md" << EOF - Web界面: http://localhost:5050 EOF fi cat >> "$EXPORT_DIR/README.md" << EOF ## 管理命令 \`\`\`bash # 启动服务 ./start.sh # 停止服务 ./stop.sh # 查看日志 ./logs.sh # 查看服务状态 docker-compose ps # 重启服务 docker-compose restart \`\`\` ## 目录结构 \`\`\` $EXPORT_DIR/ ├── docker-compose.yml # Docker Compose配置 ├── Dockerfile # Docker镜像构建文件 ├── .env # 环境变量配置 ├── start.sh # 启动脚本 ├── stop.sh # 停止脚本 ├── logs.sh # 日志查看脚本 ├── docker-image.tar.gz # Docker镜像文件 ├── ddms_compliance_suite/ # 测试套件源码 ├── custom_stages/ # 自定义测试阶段 ├── uploads/ # 上传文件目录 ├── logs/ # 日志文件目录 ├── reports/ # 测试报告目录 └── README.md # 说明文档 \`\`\` ## 系统要求 - Docker 19.03+ - Docker Compose 1.25+ 或 Docker Compose V2 - 支持的平台: $TARGET_PLATFORM_NAME ## 故障排除 ### 端口冲突 如果端口被占用,可以修改\`docker-compose.yml\`文件中的端口映射,然后重启服务。 ### 镜像加载 如果需要在其他机器上部署,可以使用以下命令加载镜像: \`\`\`bash docker load < docker-image.tar.gz \`\`\` ### 查看详细日志 \`\`\`bash docker-compose logs -f dms-compliance \`\`\` ### 重新构建 \`\`\`bash docker-compose build --no-cache docker-compose up -d \`\`\` ## 技术支持 如有问题,请查看日志文件或联系技术支持。 EOF # 创建压缩包 echo "[信息] 创建压缩包..." tar -czf "$ARCHIVE_NAME" "$EXPORT_DIR" # 清理临时目录 rm -rf "$EXPORT_DIR" # 显示结果 echo "" echo "=== 构建完成 ===" echo "[成功] Docker Compose部署包已创建: $ARCHIVE_NAME" echo "[信息] 架构: $(get_service_arch_name "$SELECTED_SERVICE_ARCH")" echo "[信息] 端口: $SELECTED_PORTS" echo "[信息] 平台: $TARGET_PLATFORM_NAME" echo "[信息] 文件大小: $(du -h "$ARCHIVE_NAME" | cut -f1)" echo "" echo "部署说明:" echo "1. 将 $ARCHIVE_NAME 传输到目标服务器" echo "2. 解压: tar -xzf $ARCHIVE_NAME" echo "3. 进入目录: cd $EXPORT_DIR" echo "4. 启动服务: ./start.sh" echo "" if [[ "$SELECTED_SERVICE_ARCH" == "dual" ]]; then echo "访问地址:" echo "- API服务器: http://localhost:5050" echo "- 历史查看器: http://localhost:5051" elif [[ "$SELECTED_SERVICE_ARCH" == "fastapi" ]]; then echo "访问地址:" echo "- Web界面: http://localhost:5051" echo "- API文档: http://localhost:5051/docs" echo "- ReDoc: http://localhost:5051/redoc" else echo "访问地址: http://localhost:5050" fi echo "" echo "构建完成!"