Skip to content

<fix>[host]: supports both querying current hostname and updating to a new hostname#2819

Closed
ZStack-Robot wants to merge 1 commit intofeature-zsv-4.10.20-UI-install-sdsfrom
sync/tao.gan/ZSV-10273@@3
Closed

<fix>[host]: supports both querying current hostname and updating to a new hostname#2819
ZStack-Robot wants to merge 1 commit intofeature-zsv-4.10.20-UI-install-sdsfrom
sync/tao.gan/ZSV-10273@@3

Conversation

@ZStack-Robot
Copy link
Copy Markdown
Collaborator

DBImpact
APIImpact

Resolves: ZSV-10273

Change-Id: I64746b656f727176647072746d6970776b66737a

sync from gitlab !8609

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Oct 27, 2025

Walkthrough

新增主机名更新功能:添加API消息与事件、内部消息与回复、数据库列与视图更新、KVM 命令/路径与处理、SDK/测试辅助方法与文档,以及将 hostname 字段贯穿 Host 对象模型和持久层。

Changes

Cohort / File(s) Change summary
API 层
header/src/main/java/org/zstack/header/host/APIUpdateHostnameMsg.java, header/src/main/java/org/zstack/header/host/APIUpdateHostnameEvent.java, header/src/main/java/org/zstack/header/host/APIUpdateHostname*Doc_zh_cn.groovy
新增 REST API 消息与事件类及中文文档,定义 PUT /hosts/hostname/{uuid}/actions 接口并封装请求/响应结构。
内部消息/回复
header/src/main/java/org/zstack/header/host/UpdateHostnameMsg.java, header/src/main/java/org/zstack/header/host/UpdateHostnameReply.java
新增内部异步消息类与回复类(实现 HostMessage / NeedReplyMessage 模式),用于在组件间传递更新 hostname 指令与结果。
主机模型与元模型
header/src/main/java/org/zstack/header/host/HostAO.java, header/src/main/java/org/zstack/header/host/HostAO_.java, header/src/main/java/org/zstack/header/host/HostInventory.java, header/src/main/java/org/zstack/header/host/HostInventoryDoc_zh_cn.groovy
在 HostAO/HostInventory/元模型中添加 hostname 字段及 getter/setter,并在文档中声明新字段。
数据库迁移
conf/db/upgrade/V4.10.20__schema.sql
为 HostEO 表添加 hostname varchar(256) 列,并更新 zstack.HostVO 视图以包含该列。
KVM 插件与命令
plugin/kvm/src/main/java/org/zstack/kvm/KVMAgentCommands.java, plugin/kvm/src/main/java/org/zstack/kvm/KVMConstant.java, plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java
为 agent 添加 HostFact hostname 字段、引入 UpdateHostnameCmd/UpdateHostnameRsp,新增常量 KVM_UPDATE_HOSTNAME_PATH,并在 KVMHost 中实现处理 UpdateHostnameMsg 的异步 HTTP 调用与 HostVO 更新逻辑。
SDK
sdk/src/main/java/org/zstack/sdk/UpdateHostnameAction.java, sdk/src/main/java/org/zstack/sdk/UpdateHostnameResult.java, sdk/src/main/java/org/zstack/sdk/HostInventory.java
新增同步/异步调用的 SDK Action、结果类型,并在 SDK HostInventory 中添加 hostname 字段与访问器。
主机基类路由
compute/src/main/java/org/zstack/compute/host/HostBase.java
在 HostBase 的 API 消息处理路径中新增对 APIUpdateHostnameMsg 的路由,构建并下发 UpdateHostnameMsg,基于回复发布 APIUpdateHostnameEvent。
测试/模拟器
testlib/src/main/java/org/zstack/testlib/KVMSimulator.groovy, testlib/src/main/java/org/zstack/testlib/ApiHelper.groovy
在 KVM 模拟器中返回 HostFact 的 hostname 并添加 /host/hostname/update 模拟处理;在 ApiHelper 中新增 updateHostname 封装方法以便测试调用。

Sequence Diagram(s)

sequenceDiagram
    participant SDK as 客户端/SDK
    participant HostBase as HostBase
    participant Router as 消息路由
    participant KVMHost as KVMHost
    participant KVMAgent as KVM Agent
    participant DB as 数据库

    SDK->>HostBase: APIUpdateHostnameMsg(uuid, hostname)
    activate HostBase
    HostBase->>Router: route to host service (UpdateHostnameMsg)
    deactivate HostBase

    Router->>KVMHost: deliver UpdateHostnameMsg
    activate KVMHost
    KVMHost->>KVMAgent: HTTP PUT /host/hostname/update (UpdateHostnameCmd)
    deactivate KVMHost

    activate KVMAgent
    KVMAgent->>KVMAgent: apply hostname change
    KVMAgent-->>KVMHost: UpdateHostnameRsp (success/error)
    deactivate KVMAgent

    activate KVMHost
    KVMHost->>DB: update HostVO.hostname
    KVMHost-->>Router: UpdateHostnameReply(inventory or error)
    deactivate KVMHost

    Router-->>HostBase: reply arrives
    activate HostBase
    HostBase-->>SDK: APIUpdateHostnameEvent(inventory or error)
    deactivate HostBase
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • 重点审查项:
    • plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java:异步链路(任务命名、HTTP 调用、返回解析、HostVO 更新)及异常处理。
    • compute/src/main/java/org/zstack/compute/host/HostBase.java:API 路由与事件发布逻辑是否正确处理 reply 成功/失败分支。
    • conf/db/upgrade/V4.10.20__schema.sql:迁移语句与视图重建的语法与兼容性。
    • 测试模拟器和 ApiHelper:模拟路径、返回数据与测试用例的一致性。

Poem

🐰 兔兔轻跳庆新篇:
名字入库换新颜,
消息穿梭异步连,
KVM 请求转回单,
SDK 与测试一同欢。

Pre-merge checks and finishing touches

❌ 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%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed PR标题"supports both querying current hostname and updating to a new hostname"准确地反映了本次变更的核心内容。通过代码摘要可以看出,PR新增了hostname字段到HostInventory(支持查询当前hostname),同时添加了APIUpdateHostnameMsg、APIUpdateHostnameEvent等完整的API基础设施(支持更新hostname),并修改了数据库schema以持久化存储hostname。标题简洁清晰,特定指向主要改动,没有使用含糊其辞的表述。
Description Check ✅ Passed PR描述虽然简洁,但与变更集相关。描述中的"DBImpact"和"APIImpact"标签准确反映了实际变更的影响范围——代码摘要显示确实包含数据库schema变更(添加hostname列)和API变更(新增更新hostname的API消息和事件)。描述还包含了关联的issue号(ZSV-10273)和源信息,表明这是从GitLab同步的变更。虽然描述信息量不大,但并未偏离主题或不相关。
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch sync/tao.gan/ZSV-10273@@3

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8f08463 and 0d6aa40.

