feat(vm.rollingDrCopy): previous backups can be removed first (#553)
See vatesfr/xo-web#2157
This commit is contained in:
parent
bd0c2385e2
commit
1bead03151
@ -858,7 +858,7 @@ exports.rollingBackup = rollingBackup
|
|||||||
|
|
||||||
#---------------------------------------------------------------------
|
#---------------------------------------------------------------------
|
||||||
|
|
||||||
rollingDrCopy = ({vm, pool, sr, tag, depth, retention = depth}) ->
|
rollingDrCopy = ({vm, pool, sr, tag, depth, retention = depth, deleteOldBackupsFirst}) ->
|
||||||
unless sr
|
unless sr
|
||||||
unless pool
|
unless pool
|
||||||
throw invalidParameters('either pool or sr param should be specified')
|
throw invalidParameters('either pool or sr param should be specified')
|
||||||
@ -868,7 +868,7 @@ rollingDrCopy = ({vm, pool, sr, tag, depth, retention = depth}) ->
|
|||||||
|
|
||||||
sr = @getObject(pool.default_SR, 'SR')
|
sr = @getObject(pool.default_SR, 'SR')
|
||||||
|
|
||||||
return @rollingDrCopyVm({vm, sr, tag, retention})
|
return @rollingDrCopyVm({vm, sr, tag, retention, deleteOldBackupsFirst})
|
||||||
|
|
||||||
rollingDrCopy.params = {
|
rollingDrCopy.params = {
|
||||||
retention: { type: 'number', optional: true }
|
retention: { type: 'number', optional: true }
|
||||||
@ -878,6 +878,7 @@ rollingDrCopy.params = {
|
|||||||
pool: { type: 'string', optional: true }
|
pool: { type: 'string', optional: true }
|
||||||
sr: { type: 'string', optional: true }
|
sr: { type: 'string', optional: true }
|
||||||
tag: { type: 'string'}
|
tag: { type: 'string'}
|
||||||
|
deleteOldBackupsFirst: {type: 'boolean', optional: true}
|
||||||
}
|
}
|
||||||
|
|
||||||
rollingDrCopy.resolve = {
|
rollingDrCopy.resolve = {
|
||||||
|
@ -555,7 +555,9 @@ export default class Xapi extends XapiBase {
|
|||||||
} = {}) {
|
} = {}) {
|
||||||
// Fall back on local copy if possible.
|
// Fall back on local copy if possible.
|
||||||
if (targetXapi === this) {
|
if (targetXapi === this) {
|
||||||
return this.copyVm(vmId, targetSrId, { nameLabel })
|
return {
|
||||||
|
vm: await this.copyVm(vmId, targetSrId, { nameLabel })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const sr = targetXapi.getObject(targetSrId)
|
const sr = targetXapi.getObject(targetSrId)
|
||||||
|
@ -998,7 +998,14 @@ export default class {
|
|||||||
await Promise.all(promises)
|
await Promise.all(promises)
|
||||||
}
|
}
|
||||||
|
|
||||||
async rollingDrCopyVm ({vm, sr, tag, retention}) {
|
_removeVms (xapi, vms) {
|
||||||
|
return Promise.all(mapToArray(vms, vm =>
|
||||||
|
// Do not consider a failure to delete an old copy as a fatal error.
|
||||||
|
xapi.deleteVm(vm.$id)::pCatch(noop)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
async rollingDrCopyVm ({vm, sr, tag, retention, deleteOldBackupsFirst}) {
|
||||||
tag = 'DR_' + tag
|
tag = 'DR_' + tag
|
||||||
const reg = new RegExp('^' + escapeStringRegexp(`${vm.name_label}_${tag}_`) + '[0-9]{8}T[0-9]{6}Z$')
|
const reg = new RegExp('^' + escapeStringRegexp(`${vm.name_label}_${tag}_`) + '[0-9]{8}T[0-9]{6}Z$')
|
||||||
|
|
||||||
@ -1015,7 +1022,16 @@ export default class {
|
|||||||
vms[vm.$id] = vm
|
vms[vm.$id] = vm
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const olderCopies = sortBy(vms, 'name_label')
|
|
||||||
|
let vmsToRemove = sortBy(vms, 'name_label')
|
||||||
|
|
||||||
|
if (retention > 1) {
|
||||||
|
vmsToRemove = vmsToRemove.slice(0, 1 - retention)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deleteOldBackupsFirst) {
|
||||||
|
await this._removeVms(targetXapi, vmsToRemove)
|
||||||
|
}
|
||||||
|
|
||||||
const copyName = `${vm.name_label}_${tag}_${safeDateFormat(new Date())}`
|
const copyName = `${vm.name_label}_${tag}_${safeDateFormat(new Date())}`
|
||||||
const data = await sourceXapi.remoteCopyVm(vm.$id, targetXapi, sr.$id, {
|
const data = await sourceXapi.remoteCopyVm(vm.$id, targetXapi, sr.$id, {
|
||||||
@ -1024,11 +1040,9 @@ export default class {
|
|||||||
|
|
||||||
await targetXapi.addTag(data.vm.$id, 'Disaster Recovery')
|
await targetXapi.addTag(data.vm.$id, 'Disaster Recovery')
|
||||||
|
|
||||||
const n = 1 - retention
|
if (!deleteOldBackupsFirst) {
|
||||||
await Promise.all(mapToArray(n ? olderCopies.slice(0, n) : olderCopies, vm =>
|
await this._removeVms(targetXapi, vmsToRemove)
|
||||||
// Do not consider a failure to delete an old copy as a fatal error.
|
}
|
||||||
targetXapi.deleteVm(vm.$id)::pCatch(noop)
|
|
||||||
))
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
size: data.size
|
size: data.size
|
||||||
|
Loading…
Reference in New Issue
Block a user