# DCU 模块设计文档

> Docker镜像打包压缩服务模块，负责执行 Download-Compress-Upload (DCU) 工作流。

## 1. 模块概述

DCU模块是一个独立运行的服务，专门处理Docker镜像的下载、压缩和上传任务。该模块采用Gin+GORM+SQLite3技术栈，通过状态机管理任务流程，支持异步执行和定时清理。

### 1.1 核心特性

| 特性 | 说明 |
|------|------|
| 独立部署 | 完全独立运行，通过HTTP API接收请求 |
| 状态管理 | 基于状态机的任务状态管理，支持持久化 |
| 异步执行 | DCU流程异步执行，不阻塞API响应 |
| 定时清理 | 支持定时清理本地gzip文件和MinIO对象 |
| 错误追踪 | 完整的错误信息记录和查询功能 |

---

## 2. 架构设计

### 2.1 系统架构图

```mermaid
graph TB
    subgraph "外部系统"
        JB[rmdc-jenkins-branch-dac] -->|HTTP Request| API
        DR[Docker Registry]
        MIO[(MinIO对象存储)]
    end
    
    subgraph "rmdc-dcu 模块"
        API[REST API Handler]
        
        subgraph "Service Layer"
            DCU[DCU Service]
            DS[Docker Service]
            CS[Compress Service]
            MS[MinIO Service]
            SCH[Scheduler]
        end
        
        subgraph "Core"
            SM[State Machine]
            DAO[DCU Task DAO]
        end
        
        DB[(SQLite3)]
    end
    
    API --> DCU
    DCU --> SM
    DCU --> DS
    DCU --> CS
    DCU --> MS
    SM --> DAO
    DAO --> DB
    DS -->|docker pull/save| DR
    MS -->|upload/delete| MIO
    SCH --> CS
    SCH --> MS
```

### 2.2 分层架构

```
┌─────────────────────────────────────────────────────┐
│                  Handler Layer                       │
│  ┌─────────────┐  ┌──────────────┐  ┌────────────┐  │
│  │ StartTask   │  │ GetStatus    │  │ QueryTasks │  │
│  └─────────────┘  └──────────────┘  └────────────┘  │
├─────────────────────────────────────────────────────┤
│                  Service Layer                       │
│  ┌─────────────┐  ┌──────────────┐  ┌────────────┐  │
│  │ DCUService  │  │ DockerSvc    │  │ CompressSvc│  │
│  ├─────────────┤  ├──────────────┤  ├────────────┤  │
│  │ MinIOSvc    │  │ Scheduler    │  │            │  │
│  └─────────────┘  └──────────────┘  └────────────┘  │
├─────────────────────────────────────────────────────┤
│                State Machine Layer                   │
│  ┌─────────────────────────────────────────────────┐│
│  │  StateMachine (状态转换 + 持久化回调)            ││
│  └─────────────────────────────────────────────────┘│
├─────────────────────────────────────────────────────┤
│                    DAO Layer                         │
│  ┌─────────────────────────────────────────────────┐│
│  │  DCUTaskDAO (CRUD + 分页查询 + 清理)             ││
│  └─────────────────────────────────────────────────┘│
├─────────────────────────────────────────────────────┤
│                  Entity Layer                        │
│  ┌─────────────────────────────────────────────────┐│
│  │  DCUTask (任务实体 + GORM映射)                   ││
│  └─────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────┘
```

---

## 3. 状态机设计

### 3.1 状态定义

| 状态 | 常量值 | 说明 | 进度 |
|------|--------|------|------|
| 等待中 | `idle` | 任务已创建，等待开始 | 0% |
| 下载中 | `downloading` | 正在执行docker pull | 25% |
| 压缩中 | `compressing` | 正在gzip压缩镜像 | 50% |
| 上传中 | `uploading` | 正在上传到MinIO | 75% |
| 已完成 | `completed` | 任务成功完成 | 100% |
| 失败 | `failed` | 任务执行失败 | -1 |

### 3.2 状态转换图

