Skip to content

<fix>[compute]: set vm bind with current cluster uuid#4155

Open
zstack-robot-2 wants to merge 1 commit into
4.8.38from
sync/yaohua.wu/bugfix/ZSTAC-85578
Open

<fix>[compute]: set vm bind with current cluster uuid#4155
zstack-robot-2 wants to merge 1 commit into
4.8.38from
sync/yaohua.wu/bugfix/ZSTAC-85578

Conversation

@zstack-robot-2
Copy link
Copy Markdown
Collaborator

Backport ZSTAC-85578 to 4.8.38

Cherry-pick of original fix from 原单 ZSTAC-66476 (source: 5.3.20).

Original commit: 06af535
Local cherry-pick HEAD: f42cb04

Changes

 .../compute/allocator/ResourceBindingAllocatorFlow.java       | 11 +++++++++++
 1 file changed, 11 insertions(+)

Related: ZSTAC-85578

sync from gitlab !10060

when vm migrate to other cluster, set vm
bind with current cluster uuid, and remove
the bind cluster uuid from system tag, and
update system tag value

Resolves: ZSTAC-66476

Change-Id: I617a776b726161746c686f696e68637565676c72
(cherry picked from commit 06af535)
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 1, 2026

Review Change Stack

Walkthrough

ResourceBindingAllocatorFlow.allocate() 中新增集群绑定清理逻辑:当解析到的绑定资源包含集群类型时,若其中的集群 UUID 与当前 VM 所在集群不符,则将系统标签更新为正确的集群条目,并移除本地映射中的过时集群绑定键,确保后续流程使用正确的配置。

Changes

集群绑定标签同步

Layer / File(s) Summary
Cluster binding tag sync and removal
compute/src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java
在资源绑定分配流程中新增检查逻辑:若集群绑定类型存在且其 UUID 与当前 VM 集群不一致,则通过 VmSystemTags.VM_RESOURCE_BINGDING.updateTagByToken 更新系统标签为 Cluster:<clusterUuid> 形式,并从 resources 映射中删除该集群类型键,避免后续使用过时的绑定解析结果。

🎯 评估

🎯 2 (Simple) | ⏱️ ~8 分钟

Poem

集群之间有迷茫,🐰 来擦亮你的标签光;
旧的绑定说拜拜,新的映射更闪亮✨
一行一行清理好,资源分配无障碍~

🚥 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 标题清晰准确地概括了主要变更:为虚拟机绑定当前集群UUID,与代码改动内容完全对应。
Description check ✅ Passed 描述相关且信息完整,包含关键上下文:从5.3.20版本反向移植的修复、提交哈希、关联的问题编号和GitLab同步信息。
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sync/yaohua.wu/bugfix/ZSTAC-85578

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: 1

🧹 Nitpick comments (1)
compute/src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java (1)

93-104: 💤 Low value

建议抽取独立方法以降低嵌套层级。

此清理逻辑形成了三层嵌套(if (!resourceConfig)if (containsKey)if (!contains))。可将集群绑定的对齐/清理逻辑抽成一个语义清晰的私有方法(如 syncClusterBindingTag()),既符合单一职责,也便于阅读与维护。

As per coding guidelines: “限制嵌套层级最多为两层,且内层不应再出现 else 分支”,并“将条件判断中的处理逻辑提前结束或抽成独立方法”。

🤖 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
`@compute/src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java`
around lines 93 - 104, The nested cleanup/alignment logic around cluster binding
in ResourceBindingAllocatorFlow (the block using resources, clusterCollector,
spec and VmSystemTags.VM_RESOURCE_BINGDING/VM_RESOURCE_BINGDING_TOKEN) should be
extracted into a private method (e.g., syncClusterBindingTag()) that takes the
resources map, clusterCollector and spec as parameters; move the
three-level-nested ifs into that method, perform early exits inside it, and
replace the original inline block with a single call to syncClusterBindingTag()
to reduce nesting and improve readability.
🤖 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
`@compute/src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java`:
- Around line 96-101: The update currently calls
VmSystemTags.VM_RESOURCE_BINGDING.updateTagByToken(...) with
newTag="Cluster:..." which replaces the entire resourceUUids token and wipes
other bindings (Host:...). Change the flow to read the existing token via
getBindedResourcesFromTag(spec.getVmInstance().getUuid(),
VM_RESOURCE_BINGDING_TOKEN), parse it into a map of type->uuid, replace or add
the Cluster entry with spec.getVmInstance().getClusterUuid(), reserialize the
map back to the resourceUUids string, and then call
VM_RESOURCE_BINGDING.updateTagByToken(...) with the original oldToken and the
new token string; keep ResourceBindingHostCollector.getType() handling and only
remove resources from the local resources map as before. Also extract the nested
if logic into a helper method to satisfy code structure requirements.

