Skip to content

<fix>[storage]: ZSV-12473 support encrypted clone upload#4301

Open
zstack-robot-2 wants to merge 4 commits into
feature-zsv-5.1.0-encryptionfrom
sync/zstackio/codex/ceph-sblk-clone-encryption
Open

<fix>[storage]: ZSV-12473 support encrypted clone upload#4301
zstack-robot-2 wants to merge 4 commits into
feature-zsv-5.1.0-encryptionfrom
sync/zstackio/codex/ceph-sblk-clone-encryption

Conversation

@zstack-robot-2

Copy link
Copy Markdown
Collaborator

Summary

Fix encrypted Ceph clone template upload so the snapshot is cloned through a KVM host with the temporary encrypted DEK before ImageStore upload.

Changes

  • Propagate encrypted upload metadata through and .
  • Add Ceph KVM host encrypted ImageStore upload command/path.
  • Route encrypted Ceph create-template-from-snapshot through temporary encrypted RBD clone cleanup.

Testing

  • git diff --check for all four repos
  • cbok zsv compile --no-deploy --docker-host none --zstack-root /Users/mizar/.config/superpowers/worktrees/zstack/ceph-sblk-clone-encryption: header, storage, ceph, premium, mevoco, sharedblock succeeded; unrelated premium/crypto failed on missing ScannerAlarmStateVO
  • python -m py_compile kvmagent/kvmagent/plugins/imagestore.py kvmagent/kvmagent/plugins/ceph_storage_plugin.py
  • GOOS=linux GOARCH=amd64 go test -c ./client and ./client/driver under src/image-store
  • CI pipeline

Resolves: ZSV-12473

sync from gitlab !10259

zhong.zhou added 2 commits June 20, 2026 18:40
Resolves: ZSV-261

Change-Id: Iff94981e12e216380d980869b951f0d38105de87
Resolves: ZSV-12473

Change-Id: I2b78b72d2126bc51978e9dc4299b304a735bbe35
@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@MatheMatrix, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 7 minutes and 25 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 84b93d10-de87-4ac8-8c7d-5c30f9d64603

📥 Commits

Reviewing files that changed from the base of the PR and between 90f7f34 and 970d3f7.

📒 Files selected for processing (1)
  • plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java

Walkthrough

为 Ceph 主存储新增加密快照临时模板创建与上传至备份存储的支持:扩展 VolumeEncryptedResourceKeyBackend 接口、UploadBitsToBackupStorageMsgMediatorUploadParam 消息字段,在 CephPrimaryStorageBase 增加 KVM host 加密命令 DTO 与 HTTP 路径常量,在 CephPrimaryStorageFactory 工作流中新增加密临时模板创建分支(含 LUKS clone、回滚、上传透传、删除清理),并提供对应的 dummy 后端实现及密钥继承守卫。

Changes

Ceph 加密快照镜像上传流程

Layer / File(s) Summary
加密接口契约与消息 DTO 扩展
storage/.../VolumeEncryptedResourceKeyBackend.java, plugin/ceph/.../UploadBitsToBackupStorageMsg.java, header/.../MediatorUploadParam.java
VolumeEncryptedResourceKeyBackend 接口新增备份密钥绑定检查与密钥复制方法声明;UploadBitsToBackupStorageMsgMediatorUploadParam 分别新增 encrypted/encryptedDek/encryptedHostUuid 字段及访问器。
Ceph KVM host 加密命令 DTO 与路径常量
plugin/ceph/.../CephPrimaryStorageBase.java
新增 KVMHostImageStoreEncryptedDownloadCmdKVMHostImageStoreEncryptedUploadCmdKVMHostImageStoreEncryptedUploadRsp 三个静态 DTO,及对应两条 HTTP 路径常量。
加密临时模板创建工作流
plugin/ceph/.../CephPrimaryStorageFactory.java
引入 snapshotEncryptionHelper 注入字段;create-temporary-template 流程新增加密分支,实现 DEK 准备、临时 install path 计算、KVM host LUKS clone 调用、元数据写入及回滚逻辑。
上传/删除步骤加密参数透传与辅助方法
plugin/ceph/.../CephPrimaryStorageFactory.java, plugin/ceph/.../CephPrimaryStorageBase.java
upload-to-backup-storagedelete-temporary-template 步骤读取并传播加密临时路径及加密参数;CephPrimaryStorageBase 上传时将加密字段写入 MediatorUploadParam;新增三个私有辅助方法。
加密后端 Dummy 实现与密钥继承守卫
storage/.../DummyVolumeEncryptedResourceKeyBackend.java, storage/.../VolumeEncryptedInitialExtension.java
DummyVolumeEncryptedResourceKeyBackend 实现三个新增接口方法;VolumeEncryptedInitialExtension 新增守卫,目标卷已绑定 key provider 时跳过 origin 密钥复制。

