feat(vm.rollingDrCopy): previous backups can be removed first (#553)

See vatesfr/xo-web#2157
This commit is contained in:
badrAZ 2017-05-26 13:18:07 +02:00 committed by Julien Fontanet
parent bd0c2385e2
commit 1bead03151
3 changed files with 27 additions and 10 deletions

View File

@ -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 = {

View File

@ -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)

View File

@ -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