@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 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/configure').catchGlobalErrors(
4
- require('@xen-orchestra/log').createLogger('xo:backups:worker')
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
- process.send({
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
- process.send({
168
+ emitMessage({
160
169
  type: 'result',
161
170
  result,
162
171
  status: 'success',
163
172
  })
164
173
  } catch (error) {
165
- process.send({
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.30.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": "^1.6.1"
54
+ "@xen-orchestra/xapi": "^2.0.0"
55
55
  },
56
56
  "license": "AGPL-3.0-or-later",
57
57
  "author": {