SuperAPI AI 工具集

pulumi-debug-failed-operation

部署与运维

查看项目

更新于 10-15 14:59

技能介绍

用途

该技能用于调试失败的 Pulumi 操作(更新或预览)。当一次 Pulumi 操作失败后,它的目标是找出失败原因并修复。用户通常会直接指出要调试的操作,因此第一步是确定要调试的是哪次操作,并在做任何其他事情之前与用户确认。由于 Pulumi 在操作失败时已经记录了错误,一旦确定是哪次操作,就可以直接从该记录中读取错误,而无需重新运行任何东西。

主要能力

  • 通过 pulumi api 子命令访问 Pulumi Cloud,按显式的 {orgName}/{projectName}/{stackName} 路径定位堆栈,无需在本地选中该堆栈即可读取其记录。
  • 读取失败更新或失败预览所记录的引擎事件,并从中提取诊断消息。
  • 区分错误类型:provider 错误带有 error 标签,而程序错误(预览失败的常见情况)以 stderr 诊断形式出现,标签为 info#err。
  • 将每个错误追溯到引发它的资源(URN 和类型)、该资源在程序中的声明位置,以及输入它的值。
  • 判断修复应落在三个位置中的哪一个:程序(代码错误)、状态(代码正确但存储状态与真实云资源不一致)、环境(凭据、权限、OIDC 或配额问题)。
  • 当用户未指明具体操作时,通过 API 查找该堆栈上最近一次由当前用户发起的操作。

使用方式

用户通常以一组字段提供操作信息:org、project、stack 以及 update 版本(或 preview id),例如“debug update 161 of vvm-dev”。缺失的字段可从上下文补齐:org、project 或 stack 可取自当前选中的堆栈(pulumi stack --show-name、pulumi stack ls)或 Pulumi.yaml;缺失的版本表示该堆栈上最近一次更新。在继续读取之前,简要确认所定位到的操作、其版本或 preview id 以及堆栈。

读取失败信息时,对失败的更新使用带版本号的 update 路径:

pulumi api /api/stacks/{orgName}/{projectName}/{stackName}/update/<version>/events \
  | jq -r '.events[].diagnosticEvent | select(. != null) | "[\(.severity)] \(.message)"' \
  | sed 's/<{%reset%}>//g'

对失败的预览使用带 preview id 的 preview 路径:

pulumi api /api/stacks/{orgName}/{projectName}/{stackName}/preview/<preview-id>/events \
  | jq -r '.events[].diagnosticEvent | select(. != null) | "[\(.severity)] \(.message)"' \
  | sed 's/<{%reset%}>//g'

应读取每一条消息,而不仅是标记为 severity == "error" 的消息。末尾的 sed 用于去除 Pulumi 嵌入文本中的终端颜色代码,否则它们会显示为 <{%reset%}>。

当用户未指明具体操作时,调试该堆栈上最近一次操作。更新列表不记录每次更新的执行者,因此需通过 API 查找:先运行 pulumi whoami 获取当前用户的登录名;再用 pulumi api /api/stacks/{orgName}/{projectName}/{stackName}/updates/latest 读取最近一次更新及其请求者,将其 requestedBy.githubLogin 与第一步的登录名比较;若匹配,则该更新就是要调试的对象;若不匹配,则用 pulumi api /api/stacks/{orgName}/{projectName}/{stackName}/updates/<n> 逐个版本向前回溯,直到 requestedBy.githubLogin 与用户匹配。最后告知用户所定位到的操作、其版本、类型和结果,并在继续之前确认这就是他们所指的操作。

适用场景

  • 用户要求调试某次失败的 Pulumi 更新或预览。
  • 需要从 Pulumi 已记录的失败信息中定位根因。
  • 需要判断修复应落在程序代码、状态还是环境配置中。

限制

  • 当诊断信息为空或过于简略而无法采取行动时,真正的错误通常不在记录中,而在资源所调用的外部日志里,需要到那里读取。
  • 如果访问该日志需要当前不具备的权限(令牌、运行、未找到),应停止并告知用户受阻之处以及需要他们提供的那一项内容。
  • 修复时应做能解决根因的最小改动;如何确认修复以及如何交付(本地编辑还是拉取请求)遵循所在模式的工作流,而非本技能。
  • 部分应用后失败的操作可能已经改变了一些资源,因此在决定之前应检查当前状态。