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 &&