@xen-orchestra/fs 2.1.0 → 3.0.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/_encryptor.js +70 -0
- package/dist/_encryptor.js.map +1 -0
- package/dist/abstract.js +113 -36
- package/dist/abstract.js.map +1 -1
- package/dist/index.js +1 -5
- package/dist/index.js.map +1 -1
- package/dist/local.js +73 -25
- package/dist/local.js.map +1 -1
- package/dist/smb.js +21 -148
- package/dist/smb.js.map +1 -1
- package/package.json +4 -3
- package/dist/smb-mount.js +0 -43
- package/dist/smb-mount.js.map +0 -1
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
readChunk
|
|
5
|
+
} = require('@vates/read-chunk');
|
|
6
|
+
|
|
7
|
+
const crypto = require('crypto');
|
|
8
|
+
|
|
9
|
+
const pumpify = require('pumpify');
|
|
10
|
+
|
|
11
|
+
function getEncryptor(key) {
|
|
12
|
+
if (key === undefined) {
|
|
13
|
+
return {
|
|
14
|
+
id: 'NULL_ENCRYPTOR',
|
|
15
|
+
algorithm: 'none',
|
|
16
|
+
key: 'none',
|
|
17
|
+
ivLength: 0,
|
|
18
|
+
encryptData: buffer => buffer,
|
|
19
|
+
encryptStream: stream => stream,
|
|
20
|
+
decryptData: buffer => buffer,
|
|
21
|
+
decryptStream: stream => stream
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const algorithm = 'aes-256-cbc';
|
|
26
|
+
const ivLength = 16;
|
|
27
|
+
|
|
28
|
+
function encryptStream(input) {
|
|
29
|
+
const iv = crypto.randomBytes(ivLength);
|
|
30
|
+
const cipher = crypto.createCipheriv(algorithm, Buffer.from(key), iv);
|
|
31
|
+
const encrypted = pumpify(input, cipher);
|
|
32
|
+
encrypted.unshift(iv);
|
|
33
|
+
return encrypted;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function decryptStream(encryptedStream) {
|
|
37
|
+
const iv = await readChunk(encryptedStream, ivLength);
|
|
38
|
+
const cipher = crypto.createDecipheriv(algorithm, Buffer.from(key), iv);
|
|
39
|
+
return pumpify(encryptedStream, cipher);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function encryptData(buffer) {
|
|
43
|
+
const iv = crypto.randomBytes(ivLength);
|
|
44
|
+
const cipher = crypto.createCipheriv(algorithm, Buffer.from(key), iv);
|
|
45
|
+
const encrypted = cipher.update(buffer);
|
|
46
|
+
return Buffer.concat([iv, encrypted, cipher.final()]);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function decryptData(buffer) {
|
|
50
|
+
const iv = buffer.slice(0, ivLength);
|
|
51
|
+
const encrypted = buffer.slice(ivLength);
|
|
52
|
+
const decipher = crypto.createDecipheriv(algorithm, Buffer.from(key), iv);
|
|
53
|
+
const decrypted = decipher.update(encrypted);
|
|
54
|
+
return Buffer.concat([decrypted, decipher.final()]);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
id: algorithm,
|
|
59
|
+
algorithm,
|
|
60
|
+
key,
|
|
61
|
+
ivLength,
|
|
62
|
+
encryptData,
|
|
63
|
+
encryptStream,
|
|
64
|
+
decryptData,
|
|
65
|
+
decryptStream
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
exports._getEncryptor = getEncryptor;
|
|
70
|
+
//# sourceMappingURL=_encryptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_encryptor.js","names":["readChunk","require","crypto","pumpify","getEncryptor","key","undefined","id","algorithm","ivLength","encryptData","buffer","encryptStream","stream","decryptData","decryptStream","input","iv","randomBytes","cipher","createCipheriv","Buffer","from","encrypted","unshift","encryptedStream","createDecipheriv","update","concat","final","slice","decipher","decrypted","exports","_getEncryptor"],"sources":["../src/_encryptor.js"],"sourcesContent":["const { readChunk } = require('@vates/read-chunk')\nconst crypto = require('crypto')\nconst pumpify = require('pumpify')\n\nfunction getEncryptor(key) {\n if (key === undefined) {\n return {\n id: 'NULL_ENCRYPTOR',\n algorithm: 'none',\n key: 'none',\n ivLength: 0,\n encryptData: buffer => buffer,\n encryptStream: stream => stream,\n decryptData: buffer => buffer,\n decryptStream: stream => stream,\n }\n }\n const algorithm = 'aes-256-cbc'\n const ivLength = 16\n\n function encryptStream(input) {\n const iv = crypto.randomBytes(ivLength)\n const cipher = crypto.createCipheriv(algorithm, Buffer.from(key), iv)\n\n const encrypted = pumpify(input, cipher)\n encrypted.unshift(iv)\n return encrypted\n }\n\n async function decryptStream(encryptedStream) {\n const iv = await readChunk(encryptedStream, ivLength)\n const cipher = crypto.createDecipheriv(algorithm, Buffer.from(key), iv)\n /**\n * WARNING\n *\n * the crytped size has an initializtion vector + a padding at the end\n * whe can't predict the decrypted size from the start of the encrypted size\n * thus, we can't set decrypted.length reliably\n *\n */\n return pumpify(encryptedStream, cipher)\n }\n\n function encryptData(buffer) {\n const iv = crypto.randomBytes(ivLength)\n const cipher = crypto.createCipheriv(algorithm, Buffer.from(key), iv)\n const encrypted = cipher.update(buffer)\n return Buffer.concat([iv, encrypted, cipher.final()])\n }\n\n function decryptData(buffer) {\n const iv = buffer.slice(0, ivLength)\n const encrypted = buffer.slice(ivLength)\n const decipher = crypto.createDecipheriv(algorithm, Buffer.from(key), iv)\n const decrypted = decipher.update(encrypted)\n return Buffer.concat([decrypted, decipher.final()])\n }\n\n return {\n id: algorithm,\n algorithm,\n key,\n ivLength,\n encryptData,\n encryptStream,\n decryptData,\n decryptStream,\n }\n}\n\nexports._getEncryptor = getEncryptor\n"],"mappings":"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"}
|
package/dist/abstract.js
CHANGED
|
@@ -7,6 +7,8 @@ exports.default = void 0;
|
|
|
7
7
|
|
|
8
8
|
var _legacy = _interopRequireDefault(require("@xen-orchestra/async-map/legacy"));
|
|
9
9
|
|
|
10
|
+
var _assert = _interopRequireDefault(require("assert"));
|
|
11
|
+
|
|
10
12
|
var _getStream = _interopRequireDefault(require("get-stream"));
|
|
11
13
|
|
|
12
14
|
var _coalesceCalls = require("@vates/coalesce-calls");
|
|
@@ -29,6 +31,8 @@ var _path = require("./path");
|
|
|
29
31
|
|
|
30
32
|
var _checksum = require("./checksum");
|
|
31
33
|
|
|
34
|
+
var _encryptor = require("./_encryptor");
|
|
35
|
+
|
|
32
36
|
var _dec, _dec2, _class;
|
|
33
37
|
|
|
34
38
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -36,6 +40,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
36
40
|
function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { var desc = {}; Object.keys(descriptor).forEach(function (key) { desc[key] = descriptor[key]; }); desc.enumerable = !!desc.enumerable; desc.configurable = !!desc.configurable; if ('value' in desc || desc.initializer) { desc.writable = true; } desc = decorators.slice().reverse().reduce(function (desc, decorator) { return decorator(target, property, desc) || desc; }, desc); if (context && desc.initializer !== void 0) { desc.value = desc.initializer ? desc.initializer.call(context) : void 0; desc.initializer = undefined; } if (desc.initializer === void 0) { Object.defineProperty(target, property, desc); desc = null; } return desc; }
|
|
37
41
|
|
|
38
42
|
const {
|
|
43
|
+
info,
|
|
39
44
|
warn
|
|
40
45
|
} = (0, _log.createLogger)('@xen-orchestra:fs');
|
|
41
46
|
|
|
@@ -48,6 +53,8 @@ const computeRate = (hrtime, size) => {
|
|
|
48
53
|
|
|
49
54
|
const DEFAULT_TIMEOUT = 6e5;
|
|
50
55
|
const DEFAULT_MAX_PARALLEL_OPERATIONS = 10;
|
|
56
|
+
const ENCRYPTION_DESC_FILENAME = 'encryption.json';
|
|
57
|
+
const ENCRYPTION_METADATA_FILENAME = 'metadata.json';
|
|
51
58
|
|
|
52
59
|
const ignoreEnoent = error => {
|
|
53
60
|
if (error == null || error.code !== 'ENOENT') {
|
|
@@ -91,6 +98,8 @@ class PrefixWrapper {
|
|
|
91
98
|
}
|
|
92
99
|
|
|
93
100
|
let RemoteHandlerAbstract = (_dec = (0, _decoratorSynchronized.synchronized)(), _dec2 = (0, _decoratorSynchronized.synchronized)(), (_class = class RemoteHandlerAbstract {
|
|
101
|
+
_encryptor;
|
|
102
|
+
|
|
94
103
|
constructor(remote, options = {}) {
|
|
95
104
|
if (remote.url === 'test://') {
|
|
96
105
|
this._remote = remote;
|
|
@@ -109,6 +118,7 @@ let RemoteHandlerAbstract = (_dec = (0, _decoratorSynchronized.synchronized)(),
|
|
|
109
118
|
highWaterMark: this._highWaterMark,
|
|
110
119
|
timeout: this._timeout = DEFAULT_TIMEOUT
|
|
111
120
|
} = options);
|
|
121
|
+
this._encryptor = (0, _encryptor._getEncryptor)(this._remote.encryptionKey);
|
|
112
122
|
const sharedLimit = (0, _limitConcurrencyDecorator.limitConcurrency)(options.maxParallelOperations ?? DEFAULT_MAX_PARALLEL_OPERATIONS);
|
|
113
123
|
this.closeFile = sharedLimit(this.closeFile);
|
|
114
124
|
this.copy = sharedLimit(this.copy);
|
|
@@ -143,53 +153,53 @@ let RemoteHandlerAbstract = (_dec = (0, _decoratorSynchronized.synchronized)(),
|
|
|
143
153
|
await this.__closeFile(fd);
|
|
144
154
|
}
|
|
145
155
|
|
|
146
|
-
createReadStream(file, {
|
|
156
|
+
async createReadStream(file, {
|
|
147
157
|
checksum = false,
|
|
148
158
|
ignoreMissingChecksum = false,
|
|
149
159
|
...options
|
|
150
160
|
} = {}) {
|
|
161
|
+
if (options.end !== undefined || options.start !== undefined) {
|
|
162
|
+
_assert.default.strictEqual(this.isEncrypted, false, `Can't read part of a file when encryption is active ${file}`);
|
|
163
|
+
}
|
|
164
|
+
|
|
151
165
|
if (typeof file === 'string') {
|
|
152
166
|
file = (0, _path.normalize)(file);
|
|
153
167
|
}
|
|
154
168
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const streamP = _promiseToolbox.timeout.call(this._createReadStream(file, { ...options,
|
|
169
|
+
let stream = await _promiseToolbox.timeout.call(this._createReadStream(file, { ...options,
|
|
158
170
|
highWaterMark: this._highWaterMark
|
|
159
|
-
}), this._timeout)
|
|
160
|
-
|
|
171
|
+
}), this._timeout);
|
|
172
|
+
await (0, _promiseToolbox.fromEvent)(stream, 'readable');
|
|
161
173
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
174
|
+
if (checksum) {
|
|
175
|
+
try {
|
|
176
|
+
const path = typeof file === 'string' ? file : file.path;
|
|
177
|
+
const checksum = await this._readFile(checksumFile(path), {
|
|
178
|
+
flags: 'r'
|
|
179
|
+
});
|
|
180
|
+
const {
|
|
181
|
+
length
|
|
182
|
+
} = stream;
|
|
183
|
+
stream = (0, _checksum.validChecksumOfReadStream)(stream, String(checksum).trim());
|
|
184
|
+
stream.length = length;
|
|
185
|
+
} catch (error) {
|
|
186
|
+
if (!(ignoreMissingChecksum && error.code === 'ENOENT')) {
|
|
187
|
+
throw error;
|
|
188
|
+
}
|
|
166
189
|
}
|
|
167
|
-
|
|
168
|
-
return promise.then(() => stream);
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
if (!checksum) {
|
|
172
|
-
return streamP;
|
|
173
190
|
}
|
|
174
191
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
} = stream;
|
|
183
|
-
stream = (0, _checksum.validChecksumOfReadStream)(stream, String(checksum).trim());
|
|
184
|
-
stream.length = length;
|
|
185
|
-
return stream;
|
|
186
|
-
}), error => {
|
|
187
|
-
if (ignoreMissingChecksum && error && error.code === 'ENOENT') {
|
|
188
|
-
return streamP;
|
|
192
|
+
if (this.isEncrypted) {
|
|
193
|
+
stream = this._encryptor.decryptStream(stream);
|
|
194
|
+
} else {
|
|
195
|
+
if (stream.length === undefined && options.end === undefined && options.start === undefined) {
|
|
196
|
+
try {
|
|
197
|
+
stream.length = await this._getSize(file);
|
|
198
|
+
} catch (error) {}
|
|
189
199
|
}
|
|
200
|
+
}
|
|
190
201
|
|
|
191
|
-
|
|
192
|
-
});
|
|
202
|
+
return stream;
|
|
193
203
|
}
|
|
194
204
|
|
|
195
205
|
async outputStream(path, input, {
|
|
@@ -199,6 +209,7 @@ let RemoteHandlerAbstract = (_dec = (0, _decoratorSynchronized.synchronized)(),
|
|
|
199
209
|
} = {}) {
|
|
200
210
|
path = (0, _path.normalize)(path);
|
|
201
211
|
let checksumStream;
|
|
212
|
+
input = this._encryptor.encryptStream(input);
|
|
202
213
|
|
|
203
214
|
if (checksum) {
|
|
204
215
|
checksumStream = (0, _checksum.createChecksumStream)();
|
|
@@ -228,7 +239,10 @@ let RemoteHandlerAbstract = (_dec = (0, _decoratorSynchronized.synchronized)(),
|
|
|
228
239
|
}
|
|
229
240
|
|
|
230
241
|
async getSize(file) {
|
|
231
|
-
|
|
242
|
+
_assert.default.strictEqual(this.isEncrypted, false, `Can't compute size of an encrypted file ${file}`);
|
|
243
|
+
|
|
244
|
+
const size = await _promiseToolbox.timeout.call(this._getSize(typeof file === 'string' ? (0, _path.normalize)(file) : file), this._timeout);
|
|
245
|
+
return size - this._encryptor.ivLength;
|
|
232
246
|
}
|
|
233
247
|
|
|
234
248
|
async list(dir, {
|
|
@@ -292,22 +306,27 @@ let RemoteHandlerAbstract = (_dec = (0, _decoratorSynchronized.synchronized)(),
|
|
|
292
306
|
dirMode,
|
|
293
307
|
flags = 'wx'
|
|
294
308
|
} = {}) {
|
|
295
|
-
|
|
309
|
+
const encryptedData = this._encryptor.encryptData(data);
|
|
310
|
+
|
|
311
|
+
await this._outputFile((0, _path.normalize)(file), encryptedData, {
|
|
296
312
|
dirMode,
|
|
297
313
|
flags
|
|
298
314
|
});
|
|
299
315
|
}
|
|
300
316
|
|
|
301
317
|
async read(file, buffer, position) {
|
|
318
|
+
_assert.default.strictEqual(this.isEncrypted, false, `Can't read part of an encrypted file ${file}`);
|
|
319
|
+
|
|
302
320
|
return this._read(typeof file === 'string' ? (0, _path.normalize)(file) : file, buffer, position);
|
|
303
321
|
}
|
|
304
322
|
|
|
305
323
|
async readFile(file, {
|
|
306
324
|
flags = 'r'
|
|
307
325
|
} = {}) {
|
|
308
|
-
|
|
326
|
+
const data = await this._readFile((0, _path.normalize)(file), {
|
|
309
327
|
flags
|
|
310
328
|
});
|
|
329
|
+
return this._encryptor.decryptData(data);
|
|
311
330
|
}
|
|
312
331
|
|
|
313
332
|
async rename(oldPath, newPath, {
|
|
@@ -350,6 +369,56 @@ let RemoteHandlerAbstract = (_dec = (0, _decoratorSynchronized.synchronized)(),
|
|
|
350
369
|
|
|
351
370
|
async sync() {
|
|
352
371
|
await this._sync();
|
|
372
|
+
|
|
373
|
+
try {
|
|
374
|
+
await this._checkMetadata();
|
|
375
|
+
} catch (error) {
|
|
376
|
+
await this._forget();
|
|
377
|
+
throw error;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
async _canWriteMetadata() {
|
|
382
|
+
const list = await this.list('/', {
|
|
383
|
+
filter: e => !e.startsWith('.') && e !== ENCRYPTION_DESC_FILENAME && e !== ENCRYPTION_METADATA_FILENAME
|
|
384
|
+
});
|
|
385
|
+
return list.length === 0;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
async _createMetadata() {
|
|
389
|
+
await Promise.all([this._writeFile((0, _path.normalize)(ENCRYPTION_DESC_FILENAME), JSON.stringify({
|
|
390
|
+
algorithm: this._encryptor.algorithm
|
|
391
|
+
}), {
|
|
392
|
+
flags: 'w'
|
|
393
|
+
}), this.writeFile(ENCRYPTION_METADATA_FILENAME, `{"random":"${(0, _crypto.randomUUID)()}"}`, {
|
|
394
|
+
flags: 'w'
|
|
395
|
+
})]);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
async _checkMetadata() {
|
|
399
|
+
try {
|
|
400
|
+
const data = await this._readFile((0, _path.normalize)(ENCRYPTION_DESC_FILENAME));
|
|
401
|
+
JSON.parse(data);
|
|
402
|
+
} catch (error) {
|
|
403
|
+
if (error.code !== 'ENOENT') {
|
|
404
|
+
throw error;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
try {
|
|
409
|
+
const data = await this.readFile(ENCRYPTION_METADATA_FILENAME);
|
|
410
|
+
JSON.parse(data);
|
|
411
|
+
} catch (error) {
|
|
412
|
+
if (error.code === 'ENOENT' || (await this._canWriteMetadata())) {
|
|
413
|
+
info('will update metadata of this remote');
|
|
414
|
+
return this._createMetadata();
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
warn(`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`, {
|
|
418
|
+
error
|
|
419
|
+
});
|
|
420
|
+
throw error;
|
|
421
|
+
}
|
|
353
422
|
}
|
|
354
423
|
|
|
355
424
|
async test() {
|
|
@@ -412,13 +481,17 @@ let RemoteHandlerAbstract = (_dec = (0, _decoratorSynchronized.synchronized)(),
|
|
|
412
481
|
}
|
|
413
482
|
|
|
414
483
|
async write(file, buffer, position) {
|
|
484
|
+
_assert.default.strictEqual(this.isEncrypted, false, `Can't write part of a file with encryption ${file}`);
|
|
485
|
+
|
|
415
486
|
await this._write(typeof file === 'string' ? (0, _path.normalize)(file) : file, buffer, position);
|
|
416
487
|
}
|
|
417
488
|
|
|
418
489
|
async writeFile(file, data, {
|
|
419
490
|
flags = 'wx'
|
|
420
491
|
} = {}) {
|
|
421
|
-
|
|
492
|
+
const encryptedData = this._encryptor.encryptData(data);
|
|
493
|
+
|
|
494
|
+
await this._writeFile((0, _path.normalize)(file), encryptedData, {
|
|
422
495
|
flags
|
|
423
496
|
});
|
|
424
497
|
}
|
|
@@ -652,6 +725,10 @@ let RemoteHandlerAbstract = (_dec = (0, _decoratorSynchronized.synchronized)(),
|
|
|
652
725
|
throw new Error('Not implemented');
|
|
653
726
|
}
|
|
654
727
|
|
|
728
|
+
get isEncrypted() {
|
|
729
|
+
return this._encryptor.id !== 'NULL_ENCRYPTOR';
|
|
730
|
+
}
|
|
731
|
+
|
|
655
732
|
}, (_applyDecoratedDescriptor(_class.prototype, "forget", [_dec], Object.getOwnPropertyDescriptor(_class.prototype, "forget"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "sync", [_dec2], Object.getOwnPropertyDescriptor(_class.prototype, "sync"), _class.prototype)), _class));
|
|
656
733
|
exports.default = RemoteHandlerAbstract;
|
|
657
734
|
|
package/dist/abstract.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"abstract.js","names":["warn","createLogger","checksumFile","file","computeRate","hrtime","size","seconds","DEFAULT_TIMEOUT","DEFAULT_MAX_PARALLEL_OPERATIONS","ignoreEnoent","error","code","noop","Function","prototype","PrefixWrapper","constructor","handler","prefix","_prefix","_handler","type","list","dir","opts","entries","_resolve","prependDir","n","length","forEach","entry","i","slice","rename","oldPath","newPath","path","normalizePath","RemoteHandlerAbstract","synchronized","remote","options","url","_remote","parse","Error","highWaterMark","_highWaterMark","timeout","_timeout","sharedLimit","limitConcurrency","maxParallelOperations","closeFile","copy","getInfo","getSize","mkdir","openFile","outputFile","read","readFile","rmdir","truncate","unlink","write","writeFile","_forget","coalesceCalls","_sync","addPrefix","fd","__closeFile","createReadStream","checksum","ignoreMissingChecksum","streamP","call","_createReadStream","then","stream","promise","fromEvent","undefined","end","start","Promise","all","ignoreErrors","_getSize","_readFile","flags","validChecksumOfReadStream","String","trim","outputStream","input","dirMode","validator","checksumStream","createChecksumStream","pipeline","_outputStream","_outputFile","forget","_getInfo","filter","ignoreMissing","virtualDir","_list","lock","dispose","_lock","mode","__mkdir","mktree","_mktree","__openFile","data","buffer","position","_read","p","_rename","_copy","_rmdir","catch","rmtree","_rmtree","sync","test","SIZE","testFileName","Date","now","fromCallback","randomBytes","step","writeStart","process","writeDuration","readStart","readDuration","equals","success","writeRate","readRate","_unlink","len","_truncate","_write","_writeFile","_closeFile","_mkdir","_openFile","useVhdDirectory","_createOutputStream","_createWriteStream","dirname","resolve","tmpPath","basename","output","getStream","files","asyncMapSettled","isPath","_writeFd","createPrefixWrapperMethods","pPw","pRha","defineProperty","getOwnPropertyDescriptor","hasOwnProperty","Object","getOwnPropertyNames","name","descriptor","value","arguments","apply"],"sources":["../src/abstract.js"],"sourcesContent":["import asyncMapSettled from '@xen-orchestra/async-map/legacy'\nimport getStream from 'get-stream'\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 } from 'crypto'\nimport { synchronized } from 'decorator-synchronized'\n\nimport { basename, dirname, normalize as normalizePath } from './path'\nimport { createChecksumStream, validChecksumOfReadStream } from './checksum'\n\nconst { warn } = createLogger('@xen-orchestra:fs')\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 ignoreEnoent = error => {\n if (error == null || error.code !== 'ENOENT') {\n throw error\n }\n}\n\nconst noop = Function.prototype\n\nclass PrefixWrapper {\n constructor(handler, prefix) {\n this._prefix = prefix\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 _resolve(path) {\n return this._prefix + normalizePath(path)\n }\n}\n\nexport default class RemoteHandlerAbstract {\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.getSize = sharedLimit(this.getSize)\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 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 closeFile(fd) {\n await this.__closeFile(fd)\n }\n\n createReadStream(file, { checksum = false, ignoreMissingChecksum = false, ...options } = {}) {\n if (typeof file === 'string') {\n file = normalizePath(file)\n }\n const path = typeof file === 'string' ? file : file.path\n const streamP = timeout\n .call(this._createReadStream(file, { ...options, highWaterMark: this._highWaterMark }), this._timeout)\n .then(stream => {\n // detect early errors\n let promise = fromEvent(stream, 'readable')\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 promise = Promise.all([\n promise,\n ignoreErrors.call(\n this._getSize(file).then(size => {\n stream.length = size\n })\n ),\n ])\n }\n\n return promise.then(() => stream)\n })\n\n if (!checksum) {\n return streamP\n }\n\n // avoid a unhandled rejection warning\n ignoreErrors.call(streamP)\n\n return this._readFile(checksumFile(path), { flags: 'r' }).then(\n checksum =>\n streamP.then(stream => {\n const { length } = stream\n stream = validChecksumOfReadStream(stream, String(checksum).trim())\n stream.length = length\n\n return stream\n }),\n error => {\n if (ignoreMissingChecksum && error && error.code === 'ENOENT') {\n return streamP\n }\n throw error\n }\n )\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, validator } = {}) {\n path = normalizePath(path)\n let checksumStream\n if (checksum) {\n checksumStream = createChecksumStream()\n pipeline(input, checksumStream, noop)\n input = checksumStream\n }\n await this._outputStream(path, input, {\n dirMode,\n validator,\n })\n if (checksum) {\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 async getSize(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 mkdir(dir, { mode } = {}) {\n await this.__mkdir(normalizePath(dir), { mode })\n }\n\n async mktree(dir, { mode } = {}) {\n await this._mktree(normalizePath(dir), { mode })\n }\n\n openFile(path, flags) {\n return this.__openFile(path, flags)\n }\n\n async outputFile(file, data, { dirMode, flags = 'wx' } = {}) {\n await this._outputFile(normalizePath(file), data, { dirMode, flags })\n }\n\n async read(file, buffer, position) {\n return this._read(typeof file === 'string' ? normalizePath(file) : file, buffer, position)\n }\n\n async readFile(file, { flags = 'r' } = {}) {\n return this._readFile(normalizePath(file), { flags })\n }\n\n async rename(oldPath, newPath, { checksum = false } = {}) {\n oldPath = normalizePath(oldPath)\n newPath = normalizePath(newPath)\n\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 return p\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 }\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 await this._write(typeof file === 'string' ? normalizePath(file) : file, buffer, position)\n }\n\n async writeFile(file, data, { flags = 'wx' } = {}) {\n await this._writeFile(normalizePath(file), data, { 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 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 asyncMapSettled(files, 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}`)\n }\n throw error\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\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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"}
|
|
1
|
+
{"version":3,"file":"abstract.js","names":["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","constructor","handler","prefix","_prefix","_handler","type","list","dir","opts","entries","_resolve","prependDir","n","length","forEach","entry","i","slice","rename","oldPath","newPath","path","normalizePath","RemoteHandlerAbstract","synchronized","_encryptor","remote","options","url","_remote","parse","Error","highWaterMark","_highWaterMark","timeout","_timeout","_getEncryptor","encryptionKey","sharedLimit","limitConcurrency","maxParallelOperations","closeFile","copy","getInfo","getSize","mkdir","openFile","outputFile","read","readFile","rmdir","truncate","unlink","write","writeFile","_forget","coalesceCalls","_sync","addPrefix","fd","__closeFile","createReadStream","checksum","ignoreMissingChecksum","end","undefined","start","assert","strictEqual","isEncrypted","stream","call","_createReadStream","fromEvent","_readFile","flags","validChecksumOfReadStream","String","trim","decryptStream","_getSize","outputStream","input","dirMode","validator","checksumStream","encryptStream","createChecksumStream","pipeline","_outputStream","_outputFile","forget","_getInfo","ivLength","filter","ignoreMissing","virtualDir","_list","lock","dispose","_lock","mode","__mkdir","mktree","_mktree","__openFile","data","encryptedData","encryptData","buffer","position","_read","decryptData","p","_rename","Promise","all","_copy","_rmdir","catch","rmtree","_rmtree","sync","_checkMetadata","_canWriteMetadata","e","startsWith","_createMetadata","_writeFile","JSON","stringify","algorithm","randomUUID","test","SIZE","testFileName","Date","now","fromCallback","randomBytes","step","writeStart","process","writeDuration","readStart","readDuration","equals","success","writeRate","readRate","ignoreErrors","_unlink","len","_truncate","_write","_closeFile","_mkdir","_openFile","useVhdDirectory","_createOutputStream","_createWriteStream","dirname","resolve","tmpPath","basename","output","then","getStream","files","asyncMapSettled","isPath","_writeFd","id","createPrefixWrapperMethods","pPw","pRha","defineProperty","getOwnPropertyDescriptor","hasOwnProperty","Object","getOwnPropertyNames","name","descriptor","value","arguments","apply"],"sources":["../src/abstract.js"],"sourcesContent":["import asyncMapSettled from '@xen-orchestra/async-map/legacy'\nimport assert from 'assert'\nimport getStream from 'get-stream'\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 { _getEncryptor } from './_encryptor'\n\nconst { info, warn } = createLogger('@xen-orchestra:fs')\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 constructor(handler, prefix) {\n this._prefix = prefix\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 _resolve(path) {\n return this._prefix + normalizePath(path)\n }\n}\n\nexport default class RemoteHandlerAbstract {\n _encryptor\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 this._encryptor = _getEncryptor(this._remote.encryptionKey)\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.getSize = sharedLimit(this.getSize)\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 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 closeFile(fd) {\n await this.__closeFile(fd)\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, 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 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 // when using encryption, the file size is aligned with the encryption block size ( 16 bytes )\n // that means that the size will be 1 to 16 bytes more than the content size + the initialized vector length (16 bytes)\n async getSize(file) {\n assert.strictEqual(this.isEncrypted, false, `Can't compute size of an encrypted file ${file}`)\n\n const size = await timeout.call(this._getSize(typeof file === 'string' ? normalizePath(file) : file), this._timeout)\n return size - this._encryptor.ivLength\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 mkdir(dir, { mode } = {}) {\n await this.__mkdir(normalizePath(dir), { mode })\n }\n\n async mktree(dir, { mode } = {}) {\n await this._mktree(normalizePath(dir), { mode })\n }\n\n openFile(path, flags) {\n return this.__openFile(path, flags)\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 = false } = {}) {\n oldPath = normalizePath(oldPath)\n newPath = normalizePath(newPath)\n\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 return p\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 await Promise.all([\n this._writeFile(\n normalizePath(ENCRYPTION_DESC_FILENAME),\n JSON.stringify({ algorithm: this._encryptor.algorithm }),\n {\n flags: 'w',\n }\n ), // not encrypted\n this.writeFile(ENCRYPTION_METADATA_FILENAME, `{\"random\":\"${randomUUID()}\"}`, { flags: 'w' }), // encrypted\n ])\n }\n\n async _checkMetadata() {\n try {\n // this file is not encrypted\n const data = await this._readFile(normalizePath(ENCRYPTION_DESC_FILENAME))\n JSON.parse(data)\n } catch (error) {\n if (error.code !== 'ENOENT') {\n throw error\n }\n }\n\n try {\n // this file is encrypted\n const data = await this.readFile(ENCRYPTION_METADATA_FILENAME)\n JSON.parse(data)\n } catch (error) {\n if (error.code === 'ENOENT' || (await this._canWriteMetadata())) {\n info('will update metadata of this remote')\n return this._createMetadata()\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 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 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 asyncMapSettled(files, 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}`)\n }\n throw error\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\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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"}
|
package/dist/index.js
CHANGED
|
@@ -17,8 +17,6 @@ var _s = _interopRequireDefault(require("./s3"));
|
|
|
17
17
|
|
|
18
18
|
var _smb = _interopRequireDefault(require("./smb"));
|
|
19
19
|
|
|
20
|
-
var _smbMount = _interopRequireDefault(require("./smb-mount"));
|
|
21
|
-
|
|
22
20
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
23
21
|
|
|
24
22
|
const HANDLERS = {
|
|
@@ -30,10 +28,8 @@ const HANDLERS = {
|
|
|
30
28
|
try {
|
|
31
29
|
_execa.default.sync('mount.cifs', ['-V']);
|
|
32
30
|
|
|
33
|
-
HANDLERS.smb = _smbMount.default;
|
|
34
|
-
} catch (_) {
|
|
35
31
|
HANDLERS.smb = _smb.default;
|
|
36
|
-
}
|
|
32
|
+
} catch (_) {}
|
|
37
33
|
|
|
38
34
|
const getHandler = (remote, ...rest) => {
|
|
39
35
|
const Handler = HANDLERS[(0, _xoRemoteParser.parse)(remote.url).type];
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["HANDLERS","file","RemoteHandlerLocal","nfs","RemoteHandlerNfs","s3","RemoteHandlerS3","execa","sync","smb","
|
|
1
|
+
{"version":3,"file":"index.js","names":["HANDLERS","file","RemoteHandlerLocal","nfs","RemoteHandlerNfs","s3","RemoteHandlerS3","execa","sync","smb","RemoteHandlerSmb","_","getHandler","remote","rest","Handler","parse","url","type","Error","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'\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;;AACA;;AAEA;;AACA;;AACA;;AACA;;;;AAEA,MAAMA,QAAQ,GAAG;EACfC,IAAI,EAAEC,cADS;EAEfC,GAAG,EAAEC,YAFU;EAGfC,EAAE,EAAEC;AAHW,CAAjB;;AAMA,IAAI;EACFC,cAAA,CAAMC,IAAN,CAAW,YAAX,EAAyB,CAAC,IAAD,CAAzB;;EACAR,QAAQ,CAACS,GAAT,GAAeC,YAAf;AACD,CAHD,CAGE,OAAOC,CAAP,EAAU,CAAE;;AAEP,MAAMC,UAAU,GAAG,CAACC,MAAD,EAAS,GAAGC,IAAZ,KAAqB;EAC7C,MAAMC,OAAO,GAAGf,QAAQ,CAAC,IAAAgB,qBAAA,EAAMH,MAAM,CAACI,GAAb,EAAkBC,IAAnB,CAAxB;;EACA,IAAI,CAACH,OAAL,EAAc;IACZ,MAAM,IAAII,KAAJ,CAAU,uBAAV,CAAN;EACD;;EACD,OAAO,IAAIJ,OAAJ,CAAYF,MAAZ,EAAoB,GAAGC,IAAvB,CAAP;AACD,CANM;;;;AAQA,MAAMM,gBAAgB,GAAG,OAAO,GAAGC,IAAV,KAAmB;EACjD,MAAMC,OAAO,GAAGV,UAAU,CAAC,GAAGS,IAAJ,CAA1B;EACA,MAAMC,OAAO,CAACd,IAAR,EAAN;EACA,OAAO;IACLe,OAAO,EAAE,MAAMD,OAAO,CAACE,MAAR,EADV;IAELC,KAAK,EAAEH;EAFF,CAAP;AAID,CAPM"}
|
package/dist/local.js
CHANGED
|
@@ -9,17 +9,38 @@ var _df = _interopRequireDefault(require("@sindresorhus/df"));
|
|
|
9
9
|
|
|
10
10
|
var _fsExtra = _interopRequireDefault(require("fs-extra"));
|
|
11
11
|
|
|
12
|
+
var _identity = _interopRequireDefault(require("lodash/identity.js"));
|
|
13
|
+
|
|
12
14
|
var _properLockfile = _interopRequireDefault(require("proper-lockfile"));
|
|
13
15
|
|
|
16
|
+
var _log = require("@xen-orchestra/log");
|
|
17
|
+
|
|
14
18
|
var _promiseToolbox = require("promise-toolbox");
|
|
15
19
|
|
|
16
20
|
var _abstract = _interopRequireDefault(require("./abstract"));
|
|
17
21
|
|
|
18
22
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
19
23
|
|
|
24
|
+
const {
|
|
25
|
+
info,
|
|
26
|
+
warn
|
|
27
|
+
} = (0, _log.createLogger)('xo:fs:local');
|
|
28
|
+
|
|
29
|
+
async function addSyncStackTrace(promise) {
|
|
30
|
+
const stackContainer = new Error();
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
return await promise;
|
|
34
|
+
} catch (error) {
|
|
35
|
+
error.stack = stackContainer.stack;
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
20
40
|
class LocalHandler extends _abstract.default {
|
|
21
41
|
constructor(remote, opts = {}) {
|
|
22
42
|
super(remote);
|
|
43
|
+
this._addSyncStackTrace = opts.syncStackTraces ?? true ? addSyncStackTrace : _identity.default;
|
|
23
44
|
this._retriesOnEagain = {
|
|
24
45
|
delay: 1e3,
|
|
25
46
|
retries: 9,
|
|
@@ -43,18 +64,18 @@ class LocalHandler extends _abstract.default {
|
|
|
43
64
|
}
|
|
44
65
|
|
|
45
66
|
async _closeFile(fd) {
|
|
46
|
-
return _fsExtra.default.close(fd);
|
|
67
|
+
return this._addSyncStackTrace(_fsExtra.default.close(fd));
|
|
47
68
|
}
|
|
48
69
|
|
|
49
70
|
async _copy(oldPath, newPath) {
|
|
50
|
-
return _fsExtra.default.copy(this._getFilePath(oldPath), this._getFilePath(newPath));
|
|
71
|
+
return this._addSyncStackTrace(_fsExtra.default.copy(this._getFilePath(oldPath), this._getFilePath(newPath)));
|
|
51
72
|
}
|
|
52
73
|
|
|
53
74
|
async _createReadStream(file, options) {
|
|
54
75
|
if (typeof file === 'string') {
|
|
55
76
|
const stream = _fsExtra.default.createReadStream(this._getFilePath(file), options);
|
|
56
77
|
|
|
57
|
-
await (0, _promiseToolbox.fromEvent)(stream, 'open');
|
|
78
|
+
await this._addSyncStackTrace((0, _promiseToolbox.fromEvent)(stream, 'open'));
|
|
58
79
|
return stream;
|
|
59
80
|
}
|
|
60
81
|
|
|
@@ -69,7 +90,7 @@ class LocalHandler extends _abstract.default {
|
|
|
69
90
|
if (typeof file === 'string') {
|
|
70
91
|
const stream = _fsExtra.default.createWriteStream(this._getFilePath(file), options);
|
|
71
92
|
|
|
72
|
-
await (0, _promiseToolbox.fromEvent)(stream, 'open');
|
|
93
|
+
await this._addSyncStackTrace((0, _promiseToolbox.fromEvent)(stream, 'open'));
|
|
73
94
|
return stream;
|
|
74
95
|
}
|
|
75
96
|
|
|
@@ -91,39 +112,66 @@ class LocalHandler extends _abstract.default {
|
|
|
91
112
|
}
|
|
92
113
|
|
|
93
114
|
async _getSize(file) {
|
|
94
|
-
const stats = await _fsExtra.default.stat(this._getFilePath(typeof file === 'string' ? file : file.path));
|
|
115
|
+
const stats = await this._addSyncStackTrace(_fsExtra.default.stat(this._getFilePath(typeof file === 'string' ? file : file.path)));
|
|
95
116
|
return stats.size;
|
|
96
117
|
}
|
|
97
118
|
|
|
98
119
|
async _list(dir) {
|
|
99
|
-
return _fsExtra.default.readdir(this._getFilePath(dir));
|
|
100
|
-
}
|
|
120
|
+
return this._addSyncStackTrace(_fsExtra.default.readdir(this._getFilePath(dir)));
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async _lock(path) {
|
|
124
|
+
const acquire = _properLockfile.default.lock.bind(undefined, this._getFilePath(path), {
|
|
125
|
+
async onCompromised(error) {
|
|
126
|
+
warn('lock compromised', {
|
|
127
|
+
error
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
release = await acquire();
|
|
132
|
+
info('compromised lock was reacquired');
|
|
133
|
+
} catch (error) {
|
|
134
|
+
warn('compromised lock could not be reacquired', {
|
|
135
|
+
error
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
});
|
|
101
141
|
|
|
102
|
-
|
|
103
|
-
return
|
|
142
|
+
let release = await acquire();
|
|
143
|
+
return async () => {
|
|
144
|
+
try {
|
|
145
|
+
await release();
|
|
146
|
+
} catch (error) {
|
|
147
|
+
warn('lock could not be released', {
|
|
148
|
+
error
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
};
|
|
104
152
|
}
|
|
105
153
|
|
|
106
154
|
_mkdir(dir, {
|
|
107
155
|
mode
|
|
108
156
|
}) {
|
|
109
|
-
return _fsExtra.default.mkdir(this._getFilePath(dir), {
|
|
157
|
+
return this._addSyncStackTrace(_fsExtra.default.mkdir(this._getFilePath(dir), {
|
|
110
158
|
mode
|
|
111
|
-
});
|
|
159
|
+
}));
|
|
112
160
|
}
|
|
113
161
|
|
|
114
162
|
async _openFile(path, flags) {
|
|
115
|
-
return _fsExtra.default.open(this._getFilePath(path), flags);
|
|
163
|
+
return this._addSyncStackTrace(_fsExtra.default.open(this._getFilePath(path), flags));
|
|
116
164
|
}
|
|
117
165
|
|
|
118
166
|
async _read(file, buffer, position) {
|
|
119
167
|
const needsClose = typeof file === 'string';
|
|
120
|
-
file = needsClose ? await _fsExtra.default.open(this._getFilePath(file), 'r') : file.fd;
|
|
168
|
+
file = needsClose ? await this._addSyncStackTrace(_fsExtra.default.open(this._getFilePath(file), 'r')) : file.fd;
|
|
121
169
|
|
|
122
170
|
try {
|
|
123
|
-
return await _fsExtra.default.read(file, buffer, 0, buffer.length, position === undefined ? null : position);
|
|
171
|
+
return await this._addSyncStackTrace(_fsExtra.default.read(file, buffer, 0, buffer.length, position === undefined ? null : position));
|
|
124
172
|
} finally {
|
|
125
173
|
if (needsClose) {
|
|
126
|
-
await _fsExtra.default.close(file);
|
|
174
|
+
await this._addSyncStackTrace(_fsExtra.default.close(file));
|
|
127
175
|
}
|
|
128
176
|
}
|
|
129
177
|
}
|
|
@@ -131,44 +179,44 @@ class LocalHandler extends _abstract.default {
|
|
|
131
179
|
async _readFile(file, options) {
|
|
132
180
|
const filePath = this._getFilePath(file);
|
|
133
181
|
|
|
134
|
-
return await (0, _promiseToolbox.retry)(() => _fsExtra.default.readFile(filePath, options), this._retriesOnEagain);
|
|
182
|
+
return await this._addSyncStackTrace((0, _promiseToolbox.retry)(() => _fsExtra.default.readFile(filePath, options), this._retriesOnEagain));
|
|
135
183
|
}
|
|
136
184
|
|
|
137
185
|
async _rename(oldPath, newPath) {
|
|
138
|
-
return _fsExtra.default.rename(this._getFilePath(oldPath), this._getFilePath(newPath));
|
|
186
|
+
return this._addSyncStackTrace(_fsExtra.default.rename(this._getFilePath(oldPath), this._getFilePath(newPath)));
|
|
139
187
|
}
|
|
140
188
|
|
|
141
189
|
async _rmdir(dir) {
|
|
142
|
-
return _fsExtra.default.rmdir(this._getFilePath(dir));
|
|
190
|
+
return this._addSyncStackTrace(_fsExtra.default.rmdir(this._getFilePath(dir)));
|
|
143
191
|
}
|
|
144
192
|
|
|
145
193
|
async _sync() {
|
|
146
194
|
const path = this._getRealPath('/');
|
|
147
195
|
|
|
148
|
-
await _fsExtra.default.ensureDir(path);
|
|
149
|
-
await _fsExtra.default.access(path, _fsExtra.default.R_OK | _fsExtra.default.W_OK);
|
|
196
|
+
await this._addSyncStackTrace(_fsExtra.default.ensureDir(path));
|
|
197
|
+
await this._addSyncStackTrace(_fsExtra.default.access(path, _fsExtra.default.R_OK | _fsExtra.default.W_OK));
|
|
150
198
|
}
|
|
151
199
|
|
|
152
200
|
_truncate(file, len) {
|
|
153
|
-
return _fsExtra.default.truncate(this._getFilePath(file), len);
|
|
201
|
+
return this._addSyncStackTrace(_fsExtra.default.truncate(this._getFilePath(file), len));
|
|
154
202
|
}
|
|
155
203
|
|
|
156
204
|
async _unlink(file) {
|
|
157
205
|
const filePath = this._getFilePath(file);
|
|
158
206
|
|
|
159
|
-
return await (0, _promiseToolbox.retry)(() => _fsExtra.default.unlink(filePath), this._retriesOnEagain);
|
|
207
|
+
return await this._addSyncStackTrace((0, _promiseToolbox.retry)(() => _fsExtra.default.unlink(filePath), this._retriesOnEagain));
|
|
160
208
|
}
|
|
161
209
|
|
|
162
210
|
_writeFd(file, buffer, position) {
|
|
163
|
-
return _fsExtra.default.write(file.fd, buffer, 0, buffer.length, position);
|
|
211
|
+
return this._addSyncStackTrace(_fsExtra.default.write(file.fd, buffer, 0, buffer.length, position));
|
|
164
212
|
}
|
|
165
213
|
|
|
166
214
|
_writeFile(file, data, {
|
|
167
215
|
flags
|
|
168
216
|
}) {
|
|
169
|
-
return _fsExtra.default.writeFile(this._getFilePath(file), data, {
|
|
217
|
+
return this._addSyncStackTrace(_fsExtra.default.writeFile(this._getFilePath(file), data, {
|
|
170
218
|
flag: flags
|
|
171
|
-
});
|
|
219
|
+
}));
|
|
172
220
|
}
|
|
173
221
|
|
|
174
222
|
}
|
package/dist/local.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local.js","names":["LocalHandler","RemoteHandlerAbstract","constructor","remote","opts","_retriesOnEagain","delay","retries","retriesOnEagain","when","code","type","_getRealPath","_remote","path","_getFilePath","file","_closeFile","fd","fs","close","_copy","oldPath","newPath","copy","_createReadStream","options","stream","createReadStream","fromEvent","autoClose","_createWriteStream","createWriteStream","_getInfo","info","df","Object","keys","forEach","key","Number","isNaN","_getSize","stats","stat","size","_list","dir","readdir","_lock","lockfile","lock","_mkdir","mode","mkdir","_openFile","flags","open","_read","buffer","position","needsClose","read","length","undefined","_readFile","filePath","retry","readFile","_rename","rename","_rmdir","rmdir","_sync","ensureDir","access","R_OK","W_OK","_truncate","len","truncate","_unlink","unlink","_writeFd","write","_writeFile","data","writeFile","flag"],"sources":["../src/local.js"],"sourcesContent":["import df from '@sindresorhus/df'\nimport fs from 'fs-extra'\nimport lockfile from 'proper-lockfile'\nimport { fromEvent, retry } from 'promise-toolbox'\n\nimport RemoteHandlerAbstract from './abstract'\n\nexport default class LocalHandler extends RemoteHandlerAbstract {\n constructor(remote, opts = {}) {\n super(remote)\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 fs.close(fd)\n }\n\n async _copy(oldPath, newPath) {\n return 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 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 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.file(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 fs.stat(this._getFilePath(typeof file === 'string' ? file : file.path))\n return stats.size\n }\n\n async _list(dir) {\n return fs.readdir(this._getFilePath(dir))\n }\n\n _lock(path) {\n return lockfile.lock(this._getFilePath(path))\n }\n\n _mkdir(dir, { mode }) {\n return fs.mkdir(this._getFilePath(dir), { mode })\n }\n\n async _openFile(path, flags) {\n return fs.open(this._getFilePath(path), flags)\n }\n\n async _read(file, buffer, position) {\n const needsClose = typeof file === 'string'\n file = needsClose ? await fs.open(this._getFilePath(file), 'r') : file.fd\n try {\n return await fs.read(file, buffer, 0, buffer.length, position === undefined ? null : position)\n } finally {\n if (needsClose) {\n await fs.close(file)\n }\n }\n }\n\n async _readFile(file, options) {\n const filePath = this._getFilePath(file)\n return await retry(() => fs.readFile(filePath, options), this._retriesOnEagain)\n }\n\n async _rename(oldPath, newPath) {\n return fs.rename(this._getFilePath(oldPath), this._getFilePath(newPath))\n }\n\n async _rmdir(dir) {\n return fs.rmdir(this._getFilePath(dir))\n }\n\n async _sync() {\n const path = this._getRealPath('/')\n await fs.ensureDir(path)\n await fs.access(path, fs.R_OK | fs.W_OK)\n }\n\n _truncate(file, len) {\n return fs.truncate(this._getFilePath(file), len)\n }\n\n async _unlink(file) {\n const filePath = this._getFilePath(file)\n return await retry(() => fs.unlink(filePath), this._retriesOnEagain)\n }\n\n _writeFd(file, buffer, position) {\n return fs.write(file.fd, buffer, 0, buffer.length, position)\n }\n\n _writeFile(file, data, { flags }) {\n return fs.writeFile(this._getFilePath(file), data, { flag: flags })\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"local.js","names":["info","warn","createLogger","addSyncStackTrace","promise","stackContainer","Error","error","stack","LocalHandler","RemoteHandlerAbstract","constructor","remote","opts","_addSyncStackTrace","syncStackTraces","identity","_retriesOnEagain","delay","retries","retriesOnEagain","when","code","type","_getRealPath","_remote","path","_getFilePath","file","_closeFile","fd","fs","close","_copy","oldPath","newPath","copy","_createReadStream","options","stream","createReadStream","fromEvent","autoClose","_createWriteStream","createWriteStream","_getInfo","df","Object","keys","forEach","key","Number","isNaN","_getSize","stats","stat","size","_list","dir","readdir","_lock","acquire","lockfile","lock","bind","undefined","onCompromised","release","_mkdir","mode","mkdir","_openFile","flags","open","_read","buffer","position","needsClose","read","length","_readFile","filePath","retry","readFile","_rename","rename","_rmdir","rmdir","_sync","ensureDir","access","R_OK","W_OK","_truncate","len","truncate","_unlink","unlink","_writeFd","write","_writeFile","data","writeFile","flag"],"sources":["../src/local.js"],"sourcesContent":["import df from '@sindresorhus/df'\nimport fs from 'fs-extra'\nimport identity from 'lodash/identity.js'\nimport lockfile from 'proper-lockfile'\nimport { createLogger } from '@xen-orchestra/log'\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(promise) {\n const stackContainer = new Error()\n try {\n return await promise\n } catch (error) {\n error.stack = stackContainer.stack\n throw error\n }\n}\n\nexport default class LocalHandler extends RemoteHandlerAbstract {\n constructor(remote, opts = {}) {\n super(remote)\n\n this._addSyncStackTrace = opts.syncStackTraces ?? true ? addSyncStackTrace : identity\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.file(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 acquire()\n\n return async () => {\n try {\n await 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(file, buffer, 0, buffer.length, 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, options) {\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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"}
|
package/dist/smb.js
CHANGED
|
@@ -5,163 +5,36 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
|
|
8
|
-
var
|
|
8
|
+
var _xoRemoteParser = require("xo-remote-parser");
|
|
9
9
|
|
|
10
|
-
var
|
|
10
|
+
var _mount = _interopRequireDefault(require("./_mount"));
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const wrapError = (error, code) => ({
|
|
15
|
-
__proto__: error,
|
|
16
|
-
cause: error,
|
|
17
|
-
code
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
const normalizeError = (error, shouldBeDirectory) => {
|
|
21
|
-
const {
|
|
22
|
-
code
|
|
23
|
-
} = error;
|
|
24
|
-
throw code === 'STATUS_DIRECTORY_NOT_EMPTY' ? wrapError(error, 'ENOTEMPTY') : code === 'STATUS_FILE_IS_A_DIRECTORY' ? wrapError(error, 'EISDIR') : code === 'STATUS_NOT_A_DIRECTORY' ? wrapError(error, 'ENOTDIR') : code === 'STATUS_OBJECT_NAME_NOT_FOUND' || code === 'STATUS_OBJECT_PATH_NOT_FOUND' ? wrapError(error, 'ENOENT') : code === 'STATUS_OBJECT_NAME_COLLISION' ? wrapError(error, 'EEXIST') : code === 'STATUS_NOT_SUPPORTED' || code === 'STATUS_INVALID_PARAMETER' ? wrapError(error, shouldBeDirectory ? 'ENOTDIR' : 'EISDIR') : error;
|
|
25
|
-
};
|
|
12
|
+
var _path = require("./path");
|
|
26
13
|
|
|
27
|
-
|
|
14
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
28
15
|
|
|
29
|
-
class SmbHandler extends
|
|
16
|
+
class SmbHandler extends _mount.default {
|
|
30
17
|
constructor(remote, opts) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
_dirname(file) {
|
|
46
|
-
const parts = file.split('\\');
|
|
47
|
-
parts.pop();
|
|
48
|
-
return parts.join('\\');
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
_closeFile(file) {
|
|
52
|
-
return this._client.close(file).catch(normalizeError);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
_createReadStream(file, options) {
|
|
56
|
-
if (typeof file === 'string') {
|
|
57
|
-
file = this._getFilePath(file);
|
|
58
|
-
} else {
|
|
59
|
-
options = {
|
|
60
|
-
autoClose: false,
|
|
61
|
-
...options,
|
|
62
|
-
fd: file.fd
|
|
63
|
-
};
|
|
64
|
-
file = '';
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return this._client.createReadStream(file, options).catch(normalizeError);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
_createWriteStream(file, options) {
|
|
71
|
-
if (typeof file === 'string') {
|
|
72
|
-
file = this._getFilePath(file);
|
|
73
|
-
} else {
|
|
74
|
-
options = {
|
|
75
|
-
autoClose: false,
|
|
76
|
-
...options,
|
|
77
|
-
fd: file.fd
|
|
78
|
-
};
|
|
79
|
-
file = '';
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return this._client.createWriteStream(file, options).catch(normalizeError);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
_forget() {
|
|
86
|
-
const client = this._client;
|
|
87
|
-
this._client = undefined;
|
|
88
|
-
return client.disconnect();
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
_getSize(file) {
|
|
92
|
-
return this._client.getSize(this._getFilePath(file)).catch(normalizeError);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
_list(dir) {
|
|
96
|
-
return this._client.readdir(this._getFilePath(dir)).catch(normalizeDirError);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
_mkdir(dir, {
|
|
100
|
-
mode
|
|
101
|
-
}) {
|
|
102
|
-
return this._client.mkdir(this._getFilePath(dir), mode).catch(normalizeDirError);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
_openFile(path, flags) {
|
|
106
|
-
return this._client.open(this._getFilePath(path), flags).catch(normalizeError);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
async _read(file, buffer, position) {
|
|
110
|
-
const client = this._client;
|
|
111
|
-
const needsClose = typeof file === 'string';
|
|
112
|
-
file = needsClose ? await client.open(this._getFilePath(file)) : file.fd;
|
|
113
|
-
|
|
114
|
-
try {
|
|
115
|
-
return await client.read(file, buffer, 0, buffer.length, position);
|
|
116
|
-
} catch (error) {
|
|
117
|
-
normalizeError(error);
|
|
118
|
-
} finally {
|
|
119
|
-
if (needsClose) {
|
|
120
|
-
await client.close(file);
|
|
18
|
+
const {
|
|
19
|
+
domain = 'WORKGROUP',
|
|
20
|
+
host,
|
|
21
|
+
password,
|
|
22
|
+
path,
|
|
23
|
+
username
|
|
24
|
+
} = (0, _xoRemoteParser.parse)(remote.url);
|
|
25
|
+
super(remote, opts, {
|
|
26
|
+
type: 'cifs',
|
|
27
|
+
device: '//' + host + (0, _path.normalize)(path),
|
|
28
|
+
options: `domain=${domain}`,
|
|
29
|
+
env: {
|
|
30
|
+
USER: username,
|
|
31
|
+
PASSWD: password
|
|
121
32
|
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
_readFile(file, options) {
|
|
126
|
-
return this._client.readFile(this._getFilePath(file), options).catch(normalizeError);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
_rename(oldPath, newPath) {
|
|
130
|
-
return this._client.rename(this._getFilePath(oldPath), this._getFilePath(newPath), {
|
|
131
|
-
replace: true
|
|
132
|
-
}).catch(normalizeError);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
_rmdir(dir) {
|
|
136
|
-
return this._client.rmdir(this._getFilePath(dir)).catch(normalizeDirError);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
_sync() {
|
|
140
|
-
const remote = this._remote;
|
|
141
|
-
this._client = new _smb.default({
|
|
142
|
-
share: `\\\\${remote.host}`,
|
|
143
|
-
domain: remote.domain,
|
|
144
|
-
username: remote.username,
|
|
145
|
-
password: remote.password,
|
|
146
|
-
autoCloseTimeout: 0
|
|
147
33
|
});
|
|
148
|
-
return this.list('.');
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
_truncate(file, len) {
|
|
152
|
-
return this._client.truncate(this._getFilePath(file), len).catch(normalizeError);
|
|
153
34
|
}
|
|
154
35
|
|
|
155
|
-
|
|
156
|
-
return
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
_writeFd(file, buffer, position) {
|
|
160
|
-
return this._client.write(file.fd, buffer, 0, buffer.length, position);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
_writeFile(file, data, options) {
|
|
164
|
-
return this._client.writeFile(this._getFilePath(file), data, options).catch(normalizeError);
|
|
36
|
+
get type() {
|
|
37
|
+
return 'smb';
|
|
165
38
|
}
|
|
166
39
|
|
|
167
40
|
}
|
package/dist/smb.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"smb.js","names":["wrapError","error","code","__proto__","cause","normalizeError","shouldBeDirectory","normalizeDirError","SmbHandler","RemoteHandlerAbstract","constructor","remote","opts","_client","undefined","prefix","_remote","path","_prefix","type","_getFilePath","file","slice","replace","_dirname","parts","split","pop","join","_closeFile","close","catch","_createReadStream","options","autoClose","fd","createReadStream","_createWriteStream","createWriteStream","_forget","client","disconnect","_getSize","getSize","_list","dir","readdir","_mkdir","mode","mkdir","_openFile","flags","open","_read","buffer","position","needsClose","read","length","_readFile","readFile","_rename","oldPath","newPath","rename","_rmdir","rmdir","_sync","Smb2","share","host","domain","username","password","autoCloseTimeout","list","_truncate","len","truncate","_unlink","unlink","_writeFd","write","_writeFile","data","writeFile"],"sources":["../src/smb.js"],"sourcesContent":["import Smb2 from '@marsaud/smb2'\n\nimport RemoteHandlerAbstract from './abstract'\n\n// Normalize the error code for file not found.\nconst wrapError = (error, code) => ({\n __proto__: error,\n cause: error,\n code,\n})\nconst normalizeError = (error, shouldBeDirectory) => {\n const { code } = error\n\n throw code === 'STATUS_DIRECTORY_NOT_EMPTY'\n ? wrapError(error, 'ENOTEMPTY')\n : code === 'STATUS_FILE_IS_A_DIRECTORY'\n ? wrapError(error, 'EISDIR')\n : code === 'STATUS_NOT_A_DIRECTORY'\n ? wrapError(error, 'ENOTDIR')\n : code === 'STATUS_OBJECT_NAME_NOT_FOUND' || code === 'STATUS_OBJECT_PATH_NOT_FOUND'\n ? wrapError(error, 'ENOENT')\n : code === 'STATUS_OBJECT_NAME_COLLISION'\n ? wrapError(error, 'EEXIST')\n : code === 'STATUS_NOT_SUPPORTED' || code === 'STATUS_INVALID_PARAMETER'\n ? wrapError(error, shouldBeDirectory ? 'ENOTDIR' : 'EISDIR')\n : error\n}\nconst normalizeDirError = error => normalizeError(error, true)\n\nexport default class SmbHandler extends RemoteHandlerAbstract {\n constructor(remote, opts) {\n super(remote, opts)\n\n // defined in _sync()\n this._client = undefined\n\n const prefix = this._remote.path\n this._prefix = prefix !== '' ? prefix + '\\\\' : prefix\n }\n\n get type() {\n return 'smb'\n }\n\n _getFilePath(file) {\n return this._prefix + (typeof file === 'string' ? file : file.path).slice(1).replace(/\\//g, '\\\\')\n }\n\n _dirname(file) {\n const parts = file.split('\\\\')\n parts.pop()\n return parts.join('\\\\')\n }\n\n _closeFile(file) {\n return this._client.close(file).catch(normalizeError)\n }\n\n _createReadStream(file, options) {\n if (typeof file === 'string') {\n file = this._getFilePath(file)\n } else {\n options = { autoClose: false, ...options, fd: file.fd }\n file = ''\n }\n return this._client.createReadStream(file, options).catch(normalizeError)\n }\n\n _createWriteStream(file, options) {\n if (typeof file === 'string') {\n file = this._getFilePath(file)\n } else {\n options = { autoClose: false, ...options, fd: file.fd }\n file = ''\n }\n return this._client.createWriteStream(file, options).catch(normalizeError)\n }\n\n _forget() {\n const client = this._client\n this._client = undefined\n return client.disconnect()\n }\n\n _getSize(file) {\n return this._client.getSize(this._getFilePath(file)).catch(normalizeError)\n }\n\n _list(dir) {\n return this._client.readdir(this._getFilePath(dir)).catch(normalizeDirError)\n }\n\n _mkdir(dir, { mode }) {\n return this._client.mkdir(this._getFilePath(dir), mode).catch(normalizeDirError)\n }\n\n // TODO: add flags\n _openFile(path, flags) {\n return this._client.open(this._getFilePath(path), flags).catch(normalizeError)\n }\n\n async _read(file, buffer, position) {\n const client = this._client\n const needsClose = typeof file === 'string'\n file = needsClose ? await client.open(this._getFilePath(file)) : file.fd\n try {\n return await client.read(file, buffer, 0, buffer.length, position)\n } catch (error) {\n normalizeError(error)\n } finally {\n if (needsClose) {\n await client.close(file)\n }\n }\n }\n\n _readFile(file, options) {\n return this._client.readFile(this._getFilePath(file), options).catch(normalizeError)\n }\n\n _rename(oldPath, newPath) {\n return this._client\n .rename(this._getFilePath(oldPath), this._getFilePath(newPath), {\n replace: true,\n })\n .catch(normalizeError)\n }\n\n _rmdir(dir) {\n return this._client.rmdir(this._getFilePath(dir)).catch(normalizeDirError)\n }\n\n _sync() {\n const remote = this._remote\n\n this._client = new Smb2({\n share: `\\\\\\\\${remote.host}`,\n domain: remote.domain,\n username: remote.username,\n password: remote.password,\n autoCloseTimeout: 0,\n })\n\n // Check access (smb2 does not expose connect in public so far...)\n return this.list('.')\n }\n\n _truncate(file, len) {\n return this._client.truncate(this._getFilePath(file), len).catch(normalizeError)\n }\n\n _unlink(file) {\n return this._client.unlink(this._getFilePath(file)).catch(normalizeError)\n }\n\n _writeFd(file, buffer, position) {\n return this._client.write(file.fd, buffer, 0, buffer.length, position)\n }\n\n _writeFile(file, data, options) {\n return this._client.writeFile(this._getFilePath(file), data, options).catch(normalizeError)\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"smb.js","names":["SmbHandler","MountHandler","constructor","remote","opts","domain","host","password","path","username","parse","url","type","device","normalize","options","env","USER","PASSWD"],"sources":["../src/smb.js"],"sourcesContent":["import { parse } from 'xo-remote-parser'\n\nimport MountHandler from './_mount'\nimport { normalize } from './path'\n\nexport default class SmbHandler extends MountHandler {\n constructor(remote, opts) {\n const { domain = 'WORKGROUP', host, password, path, username } = parse(remote.url)\n super(remote, opts, {\n type: 'cifs',\n device: '//' + host + normalize(path),\n options: `domain=${domain}`,\n env: {\n USER: username,\n PASSWD: password,\n },\n })\n }\n\n get type() {\n return 'smb'\n }\n}\n"],"mappings":";;;;;;;AAAA;;AAEA;;AACA;;;;AAEe,MAAMA,UAAN,SAAyBC,cAAzB,CAAsC;EACnDC,WAAW,CAACC,MAAD,EAASC,IAAT,EAAe;IACxB,MAAM;MAAEC,MAAM,GAAG,WAAX;MAAwBC,IAAxB;MAA8BC,QAA9B;MAAwCC,IAAxC;MAA8CC;IAA9C,IAA2D,IAAAC,qBAAA,EAAMP,MAAM,CAACQ,GAAb,CAAjE;IACA,MAAMR,MAAN,EAAcC,IAAd,EAAoB;MAClBQ,IAAI,EAAE,MADY;MAElBC,MAAM,EAAE,OAAOP,IAAP,GAAc,IAAAQ,eAAA,EAAUN,IAAV,CAFJ;MAGlBO,OAAO,EAAG,UAASV,MAAO,EAHR;MAIlBW,GAAG,EAAE;QACHC,IAAI,EAAER,QADH;QAEHS,MAAM,EAAEX;MAFL;IAJa,CAApB;EASD;;EAEO,IAAJK,IAAI,GAAG;IACT,OAAO,KAAP;EACD;;AAhBkD"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"private": false,
|
|
3
3
|
"name": "@xen-orchestra/fs",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "3.0.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",
|
|
@@ -24,11 +24,11 @@
|
|
|
24
24
|
"@aws-sdk/lib-storage": "^3.54.0",
|
|
25
25
|
"@aws-sdk/middleware-apply-body-checksum": "^3.58.0",
|
|
26
26
|
"@aws-sdk/node-http-handler": "^3.54.0",
|
|
27
|
-
"@marsaud/smb2": "^0.18.0",
|
|
28
27
|
"@sindresorhus/df": "^3.1.1",
|
|
29
28
|
"@vates/async-each": "^1.0.0",
|
|
30
29
|
"@vates/coalesce-calls": "^0.1.0",
|
|
31
30
|
"@vates/decorate-with": "^2.0.0",
|
|
31
|
+
"@vates/read-chunk": "^1.0.0",
|
|
32
32
|
"@xen-orchestra/async-map": "^0.1.2",
|
|
33
33
|
"@xen-orchestra/log": "^0.3.0",
|
|
34
34
|
"bind-property-descriptor": "^2.0.0",
|
|
@@ -40,7 +40,8 @@
|
|
|
40
40
|
"lodash": "^4.17.4",
|
|
41
41
|
"promise-toolbox": "^0.21.0",
|
|
42
42
|
"proper-lockfile": "^4.1.2",
|
|
43
|
-
"
|
|
43
|
+
"pumpify": "^2.0.1",
|
|
44
|
+
"readable-stream": "^4.1.0",
|
|
44
45
|
"through2": "^4.0.2",
|
|
45
46
|
"xo-remote-parser": "^0.9.1"
|
|
46
47
|
},
|
package/dist/smb-mount.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = void 0;
|
|
7
|
-
|
|
8
|
-
var _xoRemoteParser = require("xo-remote-parser");
|
|
9
|
-
|
|
10
|
-
var _mount = _interopRequireDefault(require("./_mount"));
|
|
11
|
-
|
|
12
|
-
var _path = require("./path");
|
|
13
|
-
|
|
14
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
-
|
|
16
|
-
class SmbMountHandler extends _mount.default {
|
|
17
|
-
constructor(remote, opts) {
|
|
18
|
-
const {
|
|
19
|
-
domain = 'WORKGROUP',
|
|
20
|
-
host,
|
|
21
|
-
password,
|
|
22
|
-
path,
|
|
23
|
-
username
|
|
24
|
-
} = (0, _xoRemoteParser.parse)(remote.url);
|
|
25
|
-
super(remote, opts, {
|
|
26
|
-
type: 'cifs',
|
|
27
|
-
device: '//' + host + (0, _path.normalize)(path),
|
|
28
|
-
options: `domain=${domain}`,
|
|
29
|
-
env: {
|
|
30
|
-
USER: username,
|
|
31
|
-
PASSWD: password
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
get type() {
|
|
37
|
-
return 'smb';
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
exports.default = SmbMountHandler;
|
|
43
|
-
//# sourceMappingURL=smb-mount.js.map
|
package/dist/smb-mount.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"smb-mount.js","names":["SmbMountHandler","MountHandler","constructor","remote","opts","domain","host","password","path","username","parse","url","type","device","normalize","options","env","USER","PASSWD"],"sources":["../src/smb-mount.js"],"sourcesContent":["import { parse } from 'xo-remote-parser'\n\nimport MountHandler from './_mount'\nimport { normalize } from './path'\n\nexport default class SmbMountHandler extends MountHandler {\n constructor(remote, opts) {\n const { domain = 'WORKGROUP', host, password, path, username } = parse(remote.url)\n super(remote, opts, {\n type: 'cifs',\n device: '//' + host + normalize(path),\n options: `domain=${domain}`,\n env: {\n USER: username,\n PASSWD: password,\n },\n })\n }\n\n get type() {\n return 'smb'\n }\n}\n"],"mappings":";;;;;;;AAAA;;AAEA;;AACA;;;;AAEe,MAAMA,eAAN,SAA8BC,cAA9B,CAA2C;EACxDC,WAAW,CAACC,MAAD,EAASC,IAAT,EAAe;IACxB,MAAM;MAAEC,MAAM,GAAG,WAAX;MAAwBC,IAAxB;MAA8BC,QAA9B;MAAwCC,IAAxC;MAA8CC;IAA9C,IAA2D,IAAAC,qBAAA,EAAMP,MAAM,CAACQ,GAAb,CAAjE;IACA,MAAMR,MAAN,EAAcC,IAAd,EAAoB;MAClBQ,IAAI,EAAE,MADY;MAElBC,MAAM,EAAE,OAAOP,IAAP,GAAc,IAAAQ,eAAA,EAAUN,IAAV,CAFJ;MAGlBO,OAAO,EAAG,UAASV,MAAO,EAHR;MAIlBW,GAAG,EAAE;QACHC,IAAI,EAAER,QADH;QAEHS,MAAM,EAAEX;MAFL;IAJa,CAApB;EASD;;EAEO,IAAJK,IAAI,GAAG;IACT,OAAO,KAAP;EACD;;AAhBuD"}
|