feat(xo-web/dashboard/health): add 'missing guest tools' section (#5376)

This commit is contained in:
Albin Hedman 2020-11-18 09:34:12 +01:00 committed by GitHub
parent 949ddbdcd7
commit 424a212cc3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 83 additions and 0 deletions

View File

@ -10,6 +10,7 @@
- [LDAP] Prevent LDAP-provided groups from being edited from XO [#1884](https://github.com/vatesfr/xen-orchestra/issues/1884) (PR [#5351](https://github.com/vatesfr/xen-orchestra/pull/5351))
- [Licensing] Allow Free and Starter users to copy VMs and create a VM from snapshot on the same pool [#4890](https://github.com/vatesfr/xen-orchestra/issues/4890) (PR [5333](https://github.com/vatesfr/xen-orchestra/pull/5333))
- [SR] Use SR type `zfs` instead of `file` for ZFS storage repositories (PR [5302](https://github.com/vatesfr/xen-orchestra/pull/5330))
- [Dashboard/Health] List VMs with missing or outdated guest tools (PR [#5376](https://github.com/vatesfr/xen-orchestra/pull/5376))
### Bug fixes

View File

@ -1401,6 +1401,10 @@ const messages = {
tooManySnapshotsTip: 'VMs with more than the recommended amount of snapshots',
noTooManySnapshotsObject: 'No VMs with too many snapshots',
numberOfSnapshots: 'Number of snapshots',
guestToolStatus: 'Guest Tools status',
guestToolStatusTip: 'VMs with missing or outdated guest tools',
noGuestToolStatusObject: 'All running VMs have up to date guest tools',
guestToolStatusColumn: 'Status',
deleteOrphanedVdi: 'Delete orphaned snapshot VDI',
deleteSelectedOrphanedVdis: 'Delete selected orphaned snapshot VDIs',
vdisOnControlDomain: 'VDIs attached to Control Domain',

View File

@ -2,6 +2,7 @@ import _ from 'intl'
import Component from 'base-component'
import decorate from 'apply-decorators'
import fromCallback from 'promise-toolbox/fromCallback'
import { get as getDefined } from '@xen-orchestra/defined'
import Icon from 'icon'
import Link from 'link'
import NoObjects from 'no-objects'
@ -368,6 +369,46 @@ const TOO_MANY_SNAPSHOT_COLUMNS = [
},
]
const GUEST_TOOLS_COLUMNS = [
{
name: _('vmNameLabel'),
itemRenderer: vm => <Link to={`vms/${vm.id}`}>{vm.name_label}</Link>,
sortCriteria: vm => vm.name_label,
},
{
name: _('vmNameDescription'),
itemRenderer: vm => vm.name_description,
sortCriteria: vm => vm.name_description,
},
{
name: _('vmContainer'),
itemRenderer: vm => <VmColContainer id={vm.$container} />,
},
{
default: true,
name: _('guestToolStatusColumn'),
itemRenderer: vm => {
if (!vm.pvDriversDetected) {
return _('noToolsDetected')
}
if (!vm.managementAgentDetected) {
return _('managementAgentNotDetected')
}
const version =
getDefined(() => vm.pvDriversVersion.split('.')[0]) > 0
? vm.pvDriversVersion
: ''
return _('managementAgentOutOfDate', {
version,
})
},
sortCriteria: vm =>
!vm.pvDriversDetected ? 0 : !vm.managementAgentDetected ? 1 : 2,
},
]
const ALARM_COLUMNS = [
{
name: _('alarmDate'),
@ -465,6 +506,13 @@ const HANDLED_VDI_TYPES = new Set(['system', 'user', 'ephemeral'])
const getTooManySnapshotsVms = createGetObjectsOfType('VM')
.filter([vm => vm.snapshots.length > MAX_HEALTHY_SNAPSHOT_COUNT])
.sort()
const getGuestToolsVms = createGetObjectsOfType('VM')
.filter([
vm =>
vm.power_state === 'Running' &&
(!vm.managementAgentDetected || !vm.pvDriversUpToDate),
])
.sort()
const getUserSrs = getSrs.filter([isSrWritable])
const getAlertMessages = createGetObjectsOfType('message').filter([
message => message.name === 'ALARM',
@ -476,6 +524,7 @@ const HANDLED_VDI_TYPES = new Set(['system', 'user', 'ephemeral'])
orphanVdis: getOrphanVdis,
orphanVmSnapshots: getOrphanVmSnapshots,
tooManySnapshotsVms: getTooManySnapshotsVms,
guestToolsVms: getGuestToolsVms,
userSrs: getUserSrs,
}
})
@ -551,6 +600,11 @@ export default class Health extends Component {
this._getPoolPredicate
)
_getGuestToolsVms = createFilter(
() => this.props.guestToolsVms,
this._getPoolPredicate
)
_getAlertMessages = createFilter(
() => this.props.alertMessages,
this._getPoolPredicate
@ -692,6 +746,30 @@ export default class Health extends Component {
</Card>
</Col>
</Row>
<Row className='guest-tools-vms'>
<Col>
<Card>
<CardHeader>
<Icon icon='administration' /> {_('guestToolStatus')}
</CardHeader>
<CardBlock>
<p>
<Icon icon='info' /> <em>{_('guestToolStatusTip')}</em>
</p>
<NoObjects
collection={
props.areObjectsFetched ? this._getGuestToolsVms() : null
}
columns={GUEST_TOOLS_COLUMNS}
component={SortedTable}
emptyMessage={_('noGuestToolStatusObject')}
shortcutsTarget='.guest-tools-vms'
stateUrlParam='s_guest_tools_vms'
/>
</CardBlock>
</Card>
</Col>
</Row>
<Row>
<Col>
<Card>