---

Nitpick comments:
In
`@compute/src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java`:
- Around line 93-104: The nested cleanup/alignment logic around cluster binding
in ResourceBindingAllocatorFlow (the block using resources, clusterCollector,
spec and VmSystemTags.VM_RESOURCE_BINGDING/VM_RESOURCE_BINGDING_TOKEN) should be
extracted into a private method (e.g., syncClusterBindingTag()) that takes the
resources map, clusterCollector and spec as parameters; move the
three-level-nested ifs into that method, perform early exits inside it, and
replace the original inline block with a single call to syncClusterBindingTag()
to reduce nesting and improve readability.
🪄 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: fc55616a-1a7e-4306-9621-6b95ef0838ca

📥 Commits

Reviewing files that changed from the base of the PR and between 00abf62 and f42cb04.

📒 Files selected for processing (1)
  • compute/src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java

Comment on lines +96 to +101
if (!uuids.contains(spec.getVmInstance().getClusterUuid())) {
String tag = String.format("Cluster:%s", spec.getVmInstance().getClusterUuid());
VmSystemTags.VM_RESOURCE_BINGDING.updateTagByToken(spec.getVmInstance().getUuid(),
VmSystemTags.VM_RESOURCE_BINGDING_TOKEN, tag);
}
resources.remove(clusterCollector.getType());
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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# 查找所有 ResourceBindingCollector 实现及其 getType() 返回值
ast-grep --pattern 'class $_ implements ResourceBindingCollector {
  $$$
}'

echo "----- getType 返回值 -----"
rg -nP -C2 'class\s+\w+\s+implements\s+ResourceBindingCollector' --type=java
rg -nP -A6 'public String getType\(\)' --type=java

Repository: MatheMatrix/zstack

Length of output: 50375


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# List ResourceBindingCollector implementations (compute allocator package only)
fd -e java "ResourceBinding*Collector*.java" compute/src/main/java/org/zstack/compute/allocator -a \
  | head -n 200

echo "----- classes implementing ResourceBindingCollector (allocator package) -----"
rg -n "implements\s+ResourceBindingCollector" compute/src/main/java/org/zstack/compute/allocator --type=java -S

echo "----- getType() values for those collectors -----"
rg -n "class\s+(\w+)\s+implements\s+ResourceBindingCollector" compute/src/main/java/org/zstack/compute/allocator --type=java -S -o --replace '$1' \
  | sort -u > /tmp/collector_classes.txt

