@xen-orchestra/fs 4.5.0 → 4.6.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/dist/abstract.js +64 -36
- package/dist/abstract.js.map +1 -1
- package/dist/azure.js +276 -0
- package/dist/azure.js.map +1 -0
- package/dist/checksum.js.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/local.js +1 -1
- package/dist/local.js.map +1 -1
- package/dist/s3.js +1 -21
- package/dist/s3.js.map +1 -1
- package/dist/utils.js +53 -0
- package/dist/utils.js.map +1 -0
- package/package.json +3 -2
package/dist/abstract.js
CHANGED
|
@@ -15,6 +15,7 @@ var _xoRemoteParser = require("xo-remote-parser");
|
|
|
15
15
|
var _stream = require("stream");
|
|
16
16
|
var _crypto = require("crypto");
|
|
17
17
|
var _decoratorSynchronized = require("decorator-synchronized");
|
|
18
|
+
var _utils = require("./utils");
|
|
18
19
|
var _path = require("./path");
|
|
19
20
|
var _checksum = require("./checksum");
|
|
20
21
|
var _encryptor = require("./_encryptor");
|
|
@@ -34,6 +35,9 @@ const DEFAULT_TIMEOUT = 6e5;
|
|
|
34
35
|
const DEFAULT_MAX_PARALLEL_OPERATIONS = 10;
|
|
35
36
|
const ENCRYPTION_DESC_FILENAME = 'encryption.json';
|
|
36
37
|
const ENCRYPTION_METADATA_FILENAME = 'metadata.json';
|
|
38
|
+
const WITH_LIMIT = ['closeFile', 'copy', 'getInfo', 'getSizeOnDisk', 'list', 'mkdir', 'openFile', 'outputFile', 'read', 'readFile', 'rename', 'rmdir', 'truncate', 'unlink', 'write', 'writeFile'];
|
|
39
|
+
const WITH_RETRY = ['_closeFile', '_copy', '_getInfo', '_getSize', '_list', '_mkdir', '_openFile', '_outputFile', '_read', '_readFile', '_rename', '_rmdir', '_truncate', '_unlink', '_write', '_writeFile'];
|
|
40
|
+
const WITH_TIMEOUT = ['_closeFile', '_createReadStream', '_getInfo', '_getSize', '_list', '_rename', '_copy', '_rmdir', '_closeFile', '_openFile', '_createOutputStream'];
|
|
37
41
|
const ignoreEnoent = error => {
|
|
38
42
|
if (error == null || error.code !== 'ENOENT') {
|
|
39
43
|
throw error;
|
|
@@ -89,27 +93,48 @@ let RemoteHandlerAbstract = exports.default = (_dec = (0, _decoratorSynchronized
|
|
|
89
93
|
;
|
|
90
94
|
({
|
|
91
95
|
highWaterMark: this._highWaterMark,
|
|
92
|
-
timeout: this._timeout = DEFAULT_TIMEOUT
|
|
96
|
+
timeout: this._timeout = DEFAULT_TIMEOUT,
|
|
97
|
+
withLimit: this._withLimit = WITH_LIMIT,
|
|
98
|
+
withTimeout: this._withTimeout = WITH_TIMEOUT,
|
|
99
|
+
withRetry: this._withRetry = WITH_RETRY
|
|
93
100
|
} = options);
|
|
101
|
+
this.#applySafeGuards(options);
|
|
102
|
+
}
|
|
103
|
+
#conditionRetry(error) {
|
|
104
|
+
return !['EEXIST', 'EISDIR', 'ENOTEMPTY', 'ENOENT', 'ENOTDIR', 'SystemInUse'].includes(error === null || error === void 0 ? void 0 : error.code);
|
|
105
|
+
}
|
|
106
|
+
#applySafeGuards(options) {
|
|
94
107
|
const sharedLimit = (0, _limitConcurrencyDecorator.limitConcurrency)(options.maxParallelOperations ?? DEFAULT_MAX_PARALLEL_OPERATIONS);
|
|
95
|
-
this.closeFile = sharedLimit(this.closeFile);
|
|
96
|
-
this.copy = sharedLimit(this.copy);
|
|
97
|
-
this.getInfo = sharedLimit(this.getInfo);
|
|
98
|
-
this.getSizeOnDisk = sharedLimit(this.getSizeOnDisk);
|
|
99
|
-
this.list = sharedLimit(this.list);
|
|
100
|
-
this.mkdir = sharedLimit(this.mkdir);
|
|
101
|
-
this.openFile = sharedLimit(this.openFile);
|
|
102
|
-
this.outputFile = sharedLimit(this.outputFile);
|
|
103
|
-
this.read = sharedLimit(this.read);
|
|
104
|
-
this.readFile = sharedLimit(this.readFile);
|
|
105
|
-
this.rename = sharedLimit(this.rename);
|
|
106
|
-
this.rmdir = sharedLimit(this.rmdir);
|
|
107
|
-
this.truncate = sharedLimit(this.truncate);
|
|
108
|
-
this.unlink = sharedLimit(this.unlink);
|
|
109
|
-
this.write = sharedLimit(this.write);
|
|
110
|
-
this.writeFile = sharedLimit(this.writeFile);
|
|
111
108
|
this._forget = (0, _coalesceCalls.coalesceCalls)(this._forget);
|
|
112
109
|
this._sync = (0, _coalesceCalls.coalesceCalls)(this._sync);
|
|
110
|
+
this._withLimit.forEach(functionName => {
|
|
111
|
+
if (this[functionName] !== undefined) {
|
|
112
|
+
this[functionName] = sharedLimit(this[functionName]);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
this._withTimeout.forEach(functionName => {
|
|
116
|
+
if (this[functionName] !== undefined) {
|
|
117
|
+
this[functionName] = (0, _utils.withTimeout)(this[functionName], DEFAULT_TIMEOUT);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
this._withRetry.forEach(functionName => {
|
|
121
|
+
if (this[functionName] !== undefined) {
|
|
122
|
+
this[functionName] = _promiseToolbox.pRetry.wrap(this[functionName], {
|
|
123
|
+
delays: [100, 200, 500, 1000, 2000],
|
|
124
|
+
when: err => this.#conditionRetry(err),
|
|
125
|
+
onRetry(error) {
|
|
126
|
+
var _this$arguments;
|
|
127
|
+
warn('retrying method on fs ', {
|
|
128
|
+
method: functionName,
|
|
129
|
+
attemptNumber: this.attemptNumber,
|
|
130
|
+
delay: this.delay,
|
|
131
|
+
error,
|
|
132
|
+
file: (_this$arguments = this.arguments) === null || _this$arguments === void 0 ? void 0 : _this$arguments[0]
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
});
|
|
113
138
|
}
|
|
114
139
|
get type() {
|
|
115
140
|
throw new Error('Not implemented');
|
|
@@ -129,10 +154,10 @@ let RemoteHandlerAbstract = exports.default = (_dec = (0, _decoratorSynchronized
|
|
|
129
154
|
if (typeof file === 'string') {
|
|
130
155
|
file = (0, _path.normalize)(file);
|
|
131
156
|
}
|
|
132
|
-
let stream = await
|
|
157
|
+
let stream = await this._createReadStream(file, {
|
|
133
158
|
...options,
|
|
134
159
|
highWaterMark: this._highWaterMark
|
|
135
|
-
})
|
|
160
|
+
});
|
|
136
161
|
await (0, _promiseToolbox.fromEvent)(stream, 'readable');
|
|
137
162
|
if (checksum) {
|
|
138
163
|
try {
|
|
@@ -153,12 +178,15 @@ let RemoteHandlerAbstract = exports.default = (_dec = (0, _decoratorSynchronized
|
|
|
153
178
|
}
|
|
154
179
|
if (this.isEncrypted) {
|
|
155
180
|
stream = this.#encryptor.decryptStream(stream);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
|
|
181
|
+
}
|
|
182
|
+
if (stream.length === undefined && options.end === undefined && options.start === undefined) {
|
|
183
|
+
try {
|
|
184
|
+
if (this.isEncrypted) {
|
|
185
|
+
stream.maxStreamLength = await this.getSizeOnDisk(file);
|
|
186
|
+
} else {
|
|
159
187
|
stream.length = await this._getSize(file);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
188
|
+
}
|
|
189
|
+
} catch (error) {}
|
|
162
190
|
}
|
|
163
191
|
return stream;
|
|
164
192
|
}
|
|
@@ -194,14 +222,14 @@ let RemoteHandlerAbstract = exports.default = (_dec = (0, _decoratorSynchronized
|
|
|
194
222
|
await this._forget();
|
|
195
223
|
}
|
|
196
224
|
async getInfo() {
|
|
197
|
-
return
|
|
225
|
+
return this._getInfo();
|
|
198
226
|
}
|
|
199
227
|
async getSize(file) {
|
|
200
228
|
_assert.default.strictEqual(this.isEncrypted, false, `Can't compute size of an encrypted file ${file}`);
|
|
201
229
|
return this.getSizeOnDisk(file);
|
|
202
230
|
}
|
|
203
231
|
async getSizeOnDisk(file) {
|
|
204
|
-
return
|
|
232
|
+
return this._getSize(typeof file === 'string' ? (0, _path.normalize)(file) : file);
|
|
205
233
|
}
|
|
206
234
|
async __list(dir, {
|
|
207
235
|
filter,
|
|
@@ -211,7 +239,7 @@ let RemoteHandlerAbstract = exports.default = (_dec = (0, _decoratorSynchronized
|
|
|
211
239
|
try {
|
|
212
240
|
const virtualDir = (0, _path.normalize)(dir);
|
|
213
241
|
dir = (0, _path.normalize)(dir);
|
|
214
|
-
let entries = await
|
|
242
|
+
let entries = await this._list(dir);
|
|
215
243
|
if (filter !== undefined) {
|
|
216
244
|
entries = entries.filter(filter);
|
|
217
245
|
}
|
|
@@ -267,7 +295,7 @@ let RemoteHandlerAbstract = exports.default = (_dec = (0, _decoratorSynchronized
|
|
|
267
295
|
checksum
|
|
268
296
|
}, createTree = true) {
|
|
269
297
|
try {
|
|
270
|
-
let p =
|
|
298
|
+
let p = this._rename(oldPath, newPath);
|
|
271
299
|
if (checksum) {
|
|
272
300
|
p = Promise.all([p, this._rename(checksumFile(oldPath), checksumFile(newPath))]);
|
|
273
301
|
}
|
|
@@ -294,14 +322,14 @@ let RemoteHandlerAbstract = exports.default = (_dec = (0, _decoratorSynchronized
|
|
|
294
322
|
} = {}) {
|
|
295
323
|
oldPath = (0, _path.normalize)(oldPath);
|
|
296
324
|
newPath = (0, _path.normalize)(newPath);
|
|
297
|
-
let p =
|
|
325
|
+
let p = this._copy(oldPath, newPath);
|
|
298
326
|
if (checksum) {
|
|
299
327
|
p = Promise.all([p, this._copy(checksumFile(oldPath), checksumFile(newPath))]);
|
|
300
328
|
}
|
|
301
329
|
return p;
|
|
302
330
|
}
|
|
303
331
|
async rmdir(dir) {
|
|
304
|
-
await
|
|
332
|
+
await this._rmdir((0, _path.normalize)(dir)).catch(ignoreEnoent);
|
|
305
333
|
}
|
|
306
334
|
async rmtree(dir) {
|
|
307
335
|
await this._rmtree((0, _path.normalize)(dir));
|
|
@@ -430,7 +458,7 @@ let RemoteHandlerAbstract = exports.default = (_dec = (0, _decoratorSynchronized
|
|
|
430
458
|
});
|
|
431
459
|
}
|
|
432
460
|
async __closeFile(fd) {
|
|
433
|
-
await
|
|
461
|
+
await this._closeFile(fd.fd);
|
|
434
462
|
}
|
|
435
463
|
async __mkdir(dir, {
|
|
436
464
|
mode
|
|
@@ -450,7 +478,7 @@ let RemoteHandlerAbstract = exports.default = (_dec = (0, _decoratorSynchronized
|
|
|
450
478
|
async __openFile(path, flags) {
|
|
451
479
|
path = (0, _path.normalize)(path);
|
|
452
480
|
return {
|
|
453
|
-
fd: await
|
|
481
|
+
fd: await this._openFile(path, flags),
|
|
454
482
|
path
|
|
455
483
|
};
|
|
456
484
|
}
|
|
@@ -548,10 +576,10 @@ let RemoteHandlerAbstract = exports.default = (_dec = (0, _decoratorSynchronized
|
|
|
548
576
|
validator
|
|
549
577
|
}) {
|
|
550
578
|
const tmpPath = `${(0, _path.dirname)(path)}/.${(0, _path.basename)(path)}`;
|
|
551
|
-
const output = await
|
|
579
|
+
const output = await this._createOutputStream(tmpPath, {
|
|
552
580
|
dirMode,
|
|
553
581
|
flags: 'wx'
|
|
554
|
-
})
|
|
582
|
+
});
|
|
555
583
|
try {
|
|
556
584
|
await (0, _promiseToolbox.fromCallback)(_stream.pipeline, input, output);
|
|
557
585
|
if (validator !== undefined) {
|
|
@@ -600,9 +628,9 @@ let RemoteHandlerAbstract = exports.default = (_dec = (0, _decoratorSynchronized
|
|
|
600
628
|
});
|
|
601
629
|
}
|
|
602
630
|
throw error;
|
|
603
|
-
}, {
|
|
631
|
+
}), {
|
|
604
632
|
concurrency: 2
|
|
605
|
-
})
|
|
633
|
+
});
|
|
606
634
|
return this._rmtree(dir);
|
|
607
635
|
}
|
|
608
636
|
async _sync() {}
|
package/dist/abstract.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"abstract.js","names":["_assert","_interopRequireDefault","require","_getStream","_asyncEach","_coalesceCalls","_log","_promiseToolbox","_limitConcurrencyDecorator","_xoRemoteParser","_stream","_crypto","_decoratorSynchronized","_path","_checksum","_encryptor","_dec","_dec2","_class","e","__esModule","default","_applyDecoratedDescriptor","i","r","n","l","a","Object","keys","forEach","enumerable","configurable","initializer","writable","slice","reverse","reduce","value","call","defineProperty","info","warn","createLogger","checksumFile","file","computeRate","hrtime","size","seconds","DEFAULT_TIMEOUT","DEFAULT_MAX_PARALLEL_OPERATIONS","ENCRYPTION_DESC_FILENAME","ENCRYPTION_METADATA_FILENAME","ignoreEnoent","error","code","noop","Function","prototype","PrefixWrapper","prefix","constructor","handler","_handler","type","list","dir","opts","entries","_resolve","prependDir","length","entry","rename","oldPath","newPath","path","normalizePath","RemoteHandlerAbstract","exports","synchronized","rawEncryptor","encryptor","#encryptor","undefined","Error","remote","options","url","_remote","parse","highWaterMark","_highWaterMark","timeout","_timeout","sharedLimit","limitConcurrency","maxParallelOperations","closeFile","copy","getInfo","getSizeOnDisk","mkdir","openFile","outputFile","read","readFile","rmdir","truncate","unlink","write","writeFile","_forget","coalesceCalls","_sync","addPrefix","createReadStream","checksum","ignoreMissingChecksum","end","start","assert","strictEqual","isEncrypted","stream","_createReadStream","fromEvent","_readFile","flags","validChecksumOfReadStream","String","trim","decryptStream","_getSize","outputStream","input","dirMode","maxStreamLength","streamLength","validator","checksumStream","encryptStream","createChecksumStream","pipeline","_outputStream","_outputFile","forget","_getInfo","getSize","__list","filter","ignoreMissing","virtualDir","_list","lock","dispose","_lock","mktree","mode","_mktree","data","encryptedData","encryptData","buffer","position","_read","__readFile","decryptData","#rename","createTree","p","_rename","Promise","all","dirname","__rename","__copy","_copy","_rmdir","catch","rmtree","_rmtree","sync","checkMetadata","canWriteMetadata","#canWriteMetadata","startsWith","createMetadata","#createMetadata","encryptionAlgorithm","encryptionKey","DEFAULT_ENCRYPTION_ALGORITHM","_getEncryptor","_writeFile","JSON","stringify","algorithm","__writeFile","randomUUID","#checkMetadata","json","includes","test","SIZE","testFileName","Date","now","fromCallback","randomBytes","step","writeStart","process","writeDuration","readStart","readDuration","equals","success","writeRate","readRate","ignoreErrors","_unlink","len","_truncate","__unlink","_write","__closeFile","fd","_closeFile","__mkdir","_mkdir","__openFile","_openFile","useVhdDirectory","_createOutputStream","_createWriteStream","resolve","tmpPath","basename","output","then","getStream","files","asyncEach","rmTreeError","concurrency","isPath","_writeFd","id","_this$encryptor","UNENCRYPTED_ALGORITHM","getOwnPropertyDescriptor","proto","method","getOwnPropertyNames","publicName","hasOwn","createPrefixWrapperMethods","pPw","pRha","hasOwnProperty","name","descriptor","arguments","apply"],"sources":["../src/abstract.js"],"sourcesContent":["import assert from 'assert'\nimport getStream from 'get-stream'\nimport { asyncEach } from '@vates/async-each'\nimport { coalesceCalls } from '@vates/coalesce-calls'\nimport { createLogger } from '@xen-orchestra/log'\nimport { fromCallback, fromEvent, ignoreErrors, timeout } from 'promise-toolbox'\nimport { limitConcurrency } from 'limit-concurrency-decorator'\nimport { parse } from 'xo-remote-parser'\nimport { pipeline } from 'stream'\nimport { randomBytes, randomUUID } from 'crypto'\nimport { synchronized } from 'decorator-synchronized'\n\nimport { basename, dirname, normalize as normalizePath } from './path'\nimport { createChecksumStream, validChecksumOfReadStream } from './checksum'\nimport { DEFAULT_ENCRYPTION_ALGORITHM, UNENCRYPTED_ALGORITHM, _getEncryptor } from './_encryptor'\n\nconst { info, warn } = createLogger('xo:fs:abstract')\n\nconst checksumFile = file => file + '.checksum'\nconst computeRate = (hrtime, size) => {\n const seconds = hrtime[0] + hrtime[1] / 1e9\n return size / seconds\n}\n\nconst DEFAULT_TIMEOUT = 6e5 // 10 min\nconst DEFAULT_MAX_PARALLEL_OPERATIONS = 10\n\nconst ENCRYPTION_DESC_FILENAME = 'encryption.json'\nconst ENCRYPTION_METADATA_FILENAME = 'metadata.json'\n\nconst ignoreEnoent = error => {\n if (error == null || error.code !== 'ENOENT') {\n throw error\n }\n}\n\nconst noop = Function.prototype\n\nclass PrefixWrapper {\n #prefix\n\n constructor(handler, prefix) {\n this.#prefix = prefix\n\n // cannot be a private field because used by methods dynamically added\n // outside of the class\n this._handler = handler\n }\n\n get type() {\n return this._handler.type\n }\n\n // necessary to remove the prefix from the path with `prependDir` option\n async list(dir, opts) {\n const entries = await this._handler.list(this._resolve(dir), opts)\n if (opts != null && opts.prependDir) {\n const n = this.#prefix.length\n entries.forEach((entry, i, entries) => {\n entries[i] = entry.slice(n)\n })\n }\n return entries\n }\n\n rename(oldPath, newPath) {\n return this._handler.rename(this._resolve(oldPath), this._resolve(newPath))\n }\n\n // cannot be a private method because used by methods dynamically added\n // outside of the class\n _resolve(path) {\n return this.#prefix + normalizePath(path)\n }\n}\n\nexport default class RemoteHandlerAbstract {\n #rawEncryptor\n\n get #encryptor() {\n if (this.#rawEncryptor === undefined) {\n throw new Error(`Can't access to encryptor before remote synchronization`)\n }\n return this.#rawEncryptor\n }\n\n constructor(remote, options = {}) {\n if (remote.url === 'test://') {\n this._remote = remote\n } else {\n this._remote = { ...remote, ...parse(remote.url) }\n if (this._remote.type !== this.type) {\n throw new Error('Incorrect remote type')\n }\n }\n ;({ highWaterMark: this._highWaterMark, timeout: this._timeout = DEFAULT_TIMEOUT } = options)\n\n const sharedLimit = limitConcurrency(options.maxParallelOperations ?? DEFAULT_MAX_PARALLEL_OPERATIONS)\n this.closeFile = sharedLimit(this.closeFile)\n this.copy = sharedLimit(this.copy)\n this.getInfo = sharedLimit(this.getInfo)\n this.getSizeOnDisk = sharedLimit(this.getSizeOnDisk)\n this.list = sharedLimit(this.list)\n this.mkdir = sharedLimit(this.mkdir)\n this.openFile = sharedLimit(this.openFile)\n this.outputFile = sharedLimit(this.outputFile)\n this.read = sharedLimit(this.read)\n this.readFile = sharedLimit(this.readFile)\n this.rename = sharedLimit(this.rename)\n this.rmdir = sharedLimit(this.rmdir)\n this.truncate = sharedLimit(this.truncate)\n this.unlink = sharedLimit(this.unlink)\n this.write = sharedLimit(this.write)\n this.writeFile = sharedLimit(this.writeFile)\n\n this._forget = coalesceCalls(this._forget)\n this._sync = coalesceCalls(this._sync)\n }\n\n // Public members\n //\n // Should not be called directly because:\n // - some concurrency limits may be applied which may lead to deadlocks\n // - some preprocessing may be applied on parameters that should not be done multiple times (e.g. prefixing paths)\n\n get type() {\n throw new Error('Not implemented')\n }\n\n addPrefix(prefix) {\n prefix = normalizePath(prefix)\n return prefix === '/' ? this : new PrefixWrapper(this, prefix)\n }\n\n async createReadStream(file, { checksum = false, ignoreMissingChecksum = false, ...options } = {}) {\n if (options.end !== undefined || options.start !== undefined) {\n assert.strictEqual(this.isEncrypted, false, `Can't read part of a file when encryption is active ${file}`)\n }\n if (typeof file === 'string') {\n file = normalizePath(file)\n }\n\n let stream = await timeout.call(\n this._createReadStream(file, { ...options, highWaterMark: this._highWaterMark }),\n this._timeout\n )\n\n // detect early errors\n await fromEvent(stream, 'readable')\n\n if (checksum) {\n try {\n const path = typeof file === 'string' ? file : file.path\n const checksum = await this._readFile(checksumFile(path), { flags: 'r' })\n\n const { length } = stream\n stream = validChecksumOfReadStream(stream, String(checksum).trim())\n stream.length = length\n } catch (error) {\n if (!(ignoreMissingChecksum && error.code === 'ENOENT')) {\n throw error\n }\n }\n }\n\n if (this.isEncrypted) {\n stream = this.#encryptor.decryptStream(stream)\n } else {\n // try to add the length prop if missing and not a range stream\n if (stream.length === undefined && options.end === undefined && options.start === undefined) {\n try {\n stream.length = await this._getSize(file)\n } catch (error) {\n // ignore errors\n }\n }\n }\n\n return stream\n }\n\n /**\n * write a stream to a file using a temporary file\n *\n * @param {string} path\n * @param {ReadableStream} input\n * @param {object} [options]\n * @param {boolean} [options.checksum]\n * @param {number} [options.dirMode]\n * @param {(this: RemoteHandlerAbstract, path: string) => Promise<undefined>} [options.validator] Function that will be called before the data is commited to the remote, if it fails, file should not exist\n */\n async outputStream(path, input, { checksum = true, dirMode, maxStreamLength, streamLength, validator } = {}) {\n path = normalizePath(path)\n let checksumStream\n\n input = this.#encryptor.encryptStream(input)\n if (checksum) {\n checksumStream = createChecksumStream()\n pipeline(input, checksumStream, noop)\n input = checksumStream\n }\n await this._outputStream(path, input, {\n dirMode,\n maxStreamLength,\n streamLength,\n validator,\n })\n if (checksum) {\n // using _outpuFile means the checksum will NOT be encrypted\n // it is by design to allow checking of encrypted files without the key\n await this._outputFile(checksumFile(path), await checksumStream.checksum, { dirMode, flags: 'wx' })\n }\n }\n\n // Free the resources possibly dedicated to put the remote at work, when it\n // is no more needed\n //\n // FIXME: Some handlers are implemented based on system-wide mecanisms (such\n // as mount), forgetting them might breaking other processes using the same\n // remote.\n @synchronized()\n async forget() {\n await this._forget()\n }\n\n async getInfo() {\n return timeout.call(this._getInfo(), this._timeout)\n }\n\n // returns the real size occupied by an unencrypted file\n // encrypted files have metadata and padding that blur the real size\n async getSize(file) {\n assert.strictEqual(this.isEncrypted, false, `Can't compute size of an encrypted file ${file}`)\n return this.getSizeOnDisk(file)\n }\n\n async getSizeOnDisk(file) {\n return timeout.call(this._getSize(typeof file === 'string' ? normalizePath(file) : file), this._timeout)\n }\n\n async __list(dir, { filter, ignoreMissing = false, prependDir = false } = {}) {\n try {\n const virtualDir = normalizePath(dir)\n dir = normalizePath(dir)\n\n let entries = await timeout.call(this._list(dir), this._timeout)\n if (filter !== undefined) {\n entries = entries.filter(filter)\n }\n\n if (prependDir) {\n entries.forEach((entry, i) => {\n entries[i] = virtualDir + '/' + entry\n })\n }\n\n return entries\n } catch (error) {\n if (ignoreMissing && error?.code === 'ENOENT') {\n return []\n }\n throw error\n }\n }\n\n async lock(path) {\n path = normalizePath(path)\n return { dispose: await this._lock(path) }\n }\n\n async mktree(dir, { mode } = {}) {\n await this._mktree(normalizePath(dir), { mode })\n }\n\n async outputFile(file, data, { dirMode, flags = 'wx' } = {}) {\n const encryptedData = this.#encryptor.encryptData(data)\n await this._outputFile(normalizePath(file), encryptedData, { dirMode, flags })\n }\n\n async read(file, buffer, position) {\n assert.strictEqual(this.isEncrypted, false, `Can't read part of an encrypted file ${file}`)\n return this._read(typeof file === 'string' ? normalizePath(file) : file, buffer, position)\n }\n\n async __readFile(file, { flags = 'r' } = {}) {\n const data = await this._readFile(normalizePath(file), { flags })\n return this.#encryptor.decryptData(data)\n }\n\n async #rename(oldPath, newPath, { checksum }, createTree = true) {\n try {\n let p = timeout.call(this._rename(oldPath, newPath), this._timeout)\n if (checksum) {\n p = Promise.all([p, this._rename(checksumFile(oldPath), checksumFile(newPath))])\n }\n await p\n } catch (error) {\n // ENOENT can be a missing target directory OR a missing source\n if (error.code === 'ENOENT' && createTree) {\n await this._mktree(dirname(newPath))\n return this.#rename(oldPath, newPath, { checksum }, false)\n }\n throw error\n }\n }\n\n __rename(oldPath, newPath, { checksum = false } = {}) {\n return this.#rename(normalizePath(oldPath), normalizePath(newPath), { checksum })\n }\n\n async __copy(oldPath, newPath, { checksum = false } = {}) {\n oldPath = normalizePath(oldPath)\n newPath = normalizePath(newPath)\n\n let p = timeout.call(this._copy(oldPath, newPath), this._timeout)\n if (checksum) {\n p = Promise.all([p, this._copy(checksumFile(oldPath), checksumFile(newPath))])\n }\n return p\n }\n\n async rmdir(dir) {\n await timeout.call(this._rmdir(normalizePath(dir)).catch(ignoreEnoent), this._timeout)\n }\n\n async rmtree(dir) {\n await this._rmtree(normalizePath(dir))\n }\n\n // Asks the handler to sync the state of the effective remote with its'\n // metadata\n //\n // This method MUST ALWAYS be called before using the handler.\n @synchronized()\n async sync() {\n await this._sync()\n try {\n await this.#checkMetadata()\n } catch (error) {\n await this._forget()\n throw error\n }\n }\n\n async #canWriteMetadata() {\n const list = await this.__list('/', {\n filter: e => !e.startsWith('.') && e !== ENCRYPTION_DESC_FILENAME && e !== ENCRYPTION_METADATA_FILENAME,\n })\n return list.length === 0\n }\n\n async #createMetadata() {\n const encryptionAlgorithm = this._remote.encryptionKey === undefined ? 'none' : DEFAULT_ENCRYPTION_ALGORITHM\n this.#rawEncryptor = _getEncryptor(encryptionAlgorithm, this._remote.encryptionKey)\n\n await Promise.all([\n this._writeFile(normalizePath(ENCRYPTION_DESC_FILENAME), JSON.stringify({ algorithm: encryptionAlgorithm }), {\n flags: 'w',\n }), // not encrypted\n this.__writeFile(ENCRYPTION_METADATA_FILENAME, `{\"random\":\"${randomUUID()}\"}`, { flags: 'w' }), // encrypted\n ])\n }\n\n async #checkMetadata() {\n let encryptionAlgorithm = 'none'\n let data\n try {\n // this file is not encrypted\n data = await this._readFile(normalizePath(ENCRYPTION_DESC_FILENAME))\n const json = JSON.parse(data)\n encryptionAlgorithm = json.algorithm\n } catch (error) {\n if (error.code !== 'ENOENT') {\n throw error\n }\n encryptionAlgorithm = this._remote.encryptionKey === undefined ? 'none' : DEFAULT_ENCRYPTION_ALGORITHM\n }\n\n try {\n this.#rawEncryptor = _getEncryptor(encryptionAlgorithm, this._remote.encryptionKey)\n // this file is encrypted\n const data = await this.__readFile(ENCRYPTION_METADATA_FILENAME)\n JSON.parse(data)\n } catch (error) {\n // can be enoent, bad algorithm, or broeken json ( bad key or algorithm)\n if (encryptionAlgorithm !== 'none') {\n if (await this.#canWriteMetadata()) {\n // any other error , but on empty remote => update with remote settings\n\n info('will update metadata of this remote')\n return this.#createMetadata()\n } else {\n // to add a new encrypted fs remote, the remote directory must be empty, otherwise metadata.json is not created\n if (error.code === 'ENOENT' && error.path.includes('metadata.json')) {\n throw new Error('Remote directory must be empty.')\n }\n\n warn(\n `The encryptionKey settings of this remote does not match the key used to create it. You won't be able to read any data from this remote`,\n { error }\n )\n // will probably send a ERR_OSSL_EVP_BAD_DECRYPT if key is incorrect\n throw error\n }\n }\n }\n }\n\n async test() {\n const SIZE = 1024 * 1024 * 10\n const testFileName = normalizePath(`${Date.now()}.test`)\n const data = await fromCallback(randomBytes, SIZE)\n let step = 'write'\n try {\n const writeStart = process.hrtime()\n await this._outputFile(testFileName, data, { flags: 'wx' })\n const writeDuration = process.hrtime(writeStart)\n\n step = 'read'\n const readStart = process.hrtime()\n const read = await this._readFile(testFileName, { flags: 'r' })\n const readDuration = process.hrtime(readStart)\n\n if (!data.equals(read)) {\n throw new Error('output and input did not match')\n }\n return {\n success: true,\n writeRate: computeRate(writeDuration, SIZE),\n readRate: computeRate(readDuration, SIZE),\n }\n } catch (error) {\n warn(`error while testing the remote at step ${step}`, { error })\n return {\n success: false,\n step,\n file: testFileName,\n error,\n }\n } finally {\n ignoreErrors.call(this._unlink(testFileName))\n }\n }\n\n async truncate(file, len) {\n await this._truncate(file, len)\n }\n\n async __unlink(file, { checksum = true } = {}) {\n file = normalizePath(file)\n\n if (checksum) {\n ignoreErrors.call(this._unlink(checksumFile(file)))\n }\n\n await this._unlink(file).catch(ignoreEnoent)\n }\n\n async write(file, buffer, position) {\n assert.strictEqual(this.isEncrypted, false, `Can't write part of a file with encryption ${file}`)\n await this._write(typeof file === 'string' ? normalizePath(file) : file, buffer, position)\n }\n\n async __writeFile(file, data, { flags = 'wx' } = {}) {\n const encryptedData = this.#encryptor.encryptData(data)\n await this._writeFile(normalizePath(file), encryptedData, { flags })\n }\n\n // Methods that can be called by private methods to avoid parallel limit on public methods\n\n async __closeFile(fd) {\n await timeout.call(this._closeFile(fd.fd), this._timeout)\n }\n\n async __mkdir(dir, { mode } = {}) {\n dir = normalizePath(dir)\n\n try {\n await this._mkdir(dir, { mode })\n } catch (error) {\n if (error == null || error.code !== 'EEXIST') {\n throw error\n }\n\n // this operation will throw if it's not already a directory\n await this._list(dir)\n }\n }\n\n async __openFile(path, flags) {\n path = normalizePath(path)\n\n return {\n fd: await timeout.call(this._openFile(path, flags), this._timeout),\n path,\n }\n }\n\n // Methods that can be implemented by inheriting classes\n\n useVhdDirectory() {\n return this._remote.useVhdDirectory ?? false\n }\n\n async _closeFile(fd) {\n throw new Error('Not implemented')\n }\n\n async _createOutputStream(file, { dirMode, ...options } = {}) {\n try {\n return await this._createWriteStream(file, { ...options, highWaterMark: this._highWaterMark })\n } catch (error) {\n if (typeof file !== 'string' || error.code !== 'ENOENT') {\n throw error\n }\n }\n\n await this._mktree(dirname(file), { mode: dirMode })\n return this._createOutputStream(file, options)\n }\n\n async _createReadStream(file, options) {\n throw new Error('Not implemented')\n }\n\n // createWriteStream takes highWaterMark as option even if it's not documented.\n // Source: https://stackoverflow.com/questions/55026306/how-to-set-writeable-highwatermark\n async _createWriteStream(file, options) {\n throw new Error('Not implemented')\n }\n\n // called to finalize the remote\n async _forget() {}\n\n async _getInfo() {\n return {}\n }\n\n async _lock(path) {\n return () => Promise.resolve()\n }\n\n async _getSize(file) {\n throw new Error('Not implemented')\n }\n\n async _list(dir) {\n throw new Error('Not implemented')\n }\n\n async _mkdir(dir) {\n throw new Error('Not implemented')\n }\n\n async _mktree(dir, { mode } = {}) {\n try {\n return await this.__mkdir(dir, { mode })\n } catch (error) {\n if (error.code !== 'ENOENT') {\n throw error\n }\n }\n\n await this._mktree(dirname(dir), { mode })\n return this._mktree(dir, { mode })\n }\n\n async _openFile(path, flags) {\n throw new Error('Not implemented')\n }\n\n async _outputFile(file, data, { dirMode, flags }) {\n try {\n return await this._writeFile(file, data, { flags })\n } catch (error) {\n if (error.code !== 'ENOENT') {\n throw error\n }\n }\n\n await this._mktree(dirname(file), { mode: dirMode })\n return this._outputFile(file, data, { flags })\n }\n\n async _outputStream(path, input, { dirMode, validator }) {\n const tmpPath = `${dirname(path)}/.${basename(path)}`\n const output = await timeout.call(\n this._createOutputStream(tmpPath, {\n dirMode,\n flags: 'wx',\n }),\n this._timeout\n )\n try {\n await fromCallback(pipeline, input, output)\n if (validator !== undefined) {\n await validator.call(this, tmpPath)\n }\n await this.__rename(tmpPath, path)\n } catch (error) {\n await this.__unlink(tmpPath)\n throw error\n }\n }\n\n _read(file, buffer, position) {\n throw new Error('Not implemented')\n }\n\n _readFile(file, options) {\n return this._createReadStream(file, { ...options, highWaterMark: this._highWaterMark }).then(getStream.buffer)\n }\n\n async _rename(oldPath, newPath) {\n throw new Error('Not implemented')\n }\n async _copy(oldPath, newPath) {\n throw new Error('Not implemented')\n }\n\n async _rmdir(dir) {\n throw new Error('Not implemented')\n }\n\n async _rmtree(dir) {\n try {\n return await this._rmdir(dir)\n } catch (error) {\n if (error.code !== 'ENOTEMPTY') {\n throw error\n }\n }\n\n const files = await this._list(dir)\n await asyncEach(files, file =>\n this._unlink(`${dir}/${file}`).catch(\n error => {\n // Unlink dir behavior is not consistent across platforms\n // https://github.com/nodejs/node-v0.x-archive/issues/5791\n if (error.code === 'EISDIR' || error.code === 'EPERM') {\n return this._rmtree(`${dir}/${file}`).catch(rmTreeError => {\n if (rmTreeError.code === 'ENOTDIR') {\n // this was realy a EPERM error, maybe with immutable backups\n throw error\n }\n throw rmTreeError\n })\n }\n throw error\n },\n // real unlink concurrency will be 2**max directory depth\n { concurrency: 2 }\n )\n )\n return this._rmtree(dir)\n }\n\n // called to initialize the remote\n async _sync() {}\n\n async _unlink(file) {\n throw new Error('Not implemented')\n }\n\n async _write(file, buffer, position) {\n const isPath = typeof file === 'string'\n if (isPath) {\n file = await this.__openFile(file, 'r+')\n }\n try {\n return await this._writeFd(file, buffer, position)\n } finally {\n if (isPath) {\n await this.__closeFile(file)\n }\n }\n }\n\n async _writeFd(fd, buffer, position) {\n throw new Error('Not implemented')\n }\n\n async _writeFile(file, data, options) {\n throw new Error('Not implemented')\n }\n\n get isEncrypted() {\n return this.#encryptor.id !== 'NULL_ENCRYPTOR'\n }\n\n get encryptionAlgorithm() {\n return this.#encryptor?.algorithm ?? UNENCRYPTED_ALGORITHM\n }\n}\n\n// from implementation methods, which names start with `__`, create public\n// accessors on which external behaviors can be added (e.g. concurrency limits, path rewriting)\n{\n const proto = RemoteHandlerAbstract.prototype\n for (const method of Object.getOwnPropertyNames(proto)) {\n if (method.startsWith('__')) {\n const publicName = method.slice(2)\n\n assert(!Object.hasOwn(proto, publicName))\n\n Object.defineProperty(proto, publicName, Object.getOwnPropertyDescriptor(proto, method))\n }\n }\n}\n\nfunction createPrefixWrapperMethods() {\n const pPw = PrefixWrapper.prototype\n const pRha = RemoteHandlerAbstract.prototype\n\n const {\n defineProperty,\n getOwnPropertyDescriptor,\n prototype: { hasOwnProperty },\n } = Object\n\n Object.getOwnPropertyNames(pRha).forEach(name => {\n let descriptor, value\n if (\n hasOwnProperty.call(pPw, name) ||\n name[0] === '_' ||\n typeof (value = (descriptor = getOwnPropertyDescriptor(pRha, name)).value) !== 'function'\n ) {\n return\n }\n\n descriptor.value = function () {\n let path\n if (arguments.length !== 0 && typeof (path = arguments[0]) === 'string') {\n arguments[0] = this._resolve(path)\n }\n return value.apply(this._handler, arguments)\n }\n\n defineProperty(pPw, name, descriptor)\n })\n}\ncreatePrefixWrapperMethods()\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"abstract.js","names":["_assert","_interopRequireDefault","require","_getStream","_asyncEach","_coalesceCalls","_log","_promiseToolbox","_limitConcurrencyDecorator","_xoRemoteParser","_stream","_crypto","_decoratorSynchronized","_utils","_path","_checksum","_encryptor","_dec","_dec2","_class","e","__esModule","default","_applyDecoratedDescriptor","i","r","n","l","a","Object","keys","forEach","enumerable","configurable","initializer","writable","slice","reverse","reduce","value","call","defineProperty","info","warn","createLogger","checksumFile","file","computeRate","hrtime","size","seconds","DEFAULT_TIMEOUT","DEFAULT_MAX_PARALLEL_OPERATIONS","ENCRYPTION_DESC_FILENAME","ENCRYPTION_METADATA_FILENAME","WITH_LIMIT","WITH_RETRY","WITH_TIMEOUT","ignoreEnoent","error","code","noop","Function","prototype","PrefixWrapper","prefix","constructor","handler","_handler","type","list","dir","opts","entries","_resolve","prependDir","length","entry","rename","oldPath","newPath","path","normalizePath","RemoteHandlerAbstract","exports","synchronized","rawEncryptor","encryptor","#encryptor","undefined","Error","remote","options","url","_remote","parse","highWaterMark","_highWaterMark","timeout","_timeout","withLimit","_withLimit","withTimeout","_withTimeout","withRetry","_withRetry","applySafeGuards","conditionRetry","#conditionRetry","includes","#applySafeGuards","sharedLimit","limitConcurrency","maxParallelOperations","_forget","coalesceCalls","_sync","functionName","pRetry","wrap","delays","when","err","onRetry","_this$arguments","method","attemptNumber","delay","arguments","addPrefix","createReadStream","checksum","ignoreMissingChecksum","end","start","assert","strictEqual","isEncrypted","stream","_createReadStream","fromEvent","_readFile","flags","validChecksumOfReadStream","String","trim","decryptStream","maxStreamLength","getSizeOnDisk","_getSize","outputStream","input","dirMode","streamLength","validator","checksumStream","encryptStream","createChecksumStream","pipeline","_outputStream","_outputFile","forget","getInfo","_getInfo","getSize","__list","filter","ignoreMissing","virtualDir","_list","lock","dispose","_lock","mktree","mode","_mktree","outputFile","data","encryptedData","encryptData","read","buffer","position","_read","__readFile","decryptData","#rename","createTree","p","_rename","Promise","all","dirname","__rename","__copy","_copy","rmdir","_rmdir","catch","rmtree","_rmtree","sync","checkMetadata","canWriteMetadata","#canWriteMetadata","startsWith","createMetadata","#createMetadata","encryptionAlgorithm","encryptionKey","DEFAULT_ENCRYPTION_ALGORITHM","_getEncryptor","_writeFile","JSON","stringify","algorithm","__writeFile","randomUUID","#checkMetadata","json","test","SIZE","testFileName","Date","now","fromCallback","randomBytes","step","writeStart","process","writeDuration","readStart","readDuration","equals","success","writeRate","readRate","ignoreErrors","_unlink","truncate","len","_truncate","__unlink","write","_write","__closeFile","fd","_closeFile","__mkdir","_mkdir","__openFile","_openFile","useVhdDirectory","_createOutputStream","_createWriteStream","resolve","tmpPath","basename","output","then","getStream","files","asyncEach","rmTreeError","concurrency","isPath","_writeFd","id","_this$encryptor","UNENCRYPTED_ALGORITHM","getOwnPropertyDescriptor","proto","getOwnPropertyNames","publicName","hasOwn","createPrefixWrapperMethods","pPw","pRha","hasOwnProperty","name","descriptor","apply"],"sources":["../src/abstract.js"],"sourcesContent":["import assert from 'assert'\nimport getStream from 'get-stream'\nimport { asyncEach } from '@vates/async-each'\nimport { coalesceCalls } from '@vates/coalesce-calls'\nimport { createLogger } from '@xen-orchestra/log'\nimport { fromCallback, fromEvent, ignoreErrors, pRetry } from 'promise-toolbox'\nimport { limitConcurrency } from 'limit-concurrency-decorator'\nimport { parse } from 'xo-remote-parser'\nimport { pipeline } from 'stream'\nimport { randomBytes, randomUUID } from 'crypto'\nimport { synchronized } from 'decorator-synchronized'\n\nimport { withTimeout } from './utils'\nimport { basename, dirname, normalize as normalizePath } from './path'\nimport { createChecksumStream, validChecksumOfReadStream } from './checksum'\nimport { DEFAULT_ENCRYPTION_ALGORITHM, UNENCRYPTED_ALGORITHM, _getEncryptor } from './_encryptor'\n\nconst { info, warn } = createLogger('xo:fs:abstract')\n\nconst checksumFile = file => file + '.checksum'\nconst computeRate = (hrtime, size) => {\n const seconds = hrtime[0] + hrtime[1] / 1e9\n return size / seconds\n}\n\nconst DEFAULT_TIMEOUT = 6e5 // 10 min\nconst DEFAULT_MAX_PARALLEL_OPERATIONS = 10\n\nconst ENCRYPTION_DESC_FILENAME = 'encryption.json'\nconst ENCRYPTION_METADATA_FILENAME = 'metadata.json'\n\nconst WITH_LIMIT = [\n 'closeFile',\n 'copy',\n 'getInfo',\n 'getSizeOnDisk',\n 'list',\n 'mkdir',\n 'openFile',\n 'outputFile',\n 'read',\n 'readFile',\n 'rename',\n 'rmdir',\n 'truncate',\n 'unlink',\n 'write',\n 'writeFile',\n]\n\nconst WITH_RETRY = [\n '_closeFile',\n '_copy',\n '_getInfo',\n '_getSize',\n '_list',\n '_mkdir',\n '_openFile',\n '_outputFile',\n '_read',\n '_readFile',\n '_rename',\n '_rmdir',\n '_truncate',\n '_unlink',\n '_write',\n '_writeFile',\n]\n\nconst WITH_TIMEOUT = [\n '_closeFile',\n '_createReadStream',\n '_getInfo',\n '_getSize',\n '_list',\n '_rename',\n '_copy',\n '_rmdir',\n '_closeFile',\n '_openFile',\n '_createOutputStream',\n]\n\nconst ignoreEnoent = error => {\n if (error == null || error.code !== 'ENOENT') {\n throw error\n }\n}\n\nconst noop = Function.prototype\n\nclass PrefixWrapper {\n #prefix\n\n constructor(handler, prefix) {\n this.#prefix = prefix\n\n // cannot be a private field because used by methods dynamically added\n // outside of the class\n this._handler = handler\n }\n\n get type() {\n return this._handler.type\n }\n\n // necessary to remove the prefix from the path with `prependDir` option\n async list(dir, opts) {\n const entries = await this._handler.list(this._resolve(dir), opts)\n if (opts != null && opts.prependDir) {\n const n = this.#prefix.length\n entries.forEach((entry, i, entries) => {\n entries[i] = entry.slice(n)\n })\n }\n return entries\n }\n\n rename(oldPath, newPath) {\n return this._handler.rename(this._resolve(oldPath), this._resolve(newPath))\n }\n\n // cannot be a private method because used by methods dynamically added\n // outside of the class\n _resolve(path) {\n return this.#prefix + normalizePath(path)\n }\n}\n\nexport default class RemoteHandlerAbstract {\n #rawEncryptor\n\n get #encryptor() {\n if (this.#rawEncryptor === undefined) {\n throw new Error(`Can't access to encryptor before remote synchronization`)\n }\n return this.#rawEncryptor\n }\n\n constructor(remote, options = {}) {\n if (remote.url === 'test://') {\n this._remote = remote\n } else {\n this._remote = { ...remote, ...parse(remote.url) }\n if (this._remote.type !== this.type) {\n throw new Error('Incorrect remote type')\n }\n }\n ;({\n highWaterMark: this._highWaterMark,\n timeout: this._timeout = DEFAULT_TIMEOUT,\n withLimit: this._withLimit = WITH_LIMIT,\n withTimeout: this._withTimeout = WITH_TIMEOUT,\n withRetry: this._withRetry = WITH_RETRY,\n } = options)\n\n this.#applySafeGuards(options)\n }\n\n #conditionRetry(error) {\n return !['EEXIST', 'EISDIR', 'ENOTEMPTY', 'ENOENT', 'ENOTDIR', 'SystemInUse'].includes(error?.code)\n }\n\n #applySafeGuards(options) {\n const sharedLimit = limitConcurrency(options.maxParallelOperations ?? DEFAULT_MAX_PARALLEL_OPERATIONS)\n\n this._forget = coalesceCalls(this._forget)\n this._sync = coalesceCalls(this._sync)\n\n this._withLimit.forEach(functionName => {\n if (this[functionName] !== undefined) {\n this[functionName] = sharedLimit(this[functionName])\n }\n })\n\n this._withTimeout.forEach(functionName => {\n if (this[functionName] !== undefined) {\n this[functionName] = withTimeout(this[functionName], DEFAULT_TIMEOUT)\n }\n })\n\n this._withRetry.forEach(functionName => {\n if (this[functionName] !== undefined) {\n // adding the retry on the top level method won't\n // cover when _functionName are called internally\n this[functionName] = pRetry.wrap(this[functionName], {\n delays: [100, 200, 500, 1000, 2000],\n // these errors should not change on retry\n when: err => this.#conditionRetry(err),\n onRetry(error) {\n warn('retrying method on fs ', {\n method: functionName,\n attemptNumber: this.attemptNumber,\n delay: this.delay,\n error,\n file: this.arguments?.[0],\n })\n },\n })\n }\n })\n }\n\n // Public members\n //\n // Should not be called directly because:\n // - some concurrency limits may be applied which may lead to deadlocks\n // - some preprocessing may be applied on parameters that should not be done multiple times (e.g. prefixing paths)\n\n get type() {\n throw new Error('Not implemented')\n }\n\n addPrefix(prefix) {\n prefix = normalizePath(prefix)\n return prefix === '/' ? this : new PrefixWrapper(this, prefix)\n }\n\n async createReadStream(file, { checksum = false, ignoreMissingChecksum = false, ...options } = {}) {\n if (options.end !== undefined || options.start !== undefined) {\n assert.strictEqual(this.isEncrypted, false, `Can't read part of a file when encryption is active ${file}`)\n }\n if (typeof file === 'string') {\n file = normalizePath(file)\n }\n\n let stream = await this._createReadStream(file, { ...options, highWaterMark: this._highWaterMark })\n // detect early errors\n await fromEvent(stream, 'readable')\n\n if (checksum) {\n try {\n const path = typeof file === 'string' ? file : file.path\n const checksum = await this._readFile(checksumFile(path), { flags: 'r' })\n\n const { length } = stream\n stream = validChecksumOfReadStream(stream, String(checksum).trim())\n stream.length = length\n } catch (error) {\n if (!(ignoreMissingChecksum && error.code === 'ENOENT')) {\n throw error\n }\n }\n }\n\n if (this.isEncrypted) {\n stream = this.#encryptor.decryptStream(stream)\n }\n\n // try to add the length prop if missing and not a range stream\n if (stream.length === undefined && options.end === undefined && options.start === undefined) {\n try {\n if (this.isEncrypted) {\n stream.maxStreamLength = await this.getSizeOnDisk(file)\n } else {\n stream.length = await this._getSize(file)\n }\n } catch (error) {\n // ignore errors\n }\n }\n\n return stream\n }\n\n /**\n * write a stream to a file using a temporary file\n *\n * @param {string} path\n * @param {ReadableStream} input\n * @param {object} [options]\n * @param {boolean} [options.checksum]\n * @param {number} [options.dirMode]\n * @param {(this: RemoteHandlerAbstract, path: string) => Promise<undefined>} [options.validator] Function that will be called before the data is commited to the remote, if it fails, file should not exist\n */\n async outputStream(path, input, { checksum = true, dirMode, maxStreamLength, streamLength, validator } = {}) {\n path = normalizePath(path)\n let checksumStream\n\n input = this.#encryptor.encryptStream(input)\n if (checksum) {\n checksumStream = createChecksumStream()\n pipeline(input, checksumStream, noop)\n input = checksumStream\n }\n await this._outputStream(path, input, {\n dirMode,\n maxStreamLength,\n streamLength,\n validator,\n })\n if (checksum) {\n // using _outputFile means the checksum will NOT be encrypted\n // it is by design to allow checking of encrypted files without the key\n await this._outputFile(checksumFile(path), await checksumStream.checksum, { dirMode, flags: 'wx' })\n }\n }\n\n // Free the resources possibly dedicated to put the remote at work, when it\n // is no longer needed\n //\n // FIXME: Some handlers are implemented based on system-wide mechanisms (such\n // as mount), forgetting them might breaking other processes using the same\n // remote.\n @synchronized()\n async forget() {\n await this._forget()\n }\n\n async getInfo() {\n return this._getInfo()\n }\n\n // returns the real size occupied by an unencrypted file\n // encrypted files have metadata and padding that blur the real size\n async getSize(file) {\n assert.strictEqual(this.isEncrypted, false, `Can't compute size of an encrypted file ${file}`)\n return this.getSizeOnDisk(file)\n }\n\n async getSizeOnDisk(file) {\n return this._getSize(typeof file === 'string' ? normalizePath(file) : file)\n }\n\n async __list(dir, { filter, ignoreMissing = false, prependDir = false } = {}) {\n try {\n const virtualDir = normalizePath(dir)\n dir = normalizePath(dir)\n\n let entries = await this._list(dir)\n if (filter !== undefined) {\n entries = entries.filter(filter)\n }\n\n if (prependDir) {\n entries.forEach((entry, i) => {\n entries[i] = virtualDir + '/' + entry\n })\n }\n\n return entries\n } catch (error) {\n if (ignoreMissing && error?.code === 'ENOENT') {\n return []\n }\n throw error\n }\n }\n\n async lock(path) {\n path = normalizePath(path)\n return { dispose: await this._lock(path) }\n }\n\n async mktree(dir, { mode } = {}) {\n await this._mktree(normalizePath(dir), { mode })\n }\n\n async outputFile(file, data, { dirMode, flags = 'wx' } = {}) {\n const encryptedData = this.#encryptor.encryptData(data)\n await this._outputFile(normalizePath(file), encryptedData, { dirMode, flags })\n }\n\n async read(file, buffer, position) {\n assert.strictEqual(this.isEncrypted, false, `Can't read part of an encrypted file ${file}`)\n return this._read(typeof file === 'string' ? normalizePath(file) : file, buffer, position)\n }\n\n async __readFile(file, { flags = 'r' } = {}) {\n const data = await this._readFile(normalizePath(file), { flags })\n return this.#encryptor.decryptData(data)\n }\n\n async #rename(oldPath, newPath, { checksum }, createTree = true) {\n try {\n let p = this._rename(oldPath, newPath)\n if (checksum) {\n p = Promise.all([p, this._rename(checksumFile(oldPath), checksumFile(newPath))])\n }\n await p\n } catch (error) {\n // ENOENT can be a missing target directory OR a missing source\n if (error.code === 'ENOENT' && createTree) {\n await this._mktree(dirname(newPath))\n return this.#rename(oldPath, newPath, { checksum }, false)\n }\n throw error\n }\n }\n\n __rename(oldPath, newPath, { checksum = false } = {}) {\n return this.#rename(normalizePath(oldPath), normalizePath(newPath), { checksum })\n }\n\n async __copy(oldPath, newPath, { checksum = false } = {}) {\n oldPath = normalizePath(oldPath)\n newPath = normalizePath(newPath)\n\n let p = this._copy(oldPath, newPath)\n if (checksum) {\n p = Promise.all([p, this._copy(checksumFile(oldPath), checksumFile(newPath))])\n }\n return p\n }\n\n async rmdir(dir) {\n await this._rmdir(normalizePath(dir)).catch(ignoreEnoent)\n }\n\n async rmtree(dir) {\n await this._rmtree(normalizePath(dir))\n }\n\n // Asks the handler to sync the state of the effective remote with its\n // metadata\n //\n // This method MUST ALWAYS be called before using the handler.\n @synchronized()\n async sync() {\n await this._sync()\n try {\n await this.#checkMetadata()\n } catch (error) {\n await this._forget()\n throw error\n }\n }\n\n async #canWriteMetadata() {\n const list = await this.__list('/', {\n filter: e => !e.startsWith('.') && e !== ENCRYPTION_DESC_FILENAME && e !== ENCRYPTION_METADATA_FILENAME,\n })\n return list.length === 0\n }\n\n async #createMetadata() {\n const encryptionAlgorithm = this._remote.encryptionKey === undefined ? 'none' : DEFAULT_ENCRYPTION_ALGORITHM\n this.#rawEncryptor = _getEncryptor(encryptionAlgorithm, this._remote.encryptionKey)\n\n await Promise.all([\n this._writeFile(normalizePath(ENCRYPTION_DESC_FILENAME), JSON.stringify({ algorithm: encryptionAlgorithm }), {\n flags: 'w',\n }), // not encrypted\n this.__writeFile(ENCRYPTION_METADATA_FILENAME, `{\"random\":\"${randomUUID()}\"}`, { flags: 'w' }), // encrypted\n ])\n }\n\n async #checkMetadata() {\n let encryptionAlgorithm = 'none'\n let data\n try {\n // this file is not encrypted\n data = await this._readFile(normalizePath(ENCRYPTION_DESC_FILENAME))\n const json = JSON.parse(data)\n encryptionAlgorithm = json.algorithm\n } catch (error) {\n if (error.code !== 'ENOENT') {\n throw error\n }\n encryptionAlgorithm = this._remote.encryptionKey === undefined ? 'none' : DEFAULT_ENCRYPTION_ALGORITHM\n }\n\n try {\n this.#rawEncryptor = _getEncryptor(encryptionAlgorithm, this._remote.encryptionKey)\n // this file is encrypted\n const data = await this.__readFile(ENCRYPTION_METADATA_FILENAME)\n JSON.parse(data)\n } catch (error) {\n // can be enoent, bad algorithm, or broken json ( bad key or algorithm)\n if (encryptionAlgorithm !== 'none') {\n if (await this.#canWriteMetadata()) {\n // any other error , but on empty remote => update with remote settings\n\n info('will update metadata of this remote')\n return this.#createMetadata()\n } else {\n // to add a new encrypted fs remote, the remote directory must be empty; otherwise, metadata.json is not created\n if (error.code === 'ENOENT' && error.path.includes('metadata.json')) {\n throw new Error('Remote directory must be empty.')\n }\n\n warn(\n `The encryptionKey settings of this remote does not match the key used to create it. You won't be able to read any data from this remote`,\n { error }\n )\n // will probably send a ERR_OSSL_EVP_BAD_DECRYPT if key is incorrect\n throw error\n }\n }\n }\n }\n\n async test() {\n const SIZE = 1024 * 1024 * 10\n const testFileName = normalizePath(`${Date.now()}.test`)\n const data = await fromCallback(randomBytes, SIZE)\n let step = 'write'\n try {\n const writeStart = process.hrtime()\n await this._outputFile(testFileName, data, { flags: 'wx' })\n const writeDuration = process.hrtime(writeStart)\n\n step = 'read'\n const readStart = process.hrtime()\n const read = await this._readFile(testFileName, { flags: 'r' })\n const readDuration = process.hrtime(readStart)\n\n if (!data.equals(read)) {\n throw new Error('output and input did not match')\n }\n return {\n success: true,\n writeRate: computeRate(writeDuration, SIZE),\n readRate: computeRate(readDuration, SIZE),\n }\n } catch (error) {\n warn(`error while testing the remote at step ${step}`, { error })\n return {\n success: false,\n step,\n file: testFileName,\n error,\n }\n } finally {\n ignoreErrors.call(this._unlink(testFileName))\n }\n }\n\n async truncate(file, len) {\n await this._truncate(file, len)\n }\n\n async __unlink(file, { checksum = true } = {}) {\n file = normalizePath(file)\n\n if (checksum) {\n ignoreErrors.call(this._unlink(checksumFile(file)))\n }\n\n await this._unlink(file).catch(ignoreEnoent)\n }\n\n async write(file, buffer, position) {\n assert.strictEqual(this.isEncrypted, false, `Can't write part of a file with encryption ${file}`)\n await this._write(typeof file === 'string' ? normalizePath(file) : file, buffer, position)\n }\n\n async __writeFile(file, data, { flags = 'wx' } = {}) {\n const encryptedData = this.#encryptor.encryptData(data)\n await this._writeFile(normalizePath(file), encryptedData, { flags })\n }\n\n // Methods that can be called by private methods to avoid parallel limit on public methods\n\n async __closeFile(fd) {\n await this._closeFile(fd.fd)\n }\n\n async __mkdir(dir, { mode } = {}) {\n dir = normalizePath(dir)\n\n try {\n await this._mkdir(dir, { mode })\n } catch (error) {\n if (error == null || error.code !== 'EEXIST') {\n throw error\n }\n\n // this operation will throw if it's not already a directory\n await this._list(dir)\n }\n }\n\n async __openFile(path, flags) {\n path = normalizePath(path)\n\n return {\n fd: await this._openFile(path, flags),\n path,\n }\n }\n\n // Methods that can be implemented by inheriting classes\n\n useVhdDirectory() {\n return this._remote.useVhdDirectory ?? false\n }\n\n async _closeFile(fd) {\n throw new Error('Not implemented')\n }\n\n async _createOutputStream(file, { dirMode, ...options } = {}) {\n try {\n return await this._createWriteStream(file, { ...options, highWaterMark: this._highWaterMark })\n } catch (error) {\n if (typeof file !== 'string' || error.code !== 'ENOENT') {\n throw error\n }\n }\n\n await this._mktree(dirname(file), { mode: dirMode })\n return this._createOutputStream(file, options)\n }\n\n async _createReadStream(file, options) {\n throw new Error('Not implemented')\n }\n\n // createWriteStream takes highWaterMark as option even if it's not documented.\n // Source: https://stackoverflow.com/questions/55026306/how-to-set-writeable-highwatermark\n async _createWriteStream(file, options) {\n throw new Error('Not implemented')\n }\n\n // called to finalize the remote\n async _forget() {}\n\n async _getInfo() {\n return {}\n }\n\n async _lock(path) {\n return () => Promise.resolve()\n }\n\n async _getSize(file) {\n throw new Error('Not implemented')\n }\n\n async _list(dir) {\n throw new Error('Not implemented')\n }\n\n async _mkdir(dir) {\n throw new Error('Not implemented')\n }\n\n async _mktree(dir, { mode } = {}) {\n try {\n return await this.__mkdir(dir, { mode })\n } catch (error) {\n if (error.code !== 'ENOENT') {\n throw error\n }\n }\n\n await this._mktree(dirname(dir), { mode })\n return this._mktree(dir, { mode })\n }\n\n async _openFile(path, flags) {\n throw new Error('Not implemented')\n }\n\n async _outputFile(file, data, { dirMode, flags }) {\n try {\n return await this._writeFile(file, data, { flags })\n } catch (error) {\n if (error.code !== 'ENOENT') {\n throw error\n }\n }\n\n await this._mktree(dirname(file), { mode: dirMode })\n return this._outputFile(file, data, { flags })\n }\n\n async _outputStream(path, input, { dirMode, validator }) {\n const tmpPath = `${dirname(path)}/.${basename(path)}`\n const output = await this._createOutputStream(tmpPath, {\n dirMode,\n flags: 'wx',\n })\n try {\n await fromCallback(pipeline, input, output)\n if (validator !== undefined) {\n await validator.call(this, tmpPath)\n }\n await this.__rename(tmpPath, path)\n } catch (error) {\n await this.__unlink(tmpPath)\n throw error\n }\n }\n\n _read(file, buffer, position) {\n throw new Error('Not implemented')\n }\n\n _readFile(file, options) {\n return this._createReadStream(file, { ...options, highWaterMark: this._highWaterMark }).then(getStream.buffer)\n }\n\n async _rename(oldPath, newPath) {\n throw new Error('Not implemented')\n }\n async _copy(oldPath, newPath) {\n throw new Error('Not implemented')\n }\n\n async _rmdir(dir) {\n throw new Error('Not implemented')\n }\n\n async _rmtree(dir) {\n try {\n return await this._rmdir(dir)\n } catch (error) {\n if (error.code !== 'ENOTEMPTY') {\n throw error\n }\n }\n\n const files = await this._list(dir)\n await asyncEach(\n files,\n file =>\n this._unlink(`${dir}/${file}`).catch(error => {\n // Unlink dir behavior is not consistent across platforms\n // https://github.com/nodejs/node-v0.x-archive/issues/5791\n if (error.code === 'EISDIR' || error.code === 'EPERM') {\n return this._rmtree(`${dir}/${file}`).catch(rmTreeError => {\n if (rmTreeError.code === 'ENOTDIR') {\n // this was really a EPERM error, maybe with immutable backups\n throw error\n }\n throw rmTreeError\n })\n }\n throw error\n }),\n // real unlink concurrency will be 2**max directory depth\n { concurrency: 2 }\n )\n return this._rmtree(dir)\n }\n\n // called to initialize the remote\n async _sync() {}\n\n async _unlink(file) {\n throw new Error('Not implemented')\n }\n\n async _write(file, buffer, position) {\n const isPath = typeof file === 'string'\n if (isPath) {\n file = await this.__openFile(file, 'r+')\n }\n try {\n return await this._writeFd(file, buffer, position)\n } finally {\n if (isPath) {\n await this.__closeFile(file)\n }\n }\n }\n\n async _writeFd(fd, buffer, position) {\n throw new Error('Not implemented')\n }\n\n async _writeFile(file, data, options) {\n throw new Error('Not implemented')\n }\n\n get isEncrypted() {\n return this.#encryptor.id !== 'NULL_ENCRYPTOR'\n }\n\n get encryptionAlgorithm() {\n return this.#encryptor?.algorithm ?? UNENCRYPTED_ALGORITHM\n }\n}\n\n// from implementation methods, which names start with `__`, create public\n// accessors on which external behaviors can be added (e.g. concurrency limits, path rewriting)\n{\n const proto = RemoteHandlerAbstract.prototype\n for (const method of Object.getOwnPropertyNames(proto)) {\n if (method.startsWith('__')) {\n const publicName = method.slice(2)\n\n assert(!Object.hasOwn(proto, publicName))\n\n Object.defineProperty(proto, publicName, Object.getOwnPropertyDescriptor(proto, method))\n }\n }\n}\n\nfunction createPrefixWrapperMethods() {\n const pPw = PrefixWrapper.prototype\n const pRha = RemoteHandlerAbstract.prototype\n\n const {\n defineProperty,\n getOwnPropertyDescriptor,\n prototype: { hasOwnProperty },\n } = Object\n\n Object.getOwnPropertyNames(pRha).forEach(name => {\n let descriptor, value\n if (\n hasOwnProperty.call(pPw, name) ||\n name[0] === '_' ||\n typeof (value = (descriptor = getOwnPropertyDescriptor(pRha, name)).value) !== 'function'\n ) {\n return\n }\n\n descriptor.value = function () {\n let path\n if (arguments.length !== 0 && typeof (path = arguments[0]) === 'string') {\n arguments[0] = this._resolve(path)\n }\n return value.apply(this._handler, arguments)\n }\n\n defineProperty(pPw, name, descriptor)\n })\n}\ncreatePrefixWrapperMethods()\n"],"mappings":"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","ignoreList":[]}
|
package/dist/azure.js
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _storageBlob = require("@azure/storage-blob");
|
|
8
|
+
var _log = require("@xen-orchestra/log");
|
|
9
|
+
var _xoRemoteParser = require("xo-remote-parser");
|
|
10
|
+
var _path = require("./path");
|
|
11
|
+
var _abstract = _interopRequireDefault(require("./abstract"));
|
|
12
|
+
var _copyStreamToBuffer = _interopRequireDefault(require("./_copyStreamToBuffer"));
|
|
13
|
+
var _stream = require("stream");
|
|
14
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
15
|
+
(0, _log.createLogger)('xo:fs:azure');
|
|
16
|
+
const MAX_BLOCK_SIZE = 1024 * 1024 * 4000;
|
|
17
|
+
const MIN_BLOCK_SIZE = 1024 * 1024 * 4;
|
|
18
|
+
const MAX_BLOCK_COUNT = 50000;
|
|
19
|
+
const AZURE_BATCH_MAX_REQUEST = 256;
|
|
20
|
+
const {
|
|
21
|
+
warn,
|
|
22
|
+
info
|
|
23
|
+
} = (0, _log.createLogger)('xo:fs:azure');
|
|
24
|
+
class AzureHandler extends _abstract.default {
|
|
25
|
+
#container;
|
|
26
|
+
#dir;
|
|
27
|
+
#blobServiceClient;
|
|
28
|
+
#containerClient;
|
|
29
|
+
constructor(remote, _opts) {
|
|
30
|
+
super(remote, _opts);
|
|
31
|
+
const {
|
|
32
|
+
username,
|
|
33
|
+
path,
|
|
34
|
+
password,
|
|
35
|
+
host,
|
|
36
|
+
protocol
|
|
37
|
+
} = (0, _xoRemoteParser.parse)(remote.url);
|
|
38
|
+
const credential = new _storageBlob.StorageSharedKeyCredential(username, password);
|
|
39
|
+
const url = this.type === 'azure' ? `${protocol}://${host}` : `${protocol}://${host}/${username}`;
|
|
40
|
+
info('Connecting to Azure blob storage...');
|
|
41
|
+
this.#blobServiceClient = new _storageBlob.BlobServiceClient(url, credential);
|
|
42
|
+
const parts = (0, _path.split)(path);
|
|
43
|
+
this.#container = parts.shift();
|
|
44
|
+
this.#dir = (0, _path.join)(...parts);
|
|
45
|
+
this.#containerClient = this.#blobServiceClient.getContainerClient(this.#container);
|
|
46
|
+
}
|
|
47
|
+
get type() {
|
|
48
|
+
return this._remote.url.startsWith('azure:') ? 'azure' : 'azurite';
|
|
49
|
+
}
|
|
50
|
+
#ensureIsDir(path) {
|
|
51
|
+
return path === '.' ? '' : path.endsWith('/') ? path : `${path}/`;
|
|
52
|
+
}
|
|
53
|
+
#makeFullPath(path) {
|
|
54
|
+
if (!path.startsWith(this.#dir) || !path.substring('/').startsWith(this.#dir)) {
|
|
55
|
+
const prefixedPath = path.startsWith('/') ? path.substring(1) : path;
|
|
56
|
+
return `${this.#ensureIsDir(this.#dir)}${prefixedPath}`;
|
|
57
|
+
} else {
|
|
58
|
+
return path;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async #isNotEmptyDir(dir) {
|
|
62
|
+
var _value$segment;
|
|
63
|
+
const prefix = this.#ensureIsDir(dir);
|
|
64
|
+
const iterator = this.#containerClient.listBlobsFlat({
|
|
65
|
+
prefix
|
|
66
|
+
}).byPage({
|
|
67
|
+
maxPageSize: 1
|
|
68
|
+
});
|
|
69
|
+
const {
|
|
70
|
+
value
|
|
71
|
+
} = await iterator.next();
|
|
72
|
+
return ((value === null || value === void 0 || (_value$segment = value.segment) === null || _value$segment === void 0 || (_value$segment = _value$segment.blobItems) === null || _value$segment === void 0 ? void 0 : _value$segment.length) ?? 0) > 0;
|
|
73
|
+
}
|
|
74
|
+
async _sync() {
|
|
75
|
+
await this.#containerClient.createIfNotExists();
|
|
76
|
+
await super._sync();
|
|
77
|
+
}
|
|
78
|
+
async _outputStream(path, input, {
|
|
79
|
+
streamLength,
|
|
80
|
+
maxStreamLength = streamLength,
|
|
81
|
+
validator
|
|
82
|
+
}) {
|
|
83
|
+
const blobClient = this.#containerClient.getBlockBlobClient(this.#makeFullPath(path));
|
|
84
|
+
let blockSize;
|
|
85
|
+
if (maxStreamLength === undefined) {
|
|
86
|
+
warn(`Writing ${path} to a azure blob storage without a max size set will cut it to 50GB`, {
|
|
87
|
+
path
|
|
88
|
+
});
|
|
89
|
+
blockSize = MIN_BLOCK_SIZE;
|
|
90
|
+
} else {
|
|
91
|
+
const minBlockSize = Math.ceil(maxStreamLength / MAX_BLOCK_COUNT);
|
|
92
|
+
const adjustedMinSize = Math.max(minBlockSize, MIN_BLOCK_SIZE);
|
|
93
|
+
blockSize = Math.min(adjustedMinSize, MAX_BLOCK_SIZE);
|
|
94
|
+
}
|
|
95
|
+
const MAX_SIZE = MAX_BLOCK_COUNT * blockSize;
|
|
96
|
+
let readCounter = 0;
|
|
97
|
+
const streamCutter = new _stream.Transform({
|
|
98
|
+
transform(chunk, encoding, callback) {
|
|
99
|
+
readCounter += chunk.length;
|
|
100
|
+
if (readCounter > MAX_SIZE) {
|
|
101
|
+
callback(new Error(`read ${readCounter} bytes, maximum size allowed is ${MAX_SIZE} `));
|
|
102
|
+
} else {
|
|
103
|
+
callback(null, chunk);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
const body = new _stream.PassThrough();
|
|
108
|
+
(0, _stream.pipeline)(input, streamCutter, body, () => {});
|
|
109
|
+
await blobClient.uploadStream(body, blockSize, 5, {
|
|
110
|
+
onProgress: ev => {},
|
|
111
|
+
abortSignal: undefined
|
|
112
|
+
});
|
|
113
|
+
if (validator !== undefined) {
|
|
114
|
+
try {
|
|
115
|
+
await validator.call(this, path);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
await this.__unlink(path);
|
|
118
|
+
throw error;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async _list(path) {
|
|
123
|
+
const fullPath = this.#makeFullPath(this.#ensureIsDir(path));
|
|
124
|
+
try {
|
|
125
|
+
const result = [];
|
|
126
|
+
for await (const item of this.#containerClient.listBlobsByHierarchy('/', {
|
|
127
|
+
prefix: fullPath
|
|
128
|
+
})) {
|
|
129
|
+
let strippedName = item.name;
|
|
130
|
+
if (item.name.startsWith(fullPath)) {
|
|
131
|
+
strippedName = item.name.substring(fullPath.length);
|
|
132
|
+
}
|
|
133
|
+
result.push(strippedName.endsWith('/') ? strippedName.slice(0, -1) : strippedName);
|
|
134
|
+
}
|
|
135
|
+
return result;
|
|
136
|
+
} catch (e) {
|
|
137
|
+
if (e.statusCode === 404) {
|
|
138
|
+
const enoentError = new Error(`ENOENT: No such file or directory from list ${path}`);
|
|
139
|
+
enoentError.code = 'ENOENT';
|
|
140
|
+
enoentError.path = path;
|
|
141
|
+
enoentError.cause = e;
|
|
142
|
+
throw enoentError;
|
|
143
|
+
}
|
|
144
|
+
throw e;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
async _writeFile(file, data) {
|
|
148
|
+
const blobClient = this.#containerClient.getBlockBlobClient(this.#makeFullPath(file));
|
|
149
|
+
await blobClient.upload(data, data.length);
|
|
150
|
+
}
|
|
151
|
+
async _createReadStream(file) {
|
|
152
|
+
try {
|
|
153
|
+
const blobClient = this.#containerClient.getBlobClient(this.#makeFullPath(file));
|
|
154
|
+
const response = await blobClient.download();
|
|
155
|
+
return await response.readableStreamBody;
|
|
156
|
+
} catch (e) {
|
|
157
|
+
if (e.name === 'RestError' && e.code === 'BlobNotFound') {
|
|
158
|
+
const error = new Error(`ENOENT: no such file '${file}'`, e);
|
|
159
|
+
error.code = 'ENOENT';
|
|
160
|
+
error.path = file;
|
|
161
|
+
throw error;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
async _unlink(file) {
|
|
166
|
+
file = this.#makeFullPath(file);
|
|
167
|
+
if (await this.#isNotEmptyDir(file)) {
|
|
168
|
+
const error = new Error(`EISDIR: illegal operation on a directory, unlink '${file}'`);
|
|
169
|
+
error.code = 'EISDIR';
|
|
170
|
+
error.path = file;
|
|
171
|
+
throw error;
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
const blobClient = this.#containerClient.getBlobClient(this.#makeFullPath(file));
|
|
175
|
+
await blobClient.delete();
|
|
176
|
+
} catch (e) {
|
|
177
|
+
if (e.name === 'RestError' && ![400, 404].includes(e.statusCode)) {
|
|
178
|
+
throw e;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
async rename(oldPath, newPath) {
|
|
183
|
+
await this._copy(oldPath, newPath);
|
|
184
|
+
await this._unlink(oldPath);
|
|
185
|
+
}
|
|
186
|
+
async _copy(oldPath, newPath) {
|
|
187
|
+
const error = new Error(`ENOENT: no such file '${oldPath}'`);
|
|
188
|
+
error.code = 'ENOENT';
|
|
189
|
+
error.path = oldPath;
|
|
190
|
+
try {
|
|
191
|
+
const sourceBlob = this.#containerClient.getBlobClient(this.#makeFullPath(oldPath));
|
|
192
|
+
const exists = await sourceBlob.exists();
|
|
193
|
+
if (!exists) {
|
|
194
|
+
throw error;
|
|
195
|
+
}
|
|
196
|
+
const destinationBlob = this.#containerClient.getBlobClient(this.#makeFullPath(newPath));
|
|
197
|
+
await destinationBlob.beginCopyFromURL(sourceBlob.url, {
|
|
198
|
+
requiresSync: true
|
|
199
|
+
});
|
|
200
|
+
} catch (e) {
|
|
201
|
+
if (e.statusCode === 404) {
|
|
202
|
+
throw error;
|
|
203
|
+
}
|
|
204
|
+
throw e;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
async _getSize(file) {
|
|
208
|
+
if (typeof file !== 'string') {
|
|
209
|
+
file = file.fd;
|
|
210
|
+
}
|
|
211
|
+
file = this.#makeFullPath(file);
|
|
212
|
+
const blobClient = this.#containerClient.getBlobClient(file);
|
|
213
|
+
const properties = await blobClient.getProperties();
|
|
214
|
+
return properties.contentLength;
|
|
215
|
+
}
|
|
216
|
+
async _read(file, buffer, position = 0) {
|
|
217
|
+
if (typeof file !== 'string') {
|
|
218
|
+
file = file.fd;
|
|
219
|
+
}
|
|
220
|
+
file = this.#makeFullPath(file);
|
|
221
|
+
try {
|
|
222
|
+
const blobClient = this.#containerClient.getBlobClient(file);
|
|
223
|
+
const downloadResponse = await blobClient.download(position, buffer.length);
|
|
224
|
+
const bytesRead = await (0, _copyStreamToBuffer.default)(downloadResponse.readableStreamBody, buffer);
|
|
225
|
+
return {
|
|
226
|
+
bytesRead,
|
|
227
|
+
buffer
|
|
228
|
+
};
|
|
229
|
+
} catch (e) {
|
|
230
|
+
if (e.statusCode === 404) {
|
|
231
|
+
if (await this.#isNotEmptyDir(file)) {
|
|
232
|
+
const error = new Error(`${file} is a directory`);
|
|
233
|
+
error.code = 'EISDIR';
|
|
234
|
+
error.path = file;
|
|
235
|
+
throw error;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
throw e;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
async _mkdir(path) {
|
|
242
|
+
const blobClient = this.#containerClient.getBlobClient(this.#makeFullPath(path));
|
|
243
|
+
if (await blobClient.exists()) {
|
|
244
|
+
const error = new Error(`ENOTDIR: file already exists, mkdir '${path}'`);
|
|
245
|
+
error.code = 'ENOTDIR';
|
|
246
|
+
error.path = path;
|
|
247
|
+
throw error;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
async _openFile(path, flags) {
|
|
251
|
+
return path;
|
|
252
|
+
}
|
|
253
|
+
async _closeFile(fd) {}
|
|
254
|
+
async _rmtree(path) {
|
|
255
|
+
const blobIterator = this.#containerClient.listBlobsFlat({
|
|
256
|
+
prefix: this.#makeFullPath(this.#ensureIsDir(path))
|
|
257
|
+
});
|
|
258
|
+
const blobBatchClient = this.#containerClient.getBlobBatchClient();
|
|
259
|
+
let batch = blobBatchClient.createBatch();
|
|
260
|
+
for await (const urlOrBlobClient of blobIterator) {
|
|
261
|
+
await batch.deleteBlob(this.#containerClient.getBlobClient(urlOrBlobClient.name));
|
|
262
|
+
if (batch.batchRequest.operationCount >= AZURE_BATCH_MAX_REQUEST - 1) {
|
|
263
|
+
await blobBatchClient.submitBatch(batch);
|
|
264
|
+
batch = blobBatchClient.createBatch();
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (batch.batchRequest.operationCount > 0) {
|
|
268
|
+
await blobBatchClient.submitBatch(batch);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
useVhdDirectory() {
|
|
272
|
+
return true;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
exports.default = AzureHandler;
|
|
276
|
+
//# sourceMappingURL=azure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"azure.js","names":["_storageBlob","require","_log","_xoRemoteParser","_path","_abstract","_interopRequireDefault","_copyStreamToBuffer","_stream","e","__esModule","default","createLogger","MAX_BLOCK_SIZE","MIN_BLOCK_SIZE","MAX_BLOCK_COUNT","AZURE_BATCH_MAX_REQUEST","warn","info","AzureHandler","RemoteHandlerAbstract","container","dir","blobServiceClient","containerClient","constructor","remote","_opts","username","path","password","host","protocol","parse","url","credential","StorageSharedKeyCredential","type","BlobServiceClient","parts","split","shift","join","getContainerClient","_remote","startsWith","ensureIsDir","#ensureIsDir","endsWith","makeFullPath","#makeFullPath","substring","prefixedPath","isNotEmptyDir","#isNotEmptyDir","_value$segment","prefix","iterator","listBlobsFlat","byPage","maxPageSize","value","next","segment","blobItems","length","_sync","createIfNotExists","_outputStream","input","streamLength","maxStreamLength","validator","blobClient","getBlockBlobClient","blockSize","undefined","minBlockSize","Math","ceil","adjustedMinSize","max","min","MAX_SIZE","readCounter","streamCutter","Transform","transform","chunk","encoding","callback","Error","body","PassThrough","pipeline","uploadStream","onProgress","ev","abortSignal","call","error","__unlink","_list","fullPath","result","item","listBlobsByHierarchy","strippedName","name","push","slice","statusCode","enoentError","code","cause","_writeFile","file","data","upload","_createReadStream","getBlobClient","response","download","readableStreamBody","_unlink","delete","includes","rename","oldPath","newPath","_copy","sourceBlob","exists","destinationBlob","beginCopyFromURL","requiresSync","_getSize","fd","properties","getProperties","contentLength","_read","buffer","position","downloadResponse","bytesRead","copyStreamToBuffer","_mkdir","_openFile","flags","_closeFile","_rmtree","blobIterator","blobBatchClient","getBlobBatchClient","batch","createBatch","urlOrBlobClient","deleteBlob","batchRequest","operationCount","submitBatch","useVhdDirectory","exports"],"sources":["../src/azure.js"],"sourcesContent":["import { BlobServiceClient, StorageSharedKeyCredential } from '@azure/storage-blob'\nimport { createLogger } from '@xen-orchestra/log'\nimport { parse } from 'xo-remote-parser'\nimport { join, split } from './path'\nimport RemoteHandlerAbstract from './abstract'\nimport copyStreamToBuffer from './_copyStreamToBuffer'\nimport { PassThrough, Transform, pipeline } from 'stream'\n\ncreateLogger('xo:fs:azure')\nconst MAX_BLOCK_SIZE = 1024 * 1024 * 4000 // 4000 MiB\nconst MIN_BLOCK_SIZE = 1024 * 1024 * 4 // 4 MiB, default max block size\nconst MAX_BLOCK_COUNT = 50000\nconst AZURE_BATCH_MAX_REQUEST = 256 // BATCH_MAX_REQUEST constant from Azure\nconst { warn, info } = createLogger('xo:fs:azure')\n\nexport default class AzureHandler extends RemoteHandlerAbstract {\n #container\n #dir\n #blobServiceClient\n #containerClient\n\n constructor(remote, _opts) {\n super(remote, _opts)\n const { username, path, password, host, protocol } = parse(remote.url)\n const credential = new StorageSharedKeyCredential(username, password)\n\n // if azurite, we need to put the username in url\n // if azure, we only need the host. Until now, it is {username}.blob.core.windows.net\n // const url = remote.url.startsWith('azure:') ? `${protocol}://${host}` : `${protocol}://${host}/${username}`\n const url = this.type === 'azure' ? `${protocol}://${host}` : `${protocol}://${host}/${username}`\n\n info('Connecting to Azure blob storage...')\n this.#blobServiceClient = new BlobServiceClient(url, credential)\n\n const parts = split(path)\n this.#container = parts.shift() // in azurite, container = first component after host, only lowercase allowed\n this.#dir = join(...parts)\n this.#containerClient = this.#blobServiceClient.getContainerClient(this.#container)\n }\n\n get type() {\n return this._remote.url.startsWith('azure:') ? 'azure' : 'azurite'\n }\n\n /**\n * Make sure a given path is a folder path\n * @param {string} path String to format\n * @returns add / at the end of path to allow azure to understand it is a \"folder\"\n */\n #ensureIsDir(path) {\n return path === '.' ? '' : path.endsWith('/') ? path : `${path}/`\n }\n\n /**\n * As Azure does not have prefix option in every methods\n * we need to add the path everywhere it is needed\n * @param {*} path relative path or blob name\n * @returns absolute path in container\n */\n #makeFullPath(path) {\n // safety check to avoid adding #dir multiple times\n // as some methods are used outside this class\n if (!path.startsWith(this.#dir) || !path.substring('/').startsWith(this.#dir)) {\n const prefixedPath = path.startsWith('/') ? path.substring(1) : path\n return `${this.#ensureIsDir(this.#dir)}${prefixedPath}`\n } else {\n return path\n }\n }\n\n /**\n *\n * @param {string} dir\n * @returns true if dir is not empty\n */\n async #isNotEmptyDir(dir) {\n const prefix = this.#ensureIsDir(dir)\n const iterator = this.#containerClient.listBlobsFlat({ prefix }).byPage({ maxPageSize: 1 })\n\n const { value } = await iterator.next()\n return (value?.segment?.blobItems?.length ?? 0) > 0\n }\n\n /**\n * Create container if it does not exist\n */\n async _sync() {\n await this.#containerClient.createIfNotExists()\n await super._sync()\n }\n\n /**\n * upload file from a stream\n * @param {string} path destination file\n * @param {object} input stream\n * @param {*} param2 details given by stream input\n */\n async _outputStream(path, input, { streamLength, maxStreamLength = streamLength, validator }) {\n const blobClient = this.#containerClient.getBlockBlobClient(this.#makeFullPath(path))\n let blockSize\n if (maxStreamLength === undefined) {\n warn(`Writing ${path} to a azure blob storage without a max size set will cut it to 50GB`, { path })\n blockSize = MIN_BLOCK_SIZE\n } else {\n const minBlockSize = Math.ceil(maxStreamLength / MAX_BLOCK_COUNT) // Minimal possible block size for the block count allowed\n const adjustedMinSize = Math.max(minBlockSize, MIN_BLOCK_SIZE) // Block size must be larger than minimum block size allowed\n blockSize = Math.min(adjustedMinSize, MAX_BLOCK_SIZE) // Block size must be smaller than max block size allowed\n }\n\n const MAX_SIZE = MAX_BLOCK_COUNT * blockSize\n\n let readCounter = 0\n\n const streamCutter = new Transform({\n transform(chunk, encoding, callback) {\n readCounter += chunk.length\n if (readCounter > MAX_SIZE) {\n callback(new Error(`read ${readCounter} bytes, maximum size allowed is ${MAX_SIZE} `))\n } else {\n callback(null, chunk)\n }\n },\n })\n\n const body = new PassThrough()\n pipeline(input, streamCutter, body, () => {})\n\n await blobClient.uploadStream(body, blockSize, 5, {\n onProgress: ev => {},\n abortSignal: undefined,\n })\n\n if (validator !== undefined) {\n try {\n await validator.call(this, path)\n } catch (error) {\n await this.__unlink(path)\n throw error\n }\n }\n }\n\n /**\n * List all blobs inside a folder\n * @param {string} path folder name inside container and #dir\n * @returns list of blobs in folder container/#dir\n */\n async _list(path) {\n const fullPath = this.#makeFullPath(this.#ensureIsDir(path))\n try {\n const result = []\n for await (const item of this.#containerClient.listBlobsByHierarchy('/', { prefix: fullPath })) {\n let strippedName = item.name\n if (item.name.startsWith(fullPath)) {\n strippedName = item.name.substring(fullPath.length)\n }\n result.push(strippedName.endsWith('/') ? strippedName.slice(0, -1) : strippedName)\n }\n return result\n } catch (e) {\n if (e.statusCode === 404) {\n const enoentError = new Error(`ENOENT: No such file or directory from list ${path}`)\n enoentError.code = 'ENOENT'\n enoentError.path = path\n enoentError.cause = e\n throw enoentError\n }\n throw e\n }\n }\n\n /**\n * uploads a file to a blob\n * @param {string} file file name\n * @param {*} data file content\n */\n async _writeFile(file, data) {\n const blobClient = this.#containerClient.getBlockBlobClient(this.#makeFullPath(file))\n await blobClient.upload(data, data.length)\n }\n\n async _createReadStream(file) {\n try {\n const blobClient = this.#containerClient.getBlobClient(this.#makeFullPath(file))\n const response = await blobClient.download()\n return await response.readableStreamBody\n } catch (e) {\n if (e.name === 'RestError' && e.code === 'BlobNotFound') {\n const error = new Error(`ENOENT: no such file '${file}'`, e)\n error.code = 'ENOENT'\n error.path = file\n throw error\n }\n }\n }\n\n async _unlink(file) {\n file = this.#makeFullPath(file)\n if (await this.#isNotEmptyDir(file)) {\n const error = new Error(`EISDIR: illegal operation on a directory, unlink '${file}'`)\n error.code = 'EISDIR'\n error.path = file\n throw error\n }\n try {\n const blobClient = this.#containerClient.getBlobClient(this.#makeFullPath(file))\n await blobClient.delete()\n } catch (e) {\n if (e.name === 'RestError' && ![400, 404].includes(e.statusCode)) {\n throw e\n }\n }\n }\n\n async rename(oldPath, newPath) {\n await this._copy(oldPath, newPath)\n await this._unlink(oldPath)\n }\n\n async _copy(oldPath, newPath) {\n const error = new Error(`ENOENT: no such file '${oldPath}'`)\n error.code = 'ENOENT'\n error.path = oldPath\n try {\n const sourceBlob = this.#containerClient.getBlobClient(this.#makeFullPath(oldPath))\n const exists = await sourceBlob.exists()\n if (!exists) {\n throw error\n }\n const destinationBlob = this.#containerClient.getBlobClient(this.#makeFullPath(newPath))\n await destinationBlob.beginCopyFromURL(sourceBlob.url, { requiresSync: true })\n } catch (e) {\n if (e.statusCode === 404) {\n throw error\n }\n throw e\n }\n }\n\n async _getSize(file) {\n if (typeof file !== 'string') {\n file = file.fd\n }\n file = this.#makeFullPath(file)\n const blobClient = this.#containerClient.getBlobClient(file)\n const properties = await blobClient.getProperties()\n return properties.contentLength\n }\n\n async _read(file, buffer, position = 0) {\n if (typeof file !== 'string') {\n file = file.fd\n }\n file = this.#makeFullPath(file)\n try {\n const blobClient = this.#containerClient.getBlobClient(file)\n const downloadResponse = await blobClient.download(position, buffer.length)\n const bytesRead = await copyStreamToBuffer(downloadResponse.readableStreamBody, buffer)\n return { bytesRead, buffer }\n } catch (e) {\n if (e.statusCode === 404) {\n if (await this.#isNotEmptyDir(file)) {\n const error = new Error(`${file} is a directory`)\n error.code = 'EISDIR'\n error.path = file\n throw error\n }\n }\n throw e\n }\n }\n\n async _mkdir(path) {\n const blobClient = this.#containerClient.getBlobClient(this.#makeFullPath(path))\n if (await blobClient.exists()) {\n const error = new Error(`ENOTDIR: file already exists, mkdir '${path}'`)\n error.code = 'ENOTDIR'\n error.path = path\n throw error\n }\n }\n\n async _openFile(path, flags) {\n return path\n }\n\n async _closeFile(fd) {}\n\n /**\n * Delete recursively a given folder\n * @param {string} path\n */\n async _rmtree(path) {\n // Create an iterator with all blobs inside a folder and its subfolder\n const blobIterator = this.#containerClient.listBlobsFlat({ prefix: this.#makeFullPath(this.#ensureIsDir(path)) })\n\n // create a batch client with a maximum number\n // of instructions given by AZURE_BATCH_MAX_REQUEST\n const blobBatchClient = this.#containerClient.getBlobBatchClient()\n let batch = blobBatchClient.createBatch()\n for await (const urlOrBlobClient of blobIterator) {\n await batch.deleteBlob(this.#containerClient.getBlobClient(urlOrBlobClient.name))\n\n // if the batch limit is reached, we send it and recreate a new one\n if (batch.batchRequest.operationCount >= AZURE_BATCH_MAX_REQUEST - 1) {\n await blobBatchClient.submitBatch(batch)\n batch = blobBatchClient.createBatch()\n }\n }\n\n // send the last batch as it can be between 0 and AZURE_BATCH_MAX_REQUEST\n if (batch.batchRequest.operationCount > 0) {\n await blobBatchClient.submitBatch(batch)\n }\n }\n\n useVhdDirectory() {\n return true\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
package/dist/checksum.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checksum.js","names":["_through","_interopRequireDefault","require","_crypto","_promiseToolbox","_invert","e","__esModule","default","ALGORITHM_TO_ID","md5","sha256","sha512","ID_TO_ALGORITHM","invert","createChecksumStream","algorithm","algorithmId","Error","hash","createHash","promise","resolve","reject","defer","stream","through2","chunk","enc","callback","update","digest","once","checksum","exports","validChecksumOfReadStream","expectedChecksum","slice","indexOf","wrapper","pipe","highWaterMark","on","error","emit","checksumVerified","fromEvent"],"sources":["../src/checksum.js"],"sourcesContent":["import through2 from 'through2'\nimport { createHash } from 'crypto'\nimport { defer, fromEvent } from 'promise-toolbox'\nimport invert from 'lodash/invert.js'\n\n// Format: $<algorithm>$<salt>$<encrypted>\n//\n// http://man7.org/linux/man-pages/man3/crypt.3.html#NOTES\nconst ALGORITHM_TO_ID = {\n md5: '1',\n sha256: '5',\n sha512: '6',\n}\n\nconst ID_TO_ALGORITHM = invert(ALGORITHM_TO_ID)\n\n// Create a through stream which computes the checksum of all data going\n// through.\n//\n// The `checksum` attribute is a promise which resolves at the end of the stream\n// with a string representation of the checksum.\n//\n// const source = ...\n// const checksumStream = source.pipe(createChecksumStream())\n// checksumStream.resume() // make the data flow without an output\n// console.log(await checksumStream.checksum)\nexport const createChecksumStream = (algorithm = 'md5') => {\n const algorithmId = ALGORITHM_TO_ID[algorithm]\n\n if (!algorithmId) {\n throw new Error(`unknown algorithm: ${algorithm}`)\n }\n\n const hash = createHash(algorithm)\n const { promise, resolve, reject } = defer()\n\n const stream = through2(\n (chunk, enc, callback) => {\n hash.update(chunk)\n callback(null, chunk)\n },\n callback => {\n resolve(`$${algorithmId}$$${hash.digest('hex')}`)\n callback()\n }\n ).once('error', reject)\n stream.checksum = promise\n return stream\n}\n\n// Check if the checksum of a readable stream is
|
|
1
|
+
{"version":3,"file":"checksum.js","names":["_through","_interopRequireDefault","require","_crypto","_promiseToolbox","_invert","e","__esModule","default","ALGORITHM_TO_ID","md5","sha256","sha512","ID_TO_ALGORITHM","invert","createChecksumStream","algorithm","algorithmId","Error","hash","createHash","promise","resolve","reject","defer","stream","through2","chunk","enc","callback","update","digest","once","checksum","exports","validChecksumOfReadStream","expectedChecksum","slice","indexOf","wrapper","pipe","highWaterMark","on","error","emit","checksumVerified","fromEvent"],"sources":["../src/checksum.js"],"sourcesContent":["import through2 from 'through2'\nimport { createHash } from 'crypto'\nimport { defer, fromEvent } from 'promise-toolbox'\nimport invert from 'lodash/invert.js'\n\n// Format: $<algorithm>$<salt>$<encrypted>\n//\n// http://man7.org/linux/man-pages/man3/crypt.3.html#NOTES\nconst ALGORITHM_TO_ID = {\n md5: '1',\n sha256: '5',\n sha512: '6',\n}\n\nconst ID_TO_ALGORITHM = invert(ALGORITHM_TO_ID)\n\n// Create a through stream which computes the checksum of all data going\n// through.\n//\n// The `checksum` attribute is a promise which resolves at the end of the stream\n// with a string representation of the checksum.\n//\n// const source = ...\n// const checksumStream = source.pipe(createChecksumStream())\n// checksumStream.resume() // make the data flow without an output\n// console.log(await checksumStream.checksum)\nexport const createChecksumStream = (algorithm = 'md5') => {\n const algorithmId = ALGORITHM_TO_ID[algorithm]\n\n if (!algorithmId) {\n throw new Error(`unknown algorithm: ${algorithm}`)\n }\n\n const hash = createHash(algorithm)\n const { promise, resolve, reject } = defer()\n\n const stream = through2(\n (chunk, enc, callback) => {\n hash.update(chunk)\n callback(null, chunk)\n },\n callback => {\n resolve(`$${algorithmId}$$${hash.digest('hex')}`)\n callback()\n }\n ).once('error', reject)\n stream.checksum = promise\n return stream\n}\n\n// Check if the checksum of a readable stream is equal to an expected checksum.\n// The given stream is wrapped in a stream which emits an error event\n// if the computed checksum is not equal to the expected checksum.\nexport const validChecksumOfReadStream = (stream, expectedChecksum) => {\n const algorithmId = expectedChecksum.slice(1, expectedChecksum.indexOf('$', 1))\n\n if (!algorithmId) {\n throw new Error(`unknown algorithm: ${algorithmId}`)\n }\n\n const hash = createHash(ID_TO_ALGORITHM[algorithmId])\n\n const wrapper = stream.pipe(\n through2(\n { highWaterMark: 0 },\n (chunk, enc, callback) => {\n hash.update(chunk)\n callback(null, chunk)\n },\n callback => {\n const checksum = `$${algorithmId}$$${hash.digest('hex')}`\n\n callback(\n checksum !== expectedChecksum ? new Error(`Bad checksum (${checksum}), expected: ${expectedChecksum}`) : null\n )\n }\n )\n )\n\n stream.on('error', error => wrapper.emit('error', error))\n wrapper.checksumVerified = fromEvent(wrapper, 'end')\n\n return wrapper\n}\n"],"mappings":"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","ignoreList":[]}
|
package/dist/index.js
CHANGED
|
@@ -28,12 +28,15 @@ var _local = _interopRequireDefault(require("./local"));
|
|
|
28
28
|
var _nfs = _interopRequireDefault(require("./nfs"));
|
|
29
29
|
var _s = _interopRequireDefault(require("./s3"));
|
|
30
30
|
var _smb = _interopRequireDefault(require("./smb"));
|
|
31
|
+
var _azure = _interopRequireDefault(require("./azure"));
|
|
31
32
|
var _encryptor = require("./_encryptor");
|
|
32
33
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
33
34
|
const HANDLERS = {
|
|
34
35
|
file: _local.default,
|
|
35
36
|
nfs: _nfs.default,
|
|
36
|
-
s3: _s.default
|
|
37
|
+
s3: _s.default,
|
|
38
|
+
azure: _azure.default,
|
|
39
|
+
azurite: _azure.default
|
|
37
40
|
};
|
|
38
41
|
try {
|
|
39
42
|
_execa.default.sync('mount.cifs', ['-V']);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["_execa","_interopRequireDefault","require","_xoRemoteParser","_local","_nfs","_s","_smb","_encryptor","e","__esModule","default","HANDLERS","file","RemoteHandlerLocal","nfs","RemoteHandlerNfs","s3","RemoteHandlerS3","execa","sync","smb","RemoteHandlerSmb","_","getHandler","remote","rest","Handler","parse","url","type","Error","exports","getSyncedHandler","opts","handler","dispose","forget","value"],"sources":["../src/index.js"],"sourcesContent":["import execa from 'execa'\nimport { parse } from 'xo-remote-parser'\n\nimport RemoteHandlerLocal from './local'\nimport RemoteHandlerNfs from './nfs'\nimport RemoteHandlerS3 from './s3'\nimport RemoteHandlerSmb from './smb'\nexport { DEFAULT_ENCRYPTION_ALGORITHM, UNENCRYPTED_ALGORITHM, isLegacyEncryptionAlgorithm } from './_encryptor'\n\nconst HANDLERS = {\n file: RemoteHandlerLocal,\n nfs: RemoteHandlerNfs,\n s3: RemoteHandlerS3,\n}\n\ntry {\n execa.sync('mount.cifs', ['-V'])\n HANDLERS.smb = RemoteHandlerSmb\n} catch (_) {}\n\nexport const getHandler = (remote, ...rest) => {\n const Handler = HANDLERS[parse(remote.url).type]\n if (!Handler) {\n throw new Error('Unhandled remote type')\n }\n return new Handler(remote, ...rest)\n}\n\nexport const getSyncedHandler = async (...opts) => {\n const handler = getHandler(...opts)\n await handler.sync()\n return {\n dispose: () => handler.forget(),\n value: handler,\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,eAAA,GAAAD,OAAA;AAEA,IAAAE,MAAA,GAAAH,sBAAA,CAAAC,OAAA;AACA,IAAAG,IAAA,GAAAJ,sBAAA,CAAAC,OAAA;AACA,IAAAI,EAAA,GAAAL,sBAAA,CAAAC,OAAA;AACA,IAAAK,IAAA,GAAAN,sBAAA,CAAAC,OAAA;AACA,IAAAM,UAAA,
|
|
1
|
+
{"version":3,"file":"index.js","names":["_execa","_interopRequireDefault","require","_xoRemoteParser","_local","_nfs","_s","_smb","_azure","_encryptor","e","__esModule","default","HANDLERS","file","RemoteHandlerLocal","nfs","RemoteHandlerNfs","s3","RemoteHandlerS3","azure","RemoteHandlerAzure","azurite","execa","sync","smb","RemoteHandlerSmb","_","getHandler","remote","rest","Handler","parse","url","type","Error","exports","getSyncedHandler","opts","handler","dispose","forget","value"],"sources":["../src/index.js"],"sourcesContent":["import execa from 'execa'\nimport { parse } from 'xo-remote-parser'\n\nimport RemoteHandlerLocal from './local'\nimport RemoteHandlerNfs from './nfs'\nimport RemoteHandlerS3 from './s3'\nimport RemoteHandlerSmb from './smb'\nimport RemoteHandlerAzure from './azure'\nexport { DEFAULT_ENCRYPTION_ALGORITHM, UNENCRYPTED_ALGORITHM, isLegacyEncryptionAlgorithm } from './_encryptor'\n\nconst HANDLERS = {\n file: RemoteHandlerLocal,\n nfs: RemoteHandlerNfs,\n s3: RemoteHandlerS3,\n azure: RemoteHandlerAzure,\n azurite: RemoteHandlerAzure,\n}\n\ntry {\n execa.sync('mount.cifs', ['-V'])\n HANDLERS.smb = RemoteHandlerSmb\n} catch (_) {}\n\nexport const getHandler = (remote, ...rest) => {\n const Handler = HANDLERS[parse(remote.url).type]\n if (!Handler) {\n throw new Error('Unhandled remote type')\n }\n return new Handler(remote, ...rest)\n}\n\nexport const getSyncedHandler = async (...opts) => {\n const handler = getHandler(...opts)\n await handler.sync()\n return {\n dispose: () => handler.forget(),\n value: handler,\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,eAAA,GAAAD,OAAA;AAEA,IAAAE,MAAA,GAAAH,sBAAA,CAAAC,OAAA;AACA,IAAAG,IAAA,GAAAJ,sBAAA,CAAAC,OAAA;AACA,IAAAI,EAAA,GAAAL,sBAAA,CAAAC,OAAA;AACA,IAAAK,IAAA,GAAAN,sBAAA,CAAAC,OAAA;AACA,IAAAM,MAAA,GAAAP,sBAAA,CAAAC,OAAA;AACA,IAAAO,UAAA,GAAAP,OAAA;AAA+G,SAAAD,uBAAAS,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAE/G,MAAMG,QAAQ,GAAG;EACfC,IAAI,EAAEC,cAAkB;EACxBC,GAAG,EAAEC,YAAgB;EACrBC,EAAE,EAAEC,UAAe;EACnBC,KAAK,EAAEC,cAAkB;EACzBC,OAAO,EAAED;AACX,CAAC;AAED,IAAI;EACFE,cAAK,CAACC,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,CAAC;EAChCX,QAAQ,CAACY,GAAG,GAAGC,YAAgB;AACjC,CAAC,CAAC,OAAOC,CAAC,EAAE,CAAC;AAEN,MAAMC,UAAU,GAAGA,CAACC,MAAM,EAAE,GAAGC,IAAI,KAAK;EAC7C,MAAMC,OAAO,GAAGlB,QAAQ,CAAC,IAAAmB,qBAAK,EAACH,MAAM,CAACI,GAAG,CAAC,CAACC,IAAI,CAAC;EAChD,IAAI,CAACH,OAAO,EAAE;IACZ,MAAM,IAAII,KAAK,CAAC,uBAAuB,CAAC;EAC1C;EACA,OAAO,IAAIJ,OAAO,CAACF,MAAM,EAAE,GAAGC,IAAI,CAAC;AACrC,CAAC;AAAAM,OAAA,CAAAR,UAAA,GAAAA,UAAA;AAEM,MAAMS,gBAAgB,GAAG,MAAAA,CAAO,GAAGC,IAAI,KAAK;EACjD,MAAMC,OAAO,GAAGX,UAAU,CAAC,GAAGU,IAAI,CAAC;EACnC,MAAMC,OAAO,CAACf,IAAI,CAAC,CAAC;EACpB,OAAO;IACLgB,OAAO,EAAEA,CAAA,KAAMD,OAAO,CAACE,MAAM,CAAC,CAAC;IAC/BC,KAAK,EAAEH;EACT,CAAC;AACH,CAAC;AAAAH,OAAA,CAAAC,gBAAA,GAAAA,gBAAA","ignoreList":[]}
|
package/dist/local.js
CHANGED
|
@@ -50,7 +50,7 @@ class LocalHandler extends _abstract.default {
|
|
|
50
50
|
#addSyncStackTrace;
|
|
51
51
|
#retriesOnEagain;
|
|
52
52
|
constructor(remote, opts = {}) {
|
|
53
|
-
super(remote);
|
|
53
|
+
super(remote, opts);
|
|
54
54
|
this.#addSyncStackTrace = opts.syncStackTraces ?? true ? addSyncStackTrace : dontAddSyncStackTrace;
|
|
55
55
|
this.#retriesOnEagain = {
|
|
56
56
|
delay: 1e3,
|
package/dist/local.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local.js","names":["_strict","_interopRequireDefault","require","_fromCallback","_fsExtra","_properLockfile","_log","_nodeChild_process","_promiseToolbox","_abstract","e","__esModule","default","info","warn","createLogger","addSyncStackTrace","fn","args","stackContainer","Error","apply","error","stack","slice","indexOf","join","DF_RE","df","path","stdout","fromCallback","execFile","lines","trim","split","assert","equal","length","matches","exec","notEqual","size","Number","used","available","dontAddSyncStackTrace","LocalHandler","RemoteHandlerAbstract","retriesOnEagain","constructor","remote","opts","syncStackTraces","delay","retries","when","code","type","getRealPath","_remote","getFilePath","file","_closeFile","fd","fs","close","_copy","oldPath","newPath","copy","_createReadStream","options","stream","createReadStream","fromEvent","autoClose","_createWriteStream","createWriteStream","_getInfo","Object","keys","forEach","key","isNaN","_getSize","stats","stat","_list","dir","readdir","_lock","acquire","lockfile","lock","bind","undefined","onCompromised","release","_mkdir","mode","mkdir","_openFile","flags","open","_read","buffer","position","needsClose","read","_readFile","flag","filePath","retry","readFile","_rename","rename","_rmdir","rmdir","_sync","ensureDir","access","R_OK","W_OK","_truncate","len","truncate","_unlink","unlink","_writeFd","write","_writeFile","data","writeFile","exports"],"sources":["../src/local.js"],"sourcesContent":["import assert from 'node:assert/strict'\nimport fromCallback from 'promise-toolbox/fromCallback'\nimport fs from 'fs-extra'\nimport lockfile from 'proper-lockfile'\nimport { createLogger } from '@xen-orchestra/log'\nimport { execFile } from 'node:child_process'\nimport { fromEvent, retry } from 'promise-toolbox'\n\nimport RemoteHandlerAbstract from './abstract'\n\nconst { info, warn } = createLogger('xo:fs:local')\n\n// save current stack trace and add it to any rejected error\n//\n// This is especially useful when the resolution is separate from the initial\n// call, which is often the case with RPC libs.\n//\n// There is a perf impact and it should be avoided in production.\nasync function addSyncStackTrace(fn, ...args) {\n const stackContainer = new Error()\n try {\n return await fn.apply(this, args)\n } catch (error) {\n let { stack } = stackContainer\n\n // remove first line which does not contain stack information, simply `Error`\n stack = stack.slice(stack.indexOf('\\n') + 1)\n\n error.stack = [error.stack, 'From:', stack].join('\\n')\n throw error\n }\n}\n\n// $filesystem $size $used $available_bytes $capacity $mountpoint\nconst DF_RE = /^(.+?)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d{1,3})%\\s+(.+)$/\n\nasync function df(path) {\n const stdout = await fromCallback(execFile, 'df', ['-kP', path])\n const lines = stdout.trim().split('\\n')\n assert.equal(lines.length, 2) // headers + first line\n const matches = DF_RE.exec(lines[1])\n assert.notEqual(matches, null)\n return {\n size: Number(matches[2]) * 1024,\n used: Number(matches[3]) * 1024,\n available: Number(matches[4]) * 1024,\n }\n}\n\nfunction dontAddSyncStackTrace(fn, ...args) {\n return fn.apply(this, args)\n}\n\nexport default class LocalHandler extends RemoteHandlerAbstract {\n #addSyncStackTrace\n #retriesOnEagain\n\n constructor(remote, opts = {}) {\n super(remote)\n\n this.#addSyncStackTrace = (opts.syncStackTraces ?? true) ? addSyncStackTrace : dontAddSyncStackTrace\n this.#retriesOnEagain = {\n delay: 1e3,\n retries: 9,\n ...opts.retriesOnEagain,\n when: {\n code: 'EAGAIN',\n },\n }\n }\n get type() {\n return 'file'\n }\n\n getRealPath() {\n return this._remote.path\n }\n\n getFilePath(file) {\n return this.getRealPath() + file\n }\n\n async _closeFile(fd) {\n return this.#addSyncStackTrace(fs.close, fd)\n }\n\n async _copy(oldPath, newPath) {\n return this.#addSyncStackTrace(fs.copy, this.getFilePath(oldPath), this.getFilePath(newPath))\n }\n\n async _createReadStream(file, options) {\n if (typeof file === 'string') {\n const stream = fs.createReadStream(this.getFilePath(file), options)\n await this.#addSyncStackTrace(fromEvent, stream, 'open')\n return stream\n }\n return fs.createReadStream('', {\n autoClose: false,\n ...options,\n fd: file.fd,\n })\n }\n\n async _createWriteStream(file, options) {\n if (typeof file === 'string') {\n const stream = fs.createWriteStream(this.getFilePath(file), options)\n await this.#addSyncStackTrace(fromEvent, stream, 'open')\n return stream\n }\n return fs.createWriteStream('', {\n autoClose: false,\n ...options,\n fd: file.fd,\n })\n }\n\n async _getInfo() {\n // df.file() resolves with an object with the following properties:\n // filesystem, type, size, used, available, capacity and mountpoint.\n // size, used, available and capacity may be `NaN` so we remove any `NaN`\n // value from the object.\n const info = await df(this.getFilePath('/'))\n Object.keys(info).forEach(key => {\n if (Number.isNaN(info[key])) {\n delete info[key]\n }\n })\n\n return info\n }\n\n async _getSize(file) {\n const stats = await this.#addSyncStackTrace(fs.stat, this.getFilePath(typeof file === 'string' ? file : file.path))\n return stats.size\n }\n\n async _list(dir) {\n return this.#addSyncStackTrace(fs.readdir, this.getFilePath(dir))\n }\n\n async _lock(path) {\n const acquire = lockfile.lock.bind(undefined, this.getFilePath(path), {\n async onCompromised(error) {\n warn('lock compromised', { error })\n try {\n release = await acquire()\n info('compromised lock was reacquired')\n } catch (error) {\n warn('compromised lock could not be reacquired', { error })\n }\n },\n })\n\n let release = await this.#addSyncStackTrace(acquire)\n\n return async () => {\n try {\n await this.#addSyncStackTrace(release)\n } catch (error) {\n warn('lock could not be released', { error })\n }\n }\n }\n\n _mkdir(dir, { mode }) {\n return this.#addSyncStackTrace(fs.mkdir, this.getFilePath(dir), { mode })\n }\n\n async _openFile(path, flags) {\n return this.#addSyncStackTrace(fs.open, this.getFilePath(path), flags)\n }\n\n async _read(file, buffer, position) {\n const needsClose = typeof file === 'string'\n file = needsClose ? await this.#addSyncStackTrace(fs.open, this.getFilePath(file), 'r') : file.fd\n try {\n return await this.#addSyncStackTrace(\n fs.read,\n file,\n buffer,\n 0,\n buffer.length,\n position === undefined ? null : position\n )\n } finally {\n if (needsClose) {\n await this.#addSyncStackTrace(fs.close, file)\n }\n }\n }\n\n async _readFile(file, { flags, ...options } = {}) {\n // contrary to createReadStream, readFile expect singular `flag`\n if (flags !== undefined) {\n options.flag = flags\n }\n\n const filePath = this.getFilePath(file)\n return await this.#addSyncStackTrace(retry, () => fs.readFile(filePath, options), this.#retriesOnEagain)\n }\n\n async _rename(oldPath, newPath) {\n return this.#addSyncStackTrace(fs.rename, this.getFilePath(oldPath), this.getFilePath(newPath))\n }\n\n async _rmdir(dir) {\n return this.#addSyncStackTrace(fs.rmdir, this.getFilePath(dir))\n }\n\n async _sync() {\n const path = this.getRealPath('/')\n await this.#addSyncStackTrace(fs.ensureDir, path)\n await this.#addSyncStackTrace(fs.access, path, fs.R_OK | fs.W_OK)\n }\n\n _truncate(file, len) {\n return this.#addSyncStackTrace(fs.truncate, this.getFilePath(file), len)\n }\n\n async _unlink(file) {\n const filePath = this.getFilePath(file)\n return await this.#addSyncStackTrace(retry, () => fs.unlink(filePath), this.#retriesOnEagain)\n }\n\n _writeFd(file, buffer, position) {\n return this.#addSyncStackTrace(fs.write, file.fd, buffer, 0, buffer.length, position)\n }\n\n _writeFile(file, data, { flags }) {\n return this.#addSyncStackTrace(fs.writeFile, this.getFilePath(file), data, { flag: flags })\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"local.js","names":["_strict","_interopRequireDefault","require","_fromCallback","_fsExtra","_properLockfile","_log","_nodeChild_process","_promiseToolbox","_abstract","e","__esModule","default","info","warn","createLogger","addSyncStackTrace","fn","args","stackContainer","Error","apply","error","stack","slice","indexOf","join","DF_RE","df","path","stdout","fromCallback","execFile","lines","trim","split","assert","equal","length","matches","exec","notEqual","size","Number","used","available","dontAddSyncStackTrace","LocalHandler","RemoteHandlerAbstract","retriesOnEagain","constructor","remote","opts","syncStackTraces","delay","retries","when","code","type","getRealPath","_remote","getFilePath","file","_closeFile","fd","fs","close","_copy","oldPath","newPath","copy","_createReadStream","options","stream","createReadStream","fromEvent","autoClose","_createWriteStream","createWriteStream","_getInfo","Object","keys","forEach","key","isNaN","_getSize","stats","stat","_list","dir","readdir","_lock","acquire","lockfile","lock","bind","undefined","onCompromised","release","_mkdir","mode","mkdir","_openFile","flags","open","_read","buffer","position","needsClose","read","_readFile","flag","filePath","retry","readFile","_rename","rename","_rmdir","rmdir","_sync","ensureDir","access","R_OK","W_OK","_truncate","len","truncate","_unlink","unlink","_writeFd","write","_writeFile","data","writeFile","exports"],"sources":["../src/local.js"],"sourcesContent":["import assert from 'node:assert/strict'\nimport fromCallback from 'promise-toolbox/fromCallback'\nimport fs from 'fs-extra'\nimport lockfile from 'proper-lockfile'\nimport { createLogger } from '@xen-orchestra/log'\nimport { execFile } from 'node:child_process'\nimport { fromEvent, retry } from 'promise-toolbox'\n\nimport RemoteHandlerAbstract from './abstract'\n\nconst { info, warn } = createLogger('xo:fs:local')\n\n// save current stack trace and add it to any rejected error\n//\n// This is especially useful when the resolution is separate from the initial\n// call, which is often the case with RPC libs.\n//\n// There is a perf impact and it should be avoided in production.\nasync function addSyncStackTrace(fn, ...args) {\n const stackContainer = new Error()\n try {\n return await fn.apply(this, args)\n } catch (error) {\n let { stack } = stackContainer\n\n // remove first line which does not contain stack information, simply `Error`\n stack = stack.slice(stack.indexOf('\\n') + 1)\n\n error.stack = [error.stack, 'From:', stack].join('\\n')\n throw error\n }\n}\n\n// $filesystem $size $used $available_bytes $capacity $mountpoint\nconst DF_RE = /^(.+?)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d{1,3})%\\s+(.+)$/\n\nasync function df(path) {\n const stdout = await fromCallback(execFile, 'df', ['-kP', path])\n const lines = stdout.trim().split('\\n')\n assert.equal(lines.length, 2) // headers + first line\n const matches = DF_RE.exec(lines[1])\n assert.notEqual(matches, null)\n return {\n size: Number(matches[2]) * 1024,\n used: Number(matches[3]) * 1024,\n available: Number(matches[4]) * 1024,\n }\n}\n\nfunction dontAddSyncStackTrace(fn, ...args) {\n return fn.apply(this, args)\n}\n\nexport default class LocalHandler extends RemoteHandlerAbstract {\n #addSyncStackTrace\n #retriesOnEagain\n\n constructor(remote, opts = {}) {\n super(remote, opts)\n\n this.#addSyncStackTrace = (opts.syncStackTraces ?? true) ? addSyncStackTrace : dontAddSyncStackTrace\n this.#retriesOnEagain = {\n delay: 1e3,\n retries: 9,\n ...opts.retriesOnEagain,\n when: {\n code: 'EAGAIN',\n },\n }\n }\n get type() {\n return 'file'\n }\n\n getRealPath() {\n return this._remote.path\n }\n\n getFilePath(file) {\n return this.getRealPath() + file\n }\n\n async _closeFile(fd) {\n return this.#addSyncStackTrace(fs.close, fd)\n }\n\n async _copy(oldPath, newPath) {\n return this.#addSyncStackTrace(fs.copy, this.getFilePath(oldPath), this.getFilePath(newPath))\n }\n\n async _createReadStream(file, options) {\n if (typeof file === 'string') {\n const stream = fs.createReadStream(this.getFilePath(file), options)\n await this.#addSyncStackTrace(fromEvent, stream, 'open')\n return stream\n }\n return fs.createReadStream('', {\n autoClose: false,\n ...options,\n fd: file.fd,\n })\n }\n\n async _createWriteStream(file, options) {\n if (typeof file === 'string') {\n const stream = fs.createWriteStream(this.getFilePath(file), options)\n await this.#addSyncStackTrace(fromEvent, stream, 'open')\n return stream\n }\n return fs.createWriteStream('', {\n autoClose: false,\n ...options,\n fd: file.fd,\n })\n }\n\n async _getInfo() {\n // df.file() resolves with an object with the following properties:\n // filesystem, type, size, used, available, capacity and mountpoint.\n // size, used, available and capacity may be `NaN` so we remove any `NaN`\n // value from the object.\n const info = await df(this.getFilePath('/'))\n Object.keys(info).forEach(key => {\n if (Number.isNaN(info[key])) {\n delete info[key]\n }\n })\n\n return info\n }\n\n async _getSize(file) {\n const stats = await this.#addSyncStackTrace(fs.stat, this.getFilePath(typeof file === 'string' ? file : file.path))\n return stats.size\n }\n\n async _list(dir) {\n return this.#addSyncStackTrace(fs.readdir, this.getFilePath(dir))\n }\n\n async _lock(path) {\n const acquire = lockfile.lock.bind(undefined, this.getFilePath(path), {\n async onCompromised(error) {\n warn('lock compromised', { error })\n try {\n release = await acquire()\n info('compromised lock was reacquired')\n } catch (error) {\n warn('compromised lock could not be reacquired', { error })\n }\n },\n })\n\n let release = await this.#addSyncStackTrace(acquire)\n\n return async () => {\n try {\n await this.#addSyncStackTrace(release)\n } catch (error) {\n warn('lock could not be released', { error })\n }\n }\n }\n\n _mkdir(dir, { mode }) {\n return this.#addSyncStackTrace(fs.mkdir, this.getFilePath(dir), { mode })\n }\n\n async _openFile(path, flags) {\n return this.#addSyncStackTrace(fs.open, this.getFilePath(path), flags)\n }\n\n async _read(file, buffer, position) {\n const needsClose = typeof file === 'string'\n file = needsClose ? await this.#addSyncStackTrace(fs.open, this.getFilePath(file), 'r') : file.fd\n try {\n return await this.#addSyncStackTrace(\n fs.read,\n file,\n buffer,\n 0,\n buffer.length,\n position === undefined ? null : position\n )\n } finally {\n if (needsClose) {\n await this.#addSyncStackTrace(fs.close, file)\n }\n }\n }\n\n async _readFile(file, { flags, ...options } = {}) {\n // contrary to createReadStream, readFile expect singular `flag`\n if (flags !== undefined) {\n options.flag = flags\n }\n\n const filePath = this.getFilePath(file)\n return await this.#addSyncStackTrace(retry, () => fs.readFile(filePath, options), this.#retriesOnEagain)\n }\n\n async _rename(oldPath, newPath) {\n return this.#addSyncStackTrace(fs.rename, this.getFilePath(oldPath), this.getFilePath(newPath))\n }\n\n async _rmdir(dir) {\n return this.#addSyncStackTrace(fs.rmdir, this.getFilePath(dir))\n }\n\n async _sync() {\n const path = this.getRealPath('/')\n await this.#addSyncStackTrace(fs.ensureDir, path)\n await this.#addSyncStackTrace(fs.access, path, fs.R_OK | fs.W_OK)\n }\n\n _truncate(file, len) {\n return this.#addSyncStackTrace(fs.truncate, this.getFilePath(file), len)\n }\n\n async _unlink(file) {\n const filePath = this.getFilePath(file)\n return await this.#addSyncStackTrace(retry, () => fs.unlink(filePath), this.#retriesOnEagain)\n }\n\n _writeFd(file, buffer, position) {\n return this.#addSyncStackTrace(fs.write, file.fd, buffer, 0, buffer.length, position)\n }\n\n _writeFile(file, data, { flags }) {\n return this.#addSyncStackTrace(fs.writeFile, this.getFilePath(file), data, { flag: flags })\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
package/dist/s3.js
CHANGED
|
@@ -18,7 +18,6 @@ var _guessAwsRegion = _interopRequireDefault(require("./_guessAwsRegion.js"));
|
|
|
18
18
|
var _abstract = _interopRequireDefault(require("./abstract"));
|
|
19
19
|
var _path = require("./path");
|
|
20
20
|
var _asyncEach = require("@vates/async-each");
|
|
21
|
-
var _promiseToolbox = require("promise-toolbox");
|
|
22
21
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
23
22
|
const MAX_PART_SIZE = 1024 * 1024 * 1024 * 5;
|
|
24
23
|
const MAX_PART_NUMBER = 10000;
|
|
@@ -33,7 +32,7 @@ class S3Handler extends _abstract.default {
|
|
|
33
32
|
#dir;
|
|
34
33
|
#s3;
|
|
35
34
|
constructor(remote, _opts) {
|
|
36
|
-
super(remote);
|
|
35
|
+
super(remote, _opts);
|
|
37
36
|
const {
|
|
38
37
|
allowUnauthorized,
|
|
39
38
|
host,
|
|
@@ -69,25 +68,6 @@ class S3Handler extends _abstract.default {
|
|
|
69
68
|
const parts = (0, _path.split)(path);
|
|
70
69
|
this.#bucket = parts.shift();
|
|
71
70
|
this.#dir = (0, _path.join)(...parts);
|
|
72
|
-
const WITH_RETRY = ['_closeFile', '_copy', '_getInfo', '_getSize', '_list', '_mkdir', '_openFile', '_outputFile', '_read', '_readFile', '_rename', '_rmdir', '_truncate', '_unlink', '_write', '_writeFile'];
|
|
73
|
-
WITH_RETRY.forEach(functionName => {
|
|
74
|
-
if (this[functionName] !== undefined) {
|
|
75
|
-
this[functionName] = _promiseToolbox.pRetry.wrap(this[functionName], {
|
|
76
|
-
delays: [100, 200, 500, 1000, 2000],
|
|
77
|
-
when: err => !['EEXIST', 'EISDIR', 'ENOTEMPTY', 'ENOENT', 'ENOTDIR', 'EISDIR'].includes(err === null || err === void 0 ? void 0 : err.code),
|
|
78
|
-
onRetry(error) {
|
|
79
|
-
var _this$arguments;
|
|
80
|
-
warn('retrying method on fs ', {
|
|
81
|
-
method: functionName,
|
|
82
|
-
attemptNumber: this.attemptNumber,
|
|
83
|
-
delay: this.delay,
|
|
84
|
-
error,
|
|
85
|
-
file: (_this$arguments = this.arguments) === null || _this$arguments === void 0 ? void 0 : _this$arguments[0]
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
71
|
}
|
|
92
72
|
get type() {
|
|
93
73
|
return 's3';
|
package/dist/s3.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"s3.js","names":["_clientS","require","_libStorage","_nodeHttpHandler","_middlewareApplyBodyChecksum","_http","_https","_log","_stream","_xoRemoteParser","_copyStreamToBuffer","_interopRequireDefault","_guessAwsRegion","_abstract","_path","_asyncEach","_promiseToolbox","e","__esModule","default","MAX_PART_SIZE","MAX_PART_NUMBER","MIN_PART_SIZE","debug","info","warn","createLogger","S3Handler","RemoteHandlerAbstract","bucket","dir","s3","constructor","remote","_opts","allowUnauthorized","host","path","username","password","protocol","region","guessAwsRegion","parse","url","S3Client","apiVersion","endpoint","forcePathStyle","credentials","accessKeyId","secretAccessKey","tls","requestHandler","NodeHttpHandler","socketTimeout","httpAgent","HttpAgent","keepAlive","httpsAgent","HttpsAgent","rejectUnauthorized","requestChecksumCalculation","responseChecksumValidation","parts","split","shift","join","WITH_RETRY","forEach","functionName","undefined","pRetry","wrap","delays","when","err","includes","code","onRetry","error","_this$arguments","method","attemptNumber","delay","file","arguments","type","makeCopySource","#makeCopySource","makeKey","#makeKey","makePrefix","#makePrefix","prefix","createParams","#createParams","Bucket","Key","multipartCopy","#multipartCopy","oldPath","newPath","size","_getSize","CopySource","multipartParams","send","CreateMultipartUploadCommand","start","partNumber","length","upload","UploadPartCopyCommand","CopySourceRange","Math","min","PartNumber","push","ETag","CopyPartResult","CompleteMultipartUploadCommand","MultipartUpload","Parts","AbortMultipartUploadCommand","_copy","CopyObjectCommand","name","Error","cause","isNotEmptyDir","#isNotEmptyDir","_result$Contents","result","ListObjectsV2Command","MaxKeys","Prefix","Contents","isFile","#isFile","HeadObjectCommand","_outputStream","input","streamLength","maxStreamLength","validator","partSize","max","ceil","readCounter","MAX_SIZE","streamCutter","Transform","transform","chunk","encoding","callback","Body","PassThrough","pipeline","Upload","client","params","leavePartsOnError","done","call","__unlink","_writeFile","data","options","PutObjectCommand","_createReadStream","GetObjectCommand","_unlink","DeleteObjectCommand","_list","NextContinuationToken","uniq","Set","Delimiter","ContinuationToken","IsTruncated","entry","CommonPrefixes","add","basename","_mkdir","_rename","__copy","fd","ContentLength","_read","buffer","position","Range","bytesRead","copyStreamToBuffer","_rmdir","_rmtree","asyncEach","concurrency","_openFile","flags","_closeFile","_sync","_res$ObjectLockConfig","res","GetObjectLockConfigurationCommand","ObjectLockConfiguration","ObjectLockEnabled","middlewareStack","use","getApplyMd5BodyChecksumPlugin","config","$metadata","httpStatusCode","Code","useVhdDirectory","exports"],"sources":["../src/s3.js"],"sourcesContent":["import {\n AbortMultipartUploadCommand,\n CompleteMultipartUploadCommand,\n CopyObjectCommand,\n CreateMultipartUploadCommand,\n DeleteObjectCommand,\n GetObjectCommand,\n GetObjectLockConfigurationCommand,\n HeadObjectCommand,\n ListObjectsV2Command,\n PutObjectCommand,\n S3Client,\n UploadPartCopyCommand,\n} from '@aws-sdk/client-s3'\nimport { Upload } from '@aws-sdk/lib-storage'\nimport { NodeHttpHandler } from '@aws-sdk/node-http-handler'\nimport { getApplyMd5BodyChecksumPlugin } from '@aws-sdk/middleware-apply-body-checksum'\nimport { Agent as HttpAgent } from 'http'\nimport { Agent as HttpsAgent } from 'https'\nimport { createLogger } from '@xen-orchestra/log'\nimport { PassThrough, Transform, pipeline } from 'stream'\nimport { parse } from 'xo-remote-parser'\nimport copyStreamToBuffer from './_copyStreamToBuffer.js'\nimport guessAwsRegion from './_guessAwsRegion.js'\nimport RemoteHandlerAbstract from './abstract'\nimport { basename, join, split } from './path'\nimport { asyncEach } from '@vates/async-each'\nimport { pRetry } from 'promise-toolbox'\n\n// endpoints https://docs.aws.amazon.com/general/latest/gr/s3.html\n\n// limits: https://docs.aws.amazon.com/AmazonS3/latest/dev/qfacts.html\nconst MAX_PART_SIZE = 1024 * 1024 * 1024 * 5 // 5GB\nconst MAX_PART_NUMBER = 10000\nconst MIN_PART_SIZE = 5 * 1024 * 1024\nconst { debug, info, warn } = createLogger('xo:fs:s3')\n\nexport default class S3Handler extends RemoteHandlerAbstract {\n #bucket\n #dir\n #s3\n\n constructor(remote, _opts) {\n super(remote)\n const {\n allowUnauthorized,\n host,\n path,\n username,\n password,\n protocol,\n region = guessAwsRegion(host),\n } = parse(remote.url)\n\n this.#s3 = new S3Client({\n apiVersion: '2006-03-01',\n endpoint: `${protocol}://${host}`,\n forcePathStyle: true,\n credentials: {\n accessKeyId: username,\n secretAccessKey: password,\n },\n tls: protocol === 'https',\n region,\n requestHandler: new NodeHttpHandler({\n socketTimeout: 600000,\n httpAgent: new HttpAgent({\n keepAlive: true,\n }),\n httpsAgent: new HttpsAgent({\n rejectUnauthorized: !allowUnauthorized,\n keepAlive: true,\n }),\n }),\n // from https://github.com/aws/aws-sdk-js-v3/issues/6810\n // some non AWS services like backblaze or cloudflare don't expect the new headers\n requestChecksumCalculation: 'WHEN_REQUIRED',\n responseChecksumValidation: 'WHEN_REQUIRED',\n })\n\n const parts = split(path)\n this.#bucket = parts.shift()\n this.#dir = join(...parts)\n const WITH_RETRY = [\n '_closeFile',\n '_copy',\n '_getInfo',\n '_getSize',\n '_list',\n '_mkdir',\n '_openFile',\n '_outputFile',\n '_read',\n '_readFile',\n '_rename',\n '_rmdir',\n '_truncate',\n '_unlink',\n '_write',\n '_writeFile',\n ]\n WITH_RETRY.forEach(functionName => {\n if (this[functionName] !== undefined) {\n // adding the retry on the top level mtehod won't\n // cover when _functionName are called internally\n this[functionName] = pRetry.wrap(this[functionName], {\n delays: [100, 200, 500, 1000, 2000],\n // these errors should not change on retry\n when: err => !['EEXIST', 'EISDIR', 'ENOTEMPTY', 'ENOENT', 'ENOTDIR', 'EISDIR'].includes(err?.code),\n onRetry(error) {\n warn('retrying method on fs ', {\n method: functionName,\n attemptNumber: this.attemptNumber,\n delay: this.delay,\n error,\n file: this.arguments?.[0],\n })\n },\n })\n }\n })\n }\n\n get type() {\n return 's3'\n }\n\n #makeCopySource(path) {\n return join(this.#bucket, this.#dir, path)\n }\n\n #makeKey(file) {\n return join(this.#dir, file)\n }\n\n #makePrefix(dir) {\n const prefix = join(this.#dir, dir, '/')\n\n // no prefix for root\n if (prefix !== './') {\n return prefix\n }\n }\n\n #createParams(file) {\n return { Bucket: this.#bucket, Key: this.#makeKey(file) }\n }\n\n async #multipartCopy(oldPath, newPath) {\n const size = await this._getSize(oldPath)\n const CopySource = this.#makeCopySource(oldPath)\n const multipartParams = await this.#s3.send(new CreateMultipartUploadCommand({ ...this.#createParams(newPath) }))\n try {\n const parts = []\n let start = 0\n while (start < size) {\n const partNumber = parts.length + 1\n const upload = await this.#s3.send(\n new UploadPartCopyCommand({\n ...multipartParams,\n CopySource,\n CopySourceRange: `bytes=${start}-${Math.min(start + MAX_PART_SIZE, size) - 1}`,\n PartNumber: partNumber,\n })\n )\n parts.push({ ETag: upload.CopyPartResult.ETag, PartNumber: partNumber })\n start += MAX_PART_SIZE\n }\n await this.#s3.send(\n new CompleteMultipartUploadCommand({\n ...multipartParams,\n MultipartUpload: { Parts: parts },\n })\n )\n } catch (e) {\n await this.#s3.send(new AbortMultipartUploadCommand(multipartParams))\n throw e\n }\n }\n\n async _copy(oldPath, newPath) {\n const CopySource = this.#makeCopySource(oldPath)\n try {\n await this.#s3.send(\n new CopyObjectCommand({\n ...this.#createParams(newPath),\n CopySource,\n })\n )\n } catch (e) {\n // object > 5GB must be copied part by part\n if (e.name === 'EntityTooLarge') {\n return this.#multipartCopy(oldPath, newPath)\n }\n // normalize this error code\n if (e.name === 'NoSuchKey') {\n const error = new Error(`ENOENT: no such file or directory '${oldPath}'`)\n error.cause = e\n error.code = 'ENOENT'\n error.path = oldPath\n throw error\n }\n throw e\n }\n }\n\n async #isNotEmptyDir(path) {\n const result = await this.#s3.send(\n new ListObjectsV2Command({\n Bucket: this.#bucket,\n MaxKeys: 1,\n Prefix: this.#makePrefix(path),\n })\n )\n return result.Contents?.length > 0\n }\n\n async #isFile(path) {\n try {\n await this.#s3.send(new HeadObjectCommand(this.#createParams(path)))\n return true\n } catch (error) {\n if (error.name === 'NotFound') {\n return false\n }\n throw error\n }\n }\n\n async _outputStream(path, input, { streamLength, maxStreamLength = streamLength, validator }) {\n // S3 storage is limited to 10K part, each part is limited to 5GB. And the total upload must be smaller than 5TB\n // a bigger partSize increase the memory consumption of aws/lib-storage exponentially\n let partSize\n if (maxStreamLength === undefined) {\n warn(`Writing ${path} to a S3 remote without a max size set will cut it to 50GB`, { path })\n partSize = MIN_PART_SIZE // min size for S3\n } else {\n partSize = Math.min(Math.max(Math.ceil(maxStreamLength / MAX_PART_NUMBER), MIN_PART_SIZE), MAX_PART_SIZE)\n }\n\n // ensure we don't try to upload a stream to big for this partSize\n let readCounter = 0\n const MAX_SIZE = MAX_PART_NUMBER * partSize\n const streamCutter = new Transform({\n transform(chunk, encoding, callback) {\n readCounter += chunk.length\n if (readCounter > MAX_SIZE) {\n callback(new Error(`read ${readCounter} bytes, maximum size allowed is ${MAX_SIZE} `))\n } else {\n callback(null, chunk)\n }\n },\n })\n\n // Workaround for \"ReferenceError: ReadableStream is not defined\"\n // https://github.com/aws/aws-sdk-js-v3/issues/2522\n const Body = new PassThrough()\n pipeline(input, streamCutter, Body, () => {})\n\n const upload = new Upload({\n client: this.#s3,\n params: {\n ...this.#createParams(path),\n Body,\n },\n partSize,\n leavePartsOnError: false,\n })\n\n await upload.done()\n\n if (validator !== undefined) {\n try {\n await validator.call(this, path)\n } catch (error) {\n await this.__unlink(path)\n throw error\n }\n }\n }\n\n async _writeFile(file, data, options) {\n return this.#s3.send(\n new PutObjectCommand({\n ...this.#createParams(file),\n Body: data,\n })\n )\n }\n\n async _createReadStream(path, options) {\n try {\n return (await this.#s3.send(new GetObjectCommand(this.#createParams(path)))).Body\n } catch (e) {\n if (e.name === 'NoSuchKey') {\n const error = new Error(`ENOENT: no such file '${path}'`)\n error.code = 'ENOENT'\n error.path = path\n throw error\n }\n throw e\n }\n }\n\n async _unlink(path) {\n await this.#s3.send(new DeleteObjectCommand(this.#createParams(path)))\n\n if (await this.#isNotEmptyDir(path)) {\n const error = new Error(`EISDIR: illegal operation on a directory, unlink '${path}'`)\n error.code = 'EISDIR'\n error.path = path\n throw error\n }\n }\n\n async _list(dir) {\n let NextContinuationToken\n const uniq = new Set()\n const Prefix = this.#makePrefix(dir)\n\n do {\n const result = await this.#s3.send(\n new ListObjectsV2Command({\n Bucket: this.#bucket,\n Prefix,\n Delimiter: '/',\n // will only return path until delimiters\n ContinuationToken: NextContinuationToken,\n })\n )\n\n if (result.IsTruncated) {\n warn(`need pagination to browse the directory ${dir} completely`)\n NextContinuationToken = result.NextContinuationToken\n } else {\n NextContinuationToken = undefined\n }\n\n // subdirectories\n for (const entry of result.CommonPrefixes ?? []) {\n uniq.add(basename(entry.Prefix))\n }\n\n // files\n for (const entry of result.Contents ?? []) {\n uniq.add(basename(entry.Key))\n }\n } while (NextContinuationToken !== undefined)\n\n return [...uniq]\n }\n\n async _mkdir(path) {\n if (await this.#isFile(path)) {\n const error = new Error(`ENOTDIR: file already exists, mkdir '${path}'`)\n error.code = 'ENOTDIR'\n error.path = path\n throw error\n }\n // nothing to do, directories do not exist, they are part of the files' path\n }\n\n // s3 doesn't have a rename operation, so copy + delete source\n async _rename(oldPath, newPath) {\n await this.__copy(oldPath, newPath)\n await this.#s3.send(new DeleteObjectCommand(this.#createParams(oldPath)))\n }\n\n async _getSize(file) {\n if (typeof file !== 'string') {\n file = file.fd\n }\n const result = await this.#s3.send(new HeadObjectCommand(this.#createParams(file)))\n return +result.ContentLength\n }\n\n async _read(file, buffer, position = 0) {\n if (typeof file !== 'string') {\n file = file.fd\n }\n const params = this.#createParams(file)\n params.Range = `bytes=${position}-${position + buffer.length - 1}`\n try {\n const result = await this.#s3.send(new GetObjectCommand(params))\n const bytesRead = await copyStreamToBuffer(result.Body, buffer)\n return { bytesRead, buffer }\n } catch (e) {\n if (e.name === 'NoSuchKey') {\n if (await this.#isNotEmptyDir(file)) {\n const error = new Error(`${file} is a directory`)\n error.code = 'EISDIR'\n error.path = file\n throw error\n }\n }\n throw e\n }\n }\n\n async _rmdir(path) {\n if (await this.#isNotEmptyDir(path)) {\n const error = new Error(`ENOTEMPTY: directory not empty, rmdir '${path}`)\n error.code = 'ENOTEMPTY'\n error.path = path\n throw error\n }\n\n // nothing to do, directories do not exist, they are part of the files' path\n }\n\n // reimplement _rmtree to handle efficiantly path with more than 1000 entries in trees\n // @todo : use parallel processing for unlink\n async _rmtree(path) {\n let NextContinuationToken\n const Prefix = this.#makePrefix(path)\n do {\n const result = await this.#s3.send(\n new ListObjectsV2Command({\n Bucket: this.#bucket,\n Prefix,\n ContinuationToken: NextContinuationToken,\n })\n )\n\n NextContinuationToken = result.IsTruncated ? result.NextContinuationToken : undefined\n await asyncEach(\n result.Contents ?? [],\n async ({ Key }) => {\n // _unlink will add the prefix, but Key contains everything\n // also we don't need to check if we delete a directory, since the list only return files\n await this.#s3.send(\n new DeleteObjectCommand({\n Bucket: this.#bucket,\n Key,\n })\n )\n },\n {\n concurrency: 16,\n }\n )\n } while (NextContinuationToken !== undefined)\n }\n\n async _openFile(path, flags) {\n return path\n }\n\n async _closeFile(fd) {}\n\n async _sync() {\n await super._sync()\n try {\n // if Object Lock is enabled, each upload must come with a contentMD5 header\n // the computation of this md5 is memory-intensive, especially when uploading a stream\n const res = await this.#s3.send(new GetObjectLockConfigurationCommand({ Bucket: this.#bucket }))\n if (res.ObjectLockConfiguration?.ObjectLockEnabled === 'Enabled') {\n // Workaround for https://github.com/aws/aws-sdk-js-v3/issues/2673\n // will automatically add the contentMD5 header to any upload to S3\n debug(`Object Lock is enable, enable content md5 header`)\n this.#s3.middlewareStack.use(getApplyMd5BodyChecksumPlugin(this.#s3.config))\n }\n } catch (error) {\n // maybe the account doesn't have enought privilege to query the object lock configuration\n // be defensive and apply the md5 just in case\n if (error.$metadata.httpStatusCode === 403) {\n info(`s3 user doesnt have enough privilege to check for Object Lock, enable content MD5 header`)\n this.#s3.middlewareStack.use(getApplyMd5BodyChecksumPlugin(this.#s3.config))\n } else if (error.Code === 'ObjectLockConfigurationNotFoundError' || error.$metadata.httpStatusCode === 501) {\n info(`Object lock is not available or not configured, don't add the content MD5 header`)\n } else {\n throw error\n }\n }\n }\n\n useVhdDirectory() {\n return true\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"s3.js","names":["_clientS","require","_libStorage","_nodeHttpHandler","_middlewareApplyBodyChecksum","_http","_https","_log","_stream","_xoRemoteParser","_copyStreamToBuffer","_interopRequireDefault","_guessAwsRegion","_abstract","_path","_asyncEach","e","__esModule","default","MAX_PART_SIZE","MAX_PART_NUMBER","MIN_PART_SIZE","debug","info","warn","createLogger","S3Handler","RemoteHandlerAbstract","bucket","dir","s3","constructor","remote","_opts","allowUnauthorized","host","path","username","password","protocol","region","guessAwsRegion","parse","url","S3Client","apiVersion","endpoint","forcePathStyle","credentials","accessKeyId","secretAccessKey","tls","requestHandler","NodeHttpHandler","socketTimeout","httpAgent","HttpAgent","keepAlive","httpsAgent","HttpsAgent","rejectUnauthorized","requestChecksumCalculation","responseChecksumValidation","parts","split","shift","join","type","makeCopySource","#makeCopySource","makeKey","#makeKey","file","makePrefix","#makePrefix","prefix","createParams","#createParams","Bucket","Key","multipartCopy","#multipartCopy","oldPath","newPath","size","_getSize","CopySource","multipartParams","send","CreateMultipartUploadCommand","start","partNumber","length","upload","UploadPartCopyCommand","CopySourceRange","Math","min","PartNumber","push","ETag","CopyPartResult","CompleteMultipartUploadCommand","MultipartUpload","Parts","AbortMultipartUploadCommand","_copy","CopyObjectCommand","name","error","Error","cause","code","isNotEmptyDir","#isNotEmptyDir","_result$Contents","result","ListObjectsV2Command","MaxKeys","Prefix","Contents","isFile","#isFile","HeadObjectCommand","_outputStream","input","streamLength","maxStreamLength","validator","partSize","undefined","max","ceil","readCounter","MAX_SIZE","streamCutter","Transform","transform","chunk","encoding","callback","Body","PassThrough","pipeline","Upload","client","params","leavePartsOnError","done","call","__unlink","_writeFile","data","options","PutObjectCommand","_createReadStream","GetObjectCommand","_unlink","DeleteObjectCommand","_list","NextContinuationToken","uniq","Set","Delimiter","ContinuationToken","IsTruncated","entry","CommonPrefixes","add","basename","_mkdir","_rename","__copy","fd","ContentLength","_read","buffer","position","Range","bytesRead","copyStreamToBuffer","_rmdir","_rmtree","asyncEach","concurrency","_openFile","flags","_closeFile","_sync","_res$ObjectLockConfig","res","GetObjectLockConfigurationCommand","ObjectLockConfiguration","ObjectLockEnabled","middlewareStack","use","getApplyMd5BodyChecksumPlugin","config","$metadata","httpStatusCode","Code","useVhdDirectory","exports"],"sources":["../src/s3.js"],"sourcesContent":["import {\n AbortMultipartUploadCommand,\n CompleteMultipartUploadCommand,\n CopyObjectCommand,\n CreateMultipartUploadCommand,\n DeleteObjectCommand,\n GetObjectCommand,\n GetObjectLockConfigurationCommand,\n HeadObjectCommand,\n ListObjectsV2Command,\n PutObjectCommand,\n S3Client,\n UploadPartCopyCommand,\n} from '@aws-sdk/client-s3'\nimport { Upload } from '@aws-sdk/lib-storage'\nimport { NodeHttpHandler } from '@aws-sdk/node-http-handler'\nimport { getApplyMd5BodyChecksumPlugin } from '@aws-sdk/middleware-apply-body-checksum'\nimport { Agent as HttpAgent } from 'http'\nimport { Agent as HttpsAgent } from 'https'\nimport { createLogger } from '@xen-orchestra/log'\nimport { PassThrough, Transform, pipeline } from 'stream'\nimport { parse } from 'xo-remote-parser'\nimport copyStreamToBuffer from './_copyStreamToBuffer.js'\nimport guessAwsRegion from './_guessAwsRegion.js'\nimport RemoteHandlerAbstract from './abstract'\nimport { basename, join, split } from './path'\nimport { asyncEach } from '@vates/async-each'\n\n// endpoints https://docs.aws.amazon.com/general/latest/gr/s3.html\n\n// limits: https://docs.aws.amazon.com/AmazonS3/latest/dev/qfacts.html\nconst MAX_PART_SIZE = 1024 * 1024 * 1024 * 5 // 5GB\nconst MAX_PART_NUMBER = 10000\nconst MIN_PART_SIZE = 5 * 1024 * 1024\nconst { debug, info, warn } = createLogger('xo:fs:s3')\n\nexport default class S3Handler extends RemoteHandlerAbstract {\n #bucket\n #dir\n #s3\n\n constructor(remote, _opts) {\n super(remote, _opts)\n const {\n allowUnauthorized,\n host,\n path,\n username,\n password,\n protocol,\n region = guessAwsRegion(host),\n } = parse(remote.url)\n\n this.#s3 = new S3Client({\n apiVersion: '2006-03-01',\n endpoint: `${protocol}://${host}`,\n forcePathStyle: true,\n credentials: {\n accessKeyId: username,\n secretAccessKey: password,\n },\n tls: protocol === 'https',\n region,\n requestHandler: new NodeHttpHandler({\n socketTimeout: 600000,\n httpAgent: new HttpAgent({\n keepAlive: true,\n }),\n httpsAgent: new HttpsAgent({\n rejectUnauthorized: !allowUnauthorized,\n keepAlive: true,\n }),\n }),\n // from https://github.com/aws/aws-sdk-js-v3/issues/6810\n // some non AWS services like backblaze or cloudflare don't expect the new headers\n requestChecksumCalculation: 'WHEN_REQUIRED',\n responseChecksumValidation: 'WHEN_REQUIRED',\n })\n\n const parts = split(path)\n this.#bucket = parts.shift()\n this.#dir = join(...parts)\n }\n\n get type() {\n return 's3'\n }\n\n #makeCopySource(path) {\n return join(this.#bucket, this.#dir, path)\n }\n\n #makeKey(file) {\n return join(this.#dir, file)\n }\n\n #makePrefix(dir) {\n const prefix = join(this.#dir, dir, '/')\n\n // no prefix for root\n if (prefix !== './') {\n return prefix\n }\n }\n\n #createParams(file) {\n return { Bucket: this.#bucket, Key: this.#makeKey(file) }\n }\n\n async #multipartCopy(oldPath, newPath) {\n const size = await this._getSize(oldPath)\n const CopySource = this.#makeCopySource(oldPath)\n const multipartParams = await this.#s3.send(new CreateMultipartUploadCommand({ ...this.#createParams(newPath) }))\n try {\n const parts = []\n let start = 0\n while (start < size) {\n const partNumber = parts.length + 1\n const upload = await this.#s3.send(\n new UploadPartCopyCommand({\n ...multipartParams,\n CopySource,\n CopySourceRange: `bytes=${start}-${Math.min(start + MAX_PART_SIZE, size) - 1}`,\n PartNumber: partNumber,\n })\n )\n parts.push({ ETag: upload.CopyPartResult.ETag, PartNumber: partNumber })\n start += MAX_PART_SIZE\n }\n await this.#s3.send(\n new CompleteMultipartUploadCommand({\n ...multipartParams,\n MultipartUpload: { Parts: parts },\n })\n )\n } catch (e) {\n await this.#s3.send(new AbortMultipartUploadCommand(multipartParams))\n throw e\n }\n }\n\n async _copy(oldPath, newPath) {\n const CopySource = this.#makeCopySource(oldPath)\n try {\n await this.#s3.send(\n new CopyObjectCommand({\n ...this.#createParams(newPath),\n CopySource,\n })\n )\n } catch (e) {\n // object > 5GB must be copied part by part\n if (e.name === 'EntityTooLarge') {\n return this.#multipartCopy(oldPath, newPath)\n }\n // normalize this error code\n if (e.name === 'NoSuchKey') {\n const error = new Error(`ENOENT: no such file or directory '${oldPath}'`)\n error.cause = e\n error.code = 'ENOENT'\n error.path = oldPath\n throw error\n }\n throw e\n }\n }\n\n async #isNotEmptyDir(path) {\n const result = await this.#s3.send(\n new ListObjectsV2Command({\n Bucket: this.#bucket,\n MaxKeys: 1,\n Prefix: this.#makePrefix(path),\n })\n )\n return result.Contents?.length > 0\n }\n\n async #isFile(path) {\n try {\n await this.#s3.send(new HeadObjectCommand(this.#createParams(path)))\n return true\n } catch (error) {\n if (error.name === 'NotFound') {\n return false\n }\n throw error\n }\n }\n\n async _outputStream(path, input, { streamLength, maxStreamLength = streamLength, validator }) {\n // S3 storage is limited to 10K part, each part is limited to 5GB. And the total upload must be smaller than 5TB\n // a bigger partSize increase the memory consumption of aws/lib-storage exponentially\n let partSize\n if (maxStreamLength === undefined) {\n warn(`Writing ${path} to a S3 remote without a max size set will cut it to 50GB`, { path })\n partSize = MIN_PART_SIZE // min size for S3\n } else {\n partSize = Math.min(Math.max(Math.ceil(maxStreamLength / MAX_PART_NUMBER), MIN_PART_SIZE), MAX_PART_SIZE)\n }\n\n // ensure we don't try to upload a stream to big for this partSize\n let readCounter = 0\n const MAX_SIZE = MAX_PART_NUMBER * partSize\n const streamCutter = new Transform({\n transform(chunk, encoding, callback) {\n readCounter += chunk.length\n if (readCounter > MAX_SIZE) {\n callback(new Error(`read ${readCounter} bytes, maximum size allowed is ${MAX_SIZE} `))\n } else {\n callback(null, chunk)\n }\n },\n })\n\n // Workaround for \"ReferenceError: ReadableStream is not defined\"\n // https://github.com/aws/aws-sdk-js-v3/issues/2522\n const Body = new PassThrough()\n pipeline(input, streamCutter, Body, () => {})\n\n const upload = new Upload({\n client: this.#s3,\n params: {\n ...this.#createParams(path),\n Body,\n },\n partSize,\n leavePartsOnError: false,\n })\n\n await upload.done()\n\n if (validator !== undefined) {\n try {\n await validator.call(this, path)\n } catch (error) {\n await this.__unlink(path)\n throw error\n }\n }\n }\n\n async _writeFile(file, data, options) {\n return this.#s3.send(\n new PutObjectCommand({\n ...this.#createParams(file),\n Body: data,\n })\n )\n }\n\n async _createReadStream(path, options) {\n try {\n return (await this.#s3.send(new GetObjectCommand(this.#createParams(path)))).Body\n } catch (e) {\n if (e.name === 'NoSuchKey') {\n const error = new Error(`ENOENT: no such file '${path}'`)\n error.code = 'ENOENT'\n error.path = path\n throw error\n }\n throw e\n }\n }\n\n async _unlink(path) {\n await this.#s3.send(new DeleteObjectCommand(this.#createParams(path)))\n\n if (await this.#isNotEmptyDir(path)) {\n const error = new Error(`EISDIR: illegal operation on a directory, unlink '${path}'`)\n error.code = 'EISDIR'\n error.path = path\n throw error\n }\n }\n\n async _list(dir) {\n let NextContinuationToken\n const uniq = new Set()\n const Prefix = this.#makePrefix(dir)\n\n do {\n const result = await this.#s3.send(\n new ListObjectsV2Command({\n Bucket: this.#bucket,\n Prefix,\n Delimiter: '/',\n // will only return path until delimiters\n ContinuationToken: NextContinuationToken,\n })\n )\n\n if (result.IsTruncated) {\n warn(`need pagination to browse the directory ${dir} completely`)\n NextContinuationToken = result.NextContinuationToken\n } else {\n NextContinuationToken = undefined\n }\n\n // subdirectories\n for (const entry of result.CommonPrefixes ?? []) {\n uniq.add(basename(entry.Prefix))\n }\n\n // files\n for (const entry of result.Contents ?? []) {\n uniq.add(basename(entry.Key))\n }\n } while (NextContinuationToken !== undefined)\n\n return [...uniq]\n }\n\n async _mkdir(path) {\n if (await this.#isFile(path)) {\n const error = new Error(`ENOTDIR: file already exists, mkdir '${path}'`)\n error.code = 'ENOTDIR'\n error.path = path\n throw error\n }\n // nothing to do, directories do not exist, they are part of the files' path\n }\n\n // s3 doesn't have a rename operation, so copy + delete source\n async _rename(oldPath, newPath) {\n await this.__copy(oldPath, newPath)\n await this.#s3.send(new DeleteObjectCommand(this.#createParams(oldPath)))\n }\n\n async _getSize(file) {\n if (typeof file !== 'string') {\n file = file.fd\n }\n const result = await this.#s3.send(new HeadObjectCommand(this.#createParams(file)))\n return +result.ContentLength\n }\n\n async _read(file, buffer, position = 0) {\n if (typeof file !== 'string') {\n file = file.fd\n }\n const params = this.#createParams(file)\n params.Range = `bytes=${position}-${position + buffer.length - 1}`\n try {\n const result = await this.#s3.send(new GetObjectCommand(params))\n const bytesRead = await copyStreamToBuffer(result.Body, buffer)\n return { bytesRead, buffer }\n } catch (e) {\n if (e.name === 'NoSuchKey') {\n if (await this.#isNotEmptyDir(file)) {\n const error = new Error(`${file} is a directory`)\n error.code = 'EISDIR'\n error.path = file\n throw error\n }\n }\n throw e\n }\n }\n\n async _rmdir(path) {\n if (await this.#isNotEmptyDir(path)) {\n const error = new Error(`ENOTEMPTY: directory not empty, rmdir '${path}`)\n error.code = 'ENOTEMPTY'\n error.path = path\n throw error\n }\n\n // nothing to do, directories do not exist, they are part of the files' path\n }\n\n // reimplement _rmtree to handle efficiently path with more than 1000 entries in trees\n // @todo : use parallel processing for unlink\n async _rmtree(path) {\n let NextContinuationToken\n const Prefix = this.#makePrefix(path)\n do {\n const result = await this.#s3.send(\n new ListObjectsV2Command({\n Bucket: this.#bucket,\n Prefix,\n ContinuationToken: NextContinuationToken,\n })\n )\n\n NextContinuationToken = result.IsTruncated ? result.NextContinuationToken : undefined\n await asyncEach(\n result.Contents ?? [],\n async ({ Key }) => {\n // _unlink will add the prefix, but Key contains everything\n // also we don't need to check if we delete a directory, since the list only return files\n await this.#s3.send(\n new DeleteObjectCommand({\n Bucket: this.#bucket,\n Key,\n })\n )\n },\n {\n concurrency: 16,\n }\n )\n } while (NextContinuationToken !== undefined)\n }\n\n async _openFile(path, flags) {\n return path\n }\n\n async _closeFile(fd) {}\n\n async _sync() {\n await super._sync()\n try {\n // if Object Lock is enabled, each upload must come with a contentMD5 header\n // the computation of this md5 is memory-intensive, especially when uploading a stream\n const res = await this.#s3.send(new GetObjectLockConfigurationCommand({ Bucket: this.#bucket }))\n if (res.ObjectLockConfiguration?.ObjectLockEnabled === 'Enabled') {\n // Workaround for https://github.com/aws/aws-sdk-js-v3/issues/2673\n // will automatically add the contentMD5 header to any upload to S3\n debug(`Object Lock is enable, enable content md5 header`)\n this.#s3.middlewareStack.use(getApplyMd5BodyChecksumPlugin(this.#s3.config))\n }\n } catch (error) {\n // maybe the account doesn't have enough privilege to query the object lock configuration\n // be defensive and apply the md5 just in case\n if (error.$metadata.httpStatusCode === 403) {\n info(`s3 user doesnt have enough privilege to check for Object Lock, enable content MD5 header`)\n this.#s3.middlewareStack.use(getApplyMd5BodyChecksumPlugin(this.#s3.config))\n } else if (error.Code === 'ObjectLockConfigurationNotFoundError' || error.$metadata.httpStatusCode === 501) {\n info(`Object lock is not available or not configured, don't add the content MD5 header`)\n } else {\n throw error\n }\n }\n }\n\n useVhdDirectory() {\n return true\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.withTimeout = withTimeout;
|
|
7
|
+
var _log = require("@xen-orchestra/log");
|
|
8
|
+
var _promiseToolbox = require("promise-toolbox");
|
|
9
|
+
const {
|
|
10
|
+
info,
|
|
11
|
+
warn
|
|
12
|
+
} = (0, _log.createLogger)('xo:fs:abstract');
|
|
13
|
+
function withTimeout(fn, timeout, {
|
|
14
|
+
onSuccessAfterTimeout,
|
|
15
|
+
onFailureAfterTimeout
|
|
16
|
+
} = {}) {
|
|
17
|
+
return function (...args) {
|
|
18
|
+
let timeoutHandle;
|
|
19
|
+
let didTimeout = false;
|
|
20
|
+
if (typeof fn !== 'function') {
|
|
21
|
+
throw new TypeError('First argument must be a function');
|
|
22
|
+
}
|
|
23
|
+
const timeoutError = new _promiseToolbox.TimeoutError('Async call timeout limit reached');
|
|
24
|
+
return new Promise((resolve, reject) => {
|
|
25
|
+
timeoutHandle = setTimeout(() => {
|
|
26
|
+
didTimeout = true;
|
|
27
|
+
reject(timeoutError);
|
|
28
|
+
}, timeout);
|
|
29
|
+
const promise = fn.apply(this, args);
|
|
30
|
+
if ((promise === null || promise === void 0 ? void 0 : promise.then) === undefined) {
|
|
31
|
+
throw new Error('Function needs to be asynchronous.');
|
|
32
|
+
}
|
|
33
|
+
promise.then(result => {
|
|
34
|
+
clearTimeout(timeoutHandle);
|
|
35
|
+
if (didTimeout) {
|
|
36
|
+
info('Success after timeout:\n', result);
|
|
37
|
+
onSuccessAfterTimeout === null || onSuccessAfterTimeout === void 0 || onSuccessAfterTimeout(result);
|
|
38
|
+
} else {
|
|
39
|
+
resolve(result);
|
|
40
|
+
}
|
|
41
|
+
}, error => {
|
|
42
|
+
clearTimeout(timeoutHandle);
|
|
43
|
+
if (didTimeout) {
|
|
44
|
+
warn('Failure after timeout:\n', error);
|
|
45
|
+
onFailureAfterTimeout === null || onFailureAfterTimeout === void 0 || onFailureAfterTimeout(error);
|
|
46
|
+
} else {
|
|
47
|
+
reject(error);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","names":["_log","require","_promiseToolbox","info","warn","createLogger","withTimeout","fn","timeout","onSuccessAfterTimeout","onFailureAfterTimeout","args","timeoutHandle","didTimeout","TypeError","timeoutError","TimeoutError","Promise","resolve","reject","setTimeout","promise","apply","then","undefined","Error","result","clearTimeout","error"],"sources":["../src/utils.js"],"sourcesContent":["import { createLogger } from '@xen-orchestra/log'\nimport { TimeoutError } from 'promise-toolbox'\n\nconst { info, warn } = createLogger('xo:fs:abstract')\n\n/**\n * Wraps an asynchronous function with timeout functionality.\n *\n * @template T\n * @param {(...args: any[]) => Promise<T>} fn - The asynchronous function to wrap\n * @param {Object} [options] - Configuration options\n * @param {(result: T) => void} [options.onSuccessAfterTimeout] - Callback invoked if original promise resolves after timeout\n * @param {(error: any) => void} [options.onFailureAfterTimeout] - Callback invoked if original promise rejects after timeout\n * @returns {(...args: any[]) => Promise<T>} A new function that will enforce the timeout\n * @throws {TypeError} If fn is not a function or timeout is not a positive number\n *\n * @example\n * // Basic usage\n * const fnWithTimeout = withTimeout(asyncFunc, 1000)\n * try {\n * const result = await fnWithTimeout()\n * } catch (error) {\n * if (error instanceof TimeoutError) {\n * // Handle timeout\n * }\n * }\n *\n * @example\n * // With callbacks\n * const fnWithTimeout = withTimeout(asyncFunc, 1000, {\n * onSuccessAfterTimeout: (result) => console.log('Late success', result),\n * onFailureAfterTimeout: (error) => console.log('Late failure', error)\n * })\n */\nexport function withTimeout(fn, timeout, { onSuccessAfterTimeout, onFailureAfterTimeout } = {}) {\n return function (...args) {\n let timeoutHandle\n let didTimeout = false\n if (typeof fn !== 'function') {\n throw new TypeError('First argument must be a function')\n }\n const timeoutError = new TimeoutError('Async call timeout limit reached')\n\n return new Promise((resolve, reject) => {\n timeoutHandle = setTimeout(() => {\n didTimeout = true\n reject(timeoutError)\n }, timeout)\n\n // if fn is synchronous and throws an error, it will throw it here\n const promise = fn.apply(this, args)\n if (promise?.then === undefined) {\n throw new Error('Function needs to be asynchronous.')\n }\n promise.then(\n result => {\n clearTimeout(timeoutHandle)\n if (didTimeout) {\n info('Success after timeout:\\n', result)\n onSuccessAfterTimeout?.(result)\n } else {\n resolve(result)\n }\n },\n error => {\n clearTimeout(timeoutHandle)\n if (didTimeout) {\n warn('Failure after timeout:\\n', error)\n onFailureAfterTimeout?.(error)\n } else {\n reject(error)\n }\n }\n )\n })\n }\n}\n"],"mappings":";;;;;;AAAA,IAAAA,IAAA,GAAAC,OAAA;AACA,IAAAC,eAAA,GAAAD,OAAA;AAEA,MAAM;EAAEE,IAAI;EAAEC;AAAK,CAAC,GAAG,IAAAC,iBAAY,EAAC,gBAAgB,CAAC;AA+B9C,SAASC,WAAWA,CAACC,EAAE,EAAEC,OAAO,EAAE;EAAEC,qBAAqB;EAAEC;AAAsB,CAAC,GAAG,CAAC,CAAC,EAAE;EAC9F,OAAO,UAAU,GAAGC,IAAI,EAAE;IACxB,IAAIC,aAAa;IACjB,IAAIC,UAAU,GAAG,KAAK;IACtB,IAAI,OAAON,EAAE,KAAK,UAAU,EAAE;MAC5B,MAAM,IAAIO,SAAS,CAAC,mCAAmC,CAAC;IAC1D;IACA,MAAMC,YAAY,GAAG,IAAIC,4BAAY,CAAC,kCAAkC,CAAC;IAEzE,OAAO,IAAIC,OAAO,CAAC,CAACC,OAAO,EAAEC,MAAM,KAAK;MACtCP,aAAa,GAAGQ,UAAU,CAAC,MAAM;QAC/BP,UAAU,GAAG,IAAI;QACjBM,MAAM,CAACJ,YAAY,CAAC;MACtB,CAAC,EAAEP,OAAO,CAAC;MAGX,MAAMa,OAAO,GAAGd,EAAE,CAACe,KAAK,CAAC,IAAI,EAAEX,IAAI,CAAC;MACpC,IAAI,CAAAU,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEE,IAAI,MAAKC,SAAS,EAAE;QAC/B,MAAM,IAAIC,KAAK,CAAC,oCAAoC,CAAC;MACvD;MACAJ,OAAO,CAACE,IAAI,CACVG,MAAM,IAAI;QACRC,YAAY,CAACf,aAAa,CAAC;QAC3B,IAAIC,UAAU,EAAE;UACdV,IAAI,CAAC,0BAA0B,EAAEuB,MAAM,CAAC;UACxCjB,qBAAqB,aAArBA,qBAAqB,eAArBA,qBAAqB,CAAGiB,MAAM,CAAC;QACjC,CAAC,MAAM;UACLR,OAAO,CAACQ,MAAM,CAAC;QACjB;MACF,CAAC,EACDE,KAAK,IAAI;QACPD,YAAY,CAACf,aAAa,CAAC;QAC3B,IAAIC,UAAU,EAAE;UACdT,IAAI,CAAC,0BAA0B,EAAEwB,KAAK,CAAC;UACvClB,qBAAqB,aAArBA,qBAAqB,eAArBA,qBAAqB,CAAGkB,KAAK,CAAC;QAChC,CAAC,MAAM;UACLT,MAAM,CAACS,KAAK,CAAC;QACf;MACF,CACF,CAAC;IACH,CAAC,CAAC;EACJ,CAAC;AACH","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"private": false,
|
|
3
3
|
"name": "@xen-orchestra/fs",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.6.0",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"description": "The File System for Xen Orchestra backups.",
|
|
7
7
|
"homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/fs",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"@aws-sdk/lib-storage": "^3.54.0",
|
|
26
26
|
"@aws-sdk/middleware-apply-body-checksum": "^3.58.0",
|
|
27
27
|
"@aws-sdk/node-http-handler": "^3.54.0",
|
|
28
|
+
"@azure/storage-blob": "^12.26.0",
|
|
28
29
|
"@vates/async-each": "^1.0.0",
|
|
29
30
|
"@vates/coalesce-calls": "^0.1.0",
|
|
30
31
|
"@vates/decorate-with": "^2.1.0",
|
|
@@ -41,7 +42,7 @@
|
|
|
41
42
|
"proper-lockfile": "^4.1.2",
|
|
42
43
|
"readable-stream": "^4.1.0",
|
|
43
44
|
"through2": "^4.0.2",
|
|
44
|
-
"xo-remote-parser": "^0.
|
|
45
|
+
"xo-remote-parser": "^0.10.0"
|
|
45
46
|
},
|
|
46
47
|
"devDependencies": {
|
|
47
48
|
"@babel/cli": "^7.0.0",
|