feat(xo-web/host): ask for confirmation to reboot the updated slave host if the master is not (#7293)
Fixes #7059 In case a slave host requires a reboot to apply updates and the master is using the same version as the slave host, a confirmation modal is triggered.
This commit is contained in:
parent
f0242380ca
commit
85ec26194b
@ -14,6 +14,7 @@
|
||||
- [Pool/Host] Add a warning if hosts do not have the same version within a pool [#7059](https://github.com/vatesfr/xen-orchestra/issues/7059) (PR [#7280](https://github.com/vatesfr/xen-orchestra/pull/7280))
|
||||
- [Plugins] Loading, or unloading, will respectively enable, or disable, _Auto-load at server start_, this should lead to least surprising behaviors (PR [#7317](https://github.com/vatesfr/xen-orchestra/pull/7317))
|
||||
- [VM/Advanced] Admin can change VM creator [Forum#7313](https://xcp-ng.org/forum/topic/7313/change-created-by-and-date-information) (PR [#7276](https://github.com/vatesfr/xen-orchestra/pull/7276))
|
||||
- [Host/Reboot] Confirmation modal to reboot an updated slave host if the master is not [#7059](https://github.com/vatesfr/xen-orchestra/issues/7059) (PR [#7293](https://github.com/vatesfr/xen-orchestra/pull/7293))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
|
@ -128,7 +128,25 @@ export async function restart({
|
||||
|
||||
bypassBlockedSuspend = force,
|
||||
bypassCurrentVmCheck = force,
|
||||
bypassVersionCheck = force,
|
||||
}) {
|
||||
|
||||
if (bypassVersionCheck) {
|
||||
log.warn('host.restart with argument "bypassVersionCheck" set to true', { hostId: host.id })
|
||||
} else {
|
||||
const pool = this.getObject(host.$poolId, 'pool')
|
||||
const master = this.getObject(pool.master, 'host')
|
||||
const hostRebootRequired = host.rebootRequired
|
||||
if (hostRebootRequired && host.id !== master.id && host.version === master.version) {
|
||||
throw incorrectState({
|
||||
actual: hostRebootRequired,
|
||||
expected: false,
|
||||
object: master.id,
|
||||
property: 'rebootRequired',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (bypassBackupCheck) {
|
||||
log.warn('host.restart with argument "bypassBackupCheck" set to true', { hostId: host.id })
|
||||
} else {
|
||||
@ -165,6 +183,10 @@ restart.params = {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
bypassVersionCheck: {
|
||||
type: 'boolean',
|
||||
optional: true,
|
||||
},
|
||||
}
|
||||
|
||||
restart.resolve = {
|
||||
|
@ -967,6 +967,8 @@ const messages = {
|
||||
// ----- Host actions ------
|
||||
disableMaintenanceMode: 'Disable maintenance mode',
|
||||
enableMaintenanceMode: 'Enable maintenance mode',
|
||||
slaveHostMoreUpToDateThanMasterAfterRestart:
|
||||
'It appears that this host will be more up-to-date than the master ({master}) after the restart. This will result in the slave being unable to contact the pool master. Please update and restart your master node first.',
|
||||
startHostLabel: 'Start',
|
||||
stopHostLabel: 'Stop',
|
||||
enableHostLabel: 'Enable',
|
||||
@ -979,6 +981,7 @@ const messages = {
|
||||
forceRebootHostLabel: 'Force reboot',
|
||||
forceSmartRebootHost:
|
||||
'Smart Reboot failed because {nVms, number} VM{nVms, plural, one {} other {s}} ha{nVms, plural, one {s} other {ve}} {nVms, plural, one {its} other {their}} Suspend operation blocked. Would you like to force?',
|
||||
restartAnyway: 'Restart anyway',
|
||||
rebootHostLabel: 'Reboot',
|
||||
noHostsAvailableErrorTitle: 'Error while restarting host',
|
||||
noHostsAvailableErrorMessage:
|
||||
|
@ -29,7 +29,7 @@ import Icon from '../icon'
|
||||
import logError from '../log-error'
|
||||
import NewAuthTokenModal from './new-auth-token-modal'
|
||||
import RegisterProxyModal from './register-proxy-modal'
|
||||
import renderXoItem, { renderXoItemFromId, Vm } from '../render-xo-item'
|
||||
import renderXoItem, { Host, renderXoItemFromId, Vm } from '../render-xo-item'
|
||||
import store from 'store'
|
||||
import WarmMigrationModal from './warm-migration-modal'
|
||||
import { alert, chooseAction, confirm } from '../modal'
|
||||
@ -900,6 +900,24 @@ const _restartHost = async ({ host, ...opts }) => {
|
||||
return _restartHost({ ...opts, host, bypassBackupCheck: true })
|
||||
}
|
||||
|
||||
if (masterNeedsUpdate(error)) {
|
||||
const state = store.getState()
|
||||
const master = getObject(state, getObject(state, host.$pool).master)
|
||||
await chooseAction({
|
||||
body: (
|
||||
<p>
|
||||
<Icon icon='alarm' />{' '}
|
||||
{_('slaveHostMoreUpToDateThanMasterAfterRestart', { master: <Host id={master.id} link /> })}
|
||||
</p>
|
||||
),
|
||||
buttons: [{ label: _('restartAnyway'), btnStyle: 'danger' }],
|
||||
icon: 'alarm',
|
||||
title: _('restartHostModalTitle'),
|
||||
})
|
||||
|
||||
return _restartHost({ ...opts, host, bypassVersionCheck: true })
|
||||
}
|
||||
|
||||
if (noHostsAvailableErrCheck(error)) {
|
||||
alert(_('noHostsAvailableErrorTitle'), _('noHostsAvailableErrorMessage'))
|
||||
}
|
||||
@ -926,6 +944,12 @@ const backupIsRunning = (err, poolId) =>
|
||||
forbiddenOperation.is(err, {
|
||||
reason: `A backup is running on the pool: ${poolId}`,
|
||||
}))
|
||||
const masterNeedsUpdate = err =>
|
||||
err !== undefined &&
|
||||
incorrectState.is(err, {
|
||||
property: 'rebootRequired',
|
||||
})
|
||||
|
||||
const noHostsAvailableErrCheck = err => err !== undefined && noHostsAvailable.is(err)
|
||||
|
||||
export const restartHosts = (hosts, force = false) => {
|
||||
|
Loading…
Reference in New Issue
Block a user