Skip to content

<fix>[storage]: ZSV-12469 support volume encryption conversion rollback#4494

Open
ZStack-Robot wants to merge 3 commits into
feature-zsv-5.1.0-encryptionfrom
sync/zstackio/dev/encrypted-volume-snapshot-conversion-rollback@@3
Open

<fix>[storage]: ZSV-12469 support volume encryption conversion rollback#4494
ZStack-Robot wants to merge 3 commits into
feature-zsv-5.1.0-encryptionfrom
sync/zstackio/dev/encrypted-volume-snapshot-conversion-rollback@@3

Conversation

@ZStack-Robot

Copy link
Copy Markdown
Collaborator

Summary

Split volume/snapshot encryption conversion rollback support into an independent base branch for ZSV-12469.

Changes

  • Add rollback message/reply for volume encryption conversion on primary storage.
  • Route conversion rollback through LocalStorage, NFS, and Ceph backends.
  • Restore source bits from sourceTrash on rollback instead of only deleting converted target bits.
  • Avoid deterministic sourceTrash install path conflicts across repeated conversion attempts.

Testing

  • git diff --check
  • cbok/default-env verification
  • CI pipeline

Resolves: ZSV-12469

sync from gitlab !10455

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

本次变更新增卷加密转换回滚消息,重构转换路径和数据库更新逻辑,并为 Ceph、LocalStorage、NFS 主存储接入回滚处理及对应测试模拟器。

Changes

卷加密转换与回滚

Layer / File(s) Summary
回滚消息与处理契约
header/src/main/java/org/zstack/header/storage/primary/..., plugin/localstorage/..., plugin/nfsPrimaryStorage/...
新增回滚消息与回复类型,移除转换项的源临时路径字段,并扩展 LocalStorage、NFS 的回滚处理接口。
转换计划与数据库更新
storage/src/main/java/org/zstack/storage/volume/VolumeBase.java
转换计划根据目标加密状态生成新路径和转换项;回滚改为发送主存储消息,并更新卷、快照路径及加密状态。
Ceph 转换与回滚执行
plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java
转换前检查目标 bits,使用新参数执行转换,支持 Ceph rollback convert,并根据实际大小或同步结果回复。
LocalStorage 与 NFS 回滚接入
plugin/localstorage/..., plugin/nfsPrimaryStorage/..., storage/src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java
新增消息路由、agent 命令、主机调用和异步结果处理;不支持的主存储类型返回错误。
转换测试模拟器
testlib/src/main/java/org/zstack/testlib/...
更新 Ceph 目标存在性模拟,并为 LocalStorage、NFS 转换创建目标 Qcow2 与实际大小响应。

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant VolumeBase
  participant PrimaryStorage
  participant StorageAgent
  VolumeBase->>PrimaryStorage: 发送回滚消息与转换条目
  PrimaryStorage->>StorageAgent: 下发卷加密回滚命令
  StorageAgent-->>PrimaryStorage: 返回执行结果
  PrimaryStorage-->>VolumeBase: 返回回滚回复
Loading

Poem

我是小兔,蹦过新路径,
抱着回滚消息轻轻行。
Ceph、NFS、LocalStorage 齐响应,
Qcow2 目标稳稳成。
加密转换收好尾,
胡萝卜庆功月下明。

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 标题准确概括了本次提交的核心变化:支持卷加密转换回滚。
Description check ✅ Passed 描述与变更内容一致,明确提到了回滚支持、主存储消息以及各后端路由。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sync/zstackio/dev/encrypted-volume-snapshot-conversion-rollback@@3

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ast-grep (0.44.1)
plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java

ast-grep timed out on this file

plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java

ast-grep retry budget exhausted before isolating this batch

plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageHypervisorBackend.java

ast-grep retry budget exhausted before isolating this batch

  • 7 others

Comment @coderabbitai help to get the list of available commands.

@MatheMatrix MatheMatrix force-pushed the sync/zstackio/dev/encrypted-volume-snapshot-conversion-rollback@@3 branch 7 times, most recently from c1f218b to 9952275 Compare July 8, 2026 07:45
@zstack-robot-2

Copy link
Copy Markdown
Collaborator

Comment from yaohua.wu:

Review: MR !10455 — ZSV-12469

