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 pool
|
||||
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')
|
||||
|
||||
return @rollingDrCopyVm({vm, sr, tag, retention})
|
||||
return @rollingDrCopyVm({vm, sr, tag, retention, deleteOldBackupsFirst})
|
||||
|
||||
rollingDrCopy.params = {
|
||||
retention: { type: 'number', optional: true }
|
||||
@ -878,6 +878,7 @@ rollingDrCopy.params = {
|
||||
pool: { type: 'string', optional: true }
|
||||
sr: { type: 'string', optional: true }
|
||||
tag: { type: 'string'}
|
||||
deleteOldBackupsFirst: {type: 'boolean', optional: true}
|
||||
}
|
||||
|
||||
rollingDrCopy.resolve = {
|
||||
|
@ -555,7 +555,9 @@ export default class Xapi extends XapiBase {
|
||||
} = {}) {
|
||||
// Fall back on local copy if possible.
|
||||
if (targetXapi === this) {
|
||||
return this.copyVm(vmId, targetSrId, { nameLabel })
|
||||
return {
|
||||
vm: await this.copyVm(vmId, targetSrId, { nameLabel })
|
||||
}
|
||||
}
|
||||
|
||||
const sr = targetXapi.getObject(targetSrId)
|
||||
|
@ -998,7 +998,14 @@ export default class {
|
||||
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
|
||||
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
|
||||
}
|
||||
})
|
||||
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 data = await sourceXapi.remoteCopyVm(vm.$id, targetXapi, sr.$id, {
|
||||
@ -1024,11 +1040,9 @@ export default class {
|
||||
|
||||
await targetXapi.addTag(data.vm.$id, 'Disaster Recovery')
|
||||
|
||||
const n = 1 - retention
|
||||
await Promise.all(mapToArray(n ? olderCopies.slice(0, n) : olderCopies, vm =>
|
||||
// Do not consider a failure to delete an old copy as a fatal error.
|
||||
targetXapi.deleteVm(vm.$id)::pCatch(noop)
|
||||
))
|
||||
if (!deleteOldBackupsFirst) {
|
||||
await this._removeVms(targetXapi, vmsToRemove)
|
||||
}
|
||||
|
||||
return {
|
||||
size: data.size
|
||||
|
Loading…
Reference in New Issue
Block a user