python3 - <<'PY'
import re, pathlib
base = pathlib.Path("compute/src/main/java/org/zstack/compute/allocator")
txt = pathlib.Path("/tmp/collector_classes.txt").read_text().splitlines()
classes = [t.strip() for t in txt if t.strip()]
for cls in classes:
    # Find the file for the class
    matches = list(base.glob(f"**/{cls}.java"))
    if not matches:
        # fallback: any file containing class declaration
        for p in base.glob("**/*.java"):
            s = p.read_text(errors="ignore")
            if re.search(rf"class\s+{re.escape(cls)}\s+extends?\s+\w*.*implements\s+ResourceBindingCollector', s):
                matches.append(p)
                break
    if not matches:
        continue
    p = matches[0]
    # Extract getType return value line(s) in that file
    content = p.read_text(errors="ignore")
    m = re.search(r"public\s+String\s+getType\s*\(\)\s*\{\s*return\s*([^;]+);", content, re.S)
    if m:
        expr = " ".join(m.group(1).split())
        print(f"{cls}: {expr}  (file: {p.as_posix()})")
    else:
        # if getType not in simple return form, just print the method block header
        m2 = re.search(r"public\s+String\s+getType\s*\([^)]*\)\s*\{", content)
        print(f"{cls}: getType() found but return not in simple form (file: {p.as_posix()})")
PY

Repository: MatheMatrix/zstack

Length of output: 765


🏁 Script executed:

#!/bin/bash
set -euo pipefail

HOST_FILE="compute/src/main/java/org/zstack/compute/allocator/ResourceBindingHostCollector.java"
CLUSTER_FILE="compute/src/main/java/org/zstack/compute/allocator/ResourceBindingClusterCollector.java"

echo "----- collectors in allocator package -----"
rg -n "class\s+ResourceBinding\w+Collector\s+implements\s+ResourceBindingCollector" compute/src/main/java/org/zstack/compute/allocator --type=java

echo "----- getType() return values -----"
echo "== $HOST_FILE =="
rg -n -C2 "String\s+getType\s*\(" "$HOST_FILE" --type=java
rg -n -C2 "return\s" "$HOST_FILE" --type=java | rg -n "getType|return" --max-count 20 || true

echo "== $CLUSTER_FILE =="
rg -n -C2 "String\s+getType\s*\(" "$CLUSTER_FILE" --type=java
rg -n -C2 "return\s" "$CLUSTER_FILE" --type=java | rg -n "getType|return" --max-count 20 || true

Repository: MatheMatrix/zstack

Length of output: 1059


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="compute/src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java"
# Show surrounding code for the reported lines
sed -n '60,140p' "$FILE" | cat -n

echo "----- find getBindedResourcesFromTag -----"
rg -n "getBindedResourcesFromTag|bindedResourcesFromTag|SPLIT|split\\(\"\\,\"\\)|VM_RESOURCE_BINGDING" "$FILE" --type=java

echo "----- show full helper(s) around parsing tag -----"
# print 20 lines before/after the match locations (limit output)
for m in $(rg -n "getBindedResourcesFromTag|VM_RESOURCE_BINGDING_TOKEN" "$FILE" --type=java -o -S | head -n 20); do
  :
done
# Use awk to extract blocks near likely helpers (simple heuristic)
rg -n "getBindedResourcesFromTag|VM_RESOURCE_BINGDING" "$FILE" --type=java | head -n 20

# Locate VmSystemTags definition
echo "----- locate VmSystemTags VM_RESOURCE_BINGDING -----"
rg -n "VM_RESOURCE_BINGDING" -S . --type=java --hidden --glob '!**/target/**' --max-count 50

# Show VmSystemTags.updateTagByToken implementation
echo "----- locate updateTagByToken implementation -----"
rg -n "updateTagByToken\\(" -S . --type=java --max-count 50

Repository: MatheMatrix/zstack

Length of output: 4239


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) 找 ResourceBindingAllocatorFlow 里的 getBindedResourcesFromTag 实现
FILE="compute/src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java"
echo "----- getBindedResourcesFromTag definition (in flow file) -----"
rg -n "getBindedResourcesFromTag" "$FILE" --type=java
rg -n "Map<\s*String\s*,\s*List<\s*String\s*>\s*>\s+getBindedResourcesFromTag|getBindedResourcesFromTag\s*\(" "$FILE" --type=java -n
# 输出方法附近若干行(避免太长)
line=$(rg -n "getBindedResourcesFromTag" "$FILE" --type=java | head -n 1 | cut -d: -f1 || true)
if [ -n "${line:-}" ]; then
  start=$((line-20))
  end=$((line+120))
  sed -n "${start},${end}p" "$FILE" | cat -n
fi

# 2) 找 VmSystemTags 里 VM_RESOURCE_BINGDING / updateTagByToken 的实现
echo "----- locate VmSystemTags VM_RESOURCE_BINGDING -----"
rg -n "VM_RESOURCE_BINGDING" -S . --type=java --hidden --glob '!**/target/**' --max-count 50

# locate the class that declares VM_RESOURCE_BINGDING
TAG_DEF_FILE=$(rg -n "VM_RESOURCE_BINGDING" -S . --type=java --hidden --glob '!**/target/**' --max-count 50 | head -n 1 | cut -d: -f1 || true)
echo "TAG_DEF_FILE=$TAG_DEF_FILE"

# 输出 VM_RESOURCE_BINGDING 相关定义附近
if [ -n "${TAG_DEF_FILE:-}" ] && [ -f "$TAG_DEF_FILE" ]; then
  sed -n '1,200p' "$TAG_DEF_FILE" | cat -n | head -n 200 || true
  # 更精确:输出含 VM_RESOURCE_BINGDING 这行附近
  tline=$(rg -n "VM_RESOURCE_BINGDING" "$TAG_DEF_FILE" --type=java | head -n 1 | cut -d: -f1 || true)
  if [ -n "${tline:-}" ]; then
    start=$((tline-40))
    end=$((tline+120))
    sed -n "${start},${end}p" "$TAG_DEF_FILE" | cat -n
  fi
fi