Background

  • Jira: ZSV-12469 — 【后端】【磁盘加密】加密属性转换
  • Bug summary: 本组 MR 为磁盘/快照加密属性转换增加失败回滚能力,避免转换后只清理 target 而未恢复 sourceTrash 中的原始 bits。Jira 描述较少,主要上下文来自 3 个 MR 的 Summary/Changes。
  • Intent & scope: zstack 侧新增 rollback message/reply,并把 VolumeBase 的转换失败回滚路由到具体 PrimaryStorage;premium 侧补 SharedBlock Java dispatch;zstack-utility 侧补 KVM agent rollback endpoints。
  • Round 1 initial findings: 0 × Critical, 1 × Warning in zstack Ceph rollback command schema;另有 1 × Warning in zstack-utility agent rollback delete safety。
  • Suggested fix direction: 对齐 Java command 与 Python agent schema,并在 agent rollback 删除 target 前复用现有 active-use / watcher 防护。

关联 MR

MR 关系
zstackio/premium !14652 SharedBlock 主存储 Java dispatch,依赖本 MR 新增的 RollbackVolumeEncryptionOnPrimaryStorageMsg
zstackio/zstack-utility !7465 KVM/Ceph/Local/NFS/SharedBlock agent rollback endpoints,必须与本 MR 的 command schema 同步合入。

Findings

Severity File:Line Issue Fix
🟡 Warning plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:506 / :3711 Ceph rollback 的 Java command 没有 volumeUuid,但 zstack-utility 的 cephagent.py:1280 在 rollback 失败时会读取 cmd.volumeUuid 组装错误。实际失败场景下会先触发 AttributeError,导致原始 rollback 失败原因被覆盖,管理节点只能看到错误格式化失败后的泛化错误。 RollbackLuksRbdCmd 增加 public String volumeUuid;,并在构造 rcmd 时设置 rcmd.volumeUuid = msg.getVolume().getUuid();;同时建议 utility 侧用 getattr(cmd, 'volumeUuid', cmd.installPath) 做兼容兜底。

Cross-Repo Notes

Check Result
Command path alignment zstack Local/NFS/Ceph path 与 zstack-utility endpoint 名称一致;premium SharedBlock path 与 utility SharedBlock endpoint 一致。
Schema alignment Local/NFS/SharedBlock 的 volumeUuid/items schema 对齐;Ceph 缺 volumeUuid,见上方 Warning。
Joint merge requirement 这 3 个 MR 使用同一 @@3 分支语义,不能只合入 zstack 侧,否则新消息会路由到未实现 agent endpoint。

Coverage

  • Local diff source: git diff 3fe399986d0b0cc90017395f08d548f451632f29..99522755c099d45ed18c046e5f4073957dd0948a
  • Generated-file filter: 0 files skipped (kept 12 / total 12)
  • Upstream freshness: target branch ref equals MR base SHA;MR metadata merge_status=can_be_merged
  • Verification run: git diff --check passed for all 3 repos
  • Testing gap: 未本地运行 cbok/default-env 或集成测试;建议覆盖 Local/NFS/SharedBlock/Ceph rollback failure path。

Verdict: REVISION_REQUIRED

Ceph rollback schema 需要与 zstack-utility 侧补齐后再合入;同时本 MR 需与两个关联 MR 联合合并。


🤖 Robot Reviewer

@MatheMatrix MatheMatrix force-pushed the sync/zstackio/dev/encrypted-volume-snapshot-conversion-rollback@@3 branch 3 times, most recently from 4e34602 to 763f2db Compare July 10, 2026 05:33
zhong.zhou added 2 commits July 11, 2026 13:10
…sion

Resolves: ZSV-12469

Tests: covered by premium EncryptVolumeConversionCase.

Change-Id: I625c1b26de3f8bb2b3c8520c936425b9d4457dcb
Related: ZSV-12469

Change-Id: I943b6c54f5cef6fafaa899c89709265b94ff7224
@MatheMatrix MatheMatrix force-pushed the sync/zstackio/dev/encrypted-volume-snapshot-conversion-rollback@@3 branch from 763f2db to 67e59ab Compare July 11, 2026 16:44
Resolves: ZSV-12469

Tests: covered by premium EncryptVolumeConversionCase.

