feat(xo-server,xo-web/SR): display maintenance mode button (#6308)
Fixes #6215
This commit is contained in:
parent
50ec614b2a
commit
16b1935f12
@ -9,6 +9,7 @@
|
||||
|
||||
- [Restore backup] Clearer error message when importing a VM backup requires restoration of CH >= 8.1 (PR [#6304](https://github.com/vatesfr/xen-orchestra/pull/6304))
|
||||
- [Backup] Users can use VHD directory on any remote type (PR [#6273](https://github.com/vatesfr/xen-orchestra/pull/6273))
|
||||
- [SR/advanced] Ability to enable/disable a maintenance mode for an SR [#6215](https://github.com/vatesfr/xen-orchestra/issues/6215) (PRs [#6308](https://github.com/vatesfr/xen-orchestra/pull/6308), [#6297](https://github.com/vatesfr/xen-orchestra/pull/6297))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
@ -33,6 +34,7 @@
|
||||
- @xen-orchestra/xapi minor
|
||||
- vhd-lib patch
|
||||
- xo-remote-parser patch
|
||||
- xo-server minor
|
||||
- xo-web minor
|
||||
|
||||
<!--packages-end-->
|
||||
|
@ -539,6 +539,7 @@ const TRANSFORMS = {
|
||||
|
||||
allocationStrategy: ALLOCATION_BY_TYPE[srType],
|
||||
current_operations: obj.current_operations,
|
||||
inMaintenanceMode: obj.other_config['xo:maintenanceState'] !== undefined,
|
||||
name_description: obj.name_description,
|
||||
name_label: obj.name_label,
|
||||
size: +obj.physical_size,
|
||||
|
@ -2208,6 +2208,7 @@ const messages = {
|
||||
downloadConfig: 'Download current config',
|
||||
|
||||
// ----- SR -----
|
||||
andNMore: 'and {n} more',
|
||||
disabledVdiMigrateTooltip: "Snapshots and base copies can't be migrated individually",
|
||||
srReconnectAllModalTitle: 'Reconnect all hosts',
|
||||
srReconnectAllModalMessage: 'This will reconnect this SR to all its hosts.',
|
||||
@ -2223,6 +2224,9 @@ const messages = {
|
||||
srAllDisconnected: 'Disconnected',
|
||||
srSomeConnected: 'Partially connected',
|
||||
srAllConnected: 'Connected',
|
||||
maintenanceSrModalBody:
|
||||
'In order to put this SR in maintenance mode, the following VM{n, plural, one {} other {s}} will be shut down. Are you sure you want to continue?',
|
||||
maintenanceMode: 'Maintenance mode',
|
||||
migrateSelectedVdis: 'Migrate selected VDIs',
|
||||
migrateVdiMessage:
|
||||
'All the VDIs attached to a VM must either be on a shared SR or on the same host (local SR) for the VM to be able to start.',
|
||||
|
@ -20,7 +20,7 @@ import invoke from '../invoke'
|
||||
import Icon from '../icon'
|
||||
import logError from '../log-error'
|
||||
import NewAuthTokenModal from './new-auth-token-modal'
|
||||
import renderXoItem, { renderXoItemFromId } from '../render-xo-item'
|
||||
import renderXoItem, { renderXoItemFromId, Vm } from '../render-xo-item'
|
||||
import store from 'store'
|
||||
import { alert, chooseAction, confirm } from '../modal'
|
||||
import { error, info, success } from '../notification'
|
||||
@ -40,6 +40,10 @@ import parseNdJson from './_parseNdJson'
|
||||
|
||||
// ===================================================================
|
||||
|
||||
const MAX_VMS = 30
|
||||
|
||||
// ===================================================================
|
||||
|
||||
export const ITEMS_PER_PAGE_OPTIONS = [10, 20, 50, 100]
|
||||
export const VDIS_TO_COALESCE_LIMIT = 10
|
||||
|
||||
@ -2108,6 +2112,41 @@ export const editSr = (sr, { nameDescription, nameLabel }) =>
|
||||
export const rescanSr = sr => _call('sr.scan', { id: resolveId(sr) })
|
||||
export const rescanSrs = srs => Promise.all(map(resolveIds(srs), id => _call('sr.scan', { id })))
|
||||
|
||||
export const toggleSrMaintenanceMode = sr => {
|
||||
const id = resolveId(sr)
|
||||
const method = sr.inMaintenanceMode ? 'disableMaintenanceMode' : 'enableMaintenanceMode'
|
||||
|
||||
return _call(`sr.${method}`, { id }).catch(async err => {
|
||||
if (
|
||||
incorrectState.is(err, {
|
||||
property: 'vmsToShutdown',
|
||||
})
|
||||
) {
|
||||
const vmIds = err.data.expected
|
||||
const nVms = vmIds.length
|
||||
await confirm({
|
||||
title: _('maintenanceMode'),
|
||||
body: (
|
||||
<div>
|
||||
{_('maintenanceSrModalBody', { n: nVms })}
|
||||
<ul>
|
||||
{vmIds.slice(0, MAX_VMS).map(id => (
|
||||
<li key={id}>
|
||||
<Vm id={id} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
{nVms > MAX_VMS && _('andNMore', { n: nVms - MAX_VMS })}
|
||||
</div>
|
||||
),
|
||||
})
|
||||
return _call(`sr.${method}`, { id, vmsToShutdown: vmIds })
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// PBDs --------------------------------------------------------------
|
||||
|
||||
export const connectPbd = pbd => _call('pbd.connect', { id: resolveId(pbd) })
|
||||
|
@ -583,6 +583,14 @@
|
||||
// SR
|
||||
&-sr,
|
||||
&-vdi {
|
||||
&-disable {
|
||||
@extend .fa;
|
||||
@extend .fa-times-circle;
|
||||
}
|
||||
&-enable {
|
||||
@extend .fa;
|
||||
@extend .fa-wrench;
|
||||
}
|
||||
&-reconnect-all {
|
||||
@extend .fa;
|
||||
@extend .fa-retweet;
|
||||
|
@ -113,6 +113,7 @@ export default class SrItem extends Component {
|
||||
<Text value={sr.name_label} onChange={this._setNameLabel} useLongClick />
|
||||
</Ellipsis>
|
||||
{isDefaultSr && <span className='tag tag-pill tag-info ml-1'>{_('defaultSr')}</span>}
|
||||
{sr.inMaintenanceMode && <span className='tag tag-pill tag-warning ml-1'>{_('maintenanceMode')}</span>}
|
||||
</EllipsisContainer>
|
||||
</Col>
|
||||
<Col largeSize={1} className='hidden-md-down'>
|
||||
|
@ -9,7 +9,7 @@ import { Container, Row, Col } from 'grid'
|
||||
import { CustomFields } from 'custom-fields'
|
||||
import { createGetObjectsOfType } from 'selectors'
|
||||
import { createSelector } from 'reselect'
|
||||
import { createSrUnhealthyVdiChainsLengthSubscription, deleteSr } from 'xo'
|
||||
import { createSrUnhealthyVdiChainsLengthSubscription, deleteSr, toggleSrMaintenanceMode } from 'xo'
|
||||
import { flowRight, isEmpty, keys, sum, values } from 'lodash'
|
||||
|
||||
// ===================================================================
|
||||
@ -59,6 +59,23 @@ export default ({ sr }) => (
|
||||
<Row>
|
||||
<Col className='text-xs-right'>
|
||||
<TabButton btnStyle='danger' handler={deleteSr} handlerParam={sr} icon='sr-remove' labelId='srRemoveButton' />
|
||||
{sr.inMaintenanceMode ? (
|
||||
<TabButton
|
||||
btnStyle='warning'
|
||||
handler={toggleSrMaintenanceMode}
|
||||
handlerParam={sr}
|
||||
icon='sr-disable'
|
||||
labelId='disableMaintenanceMode'
|
||||
/>
|
||||
) : (
|
||||
<TabButton
|
||||
btnStyle='warning'
|
||||
handler={toggleSrMaintenanceMode}
|
||||
handlerParam={sr}
|
||||
icon='sr-enable'
|
||||
labelId='enableMaintenanceMode'
|
||||
/>
|
||||
)}
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
|
Loading…
Reference in New Issue
Block a user