⛔ Files ignored due to path filters (1)
  • conf/serviceConfig/host.xml is excluded by !**/*.xml
📒 Files selected for processing (20)
  • compute/src/main/java/org/zstack/compute/host/HostBase.java (1 hunks)
  • conf/db/upgrade/V4.10.20__schema.sql (1 hunks)
  • header/src/main/java/org/zstack/header/host/APIUpdateHostnameEvent.java (1 hunks)
  • header/src/main/java/org/zstack/header/host/APIUpdateHostnameEventDoc_zh_cn.groovy (1 hunks)
  • header/src/main/java/org/zstack/header/host/APIUpdateHostnameMsg.java (1 hunks)
  • header/src/main/java/org/zstack/header/host/APIUpdateHostnameMsgDoc_zh_cn.groovy (1 hunks)
  • header/src/main/java/org/zstack/header/host/HostAO.java (2 hunks)
  • header/src/main/java/org/zstack/header/host/HostAO_.java (1 hunks)
  • header/src/main/java/org/zstack/header/host/HostInventory.java (3 hunks)
  • header/src/main/java/org/zstack/header/host/HostInventoryDoc_zh_cn.groovy (1 hunks)
  • header/src/main/java/org/zstack/header/host/UpdateHostnameMsg.java (1 hunks)
  • header/src/main/java/org/zstack/header/host/UpdateHostnameReply.java (1 hunks)
  • plugin/kvm/src/main/java/org/zstack/kvm/KVMAgentCommands.java (3 hunks)
  • plugin/kvm/src/main/java/org/zstack/kvm/KVMConstant.java (1 hunks)
  • plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java (3 hunks)
  • sdk/src/main/java/org/zstack/sdk/HostInventory.java (1 hunks)
  • sdk/src/main/java/org/zstack/sdk/UpdateHostnameAction.java (1 hunks)
  • sdk/src/main/java/org/zstack/sdk/UpdateHostnameResult.java (1 hunks)
  • testlib/src/main/java/org/zstack/testlib/ApiHelper.groovy (1 hunks)
  • testlib/src/main/java/org/zstack/testlib/KVMSimulator.groovy (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (11)
  • header/src/main/java/org/zstack/header/host/APIUpdateHostnameMsg.java
  • plugin/kvm/src/main/java/org/zstack/kvm/KVMConstant.java
  • plugin/kvm/src/main/java/org/zstack/kvm/KVMAgentCommands.java
  • compute/src/main/java/org/zstack/compute/host/HostBase.java
  • sdk/src/main/java/org/zstack/sdk/UpdateHostnameResult.java
  • header/src/main/java/org/zstack/header/host/HostInventory.java
  • conf/db/upgrade/V4.10.20__schema.sql
  • header/src/main/java/org/zstack/header/host/UpdateHostnameReply.java
  • header/src/main/java/org/zstack/header/host/UpdateHostnameMsg.java
  • header/src/main/java/org/zstack/header/host/APIUpdateHostnameEvent.java
  • testlib/src/main/java/org/zstack/testlib/KVMSimulator.groovy
🧰 Additional context used
📓 Path-based instructions (1)
**/*.java

⚙️ CodeRabbit configuration file

**/*.java: ## 1. API 设计要求

  • API 命名:
    • API 名称必须唯一,不能重复。
    • API 消息类需要继承 APIMessage;其返回类必须继承 APIReplyAPIEvent,并在注释中用 @RestResponse 进行标注。
    • API 消息上必须添加注解 @RestRequest,并满足如下规范:
      • path:
        • 针对资源使用复数形式。
        • 当 path 中引用消息类变量时,使用 {variableName} 格式。
      • HTTP 方法对应:
        • 查询操作 → HttpMethod.GET
        • 更新操作 → HttpMethod.PUT
        • 创建操作 → HttpMethod.POST
        • 删除操作 → HttpMethod.DELETE
    • API 类需要实现 __example__ 方法以便生成 API 文档,并确保生成对应的 Groovy API Template 与 API Markdown 文件。

2. 命名与格式规范

  • 类名:

    • 使用 UpperCamelCase 风格。
    • 特殊情况:
      • VO/AO/EO 类型类除外。
      • 抽象类采用 AbstractBase 前缀/后缀。
      • 异常类应以 Exception 结尾。
      • 测试类需要以 TestCase 结尾。
  • 方法名、参数名、成员变量和局部变量:

    • 使用 lowerCamelCase 风格。
  • 常量命名:

    • 全部大写,使用下划线分隔单词。
    • 要求表达清楚,避免使用含糊或不准确的名称。
  • 包名:

    • 统一使用小写,使用点分隔符,每个部分应是一个具有自然语义的英文单词(参考 Spring 框架的结构)。
  • 命名细节:

    • 避免在父子类或同一代码块中出现相同名字的成员或局部变量,防止混淆。
    • 命名缩写:
      • 不允许使用不必要的缩写,如:AbsSchedulerJobcondiFu 等。应使用完整单词提升可读性。

3. 编写自解释代码

  • 意图表达:

    • 避免使用布尔型参数造成含义不明确。例如:
      • 对于 stopAgent(boolean ignoreError),建议拆分为不同函数(如 stopAgentIgnoreError()),或使用枚举表达操作类型。
    • 命名应尽量用完整的单词组合表达意图,并在名称中体现数据类型或用途(例如在常量与变量名称中,将类型词放在末尾)。
  • 注释:

    • 代码应尽量做到自解释,对少于两行的说明可以直接写在代码中。
    • 对于较长的注释,需要仔细校对并随代码更新,确保内容正确。
    • 接口方法不应有多余的修饰符(例如 public),且必须配有有效的 Javadoc 注释。

4. 流程控制和结构优化

  • if...else 的使用:

    • 应尽量减少 if...else 结构的使用,建议:
      • 限制嵌套层级最多为两层,且内层不应再出现 else 分支。
      • 尽早返回(Early Return),将条件判断中的处理逻辑提前结束或抽成独立方法。
      • 使用 Java Stream 或 Lambda 表达式代替冗长的循环与条件判断。
  • 条件判断:

    • if 条件表达不宜过长或过于复杂,必要时可以将条件抽成 boolean 变量描述。
  • 代码块长度:

    • 单个 if 代码块不宜超过一屏显示,以提高可读性和后续维护性。

5. 异常处理与日志

  • 捕获异常的原则:
    • 对于可以通过预检查避免的 RuntimeException(如 NullPointerExceptionIndexOutOfBoundsException 等),不建议使用 try-catch 来进行处理。
    • 捕获异常应仅用于处理真正的意外情况,不应将异常逻辑当作正常流程控制。
    • 在必要时,应继续抛出异常,使上层业务处理者可以转换为用户友好的错误提示。
    • 使用 try-with-resources 语法管理资源,确保在 finally 块中正确关闭资源,并避免在 finally 中返回值。
      ...

Files:

  • header/src/main/java/org/zstack/header/host/HostAO_.java
  • header/src/main/java/org/zstack/header/host/HostAO.java
  • sdk/src/main/java/org/zstack/sdk/HostInventory.java
  • sdk/src/main/java/org/zstack/sdk/UpdateHostnameAction.java
  • plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java
🧠 Learnings (2)
📚 Learning: 2025-09-01T08:16:10.006Z
Learnt from: MatheMatrix
PR: MatheMatrix/zstack#2541
File: testlib/src/main/java/org/zstack/testlib/ApiHelper.groovy:30889-30893
Timestamp: 2025-09-01T08:16:10.006Z
Learning: ApiHelper.groovy in testlib/src/main/java/org/zstack/testlib/ApiHelper.groovy is auto-generated and should not be manually modified or receive code change suggestions.

Applied to files:

  • testlib/src/main/java/org/zstack/testlib/ApiHelper.groovy
📚 Learning: 2025-10-20T11:27:25.928Z
Learnt from: MatheMatrix
PR: MatheMatrix/zstack#2763
File: sdk/src/main/java/org/zstack/sdk/UpdateHostKernelInterfaceAction.java:31-31
Timestamp: 2025-10-20T11:27:25.928Z
Learning: UpdateHostKernelInterface API (`sdk/src/main/java/org/zstack/sdk/UpdateHostKernelInterfaceAction.java`) 在 PR #2763 时尚未被实际使用,因此对其参数约束的变更(如 name 字段从必需改为可选)不会造成破坏性影响。

Applied to files:

  • sdk/src/main/java/org/zstack/sdk/UpdateHostnameAction.java
  • header/src/main/java/org/zstack/header/host/APIUpdateHostnameMsgDoc_zh_cn.groovy
🧬 Code graph analysis (1)
sdk/src/main/java/org/zstack/sdk/UpdateHostnameAction.java (1)
sdk/src/main/java/org/zstack/sdk/ZSClient.java (1)
  • ZSClient (33-788)
🔇 Additional comments (10)
plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java (2)

725-727: 消息路由新增 UpdateHostnameMsg:一致性良好

分发逻辑与现有模式一致,无异常。


6066-6066: 保存硬件事实中的 hostname:OK

从 HostFactResponse 同步 hostname 到 HostVO,行为正确,便于后续查询展示。

header/src/main/java/org/zstack/header/host/HostInventoryDoc_zh_cn.groovy (1)

210-215: 文档添加正确。

hostname 字段的文档定义格式规范,描述清晰,版本标注正确,与其他字段定义保持一致。

header/src/main/java/org/zstack/header/host/HostAO_.java (1)

25-25: 元模型属性添加正确。

hostname 元模型属性的定义遵循 JPA 规范,与其他属性保持一致的声明模式。

header/src/main/java/org/zstack/header/host/HostAO.java (2)

43-44: 字段定义正确。

hostname 字段的声明符合 JPA 规范,使用 @column 注解,与其他字段保持一致的定义模式。


164-170: 访问器方法实现正确。

getHostname() 和 setHostname() 方法遵循 JavaBean 命名规范,实现简洁规范。

sdk/src/main/java/org/zstack/sdk/HostInventory.java (2)

255-258: 字段和 setter 方法实现正确。

hostname 字段声明和 setHostname() 方法遵循该文件的一致性模式,使用完全限定类型名称。


259-261: 修正 getter 方法的返回类型以保持一致性。

getHostname() 方法的返回类型应使用 java.lang.String 而非 String,以与文件中其他 getter 方法保持一致(参见 Line 19, 27, 35 等)。

应用以下修改:

-    public String getHostname() {
+    public java.lang.String getHostname() {
         return this.hostname;
     }

Likely an incorrect or invalid review comment.

testlib/src/main/java/org/zstack/testlib/ApiHelper.groovy (1)

8471-8495: 验证完毕:updateHostname 包装器实现正确,无问题

所有检查项已通过:

  • ✓ UpdateHostnameAction SDK 存在,REST 元信息配置完整(PUT 路由、sessionId 必需、轮询启用)
  • ✓ 包装器无重复定义
  • ✓ ApiPathTracker 和 Platform.uuid 使用模式与现有代码一致

实现质量无问题,可批准代码更改。

sdk/src/main/java/org/zstack/sdk/UpdateHostnameAction.java (1)

93-101: REST 配置符合规范

RestInfo 配置正确:

  • HTTP 方法使用 PUT 进行更新操作,符合 API 设计要求
  • 路径使用复数形式 hosts 和路径变量 {uuid},符合规范
  • parameterName 值为 "updateHostname",正确遵循了命名约定(对应 APIUpdateHostnameMsg 去掉前后缀转为 lowerCamelCase)
  • 会话和轮询配置合理

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.39.6)
plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java

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

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🧹 Nitpick comments (4)
sdk/src/main/java/org/zstack/sdk/HostInventory.java (1)

255-261: 修正返回类型声明以保持一致性。

Line 259 的 getter 方法返回类型使用了 String,而其他所有字段的 getter 都使用 java.lang.String。为保持代码一致性:

     public java.lang.String hostname;
     public void setHostname(java.lang.String hostname) {
         this.hostname = hostname;
     }
-    public String getHostname() {
+    public java.lang.String getHostname() {
         return this.hostname;
     }
header/src/main/java/org/zstack/header/host/UpdateHostnameMsg.java (1)

5-29: LGTM:内部消息定义正确且最小化

实现与 HostMessage 契约一致,无功能性问题。建议保持“hostname”这一命名在整个栈内统一(API/SDK/Inventory 一致),以降低查找和序列化/反序列化成本。

header/src/main/java/org/zstack/header/host/APIUpdateHostnameMsg.java (1)

41-46: 示例值不够贴近主机名规范

建议示例使用更贴合实际且符合 RFC 1123 的主机名,如 host-01,并与上文字段改名保持一致:

-        msg.setHostName("user");
+        msg.setHostname("host-01");
sdk/src/main/java/org/zstack/sdk/UpdateHostnameAction.java (1)

33-38: 可选:为 tags 增加泛型以提升类型安全

-    public java.util.List systemTags;
+    public java.util.List<String> systemTags;
@@
-    public java.util.List userTags;
+    public java.util.List<String> userTags;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 698a172 and 8f08463.

⛔ Files ignored due to path filters (1)
  • conf/serviceConfig/host.xml is excluded by !**/*.xml
