@xen-orchestra/backups 0.50.0 → 0.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/_runners/VmsXapi.mjs
CHANGED
|
@@ -147,8 +147,13 @@ export const IncrementalXapi = class IncrementalXapiVmBackupRunner extends Abstr
|
|
|
147
147
|
...lastExportedVdis.map(({ other_config }) => Number(other_config[DELTA_CHAIN_LENGTH] ?? 0))
|
|
148
148
|
)
|
|
149
149
|
const fullInterval = this._settings.fullInterval
|
|
150
|
-
if (
|
|
151
|
-
debug('not using base VM because fullInterval reached', {
|
|
150
|
+
if (fullInterval !== 0 && fullInterval <= deltaChainLength + 1) {
|
|
151
|
+
debug('not using base VM because fullInterval reached', {
|
|
152
|
+
fullInterval,
|
|
153
|
+
deltaChainLength,
|
|
154
|
+
eq: fullInterval < deltaChainLength + 1,
|
|
155
|
+
dc1: deltaChainLength + 1,
|
|
156
|
+
})
|
|
152
157
|
return
|
|
153
158
|
}
|
|
154
159
|
|
|
@@ -157,7 +157,7 @@ export const AbstractXapi = class AbstractXapiVmBackupRunner extends Abstract {
|
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
const snapshotRef = await vm[settings.checkpointSnapshot ? '$checkpoint' : '$snapshot']({
|
|
160
|
-
|
|
160
|
+
ignoredVdisTag: '[NOBAK]',
|
|
161
161
|
name_label: this._getSnapshotNameLabel(vm),
|
|
162
162
|
unplugVusbs: true,
|
|
163
163
|
})
|
|
@@ -227,12 +227,11 @@ export const AbstractXapi = class AbstractXapiVmBackupRunner extends Abstract {
|
|
|
227
227
|
...allSettings[scheduleId],
|
|
228
228
|
...allSettings[this._vm.uuid],
|
|
229
229
|
}
|
|
230
|
-
// ensure we never delete the last one
|
|
231
|
-
const
|
|
232
|
-
|
|
230
|
+
// ensure we never delete the last one for delta
|
|
231
|
+
const minRetention = this.job.mode === 'delta' ? 1 : 0
|
|
232
|
+
const retention = Math.max(settings.snapshotRetention ?? 0, minRetention)
|
|
233
233
|
await asyncMap(getOldEntries(retention, datetimes), async datetime => {
|
|
234
234
|
const vdis = snapshotPerDatetime[datetime]
|
|
235
|
-
|
|
236
235
|
let vmRef
|
|
237
236
|
// if there is an attached VM => destroy the VM (Non CBT backups)
|
|
238
237
|
for (const vdi of vdis) {
|
|
@@ -274,10 +273,11 @@ export const AbstractXapi = class AbstractXapiVmBackupRunner extends Abstract {
|
|
|
274
273
|
this._exportedVm?.is_a_snapshot &&
|
|
275
274
|
// user don't want to keep the snapshot data
|
|
276
275
|
this._settings.snapshotRetention === 0 &&
|
|
277
|
-
// preferNbd is not a guarantee that the backup used NBD, depending on the network configuration
|
|
276
|
+
// preferNbd is not a guarantee that the backup used NBD, depending on the network configuration,
|
|
277
|
+
// in that case next runs will be full, but there is not an easy way to prevent that
|
|
278
278
|
this._settings.preferNbd &&
|
|
279
279
|
// only delete snapshost data if the config allows it
|
|
280
|
-
this.
|
|
280
|
+
this._settings.cbtDestroySnapshotData
|
|
281
281
|
) {
|
|
282
282
|
Task.info('will delete snapshot data')
|
|
283
283
|
const vdiRefs = await this._xapi.VM_getDisks(this._exportedVm?.$ref)
|
|
@@ -285,7 +285,7 @@ export const AbstractXapi = class AbstractXapiVmBackupRunner extends Abstract {
|
|
|
285
285
|
for (const vdiRef of vdiRefs) {
|
|
286
286
|
try {
|
|
287
287
|
// data_destroy will fail with a VDI_NO_CBT_METADATA error if CBT is not enabled on this VDI
|
|
288
|
-
await xapi.
|
|
288
|
+
await xapi.call('VDI.data_destroy', vdiRef)
|
|
289
289
|
Task.info(`Snapshot data has been deleted`, { vdiRef })
|
|
290
290
|
} catch (error) {
|
|
291
291
|
Task.warning(`Couldn't deleted snapshot data`, { error, vdiRef })
|
|
@@ -19,10 +19,10 @@ export class IncrementalXapiWriter extends MixinXapiWriter(AbstractIncrementalWr
|
|
|
19
19
|
// @todo use an index if possible
|
|
20
20
|
// @todo : this seems similare to decorateVmMetadata
|
|
21
21
|
|
|
22
|
-
const replicatedVdis = sr.$VDIs
|
|
23
|
-
.filter(
|
|
22
|
+
const replicatedVdis = sr.$VDIs
|
|
23
|
+
.filter(vdi => {
|
|
24
24
|
// REPLICATED_TO_SR_UUID is not used here since we are already filtering from sr.$VDIs
|
|
25
|
-
return baseUuidToSrcVdi.has(other_config
|
|
25
|
+
return baseUuidToSrcVdi.has(vdi?.other_config[COPY_OF])
|
|
26
26
|
})
|
|
27
27
|
.map(({ other_config }) => other_config?.[COPY_OF])
|
|
28
28
|
.filter(_ => !!_)
|
|
@@ -52,10 +52,10 @@ export class IncrementalXapiWriter extends MixinXapiWriter(AbstractIncrementalWr
|
|
|
52
52
|
this.cleanup = task.wrapFn(this.cleanup, !hasHealthCheckSr)
|
|
53
53
|
this.healthCheck = task.wrapFn(this.healthCheck, hasHealthCheckSr)
|
|
54
54
|
|
|
55
|
-
return task.run(() => this._prepare())
|
|
55
|
+
return task.run(() => this._prepare(isFull))
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
async _prepare() {
|
|
58
|
+
async _prepare(isFull) {
|
|
59
59
|
const settings = this._settings
|
|
60
60
|
const { uuid: srUuid, $xapi: xapi } = this._sr
|
|
61
61
|
const vmUuid = this._vmUuid
|
|
@@ -67,14 +67,19 @@ export class IncrementalXapiWriter extends MixinXapiWriter(AbstractIncrementalWr
|
|
|
67
67
|
this._oldEntries = getOldEntries(settings.copyRetention - 1, listReplicatedVms(xapi, scheduleId, srUuid, vmUuid))
|
|
68
68
|
|
|
69
69
|
if (settings.deleteFirst) {
|
|
70
|
+
// we want to keep the baseVM when copying a delta
|
|
71
|
+
// even if we want to keep only one after
|
|
72
|
+
let mostRecentEntry
|
|
73
|
+
if (this._oldEntries.length > 1 && settings.copyRetention === 1 && !isFull) {
|
|
74
|
+
mostRecentEntry = this._oldEntries.pop()
|
|
75
|
+
}
|
|
70
76
|
await this._deleteOldEntries()
|
|
77
|
+
this._oldEntries = mostRecentEntry !== undefined ? [mostRecentEntry] : []
|
|
71
78
|
}
|
|
72
79
|
}
|
|
73
80
|
|
|
74
81
|
async cleanup() {
|
|
75
|
-
|
|
76
|
-
await this._deleteOldEntries()
|
|
77
|
-
}
|
|
82
|
+
await this._deleteOldEntries()
|
|
78
83
|
}
|
|
79
84
|
|
|
80
85
|
async _deleteOldEntries() {
|
|
@@ -98,10 +103,11 @@ export class IncrementalXapiWriter extends MixinXapiWriter(AbstractIncrementalWr
|
|
|
98
103
|
.filter(_ => !!_)
|
|
99
104
|
// @todo use index ?
|
|
100
105
|
|
|
101
|
-
const replicatedVdis = sr.$VDIs
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
106
|
+
const replicatedVdis = sr.$VDIs
|
|
107
|
+
.filter(vdi => {
|
|
108
|
+
// REPLICATED_TO_SR_UUID is not used here since we are already filtering from sr.$VDIs
|
|
109
|
+
return sourceVdiUuids.includes(vdi?.other_config[COPY_OF])
|
|
110
|
+
})
|
|
105
111
|
|
|
106
112
|
Object.values(backup.vdis).forEach(vdi => {
|
|
107
113
|
vdi.other_config[COPY_OF] = vdi.uuid
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "https://github.com/vatesfr/xen-orchestra.git"
|
|
10
10
|
},
|
|
11
|
-
"version": "0.
|
|
11
|
+
"version": "0.52.0",
|
|
12
12
|
"engines": {
|
|
13
13
|
"node": ">=14.18"
|
|
14
14
|
},
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"proper-lockfile": "^4.1.2",
|
|
47
47
|
"tar": "^6.1.15",
|
|
48
48
|
"uuid": "^9.0.0",
|
|
49
|
-
"vhd-lib": "^4.
|
|
49
|
+
"vhd-lib": "^4.11.0",
|
|
50
50
|
"xen-api": "^4.0.0",
|
|
51
51
|
"yazl": "^2.5.1"
|
|
52
52
|
},
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"tmp": "^0.2.1"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
|
-
"@xen-orchestra/xapi": "^
|
|
61
|
+
"@xen-orchestra/xapi": "^7.0.0"
|
|
62
62
|
},
|
|
63
63
|
"license": "AGPL-3.0-or-later",
|
|
64
64
|
"author": {
|