Change-Id: I49312b0d373c696f86f79adb6274e6648cdede74
@MatheMatrix MatheMatrix force-pushed the sync/zstackio/dev/encrypted-volume-snapshot-conversion-rollback@@3 branch from 67e59ab to ab4f2b5 Compare July 11, 2026 16:58

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java (1)

3649-3692: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

三处 RollbackVolumeEncryptionOnPrimaryStorageMsg 处理方法均是对同类中既有 ConvertVolumeEncryptionOnPrimaryStorageMsg 处理方法的复制粘贴,共享同一根因:新增回滚处理逻辑未与转换处理逻辑抽取公共校验/委托代码。

  • plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java#L3649-L3692:抽取公共私有方法处理 items 数量校验、resourceType 校验及路径合法性校验(与上方 handle(ConvertVolumeEncryptionOnPrimaryStorageMsg) 共用)。
  • plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java#L964-L1005:抽取公共私有方法处理 hostUuid 解析(优先 msg.getHostUuid(),否则 getHostUuidByResourceUuid)逻辑,供 Convert 与 Rollback 处理方法共用。
  • plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java#L174-L197:抽取公共私有方法处理 getUsableBackend() 为空时的报错与委托流程,供 Convert 与 Rollback 处理方法共用。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java`
around lines 3649 - 3692, 抽取 Convert 与 Rollback 处理逻辑中的重复公共流程:在
plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:3649-3692
中新增私有方法,统一处理 items 数量、resourceType 和目标路径校验,并由两个 handle 方法复用;在
plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:964-1005
中抽取 hostUuid 解析逻辑,保持优先使用 msg.getHostUuid()、否则调用 getHostUuidByResourceUuid;在
plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:174-197
中抽取 getUsableBackend() 为空时的报错与委托流程,供 Convert 和 Rollback 处理方法共同调用。
storage/src/main/java/org/zstack/storage/volume/VolumeBase.java (2)

3733-3749: 🧹 Nitpick | 🔵 Trivial

回滚失败仅记录 warn 日志,缺少进一步的可观测性。

rollbackVolumeEncryptionOnPrimaryStorage 在主存储侧回滚消息失败时,仅打印 warn 日志便继续 trigger.rollback()。这意味着"加密转换失败 + 主存储侧回滚也失败"的双重失败场景下,运维人员仅能通过日志感知,没有额外的指标或告警渠道,可能导致目标残留文件长期未被清理却难以被发现。

