Skip to content

Conversation

@Pearl1594
Copy link
Contributor

Description

This PR allows dedicating backup offerings to domains to be consistent in behaviour with other offerings

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

Screenshots (if appropriate):

How Has This Been Tested?

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

@codecov
Copy link

codecov bot commented Dec 4, 2025

Codecov Report

❌ Patch coverage is 31.61290% with 212 lines in your changes missing coverage. Please review.
✅ Project coverage is 17.70%. Comparing base (2600965) to head (385f99b).
⚠️ Report is 31 commits behind head on main.

Files with missing lines Patch % Lines
...stack/backup/dao/BackupOfferingDetailsDaoImpl.java 0.00% 52 Missing ⚠️
...che/cloudstack/backup/BackupOfferingDetailsVO.java 0.00% 28 Missing ⚠️
...rg/apache/cloudstack/backup/BackupManagerImpl.java 63.88% 15 Missing and 11 partials ⚠️
...er/src/main/java/com/cloud/utils/DomainHelper.java 0.00% 19 Missing ⚠️
...e/cloudstack/backup/dao/BackupOfferingDaoImpl.java 0.00% 13 Missing ⚠️
...c/main/java/com/cloud/user/AccountManagerImpl.java 0.00% 13 Missing ⚠️
...ver/src/main/java/com/cloud/acl/DomainChecker.java 47.61% 4 Missing and 7 partials ⚠️
.../api/command/offering/DomainAndZoneIdResolver.java 78.72% 0 Missing and 10 partials ⚠️
.../command/admin/backup/ImportBackupOfferingCmd.java 0.00% 7 Missing ⚠️
...loudstack/api/response/BackupOfferingResponse.java 0.00% 6 Missing ⚠️
... and 9 more
Additional details and impacted files
@@             Coverage Diff              @@
##               main   #12194      +/-   ##
============================================
+ Coverage     17.57%   17.70%   +0.13%     
- Complexity    15550    15933     +383     
============================================
  Files          5913     5918       +5     
  Lines        529427   541258   +11831     
  Branches      64677    69524    +4847     
============================================
+ Hits          93024    95808    +2784     
- Misses       425940   434754    +8814     
- Partials      10463    10696     +233     
Flag Coverage Δ
uitests 3.55% <ø> (-0.04%) ⬇️
unittests 18.76% <31.61%> (+0.12%) ⬆️

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

☔ View full report in Codecov by Sentry.
📢 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.

@Pearl1594 Pearl1594 closed this Dec 5, 2025
@Pearl1594 Pearl1594 reopened this Dec 5, 2025
@Pearl1594
Copy link
Contributor Author

@blueorangutan package

@blueorangutan
Copy link

@Pearl1594 a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan
Copy link

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✖️ debian ✔️ suse15. SL-JID 15952

@Pearl1594
Copy link
Contributor Author

@blueorangutan test

@blueorangutan
Copy link

@Pearl1594 a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests

@blueorangutan
Copy link

[SF] Trillian Build Failed (tid-14922)

@Pearl1594 Pearl1594 closed this Dec 8, 2025
@Pearl1594
Copy link
Contributor Author

@blueorangutan package

@blueorangutan
Copy link

@Pearl1594 a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan
Copy link

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 15976

@Pearl1594
Copy link
Contributor Author

@blueorangutan test

@blueorangutan
Copy link

@Pearl1594 a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests

@blueorangutan
Copy link

[SF] Trillian Build Failed (tid-14958)

@blueorangutan
Copy link

[SF] Trillian test result (tid-14963)
Environment: kvm-ol8 (x2), zone: Advanced Networking with Mgmt server ol8
Total time taken: 61908 seconds
Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr12194-t14963-kvm-ol8.zip
Smoke tests completed. 147 look OK, 3 have errors, 0 did not run
Only failed and skipped tests results shown below:

