From 1312df8c883c9a6427c30a929d613155cc98c2f5 Mon Sep 17 00:00:00 2001 From: "Rajaa.BARHTAOUI" Date: Thu, 31 Jan 2019 11:33:45 +0100 Subject: [PATCH] feat(xo-web/vm/advanced): set VCPUs-params:mask under Advanced (#3254) Fixes #3241 --- CHANGELOG.md | 1 + packages/xo-server/src/api/vm.js | 2 + packages/xo-server/src/xapi-object-to-xo.js | 1 + packages/xo-server/src/xapi/mixins/vm.js | 9 ++++ packages/xo-web/src/common/intl/messages.js | 2 + packages/xo-web/src/xo-app/vm/tab-advanced.js | 42 ++++++++++++++++++- 6 files changed, 56 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb2cc7b1a..0cfcd4575 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ - [SR] Display iscsi paths and mark the SR with a yellow dot if one path is not available. [#3659](https://github.com/vatesfr/xen-orchestra/issues/3659) (PR [#3829](https://github.com/vatesfr/xen-orchestra/pull/3829)) - [UI] Unifies the Signin buttons (PR [#3913](https://github.com/vatesfr/xen-orchestra/pull/3913)) - [Settings/remotes] NFS: display default option on placeholder [#3631](https://github.com/vatesfr/xen-orchestra/issues/3631) (PR [#3921](https://github.com/vatesfr/xen-orchestra/pull/3921)) +- [VM/advanced] Ability to pin vCPU to physical cores [#3241](https://github.com/vatesfr/xen-orchestra/issues/3241) (PR [#3254](https://github.com/vatesfr/xen-orchestra/pull/3254)) ### Bug fixes diff --git a/packages/xo-server/src/api/vm.js b/packages/xo-server/src/api/vm.js index c63d48b83..6b2262a79 100644 --- a/packages/xo-server/src/api/vm.js +++ b/packages/xo-server/src/api/vm.js @@ -587,6 +587,8 @@ set.params = { // Kernel arguments for PV VM. PV_args: { type: 'string', optional: true }, + cpuMask: { type: 'array', optional: true }, + cpuWeight: { type: ['integer', 'null'], optional: true }, cpuCap: { type: ['integer', 'null'], optional: true }, diff --git a/packages/xo-server/src/xapi-object-to-xo.js b/packages/xo-server/src/xapi-object-to-xo.js index 5299668ff..4798189f3 100644 --- a/packages/xo-server/src/xapi-object-to-xo.js +++ b/packages/xo-server/src/xapi-object-to-xo.js @@ -427,6 +427,7 @@ const TRANSFORMS = { let tmp if ((tmp = obj.VCPUs_params)) { tmp.cap && (vm.cpuCap = +tmp.cap) + tmp.mask && (vm.cpuMask = tmp.mask.split(',').map(_ => +_)) tmp.weight && (vm.cpuWeight = +tmp.weight) } diff --git a/packages/xo-server/src/xapi/mixins/vm.js b/packages/xo-server/src/xapi/mixins/vm.js index bbf16662e..82c3bcda6 100644 --- a/packages/xo-server/src/xapi/mixins/vm.js +++ b/packages/xo-server/src/xapi/mixins/vm.js @@ -332,6 +332,15 @@ export default { }, }, + cpuMask: { + get: vm => vm.VCPUs_params.mask && vm.VCPUs_params.mask.split(','), + set(cpuMask, vm) { + return this._updateObjectMapProperty(vm, 'VCPUs_params', { + mask: cpuMask == null ? cpuMask : cpuMask.join(','), + }) + }, + }, + cpusMax: 'cpusStaticMax', cpusStaticMax: { constraints: { diff --git a/packages/xo-web/src/common/intl/messages.js b/packages/xo-web/src/common/intl/messages.js index 711581798..9ab284670 100644 --- a/packages/xo-web/src/common/intl/messages.js +++ b/packages/xo-web/src/common/intl/messages.js @@ -1071,6 +1071,8 @@ const messages = { guestOsLabel: 'Guest OS', miscLabel: 'Misc', virtualizationMode: 'Virtualization mode', + cpuMaskLabel: 'CPU mask', + selectCpuMask: 'Select core(s)…', cpuWeightLabel: 'CPU weight', defaultCpuWeight: 'Default ({value, number})', cpuCapLabel: 'CPU cap', diff --git a/packages/xo-web/src/xo-app/vm/tab-advanced.js b/packages/xo-web/src/xo-app/vm/tab-advanced.js index e56d6aced..f9fa48767 100644 --- a/packages/xo-web/src/xo-app/vm/tab-advanced.js +++ b/packages/xo-web/src/xo-app/vm/tab-advanced.js @@ -14,7 +14,13 @@ import { error } from 'notification' import { confirm } from 'modal' import { Container, Row, Col } from 'grid' import { injectState, provideState } from 'reaclette' -import { Number, Size, Text, XoSelect } from 'editable' +import { + Number, + Select as EditableSelect, + Size, + Text, + XoSelect, +} from 'editable' import { Select, Toggle } from 'form' import { SelectResourceSet, @@ -40,6 +46,7 @@ import { isEmpty, keyBy, map, + times, some, uniq, } from 'lodash' @@ -482,6 +489,27 @@ export default class TabAdvanced extends Component { getVmsHaValues().then(vmsHaValues => this.setState({ vmsHaValues })) } + _getCpuMaskOptions = createSelector( + () => this.props.vm, + vm => + times(vm.CPUs.max, number => ({ + value: number, + label: `Core ${number}`, + })) + ) + + _getCpuMask = createSelector( + this._getCpuMaskOptions, + () => this.props.vm.cpuMask, + (options, cpuMask) => + cpuMask !== undefined + ? options.filter(({ value }) => cpuMask.includes(value)) + : undefined + ) + + _onChangeCpuMask = cpuMask => + editVm(this.props.vm, { cpuMask: map(cpuMask, 'value') }) + _onNicTypeChange = value => editVm(this.props.vm, { nicType: value === '' ? null : value }) @@ -645,6 +673,18 @@ export default class TabAdvanced extends Component { )} + + {_('cpuMaskLabel')} + + + + {_('cpuWeightLabel')}