Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,17 @@ public void allocate() {
// get bind resources from config
ResourceBindingClusterCollector clusterCollector = new ResourceBindingClusterCollector();
if (!resourceConfig) {
//remove bind cluster uuid from system tag, use current cluster uuid from config
if (resources.containsKey(clusterCollector.getType())) {
List<String> uuids = resources.get(clusterCollector.getType());
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());
Comment on lines +96 to +101
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.

}

resources.computeIfAbsent(clusterCollector.getType(), k -> new ArrayList<>()).add(spec.getVmInstance().getClusterUuid());
}

Expand Down