```mermaid
stateDiagram-v2
    [*] --> idle: 创建任务

    idle --> downloading: StartTask()
    idle --> failed: 初始化失败

    downloading --> compressing: Pull成功
    downloading --> failed: Pull失败

    compressing --> uploading: 压缩成功
    compressing --> failed: 压缩失败

    uploading --> completed: 上传成功
    uploading --> failed: 上传失败

    completed --> [*]
    failed --> [*]
```

### 3.3 状态持久化

状态机通过回调函数实现状态持久化：

```go
// 状态转换时自动调用
func (s *DCUService) onStateTransition(taskID, fromState, toState, errMsg string) error {
    return s.taskDAO.UpdateState(ctx, taskID, toState, errMsg)
}
```

---

## 4. DCU 工作流程

### 4.1 完整流程图

```mermaid
sequenceDiagram
    participant Client as 调用方
    participant API as REST API
    participant DCU as DCU Service
    participant SM as State Machine
    participant Docker as Docker CLI
    participant Compress as Compress Service
    participant MinIO as MinIO Service
    participant DB as SQLite

    Client->>API: POST /api/dcu/start
    API->>DCU: StartTask(username, imageName)
    DCU->>DB: Create task record
    DCU->>SM: RegisterTask(taskID)
    DCU-->>API: Return taskID
    API-->>Client: Response {task_id, state: "idle"}
    
    Note over DCU: 异步执行DCU流程
    
    DCU->>SM: Transition(downloading)
    SM->>DB: Update state
    DCU->>Docker: docker pull image
    Docker-->>DCU: Pull完成
    DCU->>Docker: docker save -o image.tar
    Docker-->>DCU: Save完成
    
    DCU->>SM: Transition(compressing)
    SM->>DB: Update state
    DCU->>Compress: CompressFile(tar → gzip)
    Compress-->>DCU: 压缩完成
    DCU->>DB: Update gzip_file_name
    
    DCU->>SM: Transition(uploading)
    SM->>DB: Update state
    DCU->>MinIO: Upload(objectName, gzipPath)
    MinIO-->>DCU: 上传完成
    DCU->>DB: Update minio_object_name
    
    DCU->>SM: Transition(completed)
    SM->>DB: Update state + end_time
    
    Client->>API: GET /api/dcu/status/{task_id}
    API->>DCU: GetTaskStatus(taskID)
    DCU->>DB: Query task
    DB-->>DCU: Task entity
    DCU-->>API: TaskStatusResponse
    API-->>Client: Response with progress
```

### 4.2 错误处理流程

```mermaid
flowchart TD
    A[开始DCU] --> B{Docker Pull}
    B -->|成功| C{Docker Save}
    B -->|失败| F[记录错误信息]
    C -->|成功| D{Gzip压缩}
    C -->|失败| F
    D -->|成功| E{MinIO上传}
    D -->|失败| F
    E -->|成功| G[状态: completed]
    E -->|失败| F
    F --> H[状态: failed]
    G --> I[结束]
    H --> I
```

---

## 5. API 接口说明

### 5.1 启动DCU任务

```
POST /api/dcu/start
```

**请求体：**
```json
{
    "username": "test_user",
    "docker_image_name": "nginx:latest"
}
```

**响应：**
```json
{
    "code": 0,
    "status": 200,
    "message": "任务已启动",
    "data": {
        "task_id": "550e8400-e29b-41d4-a716-446655440000",
        "state": "idle"
    }
}
```

---

### 5.2 查询任务状态

```
GET /api/dcu/status/{task_id}
```

**响应：**
```json
{
    "code": 0,
    "status": 200,
    "message": "success",
    "data": {
        "task_id": "550e8400-e29b-41d4-a716-446655440000",
        "state": "compressing",
        "state_display": "压缩镜像中",
        "docker_image_name": "nginx:latest",
        "gzip_file_name": "./data/gzip/nginx_latest.tar.gz",
        "progress": 50,
        "duration": 12345,
        "username": "test_user",
        "start_time": "2025-12-10 20:25:00"
    }
}
```

