diff --git a/src/common/intl/messages.js b/src/common/intl/messages.js index e86f61ad6..ce44dddba 100644 --- a/src/common/intl/messages.js +++ b/src/common/intl/messages.js @@ -868,6 +868,8 @@ const messages = { unknownOsKernel: 'Unknown', unknownOriginalTemplate: 'Unknown', vmLimitsLabel: 'VM limits', + resourceSet: 'Resource set', + resourceSetNone: 'None', vmCpuLimitsLabel: 'CPU limits', vmCpuTopology: 'Topology', vmChooseCoresPerSocket: 'Default behavior', diff --git a/src/common/render-xo-item.js b/src/common/render-xo-item.js index 680c347ee..4ade1211d 100644 --- a/src/common/render-xo-item.js +++ b/src/common/render-xo-item.js @@ -113,7 +113,10 @@ const xoItemToRender = { ), resourceSet: resourceSet => ( - {resourceSet.name} + + {resourceSet.name} + {' '} + ({resourceSet.id}) ), sshKey: key => ( diff --git a/src/xo-app/vm/tab-advanced.js b/src/xo-app/vm/tab-advanced.js index 6d8ecdc36..c8f9ef4b0 100644 --- a/src/xo-app/vm/tab-advanced.js +++ b/src/xo-app/vm/tab-advanced.js @@ -12,10 +12,11 @@ import Tooltip from 'tooltip' import { Toggle } from 'form' import { Number, Size, Text, XoSelect } from 'editable' import { Container, Row, Col } from 'grid' -import { SelectVgpuType } from 'select-objects' +import { SelectResourceSet, SelectVgpuType } from 'select-objects' import { confirm } from 'modal' -import { every, includes, isEmpty, map, uniq } from 'lodash' +import { assign, every, find, includes, isEmpty, map, uniq } from 'lodash' import { + addSubscriptions, connectStore, formatSize, getCoresPerSocketPossibilities, @@ -34,12 +35,13 @@ import { restartVm, resumeVm, stopVm, + subscribeResourceSets, suspendVm, XEN_DEFAULT_CPU_CAP, XEN_DEFAULT_CPU_WEIGHT, XEN_VIDEORAM_VALUES, } from 'xo' -import { createGetObjectsOfType, createSelector } from 'selectors' +import { createGetObjectsOfType, createSelector, isAdmin } from 'selectors' const forceReboot = vm => restartVm(vm, true) const forceShutdown = vm => stopVm(vm, true) @@ -102,6 +104,24 @@ class AffinityHost extends Component { } } +@addSubscriptions({ + resourceSets: subscribeResourceSets, +}) +class ResourceSetItem extends Component { + _getResourceSet = createSelector( + () => this.props.resourceSets, + () => this.props.id, + (resourceSets, id) => + assign(find(resourceSets, { id }), { type: 'resourceSet' }) + ) + + render () { + return this.props.resourceSets === undefined + ? null + : renderXoItem(this._getResourceSet()) + } +} + class NewVgpu extends Component { get value () { return this.state @@ -266,10 +286,11 @@ export default connectStore(() => { return { gpuGroup: getGpuGroup, + isAdmin, vgpus: getVgpus, vgpuTypes: getVgpuTypes, } -})(({ container, gpuGroup, vgpus, vgpuTypes, vm }) => ( +})(({ container, gpuGroup, isAdmin, vgpus, vgpuTypes, vm }) => ( @@ -574,6 +595,26 @@ export default connectStore(() => { : _('unknownOriginalTemplate')} + + {_('resourceSet')} + + {isAdmin ? ( + + editVm(vm, { + resourceSet: + resourceSet != null ? resourceSet.id : resourceSet, + }) + } + value={vm.resourceSet} + /> + ) : vm.resourceSet !== undefined ? ( + + ) : ( + _('resourceSetNone') + )} + +