winterhazel opened a new pull request, #9894:
URL: https://github.com/apache/cloudstack/pull/9894

   ### Description
   
   This PR fixes a regression introduced in 4.19.1.0 in the 
`listServiceOfferings` API.
   
   The API's query was being built with an AND where there previously was an 
OR. This regression caused the API to not return the expected offerings, 
breaking the dynamic scale of instances via the UI (#9879).
   
   Fixes: #9879
   
   ### Types of changes
   
   - [ ] Breaking change (fix or feature that would cause existing 
functionality to change)
   - [ ] New feature (non-breaking change which adds functionality)
   - [X] 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
   
   #### Bug Severity
   
   - [ ] BLOCKER
   - [ ] Critical
   - [ ] Major
   - [X] Minor
   - [ ] Trivial
   
   
   ### How Has This Been Tested?
   
   1. I tried listing the service offering for a virtual machine with dynamic 
scale enabled that uses a custom constrained offering via CMK, and verified the 
performed query.
   
   a) Before the regression, the following query would be performed:
   
   ```sql
   SELECT service_offering_view.id, service_offering_view.uuid, 
service_offering_view.name, service_offering_view.display_text, 
service_offering_view.provisioning_type, service_offering_view.tags, 
service_offering_view.use_local_storage, service_offering_view.system_use, 
service_offering_view.cpu, service_offering_view.speed, 
service_offering_view.ram_size, service_offering_view.nw_rate, 
service_offering_view.mc_rate, service_offering_view.ha_enabled, 
service_offering_view.limit_cpu_use, service_offering_view.is_volatile, 
service_offering_view.host_tag, service_offering_view.default_use, 
service_offering_view.vm_type, service_offering_view.customized_iops, 
service_offering_view.min_iops, service_offering_view.max_iops, 
service_offering_view.hv_ss_reserve, service_offering_view.sort_key, 
service_offering_view.bytes_read_rate, 
service_offering_view.bytes_read_rate_max, 
service_offering_view.bytes_read_rate_max_length, 
service_offering_view.bytes_write_rate, service_offering_view.bytes_
 write_rate_max, service_offering_view.bytes_write_rate_max_length, 
service_offering_view.iops_read_rate, service_offering_view.iops_read_rate_max, 
service_offering_view.iops_read_rate_max_length, 
service_offering_view.iops_write_rate, 
service_offering_view.iops_write_rate_max, 
service_offering_view.iops_write_rate_max_length, 
service_offering_view.created, service_offering_view.removed, 
service_offering_view.domain_id, service_offering_view.domain_uuid, 
service_offering_view.domain_name, service_offering_view.domain_path, 
service_offering_view.zone_id, service_offering_view.zone_uuid, 
service_offering_view.zone_name, service_offering_view.deployment_planner, 
service_offering_view.cache_mode, service_offering_view.min_cpu, 
service_offering_view.max_cpu, service_offering_view.min_memory, 
service_offering_view.max_memory, service_offering_view.vsphere_storage_policy, 
service_offering_view.root_disk_size, 
service_offering_view.dynamic_scaling_enabled, 
service_offering_view.disk_offering
 _strictness, service_offering_view.disk_offering_id, 
service_offering_view.disk_offering_uuid, 
service_offering_view.disk_offering_name, 
service_offering_view.disk_offering_display_text, 
service_offering_view.encrypt_root FROM service_offering_view WHERE 
service_offering_view.disk_offering_strictness = 0  AND 
service_offering_view.use_local_storage = 0  AND  ( (service_offering_view.cpu 
>= 1 )  OR  (service_offering_view.cpu IS NULL  AND 
service_offering_view.max_cpu IS NULL )  OR  (service_offering_view.cpu IS NULL 
 AND service_offering_view.max_cpu >= 1 ) )  AND  (service_offering_view.speed 
>= 1024  OR service_offering_view.speed IS NULL )  AND  ( 
(service_offering_view.ram_size >= 1024 )  OR  (service_offering_view.ram_size 
IS NULL  AND service_offering_view.max_memory IS NULL )  OR  
(service_offering_view.ram_size IS NULL  AND service_offering_view.max_memory 
>= 1024 ) )  AND service_offering_view.dynamic_scaling_enabled = 1  AND 
service_offering_view.system_use = 0  AND servic
 e_offering_view.removed IS NULL  ORDER BY service_offering_view.sort_key ASC , 
service_offering_view.id ASC  LIMIT 0, 500
   ```
   
   Originally, the section that got regressed was:
   
   ```sql
   (service_offering_view.ram_size IS NULL  AND 
service_offering_view.max_memory IS NULL )  OR  (service_offering_view.ram_size 
IS NULL  AND service_offering_view.max_memory >= 1024 )
   ```
   
   b) With the regression, the following query is performed:
   
   ```sql
   SELECT DISTINCT(service_offering.id) FROM service_offering  LEFT JOIN 
service_offering_details maxComputeDetailsSearch ON 
service_offering.id=maxComputeDetailsSearch.service_offering_id AND 
'maxcpunumber'=maxComputeDetailsSearch.name  LEFT JOIN service_offering_details 
maxMemoryDetailsSearch ON 
service_offering.id=maxMemoryDetailsSearch.service_offering_id AND 
'maxmemory'=maxMemoryDetailsSearch.name  INNER JOIN disk_offering 
diskOfferingSearch ON service_offering.disk_offering_id=diskOfferingSearch.id 
AND 'Active'=diskOfferingSearch.state WHERE service_offering.state = 'Active'  
AND service_offering.disk_offering_strictness = 0  AND  ( service_offering.cpu 
>= 1  OR  ( service_offering.cpu IS NULL  AND  ( maxComputeDetailsSearch.value 
IS NULL  OR maxComputeDetailsSearch.value >= 1  )  )  )  AND  ( 
service_offering.speed IS NULL  OR service_offering.speed >= 1024  )  AND  ( 
service_offering.ram_size >= 1024  OR  ( service_offering.ram_size IS NULL  AND 
 ( maxMemoryDetailsSearch.valu
 e IS NULL  AND maxMemoryDetailsSearch.value >= 1024  )  )  )  AND 
service_offering.dynamic_scaling_enabled = 1  AND service_offering.system_use = 
0  AND service_offering.removed IS NULL  AND  
(diskOfferingSearch.use_local_storage = 0 ) ORDER BY service_offering.sort_key 
ASC , service_offering.id ASC  LIMIT 0, 500
   ```
   
   The problematic section:
   ```sql
   ( service_offering.ram_size IS NULL  AND  ( maxMemoryDetailsSearch.value IS 
NULL  AND maxMemoryDetailsSearch.value >= 1024  )
   ```
   
   c) With the patch:
   
   ```sql
   SELECT DISTINCT(service_offering.id) FROM service_offering  LEFT JOIN 
service_offering_details maxComputeDetailsSearch ON 
service_offering.id=maxComputeDetailsSearch.service_offering_id AND 
'maxcpunumber'=maxComputeDetailsSearch.name  LEFT JOIN service_offering_details 
maxMemoryDetailsSearch ON 
service_offering.id=maxMemoryDetailsSearch.service_offering_id AND 
'maxmemory'=maxMemoryDetailsSearch.name  INNER JOIN disk_offering 
diskOfferingSearch ON service_offering.disk_offering_id=diskOfferingSearch.id 
AND 'Active'=diskOfferingSearch.state WHERE service_offering.state = 'Active'  
AND service_offering.disk_offering_strictness = 0  AND  ( service_offering.cpu 
>= 1  OR  ( service_offering.cpu IS NULL  AND  ( maxComputeDetailsSearch.value 
IS NULL  OR maxComputeDetailsSearch.value >= 1  )  )  )  AND  ( 
service_offering.speed IS NULL  OR service_offering.speed >= 1024  )  AND  ( 
service_offering.ram_size >= 1024  OR  ( service_offering.ram_size IS NULL  AND 
 ( maxMemoryDetailsSearch.valu
 e IS NULL  OR maxMemoryDetailsSearch.value >= 1024  )  )  )  AND 
service_offering.dynamic_scaling_enabled = 1  AND service_offering.system_use = 
0  AND service_offering.removed IS NULL  AND  
(diskOfferingSearch.use_local_storage = 0 ) ORDER BY service_offering.sort_key 
ASC , service_offering.id ASC  LIMIT 0, 500
   ```
   
   The second AND was reverted to an OR:
   
   ```sql
   ( service_offering.ram_size IS NULL  AND  ( maxMemoryDetailsSearch.value IS 
NULL  OR maxMemoryDetailsSearch.value >= 1024  )  )
   ```
   
   2. Via the UI, I tried to dynamic scale the VM, and verified that I was able 
to scale it successfully.
   
   ![Screenshot from 2024-11-05 
13-46-40](https://github.com/user-attachments/assets/22c7039b-24ec-4e04-9ddd-9c0b4a5e8da8)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to