Skip to content

Scope host tag-rule matches to deployment plan in allocators - #13951

Open
DaanHoogland wants to merge 1 commit into
4.20from
fix-vm-deployment-issue
Open

Scope host tag-rule matches to deployment plan in allocators#13951
DaanHoogland wants to merge 1 commit into
4.20from
fix-vm-deployment-issue

Conversation

@DaanHoogland

Copy link
Copy Markdown
Contributor

Scope host tag-rule matches to deployment plan in FirstFit/Random allocators

Problem

FirstFitAllocator and RandomAllocator both call
HostDao#findHostsWithTagRuleThatMatchComputeOferringTags(String) to pick up hosts whose
host tag is defined as a rule (a boolean/regex expression, e.g. !ssd) rather than a
literal string, so they match the compute offering's host tag.

That DAO method evaluates every rule-tagged host in the entire installation against the
offering tag and returns all matches, with no zone/pod/cluster filtering. The allocators then
unconditionally addAll/union those hosts into the candidate list for the current
deployment plan:

// before — unscoped: can return hosts from any zone/pod/cluster
clusterHosts.addAll(_hostDao.findHostsWithTagRuleThatMatchComputeOferringTags(hostTagOnOffering));

As a result, a host in a different datacenter/pod/cluster than the one being deployed into —
but whose rule tag happens to match the offering's host tag — can be added as an allocation
candidate. Once storage-pool selection is scoped correctly but the host list isn't, the two
diverge and valid host+pool pairings that should have worked can be rejected, or (in the
FirstFitAllocator path) a host outside the deployment's scope can be picked entirely.

This reproduces most easily in a setup combining host tags and storage tags with more than
one pod/cluster/zone and a host tag configured as a rule.

Fix

  • Added a scoped overload on HostDao:
    findHostsWithTagRuleThatMatchComputeOferringTags(String computeOfferingTags, Long clusterId, Long podId, Long dcId),
    implemented in HostDaoImpl by reusing the existing rule evaluation and filtering the
    matched hosts down to the given zone/pod/cluster.
  • FirstFitAllocator (both allocateTo overloads) and RandomAllocator now call the scoped
    overload with the deployment plan's dcId/podId/clusterId instead of the unscoped one.
  • On main, the rule-tag lookup lives in the shared BaseAllocator#addHostsBasedOnTagRules
    helper (used by both allocators); that helper and its two call sites were updated the same
    way.
// after — scoped to the deployment plan
clusterHosts.addAll(
    _hostDao.findHostsWithTagRuleThatMatchComputeOferringTags(hostTagOnOffering, clusterId, podId, dcId)
);

The old unscoped overload is left in place since it's still the correct primitive for the
handful of call sites (e.g. findClustersThatMatchHostTagRule) that intentionally look
system-wide.

Testing

Added/extended unit tests to assert the allocators call the scoped DAO overload (and never
fall back to the unscoped one) when resolving rule-tagged hosts:

  • FirstFitAllocatorTest (new on 4.20/4.22; extended on main)
  • RandomAllocatorTest
  • BaseAllocatorTest (main only, covers the shared helper directly)

Types of changes

  • Breaking change (fix or feature that would cause existing functionality to change)
  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Enhancement (improves an existing feature and functionality)
  • Cleanup (Code refactoring and cleanup, that may add test cases)
  • Build/CI
  • Test (unit or integration test code)

Feature/Enhancement Scale or Bug Severity

Feature/Enhancement Scale

  • Major
  • Minor

Bug Severity

  • BLOCKER
  • Critical
  • Major
  • Minor
  • Trivial

Screenshots (if appropriate):

How Has This Been Tested?

How did you try to break this feature and the system with this change?

@DaanHoogland

Copy link
Copy Markdown
Contributor Author

pretty sure I started working on this for some issue or discussion, but I lost the link.

@codecov

codecov Bot commented Aug 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 15.38462% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 16.34%. Comparing base (6136ac9) to head (f603e1b).

Files with missing lines Patch % Lines
.../src/main/java/com/cloud/host/dao/HostDaoImpl.java 0.00% 10 Missing ⚠️
...gent/manager/allocator/impl/FirstFitAllocator.java 50.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               4.20   #13951      +/-   ##
============================================
+ Coverage     16.32%   16.34%   +0.01%     
- Complexity    13556    13564       +8     
============================================
  Files          5669     5669              
  Lines        501399   501409      +10     
  Branches      60902    60903       +1     
============================================
+ Hits          81847    81941      +94     
+ Misses       410390   410273     -117     
- Partials       9162     9195      +33     
Flag Coverage Δ
uitests 4.14% <ø> (ø)
unittests 17.20% <15.38%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
4.9% Coverage on New Code (required ≥ 40%)

See analysis details on SonarQube Cloud

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