feat(xo-server/backup-ng): report missing VMs (#3522)

Fixes #3434
This commit is contained in:
badrAZ 2018-10-18 10:23:56 +02:00 committed by Julien Fontanet
parent aa5b3dc426
commit b67231c56b
4 changed files with 74 additions and 16 deletions

View File

@ -15,6 +15,7 @@
- [Settings/acls] Add bulk deletion [#3179](https://github.com/vatesfr/xen-orchestra/issues/3179) (PR [#3536](https://github.com/vatesfr/xen-orchestra/pull/3536)) - [Settings/acls] Add bulk deletion [#3179](https://github.com/vatesfr/xen-orchestra/issues/3179) (PR [#3536](https://github.com/vatesfr/xen-orchestra/pull/3536))
- [Home] Improve search usage: raw numbers also match in names [#2906](https://github.com/vatesfr/xen-orchestra/issues/2906) (PR [#3552](https://github.com/vatesfr/xen-orchestra/pull/3552)) - [Home] Improve search usage: raw numbers also match in names [#2906](https://github.com/vatesfr/xen-orchestra/issues/2906) (PR [#3552](https://github.com/vatesfr/xen-orchestra/pull/3552))
- [Backup NG] Timeout of a job is now in hours [#3550](https://github.com/vatesfr/xen-orchestra/issues/3550) (PR [#3553](https://github.com/vatesfr/xen-orchestra/pull/3553)) - [Backup NG] Timeout of a job is now in hours [#3550](https://github.com/vatesfr/xen-orchestra/issues/3550) (PR [#3553](https://github.com/vatesfr/xen-orchestra/pull/3553))
- [Backup NG] Explicit error if a VM is missing [#3434](https://github.com/vatesfr/xen-orchestra/issues/3434) (PR [#3522](https://github.com/vatesfr/xen-orchestra/pull/3522))
### Bug fixes ### Bug fixes

View File

@ -34,7 +34,7 @@ export const notImplemented = create(0, () => ({
export const noSuchObject = create(1, (id, type) => ({ export const noSuchObject = create(1, (id, type) => ({
data: { id, type }, data: { id, type },
message: 'no such object', message: `no such ${type || 'object'} ${id}`,
})) }))
export const unauthorized = create(2, () => ({ export const unauthorized = create(2, () => ({

View File

@ -1,8 +1,9 @@
import { forEach } from 'lodash' import { forEach } from 'lodash'
import { noSuchObject } from 'xo-common/api-errors'
const isSkippedError = error => const isSkippedError = error =>
error.message === 'no disks found' || error.message === 'no disks found' ||
error.message === 'no such object' || noSuchObject.is(error) ||
error.message === 'no VMs match this pattern' || error.message === 'no VMs match this pattern' ||
error.message === 'unhealthy VDI chain' error.message === 'unhealthy VDI chain'

View File

@ -410,6 +410,35 @@ const wrapTaskFn = <T>(
} }
} }
const extractIdsFromSimplePattern = (pattern: mixed) => {
if (pattern === null || typeof pattern !== 'object') {
return
}
let keys = Object.keys(pattern)
if (keys.length !== 1 || keys[0] !== 'id') {
return
}
pattern = pattern.id
if (typeof pattern === 'string') {
return [pattern]
}
if (pattern === null || typeof pattern !== 'object') {
return
}
keys = Object.keys(pattern)
if (
keys.length === 1 &&
keys[0] === '__or' &&
Array.isArray((pattern = pattern.__or)) &&
pattern.every(_ => typeof _ === 'string')
) {
return pattern
}
}
// File structure on remotes: // File structure on remotes:
// //
// <remote> // <remote>
@ -471,21 +500,48 @@ export default class BackupNg {
} }
const job: BackupJob = (job_: any) const job: BackupJob = (job_: any)
const vmsPattern = job.vms
const vms: $Dict<Vm> = app.getObjects({ let vms: $Dict<Vm>
filter: createPredicate({ if (
type: 'VM', vmsId !== undefined ||
...(vmsId !== undefined (vmsId = extractIdsFromSimplePattern(vmsPattern)) !== undefined
? { ) {
id: { vms = vmsId
__or: vmsId, .map(id => {
}, try {
} return app.getObject(id, 'VM')
: job.vms), } catch (error) {
}), const taskId: string = logger.notice(
}) `Starting backup of ${id}. (${job.id})`,
if (isEmpty(vms)) { {
throw new Error('no VMs match this pattern') event: 'task.start',
parentId: runJobId,
data: {
type: 'VM',
id,
},
}
)
logger.error(`Backuping ${id} has failed. (${job.id})`, {
event: 'task.end',
taskId,
status: 'failure',
result: serializeError(error),
})
}
})
.filter(vm => vm !== undefined)
} else {
vms = app.getObjects({
filter: createPredicate({
type: 'VM',
...vmsPattern,
}),
})
if (isEmpty(vms)) {
throw new Error('no VMs match this pattern')
}
} }
const jobId = job.id const jobId = job.id
const srs = unboxIds(job.srs).map(id => { const srs = unboxIds(job.srs).map(id => {