From 610b6c7bb0ec505d1abb93c34857e805bb93718e Mon Sep 17 00:00:00 2001 From: Mathieu <70369997+MathieuRA@users.noreply.github.com> Date: Thu, 29 Oct 2020 14:58:09 +0100 Subject: [PATCH] feat(xo-server,xo-web/host): get/set scheduler granularity (#5320) Fixes #5291 --- CHANGELOG.unreleased.md | 5 ++ packages/xo-server/src/api/host.js | 52 +++++++++++++++++++ packages/xo-web/src/common/intl/messages.js | 4 ++ packages/xo-web/src/common/xo/index.js | 30 +++++++++++ .../xo-web/src/xo-app/host/tab-advanced.js | 49 +++++++++++++++-- 5 files changed, 137 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 154c5e87a..f1a177260 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -7,6 +7,8 @@ > Users must be able to say: “Nice enhancement, I'm eager to test it” +- [Host/Advanced] Ability to change the scheduler granularity. Only available on XCP-ng >= 8.2 [#5291](https://github.com/vatesfr/xen-orchestra/issues/5291) (PR [#5320](https://github.com/vatesfr/xen-orchestra/pull/5320)) + ### Bug fixes > Users must be able to say: “I had this issue, happy to know it's fixed” @@ -27,3 +29,6 @@ > - major: if the change breaks compatibility > > In case of conflict, the highest (lowest in previous list) `$version` wins. + +- xo-server minor +- xo-web minor diff --git a/packages/xo-server/src/api/host.js b/packages/xo-server/src/api/host.js index 0e8e1f05b..253680c52 100644 --- a/packages/xo-server/src/api/host.js +++ b/packages/xo-server/src/api/host.js @@ -2,6 +2,58 @@ import { format } from 'json-rpc-peer' // =================================================================== +export async function getSchedulerGranularity({ host }) { + try { + return await this.getXapi(host).getField( + 'host', + host._xapiRef, + 'sched_gran' + ) + } catch (e) { + // This method is supported on XCP-ng >= 8.2 only. + if (e.code === 'MESSAGE_METHOD_UNKNOWN') { + return null + } + throw e + } +} + +getSchedulerGranularity.description = 'get the scheduler granularity of a host' + +getSchedulerGranularity.params = { + id: { type: 'string' }, +} + +getSchedulerGranularity.resolve = { + host: ['id', 'host', 'view'], +} + +// =================================================================== + +export async function setSchedulerGranularity({ host, schedulerGranularity }) { + await this.getXapi(host).setField( + 'host', + host._xapiRef, + 'sched_gran', + schedulerGranularity + ) +} + +setSchedulerGranularity.description = 'set scheduler granularity of a host' + +setSchedulerGranularity.params = { + id: { type: 'string' }, + schedulerGranularity: { + enum: ['cpu', 'core', 'socket'], + }, +} + +setSchedulerGranularity.resolve = { + host: ['id', 'host', 'operate'], +} + +// =================================================================== + export async function set({ host, diff --git a/packages/xo-web/src/common/intl/messages.js b/packages/xo-web/src/common/intl/messages.js index 9bd9cf66c..665e8e12f 100644 --- a/packages/xo-web/src/common/intl/messages.js +++ b/packages/xo-web/src/common/intl/messages.js @@ -31,6 +31,8 @@ const messages = { showLogs: 'Show logs', noValue: 'None', compression: 'Compression', + core: 'Core', + cpu: 'CPU', multipathing: 'Multipathing', multipathingDisabled: 'Multipathing disabled', enableMultipathing: 'Enable multipathing', @@ -42,6 +44,8 @@ const messages = { hasInactivePath: 'Has an inactive path', pools: 'Pools', remotes: 'Remotes', + schedulerGranularity: 'Scheduler granularity', + socket: 'Socket', type: 'Type', restore: 'Restore', delete: 'Delete', diff --git a/packages/xo-web/src/common/xo/index.js b/packages/xo-web/src/common/xo/index.js index c1f54a3e9..2f5cb8c2d 100644 --- a/packages/xo-web/src/common/xo/index.js +++ b/packages/xo-web/src/common/xo/index.js @@ -443,6 +443,30 @@ export const subscribeNotifications = createSubscription(async () => { ) }) +const checkSchedulerGranularitySubscriptions = {} +export const subscribeSchedulerGranularity = (host, cb) => { + if (checkSchedulerGranularitySubscriptions[host] === undefined) { + checkSchedulerGranularitySubscriptions[host] = createSubscription(() => + _call('host.getSchedulerGranularity', { host }) + ) + } + + return checkSchedulerGranularitySubscriptions[host](cb) +} +subscribeSchedulerGranularity.forceRefresh = host => { + if (host === undefined) { + forEach(checkSchedulerGranularitySubscriptions, subscription => + subscription.forceRefresh() + ) + return + } + + const subscription = checkSchedulerGranularitySubscriptions[host] + if (subscription !== undefined) { + subscription.forceRefresh() + } +} + const checkSrCurrentStateSubscriptions = {} export const subscribeCheckSrCurrentState = (pool, cb) => { const poolId = resolveId(pool) @@ -736,6 +760,12 @@ export const setPoolMaster = host => // Host -------------------------------------------------------------- +export const setSchedulerGranularity = (host, schedulerGranularity) => + _call('host.setSchedulerGranularity', { + host, + schedulerGranularity, + })::tap(() => subscribeSchedulerGranularity.forceRefresh(host)) + export const editHost = (host, props) => _call('host.set', { ...props, id: resolveId(host) }) diff --git a/packages/xo-web/src/xo-app/host/tab-advanced.js b/packages/xo-web/src/xo-app/host/tab-advanced.js index d677ec204..881786d37 100644 --- a/packages/xo-web/src/xo-app/host/tab-advanced.js +++ b/packages/xo-web/src/xo-app/host/tab-advanced.js @@ -11,7 +11,12 @@ import StateButton from 'state-button' import TabButton from 'tab-button' import Tooltip from 'tooltip' import Upgrade from 'xoa-upgrade' -import { compareVersions, connectStore, getIscsiPaths } from 'utils' +import { + addSubscriptions, + compareVersions, + connectStore, + getIscsiPaths, +} from 'utils' import { confirm } from 'modal' import { Container, Row, Col } from 'grid' import { createGetObjectsOfType, createSelector } from 'selectors' @@ -19,7 +24,7 @@ import { forEach, isEmpty, map, noop } from 'lodash' import { FormattedRelative, FormattedTime } from 'react-intl' import { Sr } from 'render-xo-item' import { Text } from 'editable' -import { Toggle } from 'form' +import { Toggle, Select } from 'form' import { detachHost, disableHost, @@ -34,12 +39,29 @@ import { restartHost, setHostsMultipathing, setRemoteSyslogHost, + setSchedulerGranularity, + subscribeSchedulerGranularity, } from 'xo' import { installCertificate } from './install-certificate' const ALLOW_INSTALL_SUPP_PACK = process.env.XOA_PLAN > 1 +const SCHED_GRAN_TYPE_OPTIONS = [ + { + label: _('core'), + value: 'core', + }, + { + label: _('cpu'), + value: 'cpu', + }, + { + label: _('socket'), + value: 'socket', + }, +] + const forceReboot = host => restartHost(host, true) const formatPack = ({ name, author, description, version }, key) => ( @@ -89,6 +111,9 @@ MultipathableSrs.propTypes = { hostId: PropTypes.string.isRequired, } +@addSubscriptions(props => ({ + schedGran: cb => subscribeSchedulerGranularity(props.host.id, cb), +})) @connectStore(() => { const getPgpus = createGetObjectsOfType('PGPU') .pick((_, { host }) => host.$PGPUs) @@ -139,6 +164,9 @@ export default class extends Component { } ) + _setSchedulerGranularity = value => + setSchedulerGranularity(this.props.host.id, value) + _setHostIscsiIqn = iscsiIqn => confirm({ icon: 'alarm', @@ -168,7 +196,7 @@ export default class extends Component { } render() { - const { host, pcis, pgpus } = this.props + const { host, pcis, pgpus, schedGran } = this.props const { isHtEnabled, isNetDataPluginInstalledOnHost, @@ -349,6 +377,21 @@ export default class extends Component { {host.multipathing && } + {schedGran != null && ( + + {_('schedulerGranularity')} + +