From 424a212cc3989317d9024b9caa1a71fc61a7d011 Mon Sep 17 00:00:00 2001 From: Albin Hedman Date: Wed, 18 Nov 2020 09:34:12 +0100 Subject: [PATCH] feat(xo-web/dashboard/health): add 'missing guest tools' section (#5376) --- CHANGELOG.unreleased.md | 1 + packages/xo-web/src/common/intl/messages.js | 4 + .../src/xo-app/dashboard/health/index.js | 78 +++++++++++++++++++ 3 files changed, 83 insertions(+) diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index f2a50d159..0472b7ca8 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -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 diff --git a/packages/xo-web/src/common/intl/messages.js b/packages/xo-web/src/common/intl/messages.js index 58035477f..03b163eba 100644 --- a/packages/xo-web/src/common/intl/messages.js +++ b/packages/xo-web/src/common/intl/messages.js @@ -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', diff --git a/packages/xo-web/src/xo-app/dashboard/health/index.js b/packages/xo-web/src/xo-app/dashboard/health/index.js index bf6c6bd06..3c8f2f23d 100644 --- a/packages/xo-web/src/xo-app/dashboard/health/index.js +++ b/packages/xo-web/src/xo-app/dashboard/health/index.js @@ -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 => {vm.name_label}, + sortCriteria: vm => vm.name_label, + }, + { + name: _('vmNameDescription'), + itemRenderer: vm => vm.name_description, + sortCriteria: vm => vm.name_description, + }, + { + name: _('vmContainer'), + itemRenderer: vm => , + }, + { + 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 { + + + + + {_('guestToolStatus')} + + +

+ {_('guestToolStatusTip')} +

+ +
+
+ +