Skip to content

ui: keep root disk size when the same template is selected again - #14606

Open
yuminn-k wants to merge 1 commit into
apache:4.22from
yuminn-k:fix/deploy-vm-autoselect-rootdisksize
Open

yuminn-k wants to merge 1 commit into
apache:4.22from
yuminn-k:fix/deploy-vm-autoselect-rootdisksize

Conversation

@yuminn-k

@yuminn-k yuminn-k commented Nov 7, 2026

Copy link
Copy Markdown

Description

This PR fixes the deploy instance wizard sending deployVirtualMachine without rootdisksize when the auto-selected compute offering links a disk offering with a custom size. The API then rejects the request with error 431, "This disk offering requires a custom size specified".

Fixes: #14524

Evidence tags: [code] = read at a permalink, [executed] = run locally, [inference] = reasoning I did not run.

Root cause

  1. With the default (OS based) image selection, the template list auto-selects the first image and emits it twice: once from the imagesList watcher (onClickRow), and again from the selected watcher when the parent passes the id back. [code]
    selected (newVal, oldVal) {
    if (newVal === oldVal) return
    this.onSelectTemplateIso()
    },
    imagesList () {
    if (this.value === '' && this.imagesList && this.imagesList.length > 0) {
    this.onClickRow(this.imagesList[0])
    }
    }
    },
    emits: ['emit-update-image', 'handle-search-filter'],
    methods: {
    onSelectTemplateIso () {
    if (this.inputDecorator === 'templateid') {
    this.value = this.preFillContent?.templateid ? this.preFillContent.templateid : this.selected
    } else {
    this.value = this.preFillContent?.isoid ? this.preFillContent.isoid : this.selected
    }
    this.$emit('emit-update-image', this.inputDecorator, this.value)
    },
    updateSelectionTemplateIso (id) {
    this.$emit('emit-update-image', this.inputDecorator, id)
    },
    onChangePage (page, pageSize) {
    this.options.page = page
    this.options.pageSize = pageSize
    this.$emit('handle-search-filter', this.options)
    },
    onChangePageSize (page, pageSize) {
    this.options.page = page
    this.options.pageSize = pageSize
    this.$emit('handle-search-filter', this.options)
    },
    onClickRow (os) {
    this.value = os.id
    this.$emit('emit-update-image', this.inputDecorator, this.value)
    }
    }
    [executed] see the trace below
  2. Each emit calls updateFieldValue('templateid', id), which calls resetFromTemplateConfiguration(). That method deletes rootdisksize from instanceConfig, which is the same object as the form. [code]
    if (name === 'templateid') {
    this.imageType = 'templateid'
    this.form.templateid = value
    this.form.isoid = null
    this.form.volumeid = null
    this.form.snapshotid = null
    this.resetFromTemplateConfiguration()
    and
    resetFromTemplateConfiguration () {
    this.deleteFrom(this.instanceConfig, ['disksize', 'rootdisksize'])
  3. The root DiskSizeSelection emits its value on mount and when minDiskSize changes. For the second emit of the same template, minrootdisksize does not change, so the size is not emitted again. [code]
    minDiskSize (newItem) {
    if (newItem && newItem > 0) {
    this.inputValue = newItem
    this.updateDiskSize(newItem)
    }
    }
    },
    computed: {
    isCustomizedDiskIOps () {
    return this.diskSelected?.iscustomizediops || false
    },
    isCustomizedIOps () {
    return this.rootDiskSelected?.iscustomizediops || false
    }
    },
    data () {
    return {
    inputValue: 0,
    error: false,
    minIOps: null,
    maxIOps: null,
    errorMinIOps: false,
    errorMaxIOps: false
    }
    },
    mounted () {
    this.fillValue()
    },
    methods: {
    fillValue () {
    this.inputValue = this.minDiskSize
    if (this.inputDecorator === 'rootdisksize') {
    this.inputValue = this.preFillContent?.rootdisksize ? this.preFillContent.rootdisksize : this.minDiskSize
    } else if (this.inputDecorator === 'size') {
    this.inputValue = this.preFillContent?.size ? this.preFillContent.size : this.minDiskSize
    }
    this.$emit('update-disk-size', this.inputDecorator, this.inputValue)
    },
  4. At submit, rootdisksize is only added when the form has it. [code]
    if (!this.serviceOffering.diskofferingstrictness && values.overridediskofferingid && !values.isoid) {
    deployVmData.overridediskofferingid = values.overridediskofferingid
    if (values.rootdisksize && values.rootdisksize > 0) {
    deployVmData.rootdisksize = values.rootdisksize
    }
    }

This only happens when the compute offering, and with it the size input, is already in place before the template is selected. That is the case when the first offering is auto-selected. Switching to another offering and back remounts DiskSizeSelection, which emits the size again. This matches the workaround in the issue. [inference], consistent with the trace below.

Change

updateFieldValue('templateid', id) now keeps form.rootdisksize when the selected template does not change. Selecting a different template still clears it, as before.

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?

  • [executed] New unit test ui/tests/unit/views/compute/DeployVMRootDiskSize.spec.js. "keeps the root disk size when the same template is selected again" fails without the change (Expected: 8, Received: undefined) and passes with it. "clears the root disk size when another template is selected" passes both before and after.
  • [executed] npm run test:unit on 4.22 with this change: 195 of 196 pass. The one failure is UsageRecords.spec.js (the daylight-saving end date case). It also fails without this change, so it is not caused by this PR.
  • [executed] vue-cli-service lint --no-fix on the changed files: no errors.
  • [executed] Local trace, not part of this PR: I mounted the real DeployVM.vue in jest with mocked API responses for one zone, one 8 GB template, one compute offering linked to a custom size disk offering, and the default image selection. Without the change, the call order was updateFieldValue("rootdisksize", 8), updateFieldValue("templateid", "t1"), then resetFromTemplateConfiguration(), and the result was a form without rootdisksize and an empty disk size in the summary. With the change, the form keeps rootdisksize: 8 and the summary shows 8 GB (Root). The same harness with the legacy image selection, or with the compute offerings loading after the template, already had the size before the change.
  • Not done: I did not deploy an instance against a running management server.

Manual check:

  1. Create a disk offering with custom disk size.
  2. Create a compute offering with "Compute only disk offering" disabled, linked to that disk offering, and make it the first offering in the list.
  3. Open Add Instance, pick a zone and let the first image and offering be auto-selected. Enter a name and launch.
  4. Before: the summary has no root disk size and the API returns 431. After: the summary shows the template size and the request has rootdisksize.

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

  • Selecting a different template still clears the root disk size (covered by the second test). The new template's size then comes from DiskSizeSelection through the changed minrootdisksize.
  • The size is only kept when the template id is unchanged. ISO, volume and snapshot selection are not touched.
  • The change applies cleanly to main.

Assisted-by: Claude Opus 5.5 (Claude Code)

The image selection list emits the selected template twice when it
auto-selects one: once for the row click and once when the selected
prop comes back. Each call resets the template state and drops
form.rootdisksize. The root DiskSizeSelection only re-emits its value
when minrootdisksize changes, and it does not change for the same
template, so the size is never set again.

When the first compute offering is auto-selected and links a disk
offering with a custom size, deployVirtualMachine is then sent without
rootdisksize and fails with error 431.

Keep the root disk size when the selected template does not change.

Fixes: apache#14524

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.

1 participant