我构建了一个带有 Rewind、断点和 Branching 的终端会话调试器

发布: (2026年2月24日 GMT+8 03:51)
8 分钟阅读
原文: Dev.to

Source: Dev.to

请提供您希望翻译的完整文本(文章正文),我将把它翻译成简体中文并保留原有的格式、Markdown 语法以及代码块和链接不变。谢谢!

问题:部署脚本失败,你只能重新开始

你正在运行一个 50 步的部署过程。第 47 步失败。你已经:

  • 完成了基础设施的配置,
  • 拉取了镜像,
  • 运行了迁移,
  • 填充了数据。

现在你有两个选项:

  1. 从第 1 步重新开始 – 浪费 45 分钟。
  2. 手动从失败的地方重新运行 – 祝你记住已经执行过的步骤。

两者都不理想。如果你能 回到第 45 步并尝试不同的路径,就像在终端里按 Ctrl+Z 一样?

这正是 devops-rewind 所做的。

3 行快速入门

pip install devops-rewind
devops-rewind record my-deploy
devops-rewind rewind my-deploy 45

Source:

工作原理

devops‑rewind 记录你运行的每一条命令——包括命令本身、stdout/stderr、退出码、工作目录和时间戳。
每条命令都会生成一个带编号的 step。当出现错误时,你可以:

  • 回溯到任意之前的 step,
  • 检查当时的精确状态,或
  • 从该点分支,尝试其他方案。

示例流程

Record a session:                     When it fails:
┌──────────────────────┐               ┌──────────────────────┐
│ [0] git pull      OK │               │ rewind to step 1     │
│ [1] make build    OK │──────────────►│ branch from step 1   │
│ [2] make test     OK │               │ try new commands     │
│ [3] make deploy FAIL│               │ diff original vs fix│
└──────────────────────┘               └──────────────────────┘
  • Step 0‑2 – 命令成功执行并被记录。
  • Step 3 – 部署失败,触发右侧 “When it fails” 所示的操作。

此时你可以回溯到任意更早的 step,检查环境,或创建一条新的命令分支来解决失败。

Source:

核心功能

记录

使用带有标识符的名称启动录制会话:

devops-rewind record my-deploy

CLI 会打开交互式提示符,捕获你运行的每一条命令:

[0] /app $ git pull
Already up to date.
[1] /app $ make build
Building...
[2] /app $ make deploy
Error: connection refused
[3] /app $ exit
Session saved: my‑deploy (3 steps)

回放

跳转到任意步骤,查看当时的具体情况:

devops-rewind rewind my-deploy 2

输出会显示该命令、其输出、当时的工作目录,以及在此之前或之后发生的任何错误的摘要。

断点

设置在特定条件下暂停回放的断点:

# 在第 47 步断点
devops-rewind breakpoint add my-deploy 47

# 在任何 kubectl 命令上断点
devops-rewind breakpoint add my-deploy --pattern "kubectl apply"

# 在任何非零退出码上断点
devops-rewind breakpoint add my-deploy --on-error

分支

从任意步骤分叉会话。新分支会继承截至该步骤的所有历史:

devops-rewind branch my-deploy 1 --exec

此时你已经进入一个新的录制会话,历史中已有第 0 步和第 1 步。可以从这里开始执行不同的命令。

差异比较

并排比较两个会话。差异引擎会找出它们分叉的确切步骤:

devops-rewind diff my-deploy my-deploy-branch-1

导出

将任意会话转换为可运行的脚本、Markdown 文档或 JSON:

devops-rewind export my-deploy --format sh > deploy.sh

为什么不直接使用 scriptasciinema

Featurescriptasciinemadevops‑rewind
Records output
Captures exit codes
Step‑by‑step replay
Rewind to any step
Breakpoints
Branch / fork
Diff two sessions
Export to shell scriptPartial

scriptasciinema 记录的是原始终端输出。它们无法识别单个命令、退出码或状态。devops‑rewind命令层面 进行记录,从而实现回放、分支和差异比较。

架构

src/devops_rewind/
├── cli.py           # Click CLI with 8 commands
├── recorder.py      # Command‑by‑command recording via subprocess
├── session.py       # Step + Session dataclasses
├── player.py        # Replay + rewind engine
├── breakpoints.py   # Step/pattern/error breakpoint types
├── branching.py     # Fork session from any step
├── differ.py        # Diverge‑point detection + diff
├── storage.py       # SQLite at ~/.devops-rewind/sessions.db
└── display.py       # Rich panels, tables, side‑by‑side columns

记录方法

我选择对每个命令使用 subprocess.run(),而不是包装 PTY。这种方式不太“真实”(记录的命令中没有交互式提示),但它具有:

  • 安全 – 每个命令都是独立的,没有 shell 注入风险
  • 可测试 – 在单元测试中易于模拟
  • 可移植 – 在 macOS、Linux 和 Windows 上均可运行
  • 结构化 – 每一步都能获得干净的 stdoutstderr,以及退出码

分支实现

分支引擎会将父会话的第 0 步到第 N 步复制到一个新的 Session 对象中,然后从该点打开一个新的记录器。父会话永不被修改。

def branch_session(session, from_step, storage, name=None):
    # Copy steps up to and including the branch point
    steps = session.steps[: from_step + 1]

    # Create a new session for the branch
    branch = Session.new(name or f"{session.name}-branch-{from_step}")

    # Deep‑copy the selected steps into the new session
    branch.steps = [step.copy() for step in steps]

    # Record branching metadata
    branch.parent_id = session.session_id
    branch.branch_point = from_step

    # Persist the new branch
    storage.save(branch)
    return branch

数字

  • 116 tests passing – 89 % coverage
  • Python 3.9‑3.12 matrix CI
  • SQLite for persistent, portable storage

实际案例

上周我在调试一个 Kubernetes 部署。过程如下:

  1. 构建 Docker 镜像
  2. 推送到镜像仓库
  3. 应用 Kubernetes 清单
  4. (其余故事在完整文档中继续)

devops-rewind 让我回到 kubectl apply 失败的确切步骤,分支出一个已修正的清单,并仅重新运行必要的命令——为我节省了超过一小时的手动回溯时间。

ConfigMap

  • 应用 Deployment
  • 等待 rollout

运行冒烟测试 — 失败

使用 devops-rewind,我记录了整个过程,回滚到第 3 步,创建了分支,并尝试了不同的 ConfigMap。差异清楚地显示有一个环境变量错误。我修复了它,将成功的分支导出为 shell 脚本,并将其添加到 CI。

节省的总时间: 大约 30 分钟,省去重新执行第 1‑5 步的时间。

试一试

pip install devops-rewind
devops-rewind record my-session

进入全屏模式
退出全屏模式

⭐️ 在 GitHub 上给它加星:
github.com/LakshmiSravyaVedantham/devops-rewind

你调试过的最长部署序列是什么?在评论区告诉我们吧。

0 浏览
Back to Blog

相关文章

阅读更多 »