feat(xo-web/health): display non shared default SRs (#6033)

Fixes #5871
This commit is contained in:
Mathieu
2021-12-13 10:00:24 +01:00
committed by GitHub
parent ee005c3679
commit 7bacd781cf
3 changed files with 80 additions and 3 deletions

View File

@@ -8,6 +8,7 @@
> Users must be able to say: “Nice enhancement, I'm eager to test it”
- [About] Show commit instead of version numbers for source users (PR [#6045](https://github.com/vatesfr/xen-orchestra/pull/6045))
- [Health] Display default SRs that aren't shared [#5871](https://github.com/vatesfr/xen-orchestra/issues/5871) (PR [#6033](https://github.com/vatesfr/xen-orchestra/pull/6033))
### Bug fixes
@@ -32,4 +33,4 @@
>
> In case of conflict, the highest (lowest in previous list) `$version` wins.
- xo-web patch
- xo-web minor

View File

@@ -849,6 +849,7 @@ const messages = {
disconnectServer: 'Disconnect',
// ----- Host item ------
host: 'Host',
noMoreMaintained: 'This host version is no longer maintained',
// ----- Host actions ------
@@ -1379,6 +1380,9 @@ const messages = {
detachedBackups: 'Detached backups',
detachedVmSnapshots: 'Detached VM snapshots',
duplicatedMacAddresses: 'Duplicated MAC addresses',
localDefaultSrs: 'Local default SRs',
localDefaultSrsStatusTip:
"It is usually recommended for a pool's default SR to be shared to avoid unexpected behaviors",
missingJob: 'Missing job',
missingVm: 'Missing VM',
missingVmInJob: 'This VM does not belong to this job',
@@ -1392,6 +1396,7 @@ const messages = {
noOrphanedObject: 'No orphans',
tooManySnapshots: 'Too many snapshots',
tooManySnapshotsTip: 'VMs with more than the recommended amount of snapshots',
noLocalDefaultSrs: 'No local default SRs',
noTooManySnapshotsObject: 'No VMs with too many snapshots',
numberOfSnapshots: 'Number of snapshots',
guestToolStatus: 'Guest Tools status',

View File

@@ -8,12 +8,12 @@ import NoObjects from 'no-objects'
import React from 'react'
import SortedTable from 'sorted-table'
import Tooltip from 'tooltip'
import { Network, Sr, Vm } from 'render-xo-item'
import { Host, Network, Pool, Sr, Vm } from 'render-xo-item'
import { SelectPool } from 'select-objects'
import { Container, Row, Col } from 'grid'
import { Card, CardHeader, CardBlock } from 'card'
import { FormattedRelative, FormattedTime } from 'react-intl'
import { flatten, forEach, includes, isEmpty, map } from 'lodash'
import { countBy, filter, flatten, forEach, includes, isEmpty, map, pick } from 'lodash'
import { connectStore, formatLogs, formatSize, noop, resolveIds } from 'utils'
import {
deleteMessage,
@@ -105,6 +105,23 @@ const DUPLICATED_MAC_ADDRESSES_FILTERS = {
filterOnlyRunningVms: 'nRunningVms:>1',
}
const LOCAL_DEFAULT_SRS_COLUMNS = [
{
name: _('pool'),
itemRenderer: pool => <Pool id={pool.id} link />,
sortCriteria: 'name_label',
},
{
name: _('sr'),
itemRenderer: pool => <Sr container={false} id={pool.default_SR} link spaceLeft={false} />,
},
{
name: _('host'),
itemRenderer: (pool, { srs }) => <Host id={srs[pool.default_SR].$container} link pool={false} />,
sortCriteria: (pool, { hosts, srs }) => hosts[srs[pool.default_SR].$container].name_label,
},
]
const SR_COLUMNS = [
{
name: _('srName'),
@@ -528,8 +545,10 @@ const HANDLED_VDI_TYPES = new Set(['system', 'user', 'ephemeral'])
return {
alertMessages: getAlertMessages,
areObjectsFetched,
hosts: createGetObjectsOfType('host'),
orphanVdis: getOrphanVdis,
orphanVmSnapshots: getOrphanVmSnapshots,
pools: createGetObjectsOfType('pool'),
tooManySnapshotsVms: getTooManySnapshotsVms,
guestToolsVms: getGuestToolsVms,
userSrs: getUserSrs,
@@ -585,6 +604,22 @@ export default class Health extends Component {
)
)
_getLocalDefaultSrs = createCollectionWrapper(
createSelector(
() => this.props.hosts,
() => this.props.pools,
() => this.props.userSrs,
() => this._getPoolIds(),
(hosts, pools, userSrs, poolIds) => {
const nbHostsPerPool = countBy(hosts, host => host.$pool)
return filter(
isEmpty(poolIds) ? pools : pick(pools, poolIds),
pool => !userSrs[pool.default_SR].shared && nbHostsPerPool[pool.id] > 1
)
}
)
)
_getPoolIds = createCollectionWrapper(createSelector(() => this.state.pools, resolveIds))
_getPoolPredicate = createSelector(this._getPoolIds, poolIds =>
@@ -616,6 +651,7 @@ export default class Health extends Component {
const { props, state } = this
const duplicatedMacAddresses = this._getDuplicatedMacAddresses()
const localDefaultSrs = this._getLocalDefaultSrs()
const userSrs = this._getUserSrs()
const orphanVdis = this._getOrphanVdis()
@@ -650,6 +686,41 @@ export default class Health extends Component {
</Card>
</Col>
</Row>
{localDefaultSrs.length > 0 && (
<Row>
<Col>
<Card>
<CardHeader>
<Icon icon='disk' /> {_('localDefaultSrs')}
</CardHeader>
<CardBlock>
<p>
<Icon icon='info' /> <em>{_('localDefaultSrsStatusTip')}</em>
</p>
<NoObjects
collection={props.areObjectsFetched ? localDefaultSrs : null}
emptyMessage={_('noLocalDefaultSrs')}
>
{() => (
<Row>
<Col>
<SortedTable
collection={localDefaultSrs}
columns={LOCAL_DEFAULT_SRS_COLUMNS}
data-hosts={props.hosts}
data-srs={userSrs}
shortcutsTarget='body'
stateUrlParam='s_local_default_srs'
/>
</Col>
</Row>
)}
</NoObjects>
</CardBlock>
</Card>
</Col>
</Row>
)}
<Row>
<Col>
<Card>