建议为该失败路径补充可观测性手段(如打点、事件或专门的 GC 巡检),便于及时发现并处理这类残留。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@storage/src/main/java/org/zstack/storage/volume/VolumeBase.java` around lines
3733 - 3749, 在 rollbackVolumeEncryptionOnPrimaryStorage 的 reply 失败分支中,除现有 warn
日志外增加项目既有的可观测性机制(如失败指标、告警事件或残留 GC 巡检登记),并携带 volume UUID、primary storage UUID
及错误详情。保持 trigger.rollback() 仍被调用,确保双重失败可被后续运维及时发现和处理。

3479-3496: 🧹 Nitpick | 🔵 Trivial

旧卷位(trash)记录失败被静默吞掉,可能造成存储泄漏。

record-old-volume-bits-in-trash 步骤将 trash.createTrash 包裹在 try/catch 中,失败时仅 warn 日志继续执行。由于此时数据库已经指向新路径,一旦 trash 记录失败,旧的卷/快照文件将不再被任何清理机制追踪,长期可能造成存储空间泄漏且难以被发现。

建议在失败时补充告警或将失败项记录到可巡检的位置(如系统标签/专用表),以便后续人工或 GC 任务介入清理。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@storage/src/main/java/org/zstack/storage/volume/VolumeBase.java` around lines
3479 - 3496, 更新“record-old-volume-bits-in-trash”流程的异常处理,避免仅通过 logger.warn
后继续执行而静默丢失失败项;在 trash.createTrash
失败时,使用现有的可巡检机制(如系统标签或专用记录表)持久化卷/快照标识及错误信息,确保后续人工或 GC
可清理。保留必要告警,并确保卷和各快照的失败记录都能被追踪。
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@header/src/main/java/org/zstack/header/storage/primary/RollbackVolumeEncryptionOnPrimaryStorageMsg.java`:
- Around line 14-17: 在 RollbackVolumeEncryptionOnPrimaryStorageMsg 的
getPrimaryStorageUuid() 中增加 volume 为空时的保护,避免路由阶段直接抛出 NullPointerException;未设置
volume 时返回可表示缺失的结果,并保留已设置 volume 时通过 getPrimaryStorageUuid() 获取主存储 UUID 的行为。

---

Nitpick comments:
In
`@plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java`:
- Around line 3649-3692: 抽取 Convert 与 Rollback 处理逻辑中的重复公共流程:在
plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:3649-3692
中新增私有方法,统一处理 items 数量、resourceType 和目标路径校验,并由两个 handle 方法复用;在
plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:964-1005
中抽取 hostUuid 解析逻辑,保持优先使用 msg.getHostUuid()、否则调用 getHostUuidByResourceUuid;在
plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:174-197
中抽取 getUsableBackend() 为空时的报错与委托流程,供 Convert 和 Rollback 处理方法共同调用。

In `@storage/src/main/java/org/zstack/storage/volume/VolumeBase.java`:
- Around line 3733-3749: 在 rollbackVolumeEncryptionOnPrimaryStorage 的 reply
失败分支中,除现有 warn 日志外增加项目既有的可观测性机制(如失败指标、告警事件或残留 GC 巡检登记),并携带 volume UUID、primary
storage UUID 及错误详情。保持 trigger.rollback() 仍被调用,确保双重失败可被后续运维及时发现和处理。
- Around line 3479-3496: 更新“record-old-volume-bits-in-trash”流程的异常处理,避免仅通过
logger.warn 后继续执行而静默丢失失败项;在 trash.createTrash
失败时,使用现有的可巡检机制(如系统标签或专用记录表)持久化卷/快照标识及错误信息,确保后续人工或 GC
可清理。保留必要告警,并确保卷和各快照的失败记录都能被追踪。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 2fe25c24-c9d9-4626-90f9-262c481dd4d6

📥 Commits

Reviewing files that changed from the base of the PR and between 61897a2 and ab4f2b5.

📒 Files selected for processing (16)
  • header/src/main/java/org/zstack/header/storage/primary/ConvertVolumeEncryptionOnPrimaryStorageMsg.java
  • header/src/main/java/org/zstack/header/storage/primary/RollbackVolumeEncryptionOnPrimaryStorageMsg.java
  • header/src/main/java/org/zstack/header/storage/primary/RollbackVolumeEncryptionOnPrimaryStorageReply.java
  • plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java
  • plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java
  • plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageHypervisorBackend.java
  • plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageKvmBackend.java
  • plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java
  • plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageBackend.java
  • plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java
  • plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackendCommands.java
  • storage/src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java
  • storage/src/main/java/org/zstack/storage/volume/VolumeBase.java
  • testlib/src/main/java/org/zstack/testlib/CephPrimaryStorageSpec.groovy
  • testlib/src/main/java/org/zstack/testlib/LocalStorageSpec.groovy
  • testlib/src/main/java/org/zstack/testlib/NfsPrimaryStorageSpec.groovy
💤 Files with no reviewable changes (1)
  • header/src/main/java/org/zstack/header/storage/primary/ConvertVolumeEncryptionOnPrimaryStorageMsg.java

Comment on lines +14 to +17
@Override
public String getPrimaryStorageUuid() {
return volume.getPrimaryStorageUuid();
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

getPrimaryStorageUuid() 未对 volume 做空值校验,可能在消息路由阶段抛出 NPE

若调用方在未设置 volume 的情况下发送该消息,消息总线路由时调用 getPrimaryStorageUuid() 会直接抛出 NullPointerException,此时 handle() 方法中已有的空值校验根本不会被执行到(路由发生在 handle() 之前)。建议在此处补充空值保护。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@header/src/main/java/org/zstack/header/storage/primary/RollbackVolumeEncryptionOnPrimaryStorageMsg.java`
around lines 14 - 17, 在 RollbackVolumeEncryptionOnPrimaryStorageMsg 的
getPrimaryStorageUuid() 中增加 volume 为空时的保护,避免路由阶段直接抛出 NullPointerException;未设置
volume 时返回可表示缺失的结果,并保留已设置 volume 时通过 getPrimaryStorageUuid() 获取主存储 UUID 的行为。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants