stephrobert/dsoxlab

GitHub: stephrobert/dsoxlab

dsoxlab 是一个领域无关的 CLI 框架,用于跨多个仓库驱动和自动化管理 DevSecOps 实操学习实验室,涵盖环境配置、系统状态验证评分和学习进度追踪。

Stars: 50 | Forks: 3

# dsoxlab — DevSecOps XL Labs CLI [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/stephrobert/dsoxlab/actions/workflows/ci.yml) [![OpenSSF Scorecard](https://img.shields.io/ossf-scorecard/github.com/stephrobert/dsoxlab?label=OpenSSF%20Scorecard)](https://securityscorecards.dev/viewer/?uri=github.com/stephrobert/dsoxlab) [![Plumber compliance](https://score.getplumber.io/github.com/stephrobert/dsoxlab.svg)](https://score.getplumber.io/github.com/stephrobert/dsoxlab) [![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](./LICENSE) [![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/) [![Code style: ruff](https://img.shields.io/badge/lint-ruff-orange.svg)](https://github.com/astral-sh/ruff) **其他语言阅读:** [Français](./README.fr.md) `dsoxlab` 是一个**领域无关的 CLI 框架**,用于驱动分布在**多个仓库**中的 实操学习实验室。每个仓库通过根目录的 `meta.yml` 文件以及每个实验室对应的 `lab.yaml` 来声明其自己的目录。 该框架可以同样出色地服务于 Linux、Ansible、Kubernetes 或 Terraform 实验室—— 任何遵循声明式契约的内容。它会配置环境、运行基础设施级别的验证(`pytest` + `pytest-testinfra`)、对进度进行评分,并在本地保存历史记录。引擎本身不包含 任何特定领域的逻辑。

dsoxlab in action: list-labs and show

## 为什么选择 dsoxlab - **一个引擎,多个目录。** 单个 CLI 即可驱动所有的培训 仓库。只需编写一个 `meta.yml` 即可添加新领域,无需修补工具。 - **验证重在证明,而非轻信。** 实验室的评分基于实际的 **系统状态**(`pytest-testinfra`),并且在重要时,会基于 **重启后的持久性**——这是导致 RHCSA/LFCS 考生失败的陷阱。 - **多种 runtime。** 可以根据每个实验室的需要,在纯 **shell**、**Incus** 容器或完整的 **KVM/libvirt** 虚拟机中运行实验室。 - **持久的进度记录。** 分数、提示消耗和历史记录会按照 XDG 规范 保存在本地 SQLite 数据库中。 - **双语用户体验。** 每个面向用户的字符串都提供英语和法语版本 (`DSOXLAB_LANG=en|fr`)。 ## 安装 需要 **Python 3.11+** 和 [uv](https://docs.astral.sh/uv/)。 ``` # 从 Git repository 安装(开发 / editable mode) git clone https://github.com/stephrobert/dsoxlab.git cd dsoxlab uv tool install --editable . # 验证 dsoxlab --version dsoxlab doctor ``` `dsoxlab doctor --fix` 会对 runtime 所需的本地工具链进行诊断(并在可能的情况下进行修复): SSH、Terraform、libvirt/Incus 以及内嵌的 `pytest` 技术栈。 ## 快速开始 实验室存在于它们自己的仓库中,与引擎分开发布。 首先克隆一个仓库,然后在其中运行 `dsoxlab`: ``` # 1. Clone 一个 lab catalog(例如 linux-dsoxlab-training) git clone https://github.com/stephrobert/linux-dsoxlab-training.git cd linux-dsoxlab-training # 2. 从 repo 的 meta.yml 自动检测 active context dsoxlab list-labs dsoxlab show linux.depanner.service-crash-loop dsoxlab guide linux.depanner.service-crash-loop # read the course in your browser dsoxlab run linux.depanner.service-crash-loop dsoxlab check linux.depanner.service-crash-loop ``` ### 阅读课程 课程本身并不打包在实验室仓库中:每个实验室都会声明一个 `doc_url` 指向培训师的网站。`dsoxlab guide` 会在真实的浏览器标签页中打开该页面, 因此它能完全按照发布时的原样进行渲染,包括其图像、代码 块和导航。 ``` dsoxlab guide # the active lab dsoxlab guide # 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, 安全规则引擎, 教育与培训, 无后门, 系统提示词, 逆向工具