Test Result Time (s) Test File
test_01_migrate_VM_and_root_volume Error 68.93 test_vm_life_cycle.py
test_02_migrate_VM_with_two_data_disks Error 21.22 test_vm_life_cycle.py
test_02_unsecure_vm_migration Error 333.36 test_vm_life_cycle.py
test_02_unsecure_vm_migration Error 333.37 test_vm_life_cycle.py
test_08_migrate_vm Error 16.74 test_vm_life_cycle.py
test_01_migrate_vm_strict_tags_success Error 71.80 test_vm_strict_host_tags.py
test_01_redundant_vpc_site2site_vpn Failure 390.27 test_vpc_vpn.py
test_01_vpc_site2site_vpn Failure 251.56 test_vpc_vpn.py

@Pearl1594
Copy link
Contributor Author

@blueorangutan test

@blueorangutan
Copy link

@Pearl1594 a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests

@blueorangutan
Copy link

[SF] Trillian test result (tid-14972)
Environment: kvm-ol8 (x2), zone: Advanced Networking with Mgmt server ol8
Total time taken: 48046 seconds
Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr12194-t14972-kvm-ol8.zip
Smoke tests completed. 140 look OK, 5 have errors, 5 did not run
Only failed and skipped tests results shown below:

Test Result Time (s) Test File
test_DeployVmAntiAffinityGroup_in_project Error 72.06 test_affinity_groups_projects.py
test_DeployVmAntiAffinityGroup Error 10.64 test_affinity_groups.py
test_03_deploy_and_scale_kubernetes_cluster Failure 31.75 test_kubernetes_clusters.py
test_08_upgrade_kubernetes_ha_cluster Failure 0.06 test_kubernetes_clusters.py
test_12_test_deploy_cluster_different_offerings_per_node_type Failure 73.69 test_kubernetes_clusters.py
test_01_non_strict_host_anti_affinity Failure 75.15 test_nonstrict_affinity_group.py
test_02_non_strict_host_affinity Error 22.13 test_nonstrict_affinity_group.py
ContextSuite context=TestMigrateVMStrictTags>:setup Error 0.00 test_vm_strict_host_tags.py
all_test_vpc_vpn Skipped --- test_vpc_vpn.py
all_test_webhook_delivery Skipped --- test_webhook_delivery.py
all_test_webhook_lifecycle Skipped --- test_webhook_lifecycle.py
all_test_host_maintenance Skipped --- test_host_maintenance.py
all_test_hostha_kvm Skipped --- test_hostha_kvm.py

Copy link
Collaborator

@abh1sar abh1sar left a comment

Choose a reason for hiding this comment

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

Great job with the DomainAndZoneIdResolver. Some minor comments.

