Skip to content

UI: allow memory setting in flex compute offering in GiB with unit selector (#14082) - #14413

Open
saurabhkushwaha438 wants to merge 1 commit into
apache:mainfrom
saurabhkushwaha438:issue-14082-flex-memory-gib
Open

saurabhkushwaha438 wants to merge 1 commit into
apache:mainfrom
saurabhkushwaha438:issue-14082-flex-memory-gib

Conversation

@saurabhkushwaha438

Copy link
Copy Markdown
Contributor

Description

Fixes #14082

1. Conversion from MiB to GiB (Display & Rounding)

  • Binary conversion is used (1 GiB = 1024 MiB).
  • When offerings with predefined constraints or initial values are loaded in MiB, or when switching from MiB to GiB:
    $$\text{displayValue} = \text{parseFloat}\left(\left(\frac{\text{rawMemory}}{1024}\right)\text{.toFixed(2)}\right)$$
  • The display value is rounded to 2 decimal places to keep the UI clean, readable, and intuitive for users.
  • Slider step dynamically adjusts:
    • In GiB mode: step is set to 0.01 (or smaller for sub-GiB offerings) with precision 2.
    • In MiB mode: step is set to 1 with integer precision 0.

2. Conversion from GiB to MiB (Backend Value Emission)

  • CloudStack APIs and backend services expect memory allocations in integer MiB.
  • When the user selects or inputs memory in GiB:
    $$\text{memoryInMiB} = \text{Math.round}(\text{displayValue} \times 1024)$$
  • Exact Boundary Protection: If a compute offering has minimum/maximum memory constraints (minMemory / maxMemory), selecting the exact minimum or maximum bound in GiB directly maps to the exact integer minMemory or maxMemory in MiB to eliminate any potential off-by-one rounding discrepancies.

💬 Feedback Needed: Fractional GiB to Integer MiB Rounding

  • Observation: Converting decimal GiB values to MiB often produces fractional values (e.g., 1.51 GiB × 1024 = 1546.24 MiB).
  • Current Behavior: The UI rounds this to the nearest integer (1546 MiB), which is then emitted in the API payload and consumed by backend hypervisor managers.
  • Reviewer Input: Looking for maintainer feedback on whether standard nearest-integer rounding (Math.round) is acceptable, or if we should apply ceiling (Math.ceil) to guarantee the VM always receives at least the requested GiB amount.
bandicam.2026-10-16.10-21-12-210.mp4

@codecov

codecov Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 20.76%. Comparing base (7ed0cec) to head (6c3f959).
⚠️ Report is 82 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main   #14413      +/-   ##
============================================
+ Coverage     19.91%   20.76%   +0.84%     
- Complexity    20198    21904    +1706     
============================================
  Files          6373     6496     +123     
  Lines        577230   591647   +14417     
  Branches      70696    72601    +1905     
============================================
+ Hits         114936   122835    +7899     
- Misses       449736   455482    +5746     
- Partials      12558    13330     +772     
Flag Coverage Δ
uitests 3.87% <ø> (+0.16%) ⬆️
unittests 22.07% <ø> (+0.88%) ⬆️

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.

@nvazquez nvazquez added this to the 24.0 milestone Oct 30, 2026
@nvazquez

Copy link
Copy Markdown
Contributor

@blueorangutan ui

@blueorangutan

Copy link
Copy Markdown

@nvazquez a Jenkins job has been kicked to build UI QA env. I'll keep you posted as I make progress.

@blueorangutan

Copy link
Copy Markdown

UI build: ✔️
Live QA URL: https://qa.cloudstack.cloud/simulator/pr/14413 (QA-JID-1003)

@saurabhkushwaha438
saurabhkushwaha438 force-pushed the issue-14082-flex-memory-gib branch 2 times, most recently from 2c7e3a6 to c401af2 Compare October 30, 2026 06:42
@Damans227

Copy link
Copy Markdown
Collaborator

@blueorangutan ui

@blueorangutan

Copy link
Copy Markdown

@Damans227 a Jenkins job has been kicked to build UI QA env. I'll keep you posted as I make progress.

@blueorangutan

Copy link
Copy Markdown

UI build: ✔️
Live QA URL: https://qa.cloudstack.cloud/simulator/pr/14413 (QA-JID-1004)

@saurabhkushwaha438
saurabhkushwaha438 force-pushed the issue-14082-flex-memory-gib branch from c401af2 to 6c3f959 Compare November 1, 2026 06:49
@nvazquez

nvazquez commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

@blueorangutan ui

@blueorangutan

Copy link
Copy Markdown

@nvazquez a Jenkins job has been kicked to build UI QA env. I'll keep you posted as I make progress.

@blueorangutan

Copy link
Copy Markdown

UI build: ✔️
Live QA URL: https://qa.cloudstack.cloud/simulator/pr/14413 (QA-JID-1005)

@nvazquez nvazquez left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hi @saurabhkushwaha438 I have tested it and I see a problem with custom unconstrained offerings as displayed in the screenshot, can you please take a look at this issue? Custom constrained is looking fine btw.

Image

…B step (apache#14082)

- Add compact unit selector dropdown (GiB/MiB) for flex compute offerings
- Use fixed 0.25 GiB steps in GiB mode (binary-exact to 256 MiB intervals, zero rounding errors)
- Maintain integer MiB as authoritative internal state to prevent lossy conversion on load
- Default to GiB for 256 MiB multiples and MiB for arbitrary sizes (e.g. 1500 MiB)
- Add hover tooltip to display exact converted values
@saurabhkushwaha438
saurabhkushwaha438 force-pushed the issue-14082-flex-memory-gib branch from 6c3f959 to 171b008 Compare November 2, 2026 07:15
@saurabhkushwaha438

Copy link
Copy Markdown
Contributor Author

Hi @saurabhkushwaha438 I have tested it and I see a problem with custom unconstrained offerings as displayed in the screenshot, can you please take a look at this issue? Custom constrained is looking fine btw.

Image

its done
image

return
}
this.$emit('update-compute-memory', this.memoryInputDecorator, value)
let memoryInMiB
if (this.memoryUnit === 'GiB') {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@saurabhkushwaha438 The memory field and its hover text show different amounts of memory value at the minimum and maximum of a constrained offering.
With min memory 100 MiB, the GiB control shows 0.25 GiB. Hovering it shows "Exact: 0.09765625 GiB (100 MiB)", and deploy sends 100 MiB. 0.25 GiB is 256 MiB, so the VM is created with a smaller size than the field shows. The same happens at the maximum.

Image Image

@@ -57,23 +57,40 @@
</a-col>
<a-col :md="colContraned" :lg="colContraned" v-if="isCustomized">
<a-form-item
:label="$t('label.memory.mb')"
:label="$t('label.memory')"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@saurabhkushwaha438 An out-of-range GiB value is rejected with "Invalid memory value, specify a value between 32 and 2147483647" and the message does not say the unit (MiB or GiB).
For example: 0.01 GiB is sent as 10 MiB and hits this error.

Image

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

i think you can raise separate issue for that

},
validateInput (input, value) {
this.errors[input].status = ''
this.errors[input].message = ''

if (value === null || value === undefined || value.length === 0) {
if (value === null || value === undefined || value.length === 0 || value === '' || value === 0) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@saurabhkushwaha438 Setting the CPU value to 0 does not clear the previously stored CPU count in the form. For example, after selecting a constrained offering, the form stores CPU = 2. When switching to an unconstrained custom offering, the CPU field displays 0 with the validation message "Please enter input". However, instance creation still proceeds successfully, and the VM is created with 2 CPUs, as the previously stored value is retained.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

well this is not related to this issue

memoryInMiB = Math.round(displayValue * 1024)
}
} else {
memoryInMiB = Math.round(displayValue)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@saurabhkushwaha438 Switching between MiB and GiB updates only the displayed memory value, while the deploy form continues to retain the previously entered MiB value.

On an unconstrained custom offering:

  • Enter 1100 MiB and then switch to GiB. The field displays 1.00 GiB, but when the instance is created, the deploy request still sends 1100 MiB (where 1.00 GiB = 1024 MiB).
  • Enter 100 MiB and then switch to GiB. The field displays 0 GiB, but instance creation still succeeds, and the deploy request sends 100 MiB, resulting in a VM being created with 100 MiB of memory.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

thanks for pointing out this "Enter 100 MiB and then switch to GiB. The field displays 0 GiB, but instance creation still succeeds, and the deploy request sends 100 MiB, resulting in a VM being created with 100 MiB of memory."

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

thanks for pointing out this "Enter 100 MiB and then switch to GiB. The field displays 0 GiB, but instance creation still succeeds, and the deploy request sends 100 MiB, resulting in a VM being created with 100 MiB of memory."

hey i am not able reproduce this problem , could you attach screenshot of it

maxMemoryInUnit () {
if (!this.maxMemory) return 0
if (this.memoryUnit === 'GiB') {
return Math.max(this.minMemoryInUnit, Math.floor(this.maxMemory / 256) * 0.25)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@saurabhkushwaha438 For custom offerings with a memory range like 2000-2300 MiB, the field is effectively restricted to 2.00 GiB when the unit is switched to GiB. The slider cannot be moved to any other value within the allowed range, preventing selection of valid memory sizes between 2000 MiB and 2300 MiB.

@saurabhkushwaha438

Copy link
Copy Markdown
Contributor Author

Description

Fixes #14082

1. Conversion from MiB to GiB (Display & Rounding)

  • Binary conversion is used (1 GiB = 1024 MiB).

  • When offerings with predefined constraints or initial values are loaded in MiB, or when switching from MiB to GiB:

    displayValue

    parseFloat

    (
    
      (
      
        rawMemory
        1024
      
      )
    
    .toFixed(2)
    )
    
  • The display value is rounded to 2 decimal places to keep the UI clean, readable, and intuitive for users.

  • Slider step dynamically adjusts:

    • In GiB mode: step is set to 0.01 (or smaller for sub-GiB offerings) with precision 2.
    • In MiB mode: step is set to 1 with integer precision 0.

2. Conversion from GiB to MiB (Backend Value Emission)

  • CloudStack APIs and backend services expect memory allocations in integer MiB.

  • When the user selects or inputs memory in GiB:

    memoryInMiB

    Math.round
    (
    displayValue
    ×
    1024
    )

  • Exact Boundary Protection: If a compute offering has minimum/maximum memory constraints (minMemory / maxMemory), selecting the exact minimum or maximum bound in GiB directly maps to the exact integer minMemory or maxMemory in MiB to eliminate any potential off-by-one rounding discrepancies.

💬 Feedback Needed: Fractional GiB to Integer MiB Rounding

  • Observation: Converting decimal GiB values to MiB often produces fractional values (e.g., 1.51 GiB × 1024 = 1546.24 MiB).
  • Current Behavior: The UI rounds this to the nearest integer (1546 MiB), which is then emitted in the API payload and consumed by backend hypervisor managers.
  • Reviewer Input: Looking for maintainer feedback on whether standard nearest-integer rounding (Math.round) is acceptable, or if we should apply ceiling (Math.ceil) to guarantee the VM always receives at least the requested GiB amount.

bandicam.2026-10-16.10-21-12-210.mp4

@suryag1201 please go through this and then later i also make other changes according to feedback i was getting and here
is other Commits Description

ui: allow memory setting in flex compute offering in GiB with 0.25 GiB step (#14082)

  • Add compact unit selector dropdown (GiB/MiB) for flex compute offerings
  • Use fixed 0.25 GiB steps in GiB mode (binary-exact to 256 MiB intervals, zero rounding errors)
  • Maintain integer MiB as authoritative internal state to prevent lossy conversion on load
  • Default to GiB for 256 MiB multiples and MiB for arbitrary sizes (e.g. 1500 MiB)
  • Add hover tooltip to display exact converted values

This branch has not been deployed

No deployments
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.

UI: Please change memory setting in flex compute offering from MiB to GiB

6 participants