# 3) 直接搜 updateTagByToken 的方法体(可能在 SystemTag 或某个 tag class)
echo "----- locate updateTagByToken implementation -----"
rg -n "updateTagByToken\s*\(" -S . --type=java --hidden --glob '!**/target/**' --max-count 50
UPD_FILE=$(rg -n "updateTagByToken\s*\(" -S . --type=java --hidden --glob '!**/target/**' --max-count 50 | head -n 1 | cut -d: -f1 || true)
echo "UPD_FILE=$UPD_FILE"
if [ -n "${UPD_FILE:-}" ] && [ -f "$UPD_FILE" ]; then
  uline=$(rg -n "updateTagByToken\s*\(" "$UPD_FILE" --type=java | head -n 1 | cut -d: -f1 || true)
  start=$((uline-60))
  end=$((uline+140))
  sed -n "${start},${end}p" "$UPD_FILE" | cat -n
fi

Repository: MatheMatrix/zstack

Length of output: 25782


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="tag/src/main/java/org/zstack/tag/PatternedSystemTag.java"
echo "----- getTokenByResourceUuid implementation -----"
line=$(rg -n "getTokenByResourceUuid\\(" "$FILE" --type=java | head -n 1 | cut -d: -f1 || true)
if [ -n "${line:-}" ]; then
  start=$((line-40))
  end=$((line+140))
  sed -n "${start},${end}p" "$FILE" | cat -n
fi

echo "----- tagFormat for VM_RESOURCE_BINGDING (VmSystemTags.java) -----"
VM_FILE="compute/src/main/java/org/zstack/compute/vm/VmSystemTags.java"
rg -n "VM_RESOURCE_BINGDING_TOKEN|VM_RESOURCE_BINGDING\s*=" "$VM_FILE" --type=java
tline=$(rg -n "VM_RESOURCE_BINGDING\\s*=" "$VM_FILE" --type=java | head -n 1 | cut -d: -f1)
sed -n "$((tline-10)),$((tline+30))p" "$VM_FILE" | cat -n

Repository: MatheMatrix/zstack

Length of output: 9263


VM_RESOURCE_BINGDING.updateTagByToken 仅写入 Cluster,会覆盖整个 resourceUUids 串导致 Host 等绑定丢失(major)

  • getBindedResourcesFromTag()VM_RESOURCE_BINGDING_TOKEN=resourceUUids 解析成 type:uuid 列表(按 ,/: 拆分),且 resourceBindings::{resourceUUids} 的 tagFormat 里只有这一段 token 值。updateTagByToken() 内部是 vo.getTag().replace(oldTag, newTag)oldTag 是“整个 resourceUUids”字符串,因此 newTag="Cluster:<current>" 会把 Host:<...> 等同 token 内的其他类型一并清空。当前 ResourceBindingHostCollector.getType() 返回 "Host",与 "Cluster" 并存时风险成立。
  • 同一逻辑块内 if (!resourceConfig) 下再嵌套多层 if(<=2 层)不满足现有代码结构要求,可考虑提取方法(minor)。
🐛 建议修复(保留非集群绑定)
                 if (!uuids.contains(spec.getVmInstance().getClusterUuid())) {
-                    String tag = String.format("Cluster:%s", spec.getVmInstance().getClusterUuid());
+                    List<String> entries = new ArrayList<>();
+                    resources.forEach((type, ids) -> {
+                        if (!type.equals(clusterCollector.getType())) {
+                            ids.forEach(id -> entries.add(type + ":" + id));
+                        }
+                    });
+                    entries.add(String.format("Cluster:%s", spec.getVmInstance().getClusterUuid()));
+                    String tag = String.join(SPLIT, entries);
                     VmSystemTags.VM_RESOURCE_BINGDING.updateTagByToken(spec.getVmInstance().getUuid(),
                             VmSystemTags.VM_RESOURCE_BINGDING_TOKEN, tag);
                 }
🤖 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
`@compute/src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java`
around lines 96 - 101, The update currently calls
VmSystemTags.VM_RESOURCE_BINGDING.updateTagByToken(...) with
newTag="Cluster:..." which replaces the entire resourceUUids token and wipes
other bindings (Host:...). Change the flow to read the existing token via
getBindedResourcesFromTag(spec.getVmInstance().getUuid(),
VM_RESOURCE_BINGDING_TOKEN), parse it into a map of type->uuid, replace or add
the Cluster entry with spec.getVmInstance().getClusterUuid(), reserialize the
map back to the resourceUUids string, and then call
VM_RESOURCE_BINGDING.updateTagByToken(...) with the original oldToken and the
new token string; keep ResourceBindingHostCollector.getType() handling and only
remove resources from the local resources map as before. Also extract the nested
if logic into a helper method to satisfy code structure requirements.

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