@Override
public void execute() {
try {
if (StringUtils.isAllEmpty(getName(), getDescription()) && getAllowUserDrivenBackups() == null) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should add getDomainIds() to the if condition otherwise update will fail if only the domainIds parameter is getting changed.

throw new CloudRuntimeException("A backup offering with the same name already exists in this zone");
}

if (org.apache.commons.collections.CollectionUtils.isNotEmpty(cmd.getDomainIds())) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not really related to this change, but can we put org.apache.commons.collections.CollectionUtils in the imports?
line 1162 is using CollectionUtils from com.amazonaws.util which can be changed to use org.apache.commons.collections.CollectionUtils

List<Long> filteredDomainIds = filterChildSubDomains(domainIds);
Collections.sort(filteredDomainIds);

boolean success =backupOfferingDao.update(id, offering);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
boolean success =backupOfferingDao.update(id, offering);
boolean success = backupOfferingDao.update(id, offering);

final Domain validDomain = base._entityMgr.findByUuid(Domain.class, trimmed);
if (validDomain == null) {
logger.warn("Invalid domain specified for {}: {}", type, trimmed);
throw new InvalidParameterValueException("Failed to create " + type + " because invalid domain has been specified.");
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does it make sense to add the invalid domainId in the exception?

return savedOffering;
}

private List<Long> filterChildSubDomains(final List<Long> domainIds) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

There are 3 implementations of filterChildSubDomains. Can we do something similar to resolveDomainIds for it?

Image

Comment on lines 2272 to 2279
if(!filteredDomainIds.equals(existingDomainIds)) {
SearchBuilder<BackupOfferingDetailsVO> sb = backupOfferingDetailsDao.createSearchBuilder();
sb.and("offeringId", sb.entity().getResourceId(), SearchCriteria.Op.EQ);
sb.and("detailName", sb.entity().getName(), SearchCriteria.Op.EQ);
sb.done();
SearchCriteria<BackupOfferingDetailsVO> sc = sb.create();
sc.setParameters("offeringId", String.valueOf(id));
sc.setParameters("detailName", ApiConstants.DOMAIN_ID);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Probably it would be better to move this to BackupOfferingDetailsDaoImpl?

public List<Long> getBackupOfferingDomains(Long offeringId) {
final BackupOffering backupOffering = backupOfferingDao.findById(offeringId);
if (backupOffering == null) {
throw new InvalidParameterValueException("Unable to find backup offering " + backupOffering);
Copy link
Collaborator

Choose a reason for hiding this comment

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

error message is accessing backupOffering which is null

dataView: true,
popup: true,
groupMap: (selection) => { return selection.map(x => { return { id: x } }) },
args: ['name', 'description', 'allowuserdrivenbackups']
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there a plan to add domainIds to updateBackupOffering UI?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

for what ever reason, domain update isn't support on UI for any of the offering types, so I chose to omit it as well.

private String domainId;

@SerializedName(ApiConstants.DOMAIN)
@Param(description = "the domain name(s) this disk offering belongs to. Ignore this information as it is not currently applicable.")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Fix the description. Also since = "4.23.0" can be added

Comment on lines 28 to 29


Copy link
Collaborator

Choose a reason for hiding this comment

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

extra lines can be removed

@Pearl1594 Pearl1594 force-pushed the dedicate-backup-offering-to-domain branch from 67721ad to 57332b0 Compare December 16, 2025 19:02
@Pearl1594 Pearl1594 force-pushed the dedicate-backup-offering-to-domain branch from 57332b0 to f7b99a4 Compare December 16, 2025 19:03
@Pearl1594
Copy link
Contributor Author

@blueorangutan package

@blueorangutan
Copy link

@Pearl1594 a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan
Copy link

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 16062

Copy link
Collaborator

@abh1sar abh1sar left a comment

Choose a reason for hiding this comment

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

some nitpicks.
but overall CLGTM from me.


@SerializedName(ApiConstants.DOMAIN_ID)
@Param(description = "the domain ID(s) this disk offering belongs to. Ignore this information as it is not currently applicable.")
@Param(description = "the domain ID(s) this disk offering belongs to. Ignore this information as it is not currently applicable.",
Copy link
Collaborator

Choose a reason for hiding this comment

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

this disk offering -> this backup offering

"Ignore this information.." thus should not be here, right?


@SerializedName(ApiConstants.DOMAIN)
@Param(description = "the domain name(s) this disk offering belongs to. Ignore this information as it is not currently applicable.")
@Param(description = "the domain name(s) this disk offering belongs to. Ignore this information as it is not currently applicable.",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same here


@DB
@Override
public void updateBackupOfferingDetails(long backupOfferingId, List<Long> filteredDomainIds) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: rename to updateBackupOfferingDomainIdsDetails?

@abh1sar
Copy link
Collaborator

abh1sar commented Dec 17, 2025

@blueorangutan test

@blueorangutan
Copy link

@abh1sar a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests

@blueorangutan
Copy link

[SF] Trillian Build Failed (tid-15008)

@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

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

See analysis details on SonarQube Cloud

@Pearl1594
Copy link
Contributor Author

@blueorangutan package

@blueorangutan
Copy link

@Pearl1594 a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan
Copy link

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 16077

@Pearl1594
Copy link
Contributor Author

@blueorangutan test

@blueorangutan
Copy link

@Pearl1594 a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests

@blueorangutan
Copy link

[SF] Trillian test result (tid-15019)
Environment: kvm-ol8 (x2), zone: Advanced Networking with Mgmt server ol8
Total time taken: 53399 seconds
Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr12194-t15019-kvm-ol8.zip
Smoke tests completed. 149 look OK, 1 have errors, 0 did not run
Only failed and skipped tests results shown below:

Test Result Time (s) Test File
test_03_deploy_and_scale_kubernetes_cluster Failure 25.80 test_kubernetes_clusters.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants