diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 3907e298d..452c12756 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -2,6 +2,8 @@ ### Enhancements +- [Self/New VM] Display confirmation modal when user will use a large amount of resources [#4044](https://github.com/vatesfr/xen-orchestra/issues/4044) (PR [#4127](https://github.com/vatesfr/xen-orchestra/pull/4127)) + ### Bug fixes - [Self/New VM] Fix missing templates when refreshing page [#3265](https://github.com/vatesfr/xen-orchestra/issues/3265) (PR [#3565](https://github.com/vatesfr/xen-orchestra/pull/3565)) diff --git a/packages/xo-web/src/common/intl/messages.js b/packages/xo-web/src/common/intl/messages.js index cab29d4c5..39a2b65f7 100644 --- a/packages/xo-web/src/common/intl/messages.js +++ b/packages/xo-web/src/common/intl/messages.js @@ -1285,6 +1285,9 @@ const messages = { spaceLeftTooltip: '{used}% used ({free} left)', // ----- New VM ----- + createVmModalTitle: 'Create VM', + createVmModalWarningMessage: + "You're about to use a large amount of resources available on the resource set. Are you sure you want to continue?", newVmCreateNewVmOn: 'Create a new VM on {select}', newVmCreateNewVmNoPermission: 'You have no permission to create a VM', newVmInfoPanel: 'Infos', diff --git a/packages/xo-web/src/xo-app/new-vm/index.js b/packages/xo-web/src/xo-app/new-vm/index.js index 98f652dae..9fae0d14d 100644 --- a/packages/xo-web/src/xo-app/new-vm/index.js +++ b/packages/xo-web/src/xo-app/new-vm/index.js @@ -18,6 +18,7 @@ import { AvailableTemplateVars, DEFAULT_CLOUD_CONFIG_TEMPLATE, } from 'cloud-config' +import { confirm } from 'modal' import { Container, Row, Col } from 'grid' import { injectIntl } from 'react-intl' import { @@ -93,6 +94,7 @@ import { import styles from './index.css' +const MULTIPLICAND = 2 const NB_VMS_MIN = 2 const NB_VMS_MAX = 100 @@ -344,6 +346,29 @@ export default class NewVm extends BaseComponent { }) } + _selfCreate = () => { + const { + CPUs, + VDIs, + existingDisks, + memoryDynamicMax, + template, + } = this.state.state + const disksSize = sumBy(VDIs, 'size') + sumBy(existingDisks, 'size') + const templateDisksSize = sumBy(template.template_info.disks, 'size') + const templateMemoryDynamicMax = template.memory.dynamic[1] + const templateVcpusMax = template.CPUs.max + + return CPUs > MULTIPLICAND * templateVcpusMax || + memoryDynamicMax > MULTIPLICAND * templateMemoryDynamicMax || + disksSize > MULTIPLICAND * templateDisksSize + ? confirm({ + title: _('createVmModalTitle'), + body: _('createVmModalWarningMessage'), + }).then(this._create) + : this._create() + } + _create = () => { const { state } = this.state let installation @@ -935,7 +960,7 @@ export default class NewVm extends BaseComponent { ) || !this._availableResources() } form='vmCreation' - handler={this._create} + handler={pool === undefined ? this._selfCreate : this._create} icon='new-vm-create' redirectOnSuccess={this._getRedirectionUrl} >