fix(xo-server,xo-web,xo-common): list missing patches error handling

This commit is contained in:
Pierre Donias
2019-09-12 15:06:28 +02:00
parent 211ede92cc
commit c4b4ee6476
8 changed files with 35 additions and 14 deletions

View File

@@ -17,6 +17,7 @@
> Users must be able to say: “I had this issue, happy to know it's fixed” > Users must be able to say: “I had this issue, happy to know it's fixed”
- [SR] Fix `[object HTMLInputElement]` name after re-attaching a SR [#4546](https://github.com/vatesfr/xen-orchestra/issues/4546) (PR [#4550](https://github.com/vatesfr/xen-orchestra/pull/4550)) - [SR] Fix `[object HTMLInputElement]` name after re-attaching a SR [#4546](https://github.com/vatesfr/xen-orchestra/issues/4546) (PR [#4550](https://github.com/vatesfr/xen-orchestra/pull/4550))
- [Patches] Better error handling when fetching missing patches (PR [#4519](https://github.com/vatesfr/xen-orchestra/pull/4519))
### Released packages ### Released packages

View File

@@ -172,3 +172,11 @@ export const patchPrecheckFailed = create(20, ({ errorType, patch }) => ({
}, },
message: `patch precheck failed: ${errorType}`, message: `patch precheck failed: ${errorType}`,
})) }))
export const missingPatchesFetchFailed = create(21, ({ host, reason }) => ({
data: {
objectId: host,
reason,
},
message: 'cannot fetch missing patches',
}))

View File

@@ -2,6 +2,7 @@ import createLogger from '@xen-orchestra/log'
import deferrable from 'golike-defer' import deferrable from 'golike-defer'
import unzip from 'julien-f-unzip' import unzip from 'julien-f-unzip'
import { filter, find, pickBy, some } from 'lodash' import { filter, find, pickBy, some } from 'lodash'
import { missingPatchesFetchFailed } from 'xo-common/api-errors'
import ensureArray from '../../_ensureArray' import ensureArray from '../../_ensureArray'
import { debounce } from '../../decorators' import { debounce } from '../../decorators'
@@ -40,7 +41,7 @@ const XCP_NG_DEBOUNCE_TIME_MS = 60000
// list all yum updates available for a XCP-ng host // list all yum updates available for a XCP-ng host
// (hostObject) → { uuid: patchObject } // (hostObject) → { uuid: patchObject }
async function _listXcpUpdates(host) { async function _listXcpUpdates(host) {
return JSON.parse( const patches = JSON.parse(
await this.call( await this.call(
'host.call_plugin', 'host.call_plugin',
host.$ref, host.$ref,
@@ -49,6 +50,10 @@ async function _listXcpUpdates(host) {
{} {}
) )
) )
if (patches.error !== undefined) {
throw missingPatchesFetchFailed({ host: host.$id, reason: patches.error })
}
return patches
} }
const _listXcpUpdateDebounced = debounceWithKey( const _listXcpUpdateDebounced = debounceWithKey(

View File

@@ -913,8 +913,8 @@ const messages = {
installAllPatchesOnHostContent: installAllPatchesOnHostContent:
'Are you sure you want to install all patches on this host?', 'Are you sure you want to install all patches on this host?',
patchRelease: 'Release', patchRelease: 'Release',
updatePluginNotInstalled: cannotFetchMissingPatches:
'An error occurred while fetching the patches. Please make sure the updater plugin is installed by running `yum install xcp-ng-updater` on the host.', 'We are unable to fetch the missing patches at the moment…',
showChangelog: 'Show changelog', showChangelog: 'Show changelog',
changelog: 'Changelog', changelog: 'Changelog',
changelogPatch: 'Patch', changelogPatch: 'Patch',

View File

@@ -761,15 +761,16 @@ export const disableHost = host =>
export const getHostMissingPatches = async host => { export const getHostMissingPatches = async host => {
const hostId = resolveId(host) const hostId = resolveId(host)
if (host.productBrand !== 'XCP-ng') { try {
const patches = await _call('pool.listMissingPatches', { host: hostId }) const patches = await _call('pool.listMissingPatches', { host: hostId })
// Hide paid patches to XS-free users // Hide paid patches to XS-free users
return host.license_params.sku_type !== 'free' if (
? patches host.productBrand !== 'XCP-ng' &&
: filter(patches, { paid: false }) host.license_params.sku_type !== 'free'
} ) {
try { return filter(patches, { paid: false })
return await _call('pool.listMissingPatches', { host: hostId }) }
return patches
} catch (_) { } catch (_) {
return null return null
} }

View File

@@ -11,7 +11,7 @@ import { Col } from 'grid'
import { Text } from 'editable' import { Text } from 'editable'
import { addTag, editPool, getHostMissingPatches, removeTag } from 'xo' import { addTag, editPool, getHostMissingPatches, removeTag } from 'xo'
import { connectStore, formatSizeShort } from 'utils' import { connectStore, formatSizeShort } from 'utils'
import { flatten, map, size, uniq } from 'lodash' import { compact, flatten, map, size, uniq } from 'lodash'
import { import {
createGetObjectsOfType, createGetObjectsOfType,
createGetHostMetrics, createGetHostMetrics,
@@ -32,7 +32,7 @@ import styles from './index.css'
getPoolHosts, getPoolHosts,
hosts => { hosts => {
return Promise.all(map(hosts, host => getHostMissingPatches(host))).then( return Promise.all(map(hosts, host => getHostMissingPatches(host))).then(
patches => uniq(map(flatten(patches), 'name')) patches => uniq(map(flatten(compact(patches)), 'name'))
) )
} }
) )

View File

@@ -285,7 +285,7 @@ export default class TabPatches extends Component {
) )
} }
if (this.props.missingPatches === null) { if (this.props.missingPatches === null) {
return <em>{_('updatePluginNotInstalled')}</em> return <em>{_('cannotFetchMissingPatches')}</em>
} }
const Patches = const Patches =
this.props.host.productBrand === 'XCP-ng' ? XcpPatches : XenServerPatches this.props.host.productBrand === 'XCP-ng' ? XcpPatches : XenServerPatches

View File

@@ -198,7 +198,13 @@ export default class TabPatches extends Component {
/> />
</Col> </Col>
</Row> </Row>
{productBrand === 'XCP-ng' ? ( {missingPatches === null ? (
<Row>
<Col>
<em>{_('cannotFetchMissingPatches')}</em>
</Col>
</Row>
) : productBrand === 'XCP-ng' ? (
<Row> <Row>
<Col> <Col>
<h3>{_('hostMissingPatches')}</h3> <h3>{_('hostMissingPatches')}</h3>