Sequence Diagram(s)

sequenceDiagram
  rect rgba(173, 216, 230, 0.5)
    Note over CephPrimaryStorageFactory: create-temporary-template(加密分支)
    CephPrimaryStorageFactory->>CephPrimaryStorageFactory: findConnectedHostForCephLuks(primaryStorageUuid)
    CephPrimaryStorageFactory->>VolumeSnapshotEncryptionHelper: prepareEncryptedTemporarySnapshotImageDek(snapshotUuid, imageUuid)
    VolumeSnapshotEncryptionHelper-->>CephPrimaryStorageFactory: encryptedDek
    CephPrimaryStorageFactory->>CephPrimaryStorageFactory: makeTemporaryTemplateInstallPath
    CephPrimaryStorageFactory->>KVMHost: KVMHostLuksCloneCmd (httpCallToKvmHost)
    KVMHost-->>CephPrimaryStorageFactory: 成功,返回 size/actualSize
    CephPrimaryStorageFactory->>WorkflowData: 写入 cephEncryptedTemporaryInstallPath/encryptedDek/hostUuid
  end
  rect rgba(144, 238, 144, 0.5)
    Note over CephPrimaryStorageFactory: upload-to-backup-storage
    CephPrimaryStorageFactory->>UploadBitsToBackupStorageMsg: 设置 primaryStorageInstallPath(加密临时路径)
    CephPrimaryStorageFactory->>UploadBitsToBackupStorageMsg: 设置 encrypted/encryptedDek/encryptedHostUuid
    CephPrimaryStorageFactory->>CephPrimaryStorageBase: 触发上传
    CephPrimaryStorageBase->>MediatorUploadParam: 设置 encrypted/encryptedDek/encryptedHostUuid
    MediatorUploadParam->>BackupStorage: 上传加密镜像
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐇 小兔打开加密箱,
DEK 密钥妥善藏,
LUKS 克隆跳一跳,
备份存储安全放。
🔐 兔子签名已上传,
镜像加密喜洋洋!

🚥 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 标题清晰准确地总结了主要变更:支持加密克隆上传到ImageStore,与所有代码改动直接相关。
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sync/zstackio/codex/ceph-sblk-clone-encryption

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

@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 (1)
storage/src/main/java/org/zstack/storage/encrypt/VolumeEncryptedResourceKeyBackend.java (1)

43-44: ⚡ Quick win

请为新增接口方法补充 Javadoc 契约说明

Line 43、Line 57、Line 59 新增了接口方法,但缺少方法级注释;这里是跨模块加密密钥复制契约,建议至少补齐参数语义与行为说明(例如“仅复制绑定关系/是否幂等/异常语义”)。

可参考的最小修改
+    /**
+     * 检查备份资源是否已绑定 key provider。
+     *
+     * `@param` backupUuid 备份资源 UUID
+     * `@return` true 表示存在绑定记录
+     */
     boolean checkBackupKeyProviderAttached(String backupUuid);

+    /**
+     * 将备份资源的密钥绑定复制到临时快照镜像。
+     */
     void copyBackupKeyToTemporarySnapshotImage(String backupUuid, String imageUuid);

+    /**
+     * 将备份资源的密钥绑定复制到卷。
+     */
     void copyBackupKeyToVolume(String backupUuid, String volumeUuid);

As per coding guidelines, “接口方法不应有多余的修饰符(例如 public),且必须配有有效的 Javadoc 注释。”

Also applies to: 57-60

