@xen-orchestra/backups 0.30.0 → 0.32.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/Backup.js +32 -34
- package/_backupWorker.js +15 -6
- package/package.json +2 -2
package/Backup.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const { asyncMap, asyncMapSettled } = require('@xen-orchestra/async-map')
|
|
4
4
|
const Disposable = require('promise-toolbox/Disposable')
|
|
5
5
|
const ignoreErrors = require('promise-toolbox/ignoreErrors')
|
|
6
|
+
const pTimeout = require('promise-toolbox/timeout')
|
|
6
7
|
const { compileTemplate } = require('@xen-orchestra/template')
|
|
7
8
|
const { limitConcurrency } = require('limit-concurrency-decorator')
|
|
8
9
|
|
|
@@ -25,6 +26,7 @@ const getAdaptersByRemote = adapters => {
|
|
|
25
26
|
const runTask = (...args) => Task.run(...args).catch(noop) // errors are handled by logs
|
|
26
27
|
|
|
27
28
|
const DEFAULT_SETTINGS = {
|
|
29
|
+
getRemoteTimeout: 300e3,
|
|
28
30
|
reportWhen: 'failure',
|
|
29
31
|
}
|
|
30
32
|
|
|
@@ -53,6 +55,13 @@ const DEFAULT_METADATA_SETTINGS = {
|
|
|
53
55
|
retentionXoMetadata: 0,
|
|
54
56
|
}
|
|
55
57
|
|
|
58
|
+
class RemoteTimeoutError extends Error {
|
|
59
|
+
constructor(remoteId) {
|
|
60
|
+
super('timeout while getting the remote ' + remoteId)
|
|
61
|
+
this.remoteId = remoteId
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
56
65
|
exports.Backup = class Backup {
|
|
57
66
|
constructor({ config, getAdapter, getConnectedRecord, job, schedule }) {
|
|
58
67
|
this._config = config
|
|
@@ -60,13 +69,6 @@ exports.Backup = class Backup {
|
|
|
60
69
|
this._job = job
|
|
61
70
|
this._schedule = schedule
|
|
62
71
|
|
|
63
|
-
this._getAdapter = Disposable.factory(function* (remoteId) {
|
|
64
|
-
return {
|
|
65
|
-
adapter: yield getAdapter(remoteId),
|
|
66
|
-
remoteId,
|
|
67
|
-
}
|
|
68
|
-
})
|
|
69
|
-
|
|
70
72
|
this._getSnapshotNameLabel = compileTemplate(config.snapshotNameLabelTpl, {
|
|
71
73
|
'{job.name}': job.name,
|
|
72
74
|
'{vm.name_label}': vm => vm.name_label,
|
|
@@ -87,6 +89,27 @@ exports.Backup = class Backup {
|
|
|
87
89
|
|
|
88
90
|
this._baseSettings = baseSettings
|
|
89
91
|
this._settings = { ...baseSettings, ...job.settings[schedule.id] }
|
|
92
|
+
|
|
93
|
+
const { getRemoteTimeout } = this._settings
|
|
94
|
+
this._getAdapter = async function (remoteId) {
|
|
95
|
+
try {
|
|
96
|
+
const disposable = await pTimeout.call(getAdapter(remoteId), getRemoteTimeout, new RemoteTimeoutError(remoteId))
|
|
97
|
+
|
|
98
|
+
return new Disposable(() => disposable.dispose(), {
|
|
99
|
+
adapter: disposable.value,
|
|
100
|
+
remoteId,
|
|
101
|
+
})
|
|
102
|
+
} catch (error) {
|
|
103
|
+
// See https://github.com/vatesfr/xen-orchestra/commit/6aa6cfba8ec939c0288f0fa740f6dfad98c43cbb
|
|
104
|
+
runTask(
|
|
105
|
+
{
|
|
106
|
+
name: 'get remote adapter',
|
|
107
|
+
data: { type: 'remote', id: remoteId },
|
|
108
|
+
},
|
|
109
|
+
() => Promise.reject(error)
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
90
113
|
}
|
|
91
114
|
|
|
92
115
|
async _runMetadataBackup() {
|
|
@@ -132,20 +155,7 @@ exports.Backup = class Backup {
|
|
|
132
155
|
})
|
|
133
156
|
)
|
|
134
157
|
),
|
|
135
|
-
Disposable.all(
|
|
136
|
-
remoteIds.map(id =>
|
|
137
|
-
this._getAdapter(id).catch(error => {
|
|
138
|
-
// See https://github.com/vatesfr/xen-orchestra/commit/6aa6cfba8ec939c0288f0fa740f6dfad98c43cbb
|
|
139
|
-
runTask(
|
|
140
|
-
{
|
|
141
|
-
name: 'get remote adapter',
|
|
142
|
-
data: { type: 'remote', id },
|
|
143
|
-
},
|
|
144
|
-
() => Promise.reject(error)
|
|
145
|
-
)
|
|
146
|
-
})
|
|
147
|
-
)
|
|
148
|
-
),
|
|
158
|
+
Disposable.all(remoteIds.map(id => this._getAdapter(id))),
|
|
149
159
|
async (pools, remoteAdapters) => {
|
|
150
160
|
// remove adapters that failed (already handled)
|
|
151
161
|
remoteAdapters = remoteAdapters.filter(_ => _ !== undefined)
|
|
@@ -233,19 +243,7 @@ exports.Backup = class Backup {
|
|
|
233
243
|
})
|
|
234
244
|
)
|
|
235
245
|
),
|
|
236
|
-
Disposable.all(
|
|
237
|
-
extractIdsFromSimplePattern(job.remotes).map(id =>
|
|
238
|
-
this._getAdapter(id).catch(error => {
|
|
239
|
-
runTask(
|
|
240
|
-
{
|
|
241
|
-
name: 'get remote adapter',
|
|
242
|
-
data: { type: 'remote', id },
|
|
243
|
-
},
|
|
244
|
-
() => Promise.reject(error)
|
|
245
|
-
)
|
|
246
|
-
})
|
|
247
|
-
)
|
|
248
|
-
),
|
|
246
|
+
Disposable.all(extractIdsFromSimplePattern(job.remotes).map(id => this._getAdapter(id))),
|
|
249
247
|
() => (settings.healthCheckSr !== undefined ? this._getRecord('SR', settings.healthCheckSr) : undefined),
|
|
250
248
|
async (srs, remoteAdapters, healthCheckSr) => {
|
|
251
249
|
// remove adapters that failed (already handled)
|
package/_backupWorker.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
require('@xen-orchestra/log
|
|
4
|
-
|
|
5
|
-
)
|
|
3
|
+
const logger = require('@xen-orchestra/log').createLogger('xo:backups:worker')
|
|
4
|
+
|
|
5
|
+
require('@xen-orchestra/log/configure').catchGlobalErrors(logger)
|
|
6
6
|
|
|
7
7
|
require('@vates/cached-dns.lookup').createCachedLookup().patchGlobal()
|
|
8
8
|
|
|
@@ -20,6 +20,8 @@ const { Backup } = require('./Backup.js')
|
|
|
20
20
|
const { RemoteAdapter } = require('./RemoteAdapter.js')
|
|
21
21
|
const { Task } = require('./Task.js')
|
|
22
22
|
|
|
23
|
+
const { debug } = logger
|
|
24
|
+
|
|
23
25
|
class BackupWorker {
|
|
24
26
|
#config
|
|
25
27
|
#job
|
|
@@ -122,6 +124,11 @@ decorateMethodsWith(BackupWorker, {
|
|
|
122
124
|
]),
|
|
123
125
|
})
|
|
124
126
|
|
|
127
|
+
const emitMessage = message => {
|
|
128
|
+
debug('message emitted', { message })
|
|
129
|
+
process.send(message)
|
|
130
|
+
}
|
|
131
|
+
|
|
125
132
|
// Received message:
|
|
126
133
|
//
|
|
127
134
|
// Message {
|
|
@@ -139,6 +146,8 @@ decorateMethodsWith(BackupWorker, {
|
|
|
139
146
|
// result?: any
|
|
140
147
|
// }
|
|
141
148
|
process.on('message', async message => {
|
|
149
|
+
debug('message received', { message })
|
|
150
|
+
|
|
142
151
|
if (message.action === 'run') {
|
|
143
152
|
const backupWorker = new BackupWorker(message.data)
|
|
144
153
|
try {
|
|
@@ -147,7 +156,7 @@ process.on('message', async message => {
|
|
|
147
156
|
{
|
|
148
157
|
name: 'backup run',
|
|
149
158
|
onLog: data =>
|
|
150
|
-
|
|
159
|
+
emitMessage({
|
|
151
160
|
data,
|
|
152
161
|
type: 'log',
|
|
153
162
|
}),
|
|
@@ -156,13 +165,13 @@ process.on('message', async message => {
|
|
|
156
165
|
)
|
|
157
166
|
: await backupWorker.run()
|
|
158
167
|
|
|
159
|
-
|
|
168
|
+
emitMessage({
|
|
160
169
|
type: 'result',
|
|
161
170
|
result,
|
|
162
171
|
status: 'success',
|
|
163
172
|
})
|
|
164
173
|
} catch (error) {
|
|
165
|
-
|
|
174
|
+
emitMessage({
|
|
166
175
|
type: 'result',
|
|
167
176
|
result: error,
|
|
168
177
|
status: 'failure',
|
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.32.0",
|
|
12
12
|
"engines": {
|
|
13
13
|
"node": ">=14.6"
|
|
14
14
|
},
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"tmp": "^0.2.1"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
|
-
"@xen-orchestra/xapi": "^
|
|
54
|
+
"@xen-orchestra/xapi": "^2.0.0"
|
|
55
55
|
},
|
|
56
56
|
"license": "AGPL-3.0-or-later",
|
|
57
57
|
"author": {
|