feat(xo-server,xo-web/host): maintenance mode (#5421)

ON: disable & evacuate host
OFF: enable host
This commit is contained in:
Mathieu
2020-12-14 17:15:27 +01:00
committed by GitHub
parent e17b6790b5
commit a84961f8ba
6 changed files with 49 additions and 12 deletions

View File

@@ -15,6 +15,7 @@
- [Host] Ability to set host control domain memory [#2218](https://github.com/vatesfr/xen-orchestra/issues/2218) (PR [#5437](https://github.com/vatesfr/xen-orchestra/pull/5437))
- [VM/disks, SR/disks] Destroy/forget VDIs: improve tooltip messages (PR [#5435](https://github.com/vatesfr/xen-orchestra/pull/5435))
- [Patches] Rolling pool update: automatically patch and restart a whole pool by live migrating running VMs back and forth as needed [#5286](https://github.com/vatesfr/xen-orchestra/issues/5286) (PR [#5430](https://github.com/vatesfr/xen-orchestra/pull/5430))
- [Host] Replace `disabled/enabled state` by `maintenance mode` (PR [#5421](https://github.com/vatesfr/xen-orchestra/pull/5421))
### Bug fixes
@@ -41,3 +42,4 @@
> In case of conflict, the highest (lowest in previous list) `$version` wins.
- xo-web minor
- xo-server minor

View File

@@ -3,6 +3,25 @@ import { format } from 'json-rpc-peer'
// ===================================================================
export function setMaintenanceMode({ host, maintenance }) {
const xapi = this.getXapi(host)
return maintenance ? xapi.clearHost({ $ref: host._xapiRef }) : xapi.enableHost(host._xapiId)
}
setMaintenanceMode.description = 'manage the maintenance mode'
setMaintenanceMode.params = {
id: { type: 'string' },
maintenance: { type: 'boolean' },
}
setMaintenanceMode.resolve = {
host: ['id', 'host', 'administrate'],
}
// ===================================================================
export async function getSchedulerGranularity({ host }) {
try {
return await this.getXapi(host).getField('host', host._xapiRef, 'sched_gran')

View File

@@ -289,7 +289,7 @@ export default class Xapi extends XapiBase {
//
// If `force` is false and the evacuation failed, the host is re-
// enabled and the error is thrown.
async _clearHost({ $ref: ref }, force) {
async clearHost({ $ref: ref }, force) {
await this.call('host.disable', ref)
try {
@@ -373,7 +373,7 @@ export default class Xapi extends XapiBase {
async rebootHost(hostId, force = false) {
const host = this.getObject(hostId)
await this._clearHost(host, force)
await this.clearHost(host, force)
await this.callAsync('host.reboot', host.$ref)
}
@@ -392,7 +392,7 @@ export default class Xapi extends XapiBase {
async shutdownHost(hostId, force = false) {
const host = this.getObject(hostId)
await this._clearHost(host, force)
await this.clearHost(host, force)
await this.callAsync('host.shutdown', host.$ref)
}

View File

@@ -841,6 +841,8 @@ const messages = {
disconnectServer: 'Disconnect',
// ----- Host actions ------
disableMaintenanceMode: 'Disable maintenance mode',
enableMaintenanceMode: 'Enable maintenance mode',
startHostLabel: 'Start',
stopHostLabel: 'Stop',
enableHostLabel: 'Enable',
@@ -866,6 +868,10 @@ const messages = {
editHostIscsiIqnMessage:
'Are you sure you want to edit the iSCSI IQN? This may result in failures connecting to existing SRs if the host is attached to iSCSI SRs.',
hostTitleRamUsage: 'Host RAM usage:',
maintenanceHostModalMessage:
'Are you sure you want to enter maintenance mode? This will migrate all the VMs running on this host to other hosts of the pool.',
maintenanceHostModalTitle: 'Maintenance mode',
maintenanceHostTooltip: 'Evacuate and disable the host',
memoryHostState: 'RAM: {memoryUsed} used on {memoryTotal} ({memoryFree} free)',
hardwareHostSettingsLabel: 'Hardware',
hyperThreading: 'Hyper-threading (SMT)',

View File

@@ -777,9 +777,19 @@ export const stopHosts = hosts => {
}).then(() => Promise.all(map(hosts, host => _call('host.stop', { id: resolveId(host) }))), noop)
}
export const enableHost = host => _call('host.enable', { id: resolveId(host) })
export const disableHost = host => _call('host.disable', { id: resolveId(host) })
export const toggleMaintenanceMode = async host => {
if (host.enabled) {
try {
await confirm({
title: _('maintenanceHostModalTitle'),
body: _('maintenanceHostModalMessage'),
})
} catch (error) {
return
}
}
return _call('host.setMaintenanceMode', { id: resolveId(host), maintenance: host.enabled })
}
export const getHostMissingPatches = async host => {
const hostId = resolveId(host)

View File

@@ -23,10 +23,8 @@ import { Text } from 'editable'
import { Toggle, Select, SizeInput } from 'form'
import {
detachHost,
disableHost,
editHost,
enableAdvancedLiveTelemetry,
enableHost,
forgetHost,
installSupplementalPack,
isHyperThreadingEnabledHost,
@@ -38,6 +36,7 @@ import {
setRemoteSyslogHost,
setSchedulerGranularity,
subscribeSchedulerGranularity,
toggleMaintenanceMode,
} from 'xo'
import { installCertificate } from './install-certificate'
@@ -262,18 +261,19 @@ export default class extends Component {
{host.enabled ? (
<TabButton
btnStyle='warning'
handler={disableHost}
handler={toggleMaintenanceMode}
handlerParam={host}
icon='host-disable'
labelId='disableHostLabel'
labelId='enableMaintenanceMode'
tooltip={_('maintenanceHostTooltip')}
/>
) : (
<TabButton
btnStyle='success'
handler={enableHost}
handler={toggleMaintenanceMode}
handlerParam={host}
icon='host-enable'
labelId='enableHostLabel'
labelId='disableMaintenanceMode'
/>
)}
<TabButton