---

### 5.3 查询任务列表

```
GET /api/dcu/query?docker_image_name=nginx&page=1&page_size=10
```

**查询参数：**
| 参数 | 类型 | 说明 |
|------|------|------|
| docker_image_name | string | 镜像名称（模糊匹配） |
| username | string | 用户名 |
| state | string | 状态筛选 |
| page | int | 页码 |
| page_size | int | 每页数量 |

**响应：**
```json
{
    "code": 0,
    "status": 200,
    "message": "success",
    "data": {
        "total": 42,
        "items": [...]
    }
}
```

---

### 5.4 健康检查

```
GET /api/dcu/health
```

---

## 6. 数据库设计

### 6.1 DCU任务表 (dcu_tasks)

| 字段 | 类型 | 说明 |
|------|------|------|
| id | INTEGER | 主键，自增 |
| task_id | VARCHAR(100) | 任务UUID，唯一索引 |
| username | VARCHAR(100) | 用户名，索引 |
| docker_image_name | VARCHAR(500) | Docker镜像名，索引 |
| gzip_file_name | VARCHAR(500) | Gzip文件路径 |
| minio_object_name | VARCHAR(500) | MinIO对象名 |
| state | VARCHAR(50) | 状态，索引 |
| error_message | VARCHAR(2000) | 错误信息 |
| start_time | DATETIME | 开始时间，索引 |
| end_time | DATETIME | 结束时间 |
| duration | INTEGER | 持续时间(毫秒) |
| created_at | DATETIME | 创建时间 |
| updated_at | DATETIME | 更新时间 |

---

## 7. 定时任务

| 任务 | 默认Cron | 说明 |
|------|----------|------|
| Gzip清理 | `0 0 * * *` | 每天凌晨清理过期gzip文件 |
| MinIO清理 | `0 0 * * 0` | 每周日凌晨清理过期MinIO对象 |

---

## 8. 配置说明

配置文件位置：`configs/config.yaml`

```yaml
server:
  host: 0.0.0.0
  port: 8090
  mode: debug

database:
  path: ./data/dcu.db

storage:
  gzip_path: ./data/gzip
  cleanup_gzip_cron: "0 0 * * *"
  cleanup_minio_cron: "0 0 * * 0"
  gzip_retention_days: 1
  minio_retention_days: 7

minio:
  endpoint: 192.168.40.50:9000
  access_key: your_access_key
  secret_key: your_secret_key
  bucket: dcu-artifacts
  use_ssl: false
```

---

## 9. 目录结构

```
rmdc-dcu/
├── cmd/
│   └── main.go                 # 应用入口
├── configs/
│   └── config.yaml             # 配置文件
├── internal/
│   ├── config/
│   │   └── config.go           # 配置结构
│   ├── dao/
│   │   ├── database.go         # 数据库初始化
│   │   └── dcu_task_dao.go     # 任务DAO
│   ├── handler/
│   │   ├── dcu_handler.go      # API处理器
│   │   └── router.go           # 路由注册
│   ├── model/
│   │   ├── dto/
│   │   │   └── dcu_dto.go      # 请求/响应DTO
│   │   └── entity/
│   │       └── dcu_task.go     # 任务实体
│   ├── service/
│   │   ├── compress_service.go # 压缩服务
│   │   ├── dcu_service.go      # DCU编排服务
│   │   ├── docker_service.go   # Docker服务
│   │   ├── minio_service.go    # MinIO服务
│   │   └── scheduler.go        # 定时调度器
│   └── statemachine/
│       ├── machine.go          # 状态机实现
│       └── state.go            # 状态定义
├── go.mod
└── go.sum
```

---

## 10. 运行要求

- **Go**: 1.24+
- **Docker**: 已安装并配置Docker CLI
- **MinIO**: 可访问的MinIO服务器
- **SQLite3**: 自动创建（通过GORM）

---

## 11. 启动命令

```bash
cd rmdc-dcu
go run ./cmd/main.go
```

服务将在 `http://0.0.0.0:8090` 启动。
