stephrobert/dsoxlab
GitHub: stephrobert/dsoxlab
dsoxlab 是一个领域无关的 CLI 框架,用于跨多个仓库驱动和自动化管理 DevSecOps 实操学习实验室,涵盖环境配置、系统状态验证评分和学习进度追踪。
Stars: 50 | Forks: 3
# dsoxlab — DevSecOps XL Labs CLI
[](https://github.com/stephrobert/dsoxlab/actions/workflows/ci.yml)
[](https://securityscorecards.dev/viewer/?uri=github.com/stephrobert/dsoxlab)
[](https://score.getplumber.io/github.com/stephrobert/dsoxlab)
[](./LICENSE)
[](https://www.python.org/)
[](https://github.com/astral-sh/ruff)
**其他语言阅读:** [Français](./README.fr.md)
`dsoxlab` 是一个**领域无关的 CLI 框架**,用于驱动分布在**多个仓库**中的
实操学习实验室。每个仓库通过根目录的 `meta.yml` 文件以及每个实验室对应的
`lab.yaml` 来声明其自己的目录。
该框架可以同样出色地服务于 Linux、Ansible、Kubernetes 或 Terraform 实验室——
任何遵循声明式契约的内容。它会配置环境、运行基础设施级别的验证(`pytest` +
`pytest-testinfra`)、对进度进行评分,并在本地保存历史记录。引擎本身不包含
任何特定领域的逻辑。
# a specific lab
dsoxlab guide --print # print the URL instead (useful over SSH)
```
该 URL 带有活动参数(`utm_source=dsoxlab`、`utm_medium=lab`、
`utm_campaign=`),这样培训师就可以看到哪些实验室实际上
将读者引导到了哪些指南。从本地界面打开的链接不携带可用的 referrer,
因此如果没有这种标记,这些阅读量将无法与直接流量区分开来。
动态切换语言:
```
DSOXLAB_LANG=fr dsoxlab fullhelp
DSOXLAB_LANG=en dsoxlab fullhelp
```
## 声明式契约
托管实验室的仓库通过两个级别的文件来描述其目录。
### 1. 仓库根目录下的 `meta.yml`
仓库元数据、基础设施拓扑(KVM/Incus)、章节排序。
```
repo:
id: linux-training
category: linux
title: "Linux Training — RHCSA + LFCS 2026"
blog_url: "https://blog.stephane-robert.info/docs/admin-serveurs/linux/"
infra:
network: lab-linux
hosts:
- { name: alma-rhcsa-1.lab, ip: 10.10.30.11, distro: alma10 }
- { name: alma-rhcsa-2.lab, ip: 10.10.30.12, distro: alma10 }
- { name: ubuntu-lfcs-1.lab, ip: 10.10.30.21, distro: ubuntu24 }
sections:
- id: depanner
title: "Troubleshooting"
labs:
- depanner/services-processus/service-crash-loop
- depanner/stockage-fs/disque-plein-mais-pas-de-fichiers
```
### 2. 每个实验室的 `lab.yaml`(位于 `labs////` 下)
特定于实验室的元数据(技能、runtime、发行版、验证)。
```
id: depanner-service-crash-loop
title: "Identify and fix a crash-looping systemd service"
section: linux
level: l2
track: [depanner, rhcsa]
skills: [systemd, journalctl, debug]
difficulty: intermediate
estimated_time: 30m
runtime:
type: kvm
host: alma-rhcsa-1.lab
distros: [rhel10, ubuntu24.04]
doc_url: https://blog.stephane-robert.info/docs/admin-serveurs/linux/depanner/services-processus/service-crash-loop/
validation:
functional: true
security: false
persistence_after_reboot: true
```
可选的 `lab.fr.yaml` 可以仅在法语环境下覆盖 `title` 和
`description`。
`dsoxlab validate-structure` 会检查整个契约是否成立:根目录的
`meta.yml` 格式正确,每个被引用的实验室都存在且具有有效的
`lab.yaml`,每个 `runtime.host` 都映射到已声明的 host,并且所有引用的
脚本和测试文件都存在。
## 命令参考
| 命令 | 用途 |
| --- | --- |
| `dsoxlab use [section[/level]]` | 设置活动上下文;`--reset` 清除上下文,`--provider` 选择基础设施 provider |
| `dsoxlab list-labs` | 列出当前仓库的实验室(可通过 `--section`/`--level`/`--type`/`--bloc` 过滤) |
| `dsoxlab show ` | 显示实验室的详细信息 |
| `dsoxlab course [section]` | 显示课程章节或目录 |
| `dsoxlab guide [id]` | 在浏览器中打开实验室的在线指南(`--print` 显示 URL) |
| `dsoxlab run ` | 准备并启动实验室环境 |
| `dsoxlab challenge ` | 显示实验室的挑战任务 |
| `dsoxlab hint ` | 显示提示(会从分数中扣除) |
| `dsoxlab check ` | 运行 `pytest` 验证并记录分数 |
| `dsoxlab submit ` | 最终提交:运行测试、记录分数、关闭会话 |
| `dsoxlab scores` | 显示运行历史记录(本地 SQLite) |
| `dsoxlab progress` | 按 bloc 查看进度(已完成实验室、平均分、挑战) |
| `dsoxlab next` | 推荐下一个要处理的实验室或挑战 |
| `dsoxlab reset ` | 将实验室重置为初始状态 |
| `dsoxlab clean ` | 运行实验室的 `cleanup.sh` |
| `dsoxlab provision` | 配置实验室基础设施(`terraform apply`) |
| `dsoxlab destroy` | 销毁实验室基础设施(`terraform destroy`) |
| `dsoxlab status` | 检查与 `meta.yml` 中所有 host 的 SSH 连接性 |
| `dsoxlab ssh ` | 在实验室 host 上开启交互式 SSH 会话 |
| `dsoxlab validate-structure` | 验证契约(`meta.yml` + 每一个 `lab.yaml`) |
| `dsoxlab doctor [--fix]` | 诊断(并修复)本地环境 |
| `dsoxlab install` | 安装 shell 包装器和自动补全 |
| `dsoxlab instructor bootstrap` | 讲师工具(例如生成实验室 SSH 密钥) |
| `dsoxlab fullhelp` | 完整的多语言指南(EN/FR) |
运行 `dsoxlab --help` 可查看任何命令的选项。
## Runtimes
| Runtime | 后端 | 典型用例 |
| --- | --- | --- |
| `shell` | 本地 shell | 快速、单机练习,无虚拟机开销 |
| `incus` | Incus 容器 | 隔离、快速启动的 Linux 环境 |
| `kvm` | Terraform + libvirt | 具备重启/持久化测试功能的完整虚拟机 |
每种 runtime 都是可选且自我描述的(`is_available()`),因此引擎
绝不会强行依赖于用户尚未安装的后端。配置模板(Terraform HCL、cloud-init)位于
`dsoxlab.templates` 下,并支持 Incus、KVM/libvirt 和 Outscale。
## 架构
```
src/dsoxlab/
├── cli.py ← Typer entry point (+ i18n command group)
├── config.py ← LAB_HOME, active context, .dsoxlab-context.json
├── i18n/ ← get_lang(), _(), en.py + fr.py
├── models/ ← typed schemas of the declarative contract
├── discovery/ ← scan meta.yml + every lab.yaml of the current repo
├── services/ ← business orchestration (get_lab, run_lab, check_lab…)
├── sessions/ ← SQLite persistence (results + hint_requests)
├── runtimes/ ← BaseRuntime, ShellRuntime, IncusRuntime, KvmRuntime
├── infra/ ← Terraform, Ansible, inventory, snapshots
├── validators/ ← contract validation (meta.yml + lab.yaml)
├── reporting/ ← Rich terminal output
├── utils/ ← centralized subprocess wrapper
└── templates/ ← provisioning templates (HCL, cloud-init)
```
引擎保持独立于任何单一的仓库布局:`discovery/`
适用于 `meta.yml` 声明的任何目录树。
## 持久化
- **本地会话:** 位于当前仓库的 `.dsoxlab-context.json`(被每个实验室
仓库 gitignore)。
- **分数和提示:** `~/.local/share/dsoxlab/progress.db`(遵循 XDG 规范)。全局
实验室 ID 为 `..`,因此 schema 保持通用。
- **用户配置:** `~/.config/dsoxlab/config.yaml`(可选)。
使用标准的 `XDG_DATA_HOME` / `XDG_CONFIG_HOME` 环境变量覆盖这些位置。
## 开发
```
uv sync # install dev dependencies
uv run pre-commit install --install-hooks # enable the git hooks
uv run ruff check src/dsoxlab # lint + security
uv run mypy src/dsoxlab # type-check (strict)
uv run pytest # tests
```
有关工作流程、提交约定以及不可商议的规则(引擎必须保持领域无关性,
每个面向用户的字符串在两种语言中都必须通过 `_()` 进行处理),请参阅 [CONTRIBUTING.md](./CONTRIBUTING.md)。
## 安全
安全态势是强制执行的,而非仅仅停留在愿景上——每次推送和 pull request 时,
每个工作流都会由其自身的工具进行扫描:
- **强化的 GitHub Actions。** 每个 action 都被固定到完整的 commit SHA,默认
token 没有任何权限(job 采用最小权限原则),并且
`checkout` 不会持久化凭据。
- **[zizmor](https://github.com/zizmorcore/zizmor)** 会在每个 PR 上对工作流
进行静态分析(`ci.yml`)。
- **[Plumber](https://getplumber.io)** 以 100% 的合规性阈值根据信任
策略(`.plumber.yaml`)验证 CI/CD,并发布
评分徽章(`plumber.yml`)。
- **[OpenSSF Scorecard](https://securityscorecards.dev)** 跟踪
供应链安全态势(`scorecard.yml`)。
- **PyPI Trusted Publishing (OIDC)。** 发布版本不携带长期 token,并且
提供 [PEP 740](https://peps.python.org/pep-0740/) 证明(`release.yml`)。
- **Pre-commit 密钥扫描。** 在每次提交前会在本地运行 TruffleHog 和
私钥检测(参见 [CONTRIBUTING.md](./CONTRIBUTING.md))。
要报告漏洞,请遵循 [SECURITY.md](./SECURITY.md)。
## 许可证与归属
基于 **Apache License 2.0** 授权——请参阅 [LICENSE](./LICENSE) 和
[NOTICE](./NOTICE)。
您可以使用、共享和修改本项目(包括商业用途),**前提是您必须对
Stephane Robert 给予适当的署名并链接回
**,同时说明是否进行了更改。
Apache-2.0 保留了这两项相同的义务——署名并说明您的
更改——并增加了明确的专利授权。
在 **0.1.12** 版本及之前,dsoxlab 是在知识共享署名 4.0 (CC BY 4.0) 下分发的。
该授权不可撤销,因此这些版本仍然可以在 CC BY 4.0 下使用。从 **0.1.13** 版本开始,
本项目采用 Apache-2.0:知识共享许可协议并非为软件而设计,
而且该协议留下了未决的专利问题,同时在 PyPI 上将此包标记为 `Other/NOASSERTION`。
© 2026 Stephane Robert。
标签:Python, 安全规则引擎, 教育与培训, 无后门, 系统提示词, 逆向工具