252 lines
9.2 KiB
Markdown
252 lines
9.2 KiB
Markdown
|
|
# Volcengine Server Manager - 设计文档
|
|||
|
|
|
|||
|
|
**日期**: 2026-04-04
|
|||
|
|
**状态**: 待审核
|
|||
|
|
|
|||
|
|
## 概述
|
|||
|
|
|
|||
|
|
Windows 桌面应用,用于管理火山引擎云服务器 ECS。首期功能:查看服务器状态、重启服务器。
|
|||
|
|
|
|||
|
|
## 技术栈
|
|||
|
|
|
|||
|
|
| 层 | 选型 | 说明 |
|
|||
|
|
|---|------|------|
|
|||
|
|
| GUI | egui + eframe (glow backend) | 纯 Rust,无外部依赖,单 exe 友好 |
|
|||
|
|
| 火山引擎 API | volcengine-rust-sdk (1.0.2) | crates.io 官方 SDK |
|
|||
|
|
| HTTP | reqwest (SDK 自带) | SDK 内部使用 |
|
|||
|
|
| 异步运行时 | tokio | API 异步调用 |
|
|||
|
|
| 序列化 | serde + serde_json | 配置读写、API 响应解析 |
|
|||
|
|
| 编译目标 | x86_64-pc-windows-gnu | MSYS2 MinGW 工具链 |
|
|||
|
|
|
|||
|
|
## 配置
|
|||
|
|
|
|||
|
|
### 配置项
|
|||
|
|
|
|||
|
|
| 配置项 | 类型 | 默认值 | 必填 | 说明 |
|
|||
|
|
|--------|------|--------|------|------|
|
|||
|
|
| access_key_id | String | 空 | 是 | 火山引擎 Access Key ID |
|
|||
|
|
| secret_access_key | String | 空 | 是 | 火山引擎 Secret Access Key |
|
|||
|
|
| endpoint | String | `ecs.volcengineapi.com` | 否 | ECS API 端点 |
|
|||
|
|
|
|||
|
|
### 存储方式
|
|||
|
|
|
|||
|
|
- 文件路径: `%APPDATA%\volcengine-server-manager\config.json`
|
|||
|
|
- 格式: JSON
|
|||
|
|
- 首次启动时检测配置是否存在,不存在则弹出配置弹窗
|
|||
|
|
|
|||
|
|
## 火山引擎 API 调用
|
|||
|
|
|
|||
|
|
### DescribeInstances(查询实例列表)
|
|||
|
|
|
|||
|
|
- **目的**: 获取用户账号下所有 ECS 实例
|
|||
|
|
- **请求参数**: `MaxResults=100`,支持分页
|
|||
|
|
- **响应关键字段**:
|
|||
|
|
- `InstanceId` - 实例 ID
|
|||
|
|
- `InstanceName` - 实例名称
|
|||
|
|
- `Status` - 实例状态(Running, Stopped, etc.)
|
|||
|
|
- `PrivateIpAddresses` - 私网 IP
|
|||
|
|
- `PublicIpAddresses` - 公网 IP
|
|||
|
|
- `ZoneId` - 可用区
|
|||
|
|
- `RegionId` - 地域
|
|||
|
|
- `InstanceType` - 实例规格
|
|||
|
|
- `CreationTime` - 创建时间
|
|||
|
|
|
|||
|
|
### RebootInstance(重启单台实例)
|
|||
|
|
|
|||
|
|
- **目的**: 重启指定 ECS 实例
|
|||
|
|
- **请求参数**: `InstanceId` (字符串)
|
|||
|
|
- **响应**: 操作结果
|
|||
|
|
- **注意**: 重启前需要用户确认弹窗
|
|||
|
|
|
|||
|
|
### 区域处理
|
|||
|
|
|
|||
|
|
- 不要求用户手动配置 Region
|
|||
|
|
- 先调用 `DescribeRegions` 获取所有可用区域列表
|
|||
|
|
- 对每个区域并发调用 `DescribeInstances` 获取该区域实例
|
|||
|
|
- 如果 `DescribeRegions` 不可用,则使用常见区域列表硬编码:`cn-beijing`, `cn-shanghai`, `cn-guangzhou`, `cn-chengdu`, `ap-singapore-1`
|
|||
|
|
|
|||
|
|
## 架构设计
|
|||
|
|
|
|||
|
|
### 模块划分
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
src/
|
|||
|
|
├── main.rs # 入口:初始化 tokio 运行时,启动 eframe
|
|||
|
|
├── app.rs # egui UI 主逻辑:渲染、事件处理、状态管理
|
|||
|
|
├── config.rs # 配置结构体、JSON 读写
|
|||
|
|
├── api.rs # 火山引擎 API 封装
|
|||
|
|
└── types.rs # 数据类型定义
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 模块职责
|
|||
|
|
|
|||
|
|
#### `types.rs`
|
|||
|
|
- `InstanceStatus` 枚举: Running, Stopped, Starting, Stopping, Rebooting, Error, Unknown
|
|||
|
|
- `InstanceInfo` 结构体: 实例完整信息
|
|||
|
|
- `AppState` 枚举: Loading, Ready, Error(String)
|
|||
|
|
|
|||
|
|
#### `config.rs`
|
|||
|
|
- `AppConfig` 结构体: 配置项
|
|||
|
|
- `load_config()` -> `Result<AppConfig>`
|
|||
|
|
- `save_config(&AppConfig)` -> `Result<()>`
|
|||
|
|
- 配置目录: `%APPDATA%\volcengine-server-manager\`
|
|||
|
|
|
|||
|
|
#### `api.rs`
|
|||
|
|
- `VolcClient` 结构体: 封装 SDK Session 或 HTTP 客户端
|
|||
|
|
- `new(access_key_id, secret_access_key, endpoint)` -> Self
|
|||
|
|
- `list_instances()` -> `Result<Vec<InstanceInfo>>`
|
|||
|
|
- `reboot_instance(instance_id)` -> `Result<()>`
|
|||
|
|
- **签名机制**: 火山引擎使用 HMAC-SHA256 签名,SDK 不支持时直接构造 HTTP 请求
|
|||
|
|
|
|||
|
|
#### `app.rs`
|
|||
|
|
- `VolcManagerApp` 结构体: egui App 实现
|
|||
|
|
- 状态: instances (Vec), app_state, config, show_config_dialog, selected_instance, loading
|
|||
|
|
- `update()`: UI 渲染主循环
|
|||
|
|
- 方法: `refresh_instances()`, `reboot_selected()`, `open_config_dialog()`, `save_config()`
|
|||
|
|
|
|||
|
|
#### `main.rs`
|
|||
|
|
- 初始化配置
|
|||
|
|
- 创建 tokio 运行时
|
|||
|
|
- 启动 eframe native window
|
|||
|
|
- 设置 `windows_subsystem = "windows"` 去掉控制台
|
|||
|
|
|
|||
|
|
### 数据流
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
用户操作 → egui 事件 → App 方法 → tokio spawn 后台任务 → API 调用 → 结果通过 channel 返回 → 更新 state → request_repaint() → UI 刷新
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### UI 布局
|
|||
|
|
|
|||
|
|
#### 主窗口
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌──────────────────────────────────────────────────────┐
|
|||
|
|
│ 火山引擎服务器管理 [刷新] [⚙ 配置] │
|
|||
|
|
├──────────────────────────────────────────────────────┤
|
|||
|
|
│ │
|
|||
|
|
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
|
|||
|
|
│ │ 实例名称 │ │ 实例名称 │ │ 实例名称 │ │
|
|||
|
|
│ │ 状态: 运行中 │ │ 状态: 已停止 │ │ 状态: 运行中 │ │
|
|||
|
|
│ │ IP: x.x.x.x │ │ IP: x.x.x.x │ │ IP: x.x.x.x │ │
|
|||
|
|
│ │ 区域: cn-beijing │ 区域: cn-shanghai │ 区域: cn-guangzhou│
|
|||
|
|
│ │ 规格: ecs.g3i.large │ 规格: ... │ 规格: ... │ │
|
|||
|
|
│ │ │ │ │
|
|||
|
|
│ │ [🔄 重启] │ [▶ 启动] │ [🔄 重启] │
|
|||
|
|
│ └────────────┘ └────────────┘ └────────────┘ │
|
|||
|
|
│ │
|
|||
|
|
│ ┌────────────┐ ┌────────────┐ │
|
|||
|
|
│ │ ... │ │ ... │ │
|
|||
|
|
│ └────────────┘ └────────────┘ │
|
|||
|
|
│ │
|
|||
|
|
├──────────────────────────────────────────────────────┤
|
|||
|
|
│ 实例数: 5 最后刷新: 2026-04-04 19:30 │
|
|||
|
|
└──────────────────────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 配置弹窗(Modal)
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌────────────────────────────────────┐
|
|||
|
|
│ 配置 │
|
|||
|
|
├────────────────────────────────────┤
|
|||
|
|
│ Access Key ID: │
|
|||
|
|
│ [________________________________]│
|
|||
|
|
│ │
|
|||
|
|
│ Secret Access Key: │
|
|||
|
|
│ [________________________________]│
|
|||
|
|
│ │
|
|||
|
|
│ Endpoint: │
|
|||
|
|
│ [ecs.volcengineapi.com___________]│
|
|||
|
|
│ │
|
|||
|
|
│ [保存] [取消] │
|
|||
|
|
└────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 重启确认弹窗
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌────────────────────────────────────┐
|
|||
|
|
│ 确认重启 │
|
|||
|
|
├────────────────────────────────────┤
|
|||
|
|
│ 确定要重启实例 "xxx" 吗? │
|
|||
|
|
│ 实例 ID: i-xxxxxxxxxxxx │
|
|||
|
|
│ │
|
|||
|
|
│ [确定] [取消] │
|
|||
|
|
└────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 状态颜色映射
|
|||
|
|
|
|||
|
|
| 状态 | 颜色 |
|
|||
|
|
|------|------|
|
|||
|
|
| Running | 绿色 |
|
|||
|
|
| Stopped | 灰色 |
|
|||
|
|
| Starting | 蓝色 |
|
|||
|
|
| Stopping | 橙色 |
|
|||
|
|
| Rebooting | 橙色 |
|
|||
|
|
| Error | 红色 |
|
|||
|
|
| Unknown | 黄色 |
|
|||
|
|
|
|||
|
|
### 错误处理
|
|||
|
|
|
|||
|
|
- API 调用失败:底部状态栏显示错误信息,3 秒后自动消失
|
|||
|
|
- 配置未设置:首次启动弹出配置弹窗,阻止主界面操作
|
|||
|
|
- 网络异常:显示 "网络连接失败,请检查网络设置"
|
|||
|
|
- 认证失败:显示 "Access Key 或 Secret Key 无效"
|
|||
|
|
|
|||
|
|
### 中文支持
|
|||
|
|
|
|||
|
|
- 加载 Windows 系统字体 `C:\Windows\Fonts\msyh.ttc`(微软雅黑)
|
|||
|
|
- 通过 `egui::FontDefinitions` 注入为默认字体
|
|||
|
|
- 如果字体加载失败,回退到 egui 内置字体(英文字符)
|
|||
|
|
|
|||
|
|
### 编译配置
|
|||
|
|
|
|||
|
|
#### Cargo.toml 关键设置
|
|||
|
|
|
|||
|
|
```toml
|
|||
|
|
[package]
|
|||
|
|
name = "volcengine-server-manager"
|
|||
|
|
version = "0.1.0"
|
|||
|
|
edition = "2021"
|
|||
|
|
|
|||
|
|
[[bin]]
|
|||
|
|
name = "volcengine-server-manager"
|
|||
|
|
path = "src/main.rs"
|
|||
|
|
|
|||
|
|
[profile.release]
|
|||
|
|
opt-level = 2
|
|||
|
|
strip = true
|
|||
|
|
lto = true
|
|||
|
|
|
|||
|
|
# Windows 子系统设置(去掉控制台窗口)
|
|||
|
|
[package.metadata.windows]
|
|||
|
|
subsystem = "windows"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
实际去掉控制台的方法:在 `main.rs` 中设置 `#![windows_subsystem = "windows"]` 属性。
|
|||
|
|
|
|||
|
|
### 依赖列表
|
|||
|
|
|
|||
|
|
```toml
|
|||
|
|
[dependencies]
|
|||
|
|
eframe = { version = "0.29", default-features = false, features = ["glow"] }
|
|||
|
|
egui = "0.29"
|
|||
|
|
volcengine-rust-sdk = "1.0.2"
|
|||
|
|
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
|
|||
|
|
serde = { version = "1", features = ["derive"] }
|
|||
|
|
serde_json = "1"
|
|||
|
|
dirs = "5"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 编译命令
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 在 MSYS2 MinGW 环境下
|
|||
|
|
rustup target add x86_64-pc-windows-gnu
|
|||
|
|
cargo build --release --target x86_64-pc-windows-gnu
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
输出文件: `target/x86_64-pc-windows-gnu/release/volcengine-server-manager.exe`
|