fix(xo-server,xo-web,xo-common): list missing patches error handling
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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',
|
||||||
|
}))
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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'))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user