📒 Files selected for processing (19)
  • compute/src/main/java/org/zstack/compute/host/HostBase.java (1 hunks)
  • conf/db/upgrade/V4.10.20__schema.sql (1 hunks)
  • header/src/main/java/org/zstack/header/host/APIUpdateHostnameEvent.java (1 hunks)
  • header/src/main/java/org/zstack/header/host/APIUpdateHostnameEventDoc_zh_cn.groovy (1 hunks)
  • header/src/main/java/org/zstack/header/host/APIUpdateHostnameMsg.java (1 hunks)
  • header/src/main/java/org/zstack/header/host/APIUpdateHostnameMsgDoc_zh_cn.groovy (1 hunks)
  • header/src/main/java/org/zstack/header/host/HostAO.java (2 hunks)
  • header/src/main/java/org/zstack/header/host/HostInventory.java (2 hunks)
  • header/src/main/java/org/zstack/header/host/HostInventoryDoc_zh_cn.groovy (1 hunks)
  • header/src/main/java/org/zstack/header/host/UpdateHostnameMsg.java (1 hunks)
  • header/src/main/java/org/zstack/header/host/UpdateHostnameReply.java (1 hunks)
  • plugin/kvm/src/main/java/org/zstack/kvm/KVMAgentCommands.java (3 hunks)
  • plugin/kvm/src/main/java/org/zstack/kvm/KVMConstant.java (1 hunks)
  • plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java (2 hunks)
  • sdk/src/main/java/org/zstack/sdk/HostInventory.java (1 hunks)
  • sdk/src/main/java/org/zstack/sdk/UpdateHostnameAction.java (1 hunks)
  • sdk/src/main/java/org/zstack/sdk/UpdateHostnameResult.java (1 hunks)
  • testlib/src/main/java/org/zstack/testlib/ApiHelper.groovy (1 hunks)
  • testlib/src/main/java/org/zstack/testlib/KVMSimulator.groovy (2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.java

⚙️ CodeRabbit configuration file

**/*.java: ## 1. API 设计要求

  • API 命名:
    • API 名称必须唯一,不能重复。
    • API 消息类需要继承 APIMessage;其返回类必须继承 APIReplyAPIEvent,并在注释中用 @RestResponse 进行标注。
    • API 消息上必须添加注解 @RestRequest,并满足如下规范:
      • path:
        • 针对资源使用复数形式。
        • 当 path 中引用消息类变量时,使用 {variableName} 格式。
      • HTTP 方法对应:
        • 查询操作 → HttpMethod.GET
        • 更新操作 → HttpMethod.PUT
        • 创建操作 → HttpMethod.POST
        • 删除操作 → HttpMethod.DELETE
    • API 类需要实现 __example__ 方法以便生成 API 文档,并确保生成对应的 Groovy API Template 与 API Markdown 文件。

2. 命名与格式规范

  • 类名:

    • 使用 UpperCamelCase 风格。
    • 特殊情况:
      • VO/AO/EO 类型类除外。
      • 抽象类采用 AbstractBase 前缀/后缀。
      • 异常类应以 Exception 结尾。
      • 测试类需要以 TestCase 结尾。
  • 方法名、参数名、成员变量和局部变量:

    • 使用 lowerCamelCase 风格。
  • 常量命名:

    • 全部大写,使用下划线分隔单词。
    • 要求表达清楚,避免使用含糊或不准确的名称。
  • 包名:

    • 统一使用小写,使用点分隔符,每个部分应是一个具有自然语义的英文单词(参考 Spring 框架的结构)。
  • 命名细节:

    • 避免在父子类或同一代码块中出现相同名字的成员或局部变量,防止混淆。
    • 命名缩写:
      • 不允许使用不必要的缩写,如:AbsSchedulerJobcondiFu 等。应使用完整单词提升可读性。

3. 编写自解释代码

  • 意图表达:

    • 避免使用布尔型参数造成含义不明确。例如:
      • 对于 stopAgent(boolean ignoreError),建议拆分为不同函数(如 stopAgentIgnoreError()),或使用枚举表达操作类型。
    • 命名应尽量用完整的单词组合表达意图,并在名称中体现数据类型或用途(例如在常量与变量名称中,将类型词放在末尾)。
  • 注释:

    • 代码应尽量做到自解释,对少于两行的说明可以直接写在代码中。
    • 对于较长的注释,需要仔细校对并随代码更新,确保内容正确。
    • 接口方法不应有多余的修饰符(例如 public),且必须配有有效的 Javadoc 注释。

4. 流程控制和结构优化

  • if...else 的使用:

    • 应尽量减少 if...else 结构的使用,建议:
      • 限制嵌套层级最多为两层,且内层不应再出现 else 分支。
      • 尽早返回(Early Return),将条件判断中的处理逻辑提前结束或抽成独立方法。
      • 使用 Java Stream 或 Lambda 表达式代替冗长的循环与条件判断。
  • 条件判断:

    • if 条件表达不宜过长或过于复杂,必要时可以将条件抽成 boolean 变量描述。
  • 代码块长度:

    • 单个 if 代码块不宜超过一屏显示,以提高可读性和后续维护性。

5. 异常处理与日志

  • 捕获异常的原则:
    • 对于可以通过预检查避免的 RuntimeException(如 NullPointerExceptionIndexOutOfBoundsException 等),不建议使用 try-catch 来进行处理。
    • 捕获异常应仅用于处理真正的意外情况,不应将异常逻辑当作正常流程控制。
    • 在必要时,应继续抛出异常,使上层业务处理者可以转换为用户友好的错误提示。
    • 使用 try-with-resources 语法管理资源,确保在 finally 块中正确关闭资源,并避免在 finally 中返回值。
      ...

Files:

  • header/src/main/java/org/zstack/header/host/APIUpdateHostnameMsg.java
  • sdk/src/main/java/org/zstack/sdk/HostInventory.java
  • header/src/main/java/org/zstack/header/host/HostInventory.java
  • plugin/kvm/src/main/java/org/zstack/kvm/KVMAgentCommands.java
  • sdk/src/main/java/org/zstack/sdk/UpdateHostnameResult.java
  • header/src/main/java/org/zstack/header/host/UpdateHostnameMsg.java
  • header/src/main/java/org/zstack/header/host/APIUpdateHostnameEvent.java
  • compute/src/main/java/org/zstack/compute/host/HostBase.java
  • header/src/main/java/org/zstack/header/host/HostAO.java
  • header/src/main/java/org/zstack/header/host/UpdateHostnameReply.java
  • plugin/kvm/src/main/java/org/zstack/kvm/KVMConstant.java
  • plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java
  • sdk/src/main/java/org/zstack/sdk/UpdateHostnameAction.java
**/*.sql

⚙️ CodeRabbit configuration file

**/*.sql: Review the SQL code, make sure has no errors and confirm that:

  • Upgrading scene has been carefully handled
  • Do not use DEFAULT 0000-00-00 00:00:00 , use DEFAULT CURRENT_TIMESTAMP instead
  • When NOT NULL exists, must use stored procedure or other functions to process historical data, this is very very important

Files:

  • conf/db/upgrade/V4.10.20__schema.sql
🧠 Learnings (4)
📓 Common learnings
Learnt from: MatheMatrix
PR: MatheMatrix/zstack#2763
File: sdk/src/main/java/org/zstack/sdk/UpdateHostKernelInterfaceAction.java:31-31
Timestamp: 2025-10-20T11:27:25.928Z
Learning: UpdateHostKernelInterface API (`sdk/src/main/java/org/zstack/sdk/UpdateHostKernelInterfaceAction.java`) 在 PR #2763 时尚未被实际使用,因此对其参数约束的变更(如 name 字段从必需改为可选)不会造成破坏性影响。
📚 Learning: 2025-09-01T08:16:10.006Z
Learnt from: MatheMatrix
PR: MatheMatrix/zstack#2541
File: testlib/src/main/java/org/zstack/testlib/ApiHelper.groovy:30889-30893
Timestamp: 2025-09-01T08:16:10.006Z
Learning: ApiHelper.groovy in testlib/src/main/java/org/zstack/testlib/ApiHelper.groovy is auto-generated and should not be manually modified or receive code change suggestions.

Applied to files:

  • testlib/src/main/java/org/zstack/testlib/ApiHelper.groovy
📚 Learning: 2025-10-24T06:45:56.220Z
Learnt from: zstack-robot-1
PR: MatheMatrix/zstack#2798
File: plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java:6888-6942
Timestamp: 2025-10-24T06:45:56.220Z
Learning: KVM 数据面(agent)在/host/file/download路径会校验上传URL的scheme;管理面KVMHost.uploadFileToHost当前仅做非空scheme检测。

Applied to files:

  • plugin/kvm/src/main/java/org/zstack/kvm/KVMConstant.java
📚 Learning: 2025-10-20T11:27:25.928Z
Learnt from: MatheMatrix
PR: MatheMatrix/zstack#2763
File: sdk/src/main/java/org/zstack/sdk/UpdateHostKernelInterfaceAction.java:31-31
Timestamp: 2025-10-20T11:27:25.928Z
Learning: UpdateHostKernelInterface API (`sdk/src/main/java/org/zstack/sdk/UpdateHostKernelInterfaceAction.java`) 在 PR #2763 时尚未被实际使用,因此对其参数约束的变更(如 name 字段从必需改为可选)不会造成破坏性影响。

Applied to files:

  • sdk/src/main/java/org/zstack/sdk/UpdateHostnameAction.java
🧬 Code graph analysis (2)
header/src/main/java/org/zstack/header/host/APIUpdateHostnameMsg.java (1)
header/src/main/java/org/zstack/header/message/APIMessage.java (1)
  • APIMessage (16-245)
sdk/src/main/java/org/zstack/sdk/UpdateHostnameAction.java (1)
sdk/src/main/java/org/zstack/sdk/ZSClient.java (1)
  • ZSClient (33-788)
🔇 Additional comments (19)
conf/db/upgrade/V4.10.20__schema.sql (2)

1-15: 确认 SoftwarePackageVO 表是否应在此迁移文件中。

此表的创建似乎与 hostname 功能无关。请确认 SoftwarePackageVO 表是否有意包含在此版本迁移中,或是否应该在单独的迁移文件中。


18-20: 数据库变更正确。

hostname 列的添加和视图更新实现正确:

  • 列定义为可空,符合升级场景的兼容性要求
  • 使用 INSERT_COLUMN 存储过程是良好的实践
  • 视图重建正确包含了新增的 hostname 列

根据编码规范,由于新列允许 NULL,无需使用存储过程处理历史数据。

header/src/main/java/org/zstack/header/host/HostAO.java (2)

43-44: 字段声明符合规范。

hostname 字段的声明遵循了代码规范:

  • 使用 lowerCamelCase 命名风格
  • 正确使用 @Column 注解
  • String 类型与数据库中的 varchar(256) 可空列兼容

164-170: 访问器方法实现正确。

getter 和 setter 方法遵循标准 Java Bean 约定,实现简洁清晰,与类中其他字段的访问器保持一致。

testlib/src/main/java/org/zstack/testlib/ApiHelper.groovy (1)

8471-8495: ---

✅ 验证通过:updateHostname 助手方法实现正确

核验结果确认:

  1. 方法定义唯一:apiHelper.groovy 中 updateHostname 仅定义一次(行 8471)
  2. SDK Action 存在:UpdateHostnameAction 类存在于 sdk/src/main/java/org/zstack/sdk/UpdateHostnameAction.java,继承自 AbstractAction
  3. 实现模式一致:创建 Action → 注入 sessionId → 配置委托 → 调用 → apipath 跟踪 → errorOut 返回的流程与既有方法保持一致

代码无逻辑或异常处理缺口。由于该文件为自动生成,此次改动应确实来自代码生成器而非手工编辑。

plugin/kvm/src/main/java/org/zstack/kvm/KVMConstant.java (1)

121-121: LGTM!

新增常量命名规范,路径格式与其他主机更新路径保持一致。位置合理,紧邻 Line 120 的 KVM_UPDATE_HOST_NQN_PATH

header/src/main/java/org/zstack/header/host/HostInventoryDoc_zh_cn.groovy (1)

210-215: LGTM!

文档字段定义格式规范,位置合理(位于 nqn 字段之后,createDate 之前),版本号标注正确。

testlib/src/main/java/org/zstack/testlib/KVMSimulator.groovy (2)

182-182: LGTM!

在测试模拟器的主机信息响应中添加 hostname 字段,使用固定值 "hostname" 用于测试场景是合理的。


678-680: LGTM!

新增的模拟器处理器实现简洁,与其他类似处理器(如 Line 651-654 的 KVM_UPDATE_HOST_NQN_PATH)保持一致的模式。

header/src/main/java/org/zstack/header/host/HostInventory.java (1)

515-521: LGTM!

getter 和 setter 方法实现正确,遵循命名规范。

header/src/main/java/org/zstack/header/host/UpdateHostnameReply.java (1)

1-15: LGTM!

UpdateHostnameReply 类实现正确:

  • 继承 MessageReply 适用于内部消息回复
  • 字段可见性合理(包级私有)
  • 访问器方法定义正确
  • 与其他类似的 Reply 类(如 UpdateHostNqnReply)保持一致的模式
sdk/src/main/java/org/zstack/sdk/UpdateHostnameResult.java (1)

1-12: 该审查意见不适用于当前代码库。

根据对 SDK 中 600+ 个 Result 类的验证,所有结果类(包括 UpdateHostnameResult)都遵循统一的架构模式:公开字段 + getter/setter 方法。这不是代码异味,而是项目的一致惯例。

样本验证结果:

  • GetNodeRolesResultpublic java.util.List inventories
  • PrimaryStorageMigrateVolumeResultpublic VolumeInventory inventory
  • DeleteLoadBalancerListenerResultpublic LoadBalancerInventory inventory

将此类改为私有字段会破坏代码库的一致性。该代码按照既定模式正确实现。

Likely an incorrect or invalid review comment.

compute/src/main/java/org/zstack/compute/host/HostBase.java (1)

196-215: 所有字段引用均正确,无需修改。

验证结果确认:

  1. Line 200 msg.getHostName():✓ 正确

    • APIUpdateHostnameMsg 包含字段 hostName(首字母大写)
    • 获取器 getHostName() 返回该字段
    • 传入 umsg.setHostname() 时正确转换为 UpdateHostnameMsg 中的 hostname 字段
  2. Line 201 msg.getHostUuid():✓ 正确

    • APIUpdateHostnameMsg 实现了 HostMessage 接口
    • 提供 getHostUuid() 方法,正确返回 uuid 字段

该实现无误,代码可接受。

plugin/kvm/src/main/java/org/zstack/kvm/KVMAgentCommands.java (3)

487-487: 代码实现正确:HostFactResponse 新增 hostname 字段

HostFactResponse 类中添加 hostname 字段的实现是正确的,遵循了现有代码模式(与 nqn 字段一致)。


777-783: LGTM:hostname 的 getter 和 setter 实现正确

getter 和 setter 方法遵循 JavaBean 命名规范,实现正确。


4607-4612: LGTM:UpdateHostnameCmd 和 UpdateHostnameRsp 实现正确

新增的命令和响应类遵循了现有模式:

  • UpdateHostnameCmd 继承 AgentCommand,使用 public 字段
  • UpdateHostnameRsp 继承 AgentResponse,空实现
  • 命名和结构与类似的 UpdateHostNqnCmd/Rsp(第 4600-4605 行)保持一致
plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java (1)

725-726: 消息路由新增项看起来正确

为 UpdateHostnameMsg 增加分发分支与既有风格一致,无功能性风险。

header/src/main/java/org/zstack/header/host/APIUpdateHostnameEvent.java (1)

6-44: LGTM:事件定义与示例完备

事件模型与文档生成要求匹配,示例中已包含 hostname 字段,便于联调与文档产出。

header/src/main/java/org/zstack/header/host/APIUpdateHostnameMsg.java (1)

8-13: 评审意见应被撤销

实际验证结果表明 /hosts/hostname/{uuid}/actions 的路径设计已遵循 ZStack 既有约定。在 Host 相关 Update API 中存在明确的设计模式:

  • 通用主机更新:/hosts/{uuid}/actions(APIUpdateHostMsg)
  • 特定属性更新:/hosts/{property}/{uuid}/actions
    • /hosts/ipmi/{uuid}/actions(APIUpdateHostIpmiMsg)
    • /hosts/nqn/{uuid}/actions(APIUpdateHostNqnMsg)
    • /hosts/hostname/{uuid}/actions(APIUpdateHostnameMsg)

所有特定属性更新 API 采用统一的 /{property} 子资源单数形式,路径已具有一致性,无需调整。

Likely an incorrect or invalid review comment.

Comment on lines +9 to +16
ref {
name "inventory"
path "org.zstack.header.host.APIUpdateHostNqnEvent.inventory"
desc "null"
type "HostInventory"
since "4.10.18"
clz HostInventory.class
}
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 | 🔴 Critical

路径引用错误:inventory 引用了错误的事件类

第 11 行的 path 引用了 org.zstack.header.host.APIUpdateHostNqnEvent.inventory,应该引用 org.zstack.header.host.APIUpdateHostnameEvent.inventory

 	ref {
 		name "inventory"
-		path "org.zstack.header.host.APIUpdateHostNqnEvent.inventory"
+		path "org.zstack.header.host.APIUpdateHostnameEvent.inventory"
 		desc "null"
 		type "HostInventory"
 		since "4.10.18"
 		clz HostInventory.class
 	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ref {
name "inventory"
path "org.zstack.header.host.APIUpdateHostNqnEvent.inventory"
desc "null"
type "HostInventory"
since "4.10.18"
clz HostInventory.class
}
ref {
name "inventory"
path "org.zstack.header.host.APIUpdateHostnameEvent.inventory"
desc "null"
type "HostInventory"
since "4.10.18"
clz HostInventory.class
}
🤖 Prompt for AI Agents
In
header/src/main/java/org/zstack/header/host/APIUpdateHostnameEventDoc_zh_cn.groovy
around lines 9 to 16, the ref block's path incorrectly points to
org.zstack.header.host.APIUpdateHostNqnEvent.inventory; update the path to
org.zstack.header.host.APIUpdateHostnameEvent.inventory so it references the
correct event class, verify the path string matches the current event class name
and run tests or build to ensure no broken references.

Comment on lines +23 to +30
ref {
name "error"
path "org.zstack.header.host.APIUpdateHostNqnEvent.error"
desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false
type "ErrorCode"
since "4.10.18"
clz ErrorCode.class
}
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 | 🔴 Critical

路径引用错误:error 引用了错误的事件类

第 25 行的 path 引用了 org.zstack.header.host.APIUpdateHostNqnEvent.error,应该引用 org.zstack.header.host.APIUpdateHostnameEvent.error

 	ref {
 		name "error"
-		path "org.zstack.header.host.APIUpdateHostNqnEvent.error"
+		path "org.zstack.header.host.APIUpdateHostnameEvent.error"
 		desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false
 		type "ErrorCode"
 		since "4.10.18"
 		clz ErrorCode.class
 	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ref {
name "error"
path "org.zstack.header.host.APIUpdateHostNqnEvent.error"
desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false
type "ErrorCode"
since "4.10.18"
clz ErrorCode.class
}
ref {
name "error"
path "org.zstack.header.host.APIUpdateHostnameEvent.error"
desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false
type "ErrorCode"
since "4.10.18"
clz ErrorCode.class
}
🤖 Prompt for AI Agents
In
header/src/main/java/org/zstack/header/host/APIUpdateHostnameEventDoc_zh_cn.groovy
around lines 23 to 30, the ref for the "error" field incorrectly points to
org.zstack.header.host.APIUpdateHostNqnEvent.error; update the path to
org.zstack.header.host.APIUpdateHostnameEvent.error so the documentation
references the correct event class and field.

Comment on lines +15 to +39
@APIParam(resourceType = HostVO.class)
private String uuid;
@APIParam(nonempty = true, emptyString = false)
private String hostName;

public String getUuid() {
return uuid;
}

public void setUuid(String uuid) {
this.uuid = uuid;
}

@Override
public String getHostUuid() {
return uuid;
}

public String getHostName() {
return hostName;
}

public void setHostName(String hostName) {
this.hostName = hostName;
}
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 | 🔴 Critical

🧩 Analysis chain

阻断:API 字段名与 SDK/Inventory 不一致,存在反序列化失败风险

服务端定义为 hostName,SDK 请求体字段为 hostname。Gson 默认不会将 hostname 映射到 hostName,将导致 hostName 取值为 null,触发 APIParam(nonempty) 校验失败。建议全栈统一为 hostname。下面提供服务端改名补丁(更小改动面,且与 HostInventory/内部消息保持一致):

-    @APIParam(nonempty = true, emptyString = false)
-    private String hostName;
+    @APIParam(nonempty = true, emptyString = false)
+    private String hostname;
@@
-    public String getHostName() {
-        return hostName;
+    public String getHostname() {
+        return hostname;
@@
-    public void setHostName(String hostName) {
-        this.hostName = hostName;
+    public void setHostname(String hostname) {
+        this.hostname = hostname;

并同步更新示例方法(见下条评论)。若坚持保留 hostName,则必须同步修改 SDK 字段名为 hostName 或使用与之兼容的序列化策略。


🏁 Script executed:

#!/bin/bash
# 搜索 SDK 中的 APIUpdateHostnameMsg 或生成的客户端代码
echo "=== 1. 搜索 SDK 目录中与 UpdateHostname 相关的代码 ==="
rg -n "UpdateHostname" --type java -A 10 -B 5 | head -100

echo ""
echo "=== 2. 搜索 HostInventory 或相关内部消息中的字段定义 ==="
rg -n "class HostInventory" --type java -A 30 | head -60

echo ""
echo "=== 3. 搜索 hostname 字段在各类中的定义 ==="
rg -n "private String hostname" --type java -C 3 | head -80

echo ""
echo "=== 4. 搜索 hostName 字段在各类中的定义 ==="
rg -n "private String hostName" --type java -C 3 | head -80

echo ""
echo "=== 5. 搜索其他 Update*Hostname* 相关 API ==="
rg -n "class.*Update.*[Hh]ostname" --type java -A 5 | head -60

echo ""
echo "=== 6. 检查 @RestRequest 中的路径规范 ==="
rg -n "@RestRequest.*hostname" --type java -B 2 -A 8 | head -60

Length of output: 31190


🏁 Script executed:

#!/bin/bash
# 查看 APIUpdateHostnameMsg 的完整文件
echo "=== 1. APIUpdateHostnameMsg 完整文件 ==="
cat header/src/main/java/org/zstack/header/host/APIUpdateHostnameMsg.java 2>/dev/null || echo "文件未找到"

echo ""
echo "=== 2. UpdateHostnameMsg 完整文件 ==="
cat header/src/main/java/org/zstack/header/host/UpdateHostnameMsg.java 2>/dev/null || echo "文件未找到"

echo ""
echo "=== 3. SDK 中 UpdateHostnameAction.java 的参数配置部分 ==="
grep -n "parameterMap\|hostname\|hostName" sdk/src/main/java/org/zstack/sdk/UpdateHostnameAction.java | head -30

echo ""
echo "=== 4. 检查是否有 SDK 中生成的对应 API 消息类 ==="
find sdk/src -name "*UpdateHostname*" -type f 2>/dev/null | head -20

echo ""
echo "=== 5. SDK 生成的完整 UpdateHostnameAction 类 ==="
cat sdk/src/main/java/org/zstack/sdk/UpdateHostnameAction.java 2>/dev/null || echo "文件未找到"

Length of output: 5114


🏁 Script executed:

#!/bin/bash
# 查找如何处理 APIUpdateHostnameMsg 并转换为 UpdateHostnameMsg
echo "=== 1. 搜索 APIUpdateHostnameMsg 的处理器 ==="
rg -n "APIUpdateHostnameMsg" --type java -C 5 | grep -E "class|handle|process|listener" | head -30

echo ""
echo "=== 2. 搜索 UpdateHostnameMsg 被创建/赋值的地方 ==="
rg -n "UpdateHostnameMsg" --type java -B 3 -A 3 "new UpdateHostnameMsg\|setHostname" | head -60

echo ""
echo "=== 3. 查找 HostManagerImpl 或类似处理类 ==="
rg -n "class HostManager" --type java -A 5 | head -20

echo ""
echo "=== 4. 搜索是否有 API 参数名到字段名的映射(如 @APIParam 中的 name 属性) ==="
rg -n "@APIParam.*name\s*=" --type java | head -20

echo ""
echo "=== 5. 查看 @Param 注解中是否定义了 JSON 字段名 ==="
grep -A 1 '@Param.*hostname' sdk/src/main/java/org/zstack/sdk/UpdateHostnameAction.java

echo ""
echo "=== 6. 搜索消息参数映射工具 ==="
find . -name "*MessageUtil*" -o -name "*ParamUtil*" 2>/dev/null | grep -E "\\.java$" | head -10

Length of output: 1999


🏁 Script executed:

#!/bin/bash
# 查看 HostBase 中对 APIUpdateHostnameMsg 的处理
echo "=== 1. HostBase 中 handle(APIUpdateHostnameMsg) 实现 ==="
rg -n "private void handle\(APIUpdateHostnameMsg" --type java -A 20

echo ""
echo "=== 2. 查看 APIUpdateHostnameMsg 中是否有 @SerializedName 或其他注解 ==="
cat header/src/main/java/org/zstack/header/host/APIUpdateHostnameMsg.java | grep -E "@|private|public"

echo ""
echo "=== 3. 查找 RestRequest 或 @RestRequest 的拦截器处理 ==="
rg -n "RestRequest\|@RestRequest" --type java | grep -i "interceptor\|filter\|advice" | head -10

echo ""
echo "=== 4. 搜索是否有针对 hostName 字段的特殊映射或别名定义 ==="
rg -n "hostName|hostname" --type java header/src/main/java/org/zstack/header/host/APIUpdateHostnameMsg.java

echo ""
echo "=== 5. 查找 APIMessage 的 Gson 配置 ==="
rg -n "GsonBuilder\|registerTypeAdapter\|setFieldNamingStrategy" --type java | head -20

Length of output: 3133


字段命名不一致导致反序列化失败,需统一为 hostname

服务端 APIUpdateHostnameMsg 定义字段为 hostName,但 SDK UpdateHostnameAction 生成的请求体字段为 hostname。Gson 无特殊映射配置,JSON 中的 hostname 无法反序列化到 hostName 字段,导致该字段为 null,触发 @APIParam(nonempty=true) 校验失败。

建议统一为 hostname(与内部消息 UpdateHostnameMsg、SDK 定义、KVM Agent Command 保持一致):

-    @APIParam(nonempty = true, emptyString = false)
-    private String hostName;
+    @APIParam(nonempty = true, emptyString = false)
+    private String hostname;
@@
-    public String getHostName() {
-        return hostName;
+    public String getHostname() {
+        return hostname;
@@
-    public void setHostName(String hostName) {
-        this.hostName = hostName;
+    public void setHostname(String hostname) {
+        this.hostname = hostname;

同时更新 HostBase.java 第 200 行的调用为 umsg.setHostname(msg.getHostname());,以及 example 方法的示例值。

🤖 Prompt for AI Agents
In header/src/main/java/org/zstack/header/host/APIUpdateHostnameMsg.java around
lines 15 to 39, the field is named hostName but the SDK and JSON use hostname,
causing Gson deserialization to leave the field null and fail
@APIParam(nonempty=true) validation; rename the field and its getters/setters
from hostName/getHostName/setHostName to hostname/getHostname/setHostname (and
keep getHostUuid/setUuid unchanged) so the JSON key matches the Java field, then
update callers: change HostBase.java line ~200 to call
umsg.setHostname(msg.getHostname()); and update the __example__ method's sample
value to use the hostname property name.

Comment on lines +1 to +65
package org.zstack.header.host

doc {
title "UpdateHostNqn"

category "host"

desc """更新主机nqn"""

rest {
request {
url "PUT /v1/hosts/nqn/{uuid}/actions"

header (Authorization: 'OAuth the-session-uuid')

clz APIUpdateHostNqnMsg.class

desc """更新主机nqn"""

params {

column {
name "uuid"
enclosedIn "updateHostNqn"
desc "资源的UUID,唯一标示该资源"
location "url"
type "String"
optional false
since "4.10.6"
}
column {
name "nqn"
enclosedIn "updateHostNqn"
desc "NVMe 限定名称"
location "body"
type "String"
optional false
since "4.10.6"
}
column {
name "systemTags"
enclosedIn ""
desc "系统标签"
location "body"
type "List"
optional true
since "4.10.6"
}
column {
name "userTags"
enclosedIn ""
desc "用户标签"
location "body"
type "List"
optional true
since "4.10.6"
}
}
}

response {
clz APIUpdateHostNqnEvent.class
}
}
} No newline at end of file
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 | 🔴 Critical

严重问题:文档内容完全错误,所有引用均指向 NQN 而非 hostname

该文件存在严重的复制粘贴错误,所有内容都引用了 NQN 相关的类和字段,而不是 hostname。需要修正:

  1. 标题(第 4 行):应为 "UpdateHostname" 而非 "UpdateHostNqn"
  2. 描述(第 8、18 行):应为 "更新主机hostname" 而非 "更新主机nqn"
  3. URL 路径(第 12 行):应为 "PUT /v1/hosts/hostname/{uuid}/actions" 而非 "PUT /v1/hosts/nqn/{uuid}/actions"
  4. 类引用(第 16 行):应为 APIUpdateHostnameMsg.class 而非 APIUpdateHostNqnMsg.class
  5. 参数名称(第 32 行):应为 "hostname" 而非 "nqn"
  6. enclosedIn(第 24、33 行):应为 "updateHostname" 而非 "updateHostNqn"
  7. 参数描述(第 34 行):应为 "主机名称" 而非 "NVMe 限定名称"
  8. 响应类(第 62 行):应为 APIUpdateHostnameEvent.class 而非 APIUpdateHostNqnEvent.class

建议应用以下修复:

 package org.zstack.header.host

 doc {
-	title "UpdateHostNqn"
+	title "UpdateHostname"

 	category "host"

-	desc """更新主机nqn"""
+	desc """更新主机hostname"""

 	rest {
 		request {
-			url "PUT /v1/hosts/nqn/{uuid}/actions"
+			url "PUT /v1/hosts/hostname/{uuid}/actions"

 			header (Authorization: 'OAuth the-session-uuid')

-			clz APIUpdateHostNqnMsg.class
+			clz APIUpdateHostnameMsg.class

-			desc """更新主机nqn"""
+			desc """更新主机hostname"""

 			params {

 				column {
 					name "uuid"
-					enclosedIn "updateHostNqn"
+					enclosedIn "updateHostname"
 					desc "资源的UUID,唯一标示该资源"
 					location "url"
 					type "String"
 					optional false
 					since "4.10.6"
 				}
 				column {
-					name "nqn"
-					enclosedIn "updateHostNqn"
-					desc "NVMe 限定名称"
+					name "hostname"
+					enclosedIn "updateHostname"
+					desc "主机名称"
 					location "body"
 					type "String"
 					optional false
 					since "4.10.6"
 				}
 				column {
 					name "systemTags"
 					enclosedIn ""
 					desc "系统标签"
 					location "body"
 					type "List"
 					optional true
 					since "4.10.6"
 				}
 				column {
 					name "userTags"
 					enclosedIn ""
 					desc "用户标签"
 					location "body"
 					type "List"
 					optional true
 					since "4.10.6"
 				}
 			}
 		}

 		response {
-			clz APIUpdateHostNqnEvent.class
+			clz APIUpdateHostnameEvent.class
 		}
 	}
 }
🤖 Prompt for AI Agents
In
header/src/main/java/org/zstack/header/host/APIUpdateHostnameMsgDoc_zh_cn.groovy
around lines 1 to 65, the doc is a copy-paste of the NQN API; update all NQN
references to hostname: change title to "UpdateHostname", change both desc
strings to "更新主机hostname", change URL to "PUT
/v1/hosts/hostname/{uuid}/actions", change clz to APIUpdateHostnameMsg.class,
change enclosedIn values from "updateHostNqn" to "updateHostname" for the uuid
and hostname params, rename the "nqn" parameter to "hostname" and set its desc
to "主机名称", and change response clz to APIUpdateHostnameEvent.class.

Comment on lines +786 to +834
private void handle(UpdateHostnameMsg msg) {
UpdateHostnameReply ureply = new UpdateHostnameReply();
thdf.chainSubmit(new ChainTask(msg) {
@Override
public String getSyncSignature() {
return id;
}

@Override
public void run(SyncTaskChain chain) {
UpdateHostnameCmd cmd = new UpdateHostnameCmd();
cmd.hostname = msg.getHostname();

KVMHostAsyncHttpCallMsg kmsg = new KVMHostAsyncHttpCallMsg();
kmsg.setCommand(cmd);
kmsg.setPath(KVMConstant.KVM_UPDATE_HOSTNAME_PATH);
kmsg.setHostUuid(msg.getHostUuid());
bus.makeTargetServiceIdByResourceUuid(kmsg, HostConstant.SERVICE_ID, msg.getHostUuid());
bus.send(kmsg, new CloudBusCallBack(chain) {
@Override
public void run(MessageReply reply) {
if (!reply.isSuccess()) {
ureply.setError(operr("fail to update hostname of host[uuid:%s], because %s", msg.getHostUuid(), reply.getError()));
} else {
KVMHostAsyncHttpCallReply r = reply.castReply();
UpdateHostNqnRsp rsp = r.toResponse(UpdateHostNqnRsp.class);
if (!rsp.isSuccess()) {
ureply.setError(operr("fail to update hostname of host[uuid:%s], because %s", msg.getHostUuid(), rsp.getError()));
} else {
SQL.New(HostVO.class).eq(HostVO_.uuid, msg.getHostUuid())
.set(HostVO_.nqn, msg.getHostname())
.update();

self = dbf.reload(self);
ureply.setInventory(getSelfInventory());
}
}
bus.reply(msg, ureply);
chain.next();
}
});
}

@Override
public String getName() {
return String.format("update-hostname-of-host-%s", msg.getHostUuid());
}
});
}
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 | 🔴 Critical

🧩 Analysis chain

错误:Rsp 类型不匹配且写入了错误的数据库字段

  • 回包解析使用了 UpdateHostNqnRsp,应为 UpdateHostnameRsp。
  • 成功后写 DB 的字段是 HostVO_.nqn,应写 HostVO_.hostname。

请按下述补丁修复:

@@
-                            UpdateHostNqnRsp rsp = r.toResponse(UpdateHostNqnRsp.class);
+                            UpdateHostnameRsp rsp = r.toResponse(UpdateHostnameRsp.class);
@@
-                                SQL.New(HostVO.class).eq(HostVO_.uuid, msg.getHostUuid())
-                                        .set(HostVO_.nqn, msg.getHostname())
-                                        .update();
+                                SQL.New(HostVO.class).eq(HostVO_.uuid, msg.getHostUuid())
+                                        .set(HostVO_.hostname, msg.getHostname())
+                                        .update();

同时请确认 Header/Agent 两侧均提供了 UpdateHostnameRsp,并已在 HostVO/HostInventory 增加 hostname 字段,保证 API/DB 对齐。

为避免遗漏,可在仓库跑以下核查脚本:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "1) 检查 HostVO 是否存在 hostname 字段/元模型:"
rg -nP 'class\s+HostVO\b' -C2
rg -nP '\bhostname\b' -n -C2 | head -n 50
rg -nP 'HostVO_\s*\.hostname\b' -n -C2

echo ""
echo "2) 检查 Inventory 是否已暴露 hostname:"
rg -nP 'class\s+HostInventory\b' -C2
rg -nP '\bgetHostname\(|\bsetHostname\(' -n -C2

echo ""
echo "3) 检查 Agent 侧是否实现 UpdateHostnameRsp:"
rg -nP 'class\s+UpdateHostnameRsp\b' -n -C3
rg -nP '\bKVM_UPDATE_HOSTNAME_PATH\b' -n -C2

echo ""
echo "4) 其它对 hostname 的使用场景(便于回归):"
rg -nP '\bhostname\b' --type=java -n -C2 | head -n 100

Length of output: 5013


需要进一步验证。让我执行更细致的检查脚本:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== 1) 检查 HostAO(HostVO的父类)是否有 hostname 字段 ==="
rg -nP 'class\s+HostAO\b' -A20 | head -40
rg -nP '@Column.*hostname|private.*hostname|public.*hostname' -A1 -B1

echo ""
echo "=== 2) 搜索 UpdateHostnameRsp 和 UpdateHostNqnRsp 定义 ==="
rg -nP 'class\s+(UpdateHostname|UpdateHostNqn)Rsp\b' -A3

echo ""
echo "=== 3) 检查当前代码中 UpdateHostNqnRsp 的使用 ==="
fd -e java | xargs grep -l UpdateHostNqnRsp || echo "未找到 UpdateHostNqnRsp"

echo ""
echo "=== 4) 检查 KVM_UPDATE_HOSTNAME_PATH 相关的文件 ==="
rg -nP 'UPDATE_HOSTNAME_PATH' -C2

echo ""
echo "=== 5) 检查 .nqn 字段在 HostVO 中的使用 ==="
rg -nP 'HostVO_\s*\.(nqn|hostname)' -n

echo ""
echo "=== 6) 搜索 set.*nqn 的使用情况 ==="
rg -nP '\.set\(HostVO_\.nqn' -C3

Length of output: 63520


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== 检查 KVMHost.java 786-834 行的实际代码 ==="
sed -n '786,834p' plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java

echo ""
echo "=== 查看 UpdateHostnameMsg 的 getHostname() 方法 ==="
rg -nP 'class\s+UpdateHostnameMsg\b' -A15 | head -30

Length of output: 3842


修复 KVMHost 中的 UpdateHostname 错误:错误的响应类型与数据库字段

代码第 811 行使用了错误的响应类型 UpdateHostNqnRsp,应为 UpdateHostnameRsp。同时第 816 行写入了错误的数据库字段 HostVO_.nqn,应为 HostVO_.hostname

@@
-                            UpdateHostNqnRsp rsp = r.toResponse(UpdateHostNqnRsp.class);
+                            UpdateHostnameRsp rsp = r.toResponse(UpdateHostnameRsp.class);
@@
-                                SQL.New(HostVO.class).eq(HostVO_.uuid, msg.getHostUuid())
-                                        .set(HostVO_.nqn, msg.getHostname())
-                                        .update();
+                                SQL.New(HostVO.class).eq(HostVO_.uuid, msg.getHostUuid())
+                                        .set(HostVO_.hostname, msg.getHostname())
+                                        .update();
🤖 Prompt for AI Agents
In plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java around lines 786 to 834,
the handler uses the wrong response class and writes the wrong DB column: change
the cast from UpdateHostNqnRsp to UpdateHostnameRsp (use the correct response
type to check success and get error), and update the SQL setter to write
HostVO_.hostname (not HostVO_.nqn) with msg.getHostname(); keep the rest of the
flow (reply, reload self, set inventory) unchanged.

Comment on lines +27 to +31
@Param(required = true, nonempty = false, nullElements = false, emptyString = true, noTrim = false)
public String uuid;

@Param(required = true, nonempty = true, nullElements = false, emptyString = false, noTrim = false)
public String hostname;
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

修复:uuid 不应允许空串

uuid 作为路径变量必须为非空字符串,否则会在 URL 占位符替换阶段失败。请调整注解:

-    @Param(required = true, nonempty = false, nullElements = false, emptyString = true, noTrim = false)
+    @Param(required = true, nonempty = false, nullElements = false, emptyString = false, noTrim = false)
     public String uuid;
🤖 Prompt for AI Agents
In sdk/src/main/java/org/zstack/sdk/UpdateHostnameAction.java around lines 27 to
31, the uuid field is currently annotated to allow empty strings which will
break URL path replacement; update the @Param on uuid to require a non-empty
string by setting nonempty = true and emptyString = false (keep other attributes
as appropriate) so the uuid cannot be an empty string.

Comment on lines +93 to +101
protected RestInfo getRestInfo() {
RestInfo info = new RestInfo();
info.httpMethod = "PUT";
info.path = "/hosts/hostname/{uuid}/actions";
info.needSession = true;
info.needPoll = true;
info.parameterName = "updateHostHostname";
return info;
}
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 | 🔴 Critical

🧩 Analysis chain

parameterName 可能与服务端默认解析名不一致

SDK 组装请求体顶层 key 为 "updateHostHostname",而服务端通常以 API 类名去掉 API/Msg 的 lowerCamelCase 作为默认解析名(本类对应多为 updateHostname)。建议改为:

-        info.parameterName = "updateHostHostname";
+        info.parameterName = "updateHostname";

请用脚本核对既有 Host 更新类 API 的 parameterName 一致性:


🏁 Script executed:

#!/bin/bash
# SDK 侧:列出所有 Update*Action 的 parameterName
rg -nP --type=java 'class\s+Update\w+Action\b(?s).*parameterName\s*=\s*"[^"]+"' sdk/src/main/java | sed -E 's/^\s*//'
# Header 侧:列出对应 API 类,辅助人工比对
rg -nP --type=java 'class\s+APIUpdate\w+Msg\b' header/src/main/java | sed -E 's/^\s*//'

Length of output: 5798


Now running verification scripts to examine the Update*Action SDK classes and their parameterName values:

Now let me run a script to directly examine the UpdateHostnameAction file and verify the parameterName:


Once you execute this and return results, I'll be able to verify the exact current value and compare it with the API message class to determine if the review comment is valid.

---

🏁 Script executed:

```shell
#!/bin/bash
# Find and examine UpdateHostnameAction.java
fd -t f "UpdateHostnameAction.java" sdk/ --exec cat {}

Length of output: 91



---

🏁 Script executed:

```shell
#!/bin/bash
# Find and examine UpdateHostnameAction.java file
find . -name "UpdateHostnameAction.java" -type f | head -1 | xargs cat

Length of output: 2820


Now let me verify the pattern with other Host-related API actions:


---

🏁 Script executed:

```shell
#!/bin/bash
# Find all UpdateHost* Action classes and extract their parameterName
find sdk/src/main/java -name "UpdateHost*.java" -type f | while read file; do
  echo "=== $file ==="
  grep -A 5 "protected RestInfo getRestInfo()" "$file" | grep "parameterName"
done

Length of output: 1311



---

🏁 Script executed:

```shell
#!/bin/bash
# Extract parameterName from multiple UpdateHost* Action files
echo "=== UpdateHostAction.java ==="
grep "parameterName" sdk/src/main/java/org/zstack/sdk/UpdateHostAction.java

echo -e "\n=== UpdateHostIpmiAction.java ==="
grep "parameterName" sdk/src/main/java/org/zstack/sdk/UpdateHostIpmiAction.java

echo -e "\n=== UpdateHostnameAction.java ==="
grep "parameterName" sdk/src/main/java/org/zstack/sdk/UpdateHostnameAction.java

echo -e "\n=== UpdateHostNetworkInterfaceAction.java ==="
grep "parameterName" sdk/src/main/java/org/zstack/sdk/UpdateHostNetworkInterfaceAction.java

echo -e "\n=== UpdateHostKernelInterfaceAction.java ==="
grep "parameterName" sdk/src/main/java/org/zstack/sdk/UpdateHostKernelInterfaceAction.java

# Also check corresponding API message classes
echo -e "\n=== API Message Classes ==="
echo "UpdateHostMsg:"
grep "class APIUpdateHostMsg" header/src/main/java/org/zstack/header/host/APIUpdateHostMsg.java

echo -e "UpdateHostIpmiMsg:"
grep "class APIUpdateHostIpmiMsg" header/src/main/java/org/zstack/header/host/APIUpdateHostIpmiMsg.java

echo -e "UpdateHostnameMsg:"
grep "class APIUpdateHostnameMsg" header/src/main/java/org/zstack/header/host/APIUpdateHostnameMsg.java

Length of output: 742



---

🏁 Script executed:

```shell
#!/bin/bash
# Verify if UpdateHostnameAction is actively used
echo "=== Searching for UpdateHostnameAction usage ==="
rg -n "UpdateHostnameAction" --type=java --type=groovy -g '!**/sdk/src/main/java' 2>/dev/null | head -20

echo -e "\n=== Searching for updateHostname parameter usage ==="
rg -n '"updateHostname"' --type=java --type=groovy 2>/dev/null | head -20

Length of output: 418


parameterName 应更正为 "updateHostname"

验证确认:SDK 中所有 UpdateHost* Action 类的 parameterName 遵循统一规则——对应 API 消息类名去掉 API 前缀和 Msg 后缀后转换为 lowerCamelCase:

  • UpdateHostAction: "updateHost" ✓ (对应 APIUpdateHostMsg)
  • UpdateHostIpmiAction: "updateHostIpmi" ✓ (对应 APIUpdateHostIpmiMsg)
  • UpdateHostKernelInterfaceAction: "updateHostKernelInterface"
  • UpdateHostnameAction: "updateHostHostname" ✗ (对应 APIUpdateHostnameMsg,应为 "updateHostname")

当前值包含多余的 "Host",违反命名规范。建议修改如下:

-        info.parameterName = "updateHostHostname";
+        info.parameterName = "updateHostname";
🤖 Prompt for AI Agents
In sdk/src/main/java/org/zstack/sdk/UpdateHostnameAction.java around lines 93 to
101, the RestInfo.parameterName is incorrectly set to "updateHostHostname";
change it to "updateHostname" to match the API message class naming convention
(APIUpdateHostnameMsg → lowerCamelCase "updateHostname") so it follows the same
rule as other UpdateHost* actions.

@MatheMatrix MatheMatrix force-pushed the sync/tao.gan/ZSV-10273@@3 branch 3 times, most recently from 4e6bd23 to df8e464 Compare October 27, 2025 09:46
…a new hostname

DBImpact
APIImpact

Resolves: ZSV-10273

Change-Id: I64746b656f727176647072746d6970776b66737a
@MatheMatrix MatheMatrix force-pushed the sync/tao.gan/ZSV-10273@@3 branch from df8e464 to 0d6aa40 Compare October 27, 2025 09:48
@zstack-robot-1 zstack-robot-1 deleted the sync/tao.gan/ZSV-10273@@3 branch October 27, 2025 09:51
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.

3 participants