snapshot orchestration

This commit is contained in:
iceBear67
2026-06-03 15:31:27 +08:00
parent b27a0a564e
commit 0e5c3d6c65
3 changed files with 276 additions and 62 deletions

114
USAGE.md Normal file
View File

@@ -0,0 +1,114 @@
# Composer
多租户 Docker Compose 编排工具。扫描 `users/` 下的用户目录,校验每个用户的 `compose.yml`,生成注入网络配置的快照,然后启动所有服务。
## 目录结构
```
<root>/
├── users/
│ ├── 10-alice/ # 优先级-用户名
│ │ ├── compose.yml # 必需
│ │ ├── .env # 可选(明文)
│ │ ├── .env.gpg # 可选(加密,二选一即可)
│ │ ├── app/
│ │ │ └── Dockerfile
│ │ └── ...
│ └── 20-bob/
│ └── ...
└── snapshots/ # 自动生成(每次覆盖)
├── 10-alice/
│ └── compose.yml # 已注入网络配置的版本
└── 20-bob/
```
- 目录名格式:`<数字优先级>-<用户名>`
- 用户名:`[a-z0-9]+`
- 优先级数字越小越先处理
## CLI 参数
| 参数 | 必需 | 默认值 | 说明 |
|------|------|--------|------|
| `--root` | | `.` | 项目根目录 |
| `--network` | | `cloud` | 注入到 services 的外部网络名 |
| `--volume-parent` | ✓ | | 卷挂载路径白名单前缀 |
| `--dry` | | `false` | 只打印操作,不实际执行 |
## compose.yml 约束
### 允许的顶层字段
只有 `services` 被识别。如果 YAML 中有 `networks``volumes``version` 等额外顶层键,会触发 **WARN** —— 它们会被 Pydantic 静默丢弃,可能与网络注入冲突。
### 允许的 service 字段
`build` `image` `volumes` `command` `depends_on` `entrypoint` `env_file` `environment`
`build` 可以是字符串(指向含 Dockerfile 的目录)或对象 `{context, dockerfile, args}`。其他键同样触发 WARN。
### 卷约束
所有 volume 的宿主机路径必须以 `--volume-parent` 为前缀,且只允许 `ro` 模式。
### 环境文件
- 支持明文 `.env` 或 GPG 加密 `.env.gpg`
- 只校验明文文件的内容格式(`KEY=value``export KEY=value`
- 如果只存在 `.env.gpg` 则跳过内容校验
## 运行流程
```
1. 扫描 users/ → 解析优先级和用户名
2. 加载每个 compose.yml → Pydantic 校验
3. 检测注入干扰字段WARN
4. 校验 service 引用、Dockerfile 存在性、卷路径、env_file
5. ── 有错则退出 ──
6. 为每个用户创建 snapshots/<prio>-<name>/
7. 拷贝所有文件compose.yml 注入网络配置,.gpg 文件解密
8. ── 快照失败则退出 ──
9. 在每个快照目录执行 docker compose up --remove-orphans --build --detach
```
## 网络注入
快照中的 `compose.yml` 会被注入:
```yaml
networks:
cloud: # --network 参数值
external: true
alice: # 用户名
name: alice
services:
app:
networks: [cloud, alice]
```
每个 service 的 `networks` 会被**覆盖**为 `[<network>, <username>]`
## GPG 解密
快照拷贝时,`.gpg` 后缀的文件会调用系统 `gpg --decrypt --batch` 解密,输出到去掉 `.gpg` 后缀的路径。原 `.gpg` 文件不进入快照。
要求运行环境已配置好 GPG 密钥,且能无交互解密。
## Dry-run 模式
`--dry` 执行全部校验,但只打印操作摘要:
```
[dry] would snapshot users/10-alice -> snapshots/10-alice
[dry] inject networks: .networks.cloud.external=true, ...
[dry] would run: docker compose -f snapshots/10-alice/compose.yml up ...
```
不创建目录、不写文件、不解密、不启动容器。
## 错误处理
- **校验阶段有错** → 打印错误并 `exit 1`(不创建快照)
- **快照创建失败**(单个用户)→ 标记错误,跳过该用户,继续处理其他用户;全部完成后 `exit 1`
- **compose up 失败**(单个用户)→ 标记错误,继续启动其他用户;全部完成后 `exit 1`