🤖 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/encrypt/VolumeEncryptedResourceKeyBackend.java`
around lines 43 - 44, Add Javadoc documentation to the new interface methods
checkBackupKeyProviderAttached (line 43) and the two additional methods
mentioned at lines 57-60. Each Javadoc comment should include parameter
descriptions (explaining what the input parameters like backupUuid represent), a
description of the method's behavior and return value, and any relevant contract
details specific to this cross-module encrypted key copying scenario (such as
whether the operation is idempotent, what binding relationships are affected, or
what exceptions may be thrown). Ensure the comments clearly document the
operational contract for callers of these interface methods.

Source: Coding guidelines

🤖 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
`@plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java`:
- Around line 5230-5232: Add validation for the encryption upload parameters
before transparently passing them through. In the CephPrimaryStorageBase class
where param.encrypted, param.encryptedDek, and param.encryptedHostUuid are being
assigned from the message, first validate that when msg.getEncrypted() is true,
both msg.getEncryptedDek() and msg.getEncryptedHostUuid() must be present and
non-null. If encrypted is true but either of these required fields is missing,
fail fast by throwing an exception with a clear error message indicating the
missing encryption contract fields. Only populate param.encryptedDek and
param.encryptedHostUuid when the encrypted flag is actually true, to avoid
propagating incomplete encryption data downstream.

---

Nitpick comments:
In
`@storage/src/main/java/org/zstack/storage/encrypt/VolumeEncryptedResourceKeyBackend.java`:
- Around line 43-44: Add Javadoc documentation to the new interface methods
checkBackupKeyProviderAttached (line 43) and the two additional methods
mentioned at lines 57-60. Each Javadoc comment should include parameter
descriptions (explaining what the input parameters like backupUuid represent), a
description of the method's behavior and return value, and any relevant contract
details specific to this cross-module encrypted key copying scenario (such as
whether the operation is idempotent, what binding relationships are affected, or
what exceptions may be thrown). Ensure the comments clearly document the
operational contract for callers of these interface methods.
🪄 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: 5bd87bf8-253e-4a19-8631-b94a232687de

📥 Commits

Reviewing files that changed from the base of the PR and between 4883c8b and 90f7f34.

📒 Files selected for processing (7)
  • header/src/main/java/org/zstack/header/storage/primary/MediatorUploadParam.java
  • plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java
  • plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java
  • plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/UploadBitsToBackupStorageMsg.java
  • storage/src/main/java/org/zstack/storage/encrypt/DummyVolumeEncryptedResourceKeyBackend.java
  • storage/src/main/java/org/zstack/storage/encrypt/VolumeEncryptedInitialExtension.java
  • storage/src/main/java/org/zstack/storage/encrypt/VolumeEncryptedResourceKeyBackend.java

Comment on lines +5230 to +5232
param.encrypted = msg.getEncrypted();
param.encryptedDek = msg.getEncryptedDek();
param.encryptedHostUuid = msg.getEncryptedHostUuid();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

先校验加密上传参数再透传。

encrypted=true 时,encryptedDekencryptedHostUuid 是后续 KVM/ImageStore 加密上传的必需契约;这里直接透传会把缺失字段推迟到下游失败,可能产出不可用的备份模板。建议在消息边界 fail fast,并只在加密场景填充敏感字段。

建议修复
         param.primaryStorageUuid = msg.getPrimaryStorageUuid();
         param.primaryStorageInstallPath = msg.getPrimaryStorageInstallPath();
         param.backupStorageInstallPath = msg.getBackupStorageInstallPath();
-        param.encrypted = msg.getEncrypted();
-        param.encryptedDek = msg.getEncryptedDek();
-        param.encryptedHostUuid = msg.getEncryptedHostUuid();
+        if (Boolean.TRUE.equals(msg.getEncrypted()) &&
+                (StringUtils.isBlank(msg.getEncryptedDek()) || StringUtils.isBlank(msg.getEncryptedHostUuid()))) {
+            reply.setError(operr(
+                    "encrypted upload requires encryptedDek and encryptedHostUuid; image[uuid:%s], backupStorage[uuid:%s]",
+                    msg.getImageUuid(), msg.getBackupStorageUuid()));
+            bus.reply(msg, reply);
+            completion.done();
+            return;
+        }
+        param.encrypted = Boolean.TRUE.equals(msg.getEncrypted());
+        if (param.encrypted) {
+            param.encryptedDek = msg.getEncryptedDek();
+            param.encryptedHostUuid = msg.getEncryptedHostUuid();
+        }
🤖 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 5230 - 5232, Add validation for the encryption upload parameters
before transparently passing them through. In the CephPrimaryStorageBase class
where param.encrypted, param.encryptedDek, and param.encryptedHostUuid are being
assigned from the message, first validate that when msg.getEncrypted() is true,
both msg.getEncryptedDek() and msg.getEncryptedHostUuid() must be present and
non-null. If encrypted is true but either of these required fields is missing,
fail fast by throwing an exception with a clear error message indicating the
missing encryption contract fields. Only populate param.encryptedDek and
param.encryptedHostUuid when the encrypted flag is actually true, to avoid
propagating incomplete encryption data downstream.

zhong.zhou added 2 commits June 22, 2026 14:12
Resolves: ZSV-12473

Change-Id: Ifcfb943d26a5bb4319a3bdbb5e9576524d8ef51e
Resolves: ZSV-12473

Change-Id: I6f6a8bccffe7b94df8c27617376008a9db14e17b
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.

1 participant