@datatruck/cli 0.18.0 → 0.19.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/Action/BackupAction.js +4 -2
- package/Action/BackupSessionsAction.js +2 -0
- package/Action/CleanCacheAction.js +1 -0
- package/Action/ConfigAction.js +1 -0
- package/Action/InitAction.js +2 -0
- package/Action/PruneAction.js +2 -0
- package/Action/RestoreAction.js +4 -2
- package/Action/RestoreSessionsAction.js +2 -0
- package/Action/SnapshotsAction.js +2 -0
- package/Command/CommandAbstract.js +2 -0
- package/Entity/BackupSessionEntity.js +5 -2
- package/Entity/BackupSessionRepositoryEntity.js +5 -2
- package/Entity/BackupSessionTaskEntity.js +4 -2
- package/Entity/CrudEntityAbstract.js +3 -0
- package/Entity/RestoreSessionEntity.js +4 -2
- package/Entity/RestoreSessionRepositoryEntity.js +5 -2
- package/Entity/RestoreSessionTaskEntity.js +4 -2
- package/Entity/StateEntityAbstract.js +5 -0
- package/Factory/CommandFactory.js +1 -1
- package/JsonSchema/DefinitionEnum.js +1 -1
- package/Repository/DatatruckRepository.d.ts +8 -13
- package/Repository/DatatruckRepository.js +112 -229
- package/Repository/GitRepository.js +1 -1
- package/Repository/RepositoryAbstract.js +4 -2
- package/Repository/ResticRepository.js +2 -1
- package/SessionDriver/ConsoleSessionDriver.js +9 -5
- package/SessionDriver/SessionDriverAbstract.js +3 -2
- package/SessionDriver/SqliteSessionDriver.js +2 -4
- package/SessionManager/BackupSessionManager.js +3 -6
- package/SessionManager/RestoreSessionManager.js +3 -6
- package/SessionManager/SessionManagerAbstract.js +4 -0
- package/Task/GitTask.js +1 -0
- package/Task/MariadbTask.js +5 -4
- package/Task/MssqlTask.js +2 -1
- package/Task/ScriptTask.js +1 -0
- package/Task/SqlDumpTaskAbstract.js +1 -0
- package/Task/TaskAbstract.js +2 -1
- package/config.schema.json +23 -37
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +9 -8
- package/utils/DataFormat.js +1 -0
- package/utils/Git.js +1 -0
- package/utils/ObjectVault.js +3 -5
- package/utils/Restic.js +1 -0
- package/utils/fs.d.ts +3 -9
- package/utils/fs.js +24 -32
- package/utils/tar.d.ts +32 -0
- package/utils/tar.js +92 -0
- package/utils/zip.d.ts +0 -97
- package/utils/zip.js +0 -238
|
@@ -7,14 +7,12 @@ const cli_1 = require("../utils/cli");
|
|
|
7
7
|
const paths_1 = require("../utils/datatruck/paths");
|
|
8
8
|
const fs_1 = require("../utils/fs");
|
|
9
9
|
const string_1 = require("../utils/string");
|
|
10
|
-
const
|
|
10
|
+
const tar_1 = require("../utils/tar");
|
|
11
11
|
const RepositoryAbstract_1 = require("./RepositoryAbstract");
|
|
12
12
|
const assert_1 = require("assert");
|
|
13
|
-
const fs_2 = require("fs");
|
|
14
13
|
const promises_1 = require("fs/promises");
|
|
15
14
|
const micromatch_1 = require("micromatch");
|
|
16
15
|
const path_1 = require("path");
|
|
17
|
-
const readline_1 = require("readline");
|
|
18
16
|
exports.datatruckRepositoryName = "datatruck";
|
|
19
17
|
exports.datatruckRepositoryDefinition = {
|
|
20
18
|
type: "object",
|
|
@@ -30,39 +28,26 @@ exports.datatruckPackageRepositoryDefinition = {
|
|
|
30
28
|
additionalProperties: false,
|
|
31
29
|
properties: {
|
|
32
30
|
compress: {
|
|
33
|
-
|
|
34
|
-
{
|
|
35
|
-
type: "boolean",
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
type: "object",
|
|
39
|
-
additionalProperties: false,
|
|
40
|
-
properties: {
|
|
41
|
-
packs: {
|
|
42
|
-
type: "array",
|
|
43
|
-
items: {
|
|
44
|
-
type: "object",
|
|
45
|
-
additionalProperties: false,
|
|
46
|
-
required: ["include"],
|
|
47
|
-
properties: {
|
|
48
|
-
name: { type: "string" },
|
|
49
|
-
include: (0, DefinitionEnum_1.makeRef)(DefinitionEnum_1.DefinitionEnum.stringListUtil),
|
|
50
|
-
exclude: (0, DefinitionEnum_1.makeRef)(DefinitionEnum_1.DefinitionEnum.stringListUtil),
|
|
51
|
-
onePackByResult: { type: "boolean" },
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
],
|
|
31
|
+
type: "boolean",
|
|
58
32
|
},
|
|
59
|
-
|
|
60
|
-
type: "
|
|
61
|
-
|
|
33
|
+
packs: {
|
|
34
|
+
type: "array",
|
|
35
|
+
items: {
|
|
36
|
+
type: "object",
|
|
37
|
+
additionalProperties: false,
|
|
38
|
+
required: ["include"],
|
|
39
|
+
properties: {
|
|
40
|
+
name: { type: "string" },
|
|
41
|
+
include: (0, DefinitionEnum_1.makeRef)(DefinitionEnum_1.DefinitionEnum.stringListUtil),
|
|
42
|
+
exclude: (0, DefinitionEnum_1.makeRef)(DefinitionEnum_1.DefinitionEnum.stringListUtil),
|
|
43
|
+
onePackByResult: { type: "boolean" },
|
|
44
|
+
},
|
|
45
|
+
},
|
|
62
46
|
},
|
|
63
47
|
},
|
|
64
48
|
};
|
|
65
49
|
class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
50
|
+
static zipBasenameTpl = `.*.dd.tar.gz`;
|
|
66
51
|
static buildSnapshotName(data) {
|
|
67
52
|
const date = data.snapshotDate.replace(/:/g, "-");
|
|
68
53
|
const pkgName = encodeURIComponent(data.packageName).replace(/%40/g, "@");
|
|
@@ -159,22 +144,6 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
159
144
|
}
|
|
160
145
|
return snapshots;
|
|
161
146
|
}
|
|
162
|
-
normalizeCompressConfig(packageConfig) {
|
|
163
|
-
let compress = packageConfig?.compress ?? this.config.compress;
|
|
164
|
-
if (compress === true || (compress && !Array.isArray(compress.packs))) {
|
|
165
|
-
return {
|
|
166
|
-
packs: [
|
|
167
|
-
{
|
|
168
|
-
include: ["**"],
|
|
169
|
-
},
|
|
170
|
-
],
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
else if (!compress) {
|
|
174
|
-
return undefined;
|
|
175
|
-
}
|
|
176
|
-
return compress;
|
|
177
|
-
}
|
|
178
147
|
async onBackup(data) {
|
|
179
148
|
const snapshotName = DatatruckRepository.buildSnapshotName({
|
|
180
149
|
snapshotId: data.snapshot.id,
|
|
@@ -183,134 +152,74 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
183
152
|
});
|
|
184
153
|
const outPath = (0, path_1.resolve)((0, path_1.join)(this.config.outPath, snapshotName));
|
|
185
154
|
const pkg = data.package;
|
|
186
|
-
await (0, promises_1.mkdir)(outPath, {
|
|
187
|
-
recursive: true,
|
|
188
|
-
});
|
|
189
155
|
const sourcePath = data.targetPath ?? pkg.path;
|
|
190
156
|
(0, assert_1.ok)(sourcePath);
|
|
191
|
-
|
|
192
|
-
const include = await (0, paths_1.parsePaths)(pkg.include ?? ["**"], {
|
|
193
|
-
cwd: sourcePath,
|
|
194
|
-
verbose: data.options.verbose,
|
|
195
|
-
});
|
|
196
|
-
const exclude = pkg.exclude
|
|
197
|
-
? await (0, paths_1.parsePaths)(pkg.exclude, {
|
|
198
|
-
cwd: sourcePath,
|
|
199
|
-
verbose: data.options.verbose,
|
|
200
|
-
})
|
|
201
|
-
: undefined;
|
|
202
|
-
const packs = compress?.packs || [];
|
|
203
|
-
const tmpDir = await this.mkTmpDir("path-lists");
|
|
204
|
-
const unpackedStream = (0, fs_2.createWriteStream)((0, path_1.join)(tmpDir, "unpacked.txt"));
|
|
205
|
-
const singlePackStream = (0, fs_2.createWriteStream)((0, path_1.join)(tmpDir, "single-pack.txt"));
|
|
206
|
-
const packStreams = Array.from({ length: packs.length }).map((v, i) => (0, fs_2.createWriteStream)((0, path_1.join)(tmpDir, `pack-${i}.txt`)));
|
|
207
|
-
const streams = [unpackedStream, singlePackStream, ...packStreams];
|
|
208
|
-
if (data.options.verbose)
|
|
209
|
-
(0, cli_1.logExec)(`Writing file lists in ${tmpDir}`);
|
|
157
|
+
await (0, promises_1.mkdir)(outPath, { recursive: true });
|
|
210
158
|
const scanner = await (0, fs_1.createFileScanner)({
|
|
159
|
+
onProgress: data.onProgress,
|
|
211
160
|
glob: {
|
|
212
|
-
include,
|
|
213
161
|
cwd: sourcePath,
|
|
214
|
-
ignore: exclude,
|
|
215
162
|
onlyFiles: false,
|
|
163
|
+
include: await (0, paths_1.parsePaths)(pkg.include ?? ["**"], {
|
|
164
|
+
cwd: sourcePath,
|
|
165
|
+
verbose: data.options.verbose,
|
|
166
|
+
}),
|
|
167
|
+
ignore: pkg.exclude
|
|
168
|
+
? await (0, paths_1.parsePaths)(pkg.exclude, {
|
|
169
|
+
cwd: sourcePath,
|
|
170
|
+
verbose: data.options.verbose,
|
|
171
|
+
})
|
|
172
|
+
: undefined,
|
|
216
173
|
},
|
|
217
|
-
onProgress: data.onProgress,
|
|
218
|
-
disableCounting: true,
|
|
219
174
|
});
|
|
220
|
-
|
|
221
|
-
...
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
? await (0, fs_1.isEmptyDir)((0, path_1.join)(sourcePath, entry.path))
|
|
244
|
-
: true
|
|
245
|
-
: true;
|
|
246
|
-
if (include) {
|
|
247
|
-
let value = entry.path;
|
|
248
|
-
if (isUnpackedStream) {
|
|
249
|
-
value += `:${entry.stats.uid}:${entry.stats.gid}:${entry.stats.mode}`;
|
|
250
|
-
}
|
|
251
|
-
else if (isSinglePackStream) {
|
|
252
|
-
value += `:${successPackIndex}`;
|
|
253
|
-
}
|
|
254
|
-
if (!entry.stats.isDirectory())
|
|
255
|
-
scanner.total++;
|
|
256
|
-
stream.write(`${value}\n`);
|
|
257
|
-
}
|
|
175
|
+
const configPacks = (data.packageConfig?.packs ?? []).map((p) => ({
|
|
176
|
+
...p,
|
|
177
|
+
compress: p.compress ?? data.packageConfig?.compress ?? this.config.compress,
|
|
178
|
+
includeResult: [],
|
|
179
|
+
}));
|
|
180
|
+
const defaultsPack = {
|
|
181
|
+
name: "defaults",
|
|
182
|
+
compress: data.packageConfig?.compress ?? this.config.compress,
|
|
183
|
+
include: [],
|
|
184
|
+
includeResult: [],
|
|
185
|
+
};
|
|
186
|
+
const packs = [...configPacks, defaultsPack];
|
|
187
|
+
await scanner.start(async (entry) => {
|
|
188
|
+
if (entry.dirent.isDirectory() &&
|
|
189
|
+
!(await (0, fs_1.isEmptyDir)((0, path_1.join)(sourcePath, entry.path))))
|
|
190
|
+
return false;
|
|
191
|
+
const pack = configPacks.find((pack) => (0, string_1.checkPath)(entry.path, pack.include, pack.exclude)) || defaultsPack;
|
|
192
|
+
if (pack.onePackByResult) {
|
|
193
|
+
const subname = (0, path_1.basename)(entry.path);
|
|
194
|
+
packs.push({
|
|
195
|
+
...pack,
|
|
196
|
+
name: pack.name ? `${pack.name}-${subname}` : subname,
|
|
197
|
+
includeResult: [entry.path],
|
|
258
198
|
});
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
const unpackedPath = (0, path_1.join)(outPath, "unpacked");
|
|
265
|
-
await (0, promises_1.mkdir)(unpackedPath);
|
|
266
|
-
await (0, promises_1.copyFile)(unpackedStream.path, (0, path_1.join)(outPath, "permissions.txt"));
|
|
267
|
-
// Non pack
|
|
268
|
-
if (data.options.verbose)
|
|
269
|
-
(0, cli_1.logExec)(`Copying files from ${unpackedStream.path.toString()} to ${unpackedPath}`);
|
|
270
|
-
await (0, fs_1.cpy)({
|
|
271
|
-
input: {
|
|
272
|
-
type: "pathList",
|
|
273
|
-
path: unpackedStream.path.toString(),
|
|
274
|
-
basePath: sourcePath,
|
|
275
|
-
},
|
|
276
|
-
targetPath: unpackedPath,
|
|
277
|
-
skipNotFoundError: true,
|
|
278
|
-
concurrency: this.config.fileCopyConcurrency,
|
|
279
|
-
onProgress: async (progress) => await scanner.progress(progress.type === "end" ? "Files copied" : "Copying file", progress),
|
|
280
|
-
});
|
|
281
|
-
// Single pack
|
|
282
|
-
const singleReader = (0, readline_1.createInterface)({
|
|
283
|
-
input: (0, fs_2.createReadStream)(singlePackStream.path),
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
pack.includeResult.push(entry.path);
|
|
202
|
+
}
|
|
203
|
+
return true;
|
|
284
204
|
});
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
const
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
}
|
|
302
|
-
// Packs
|
|
303
|
-
for (const [packIndex, packStream] of packStreams.entries()) {
|
|
304
|
-
const pack = packs[packIndex];
|
|
305
|
-
const target = (0, path_1.join)(outPath, `pack-${packIndex}${pack.name ? `-${pack.name}` : ""}.zip`);
|
|
306
|
-
await (0, zip_1.zip)({
|
|
307
|
-
path: sourcePath,
|
|
308
|
-
output: target,
|
|
309
|
-
includeList: packStream.path.toString(),
|
|
310
|
-
verbose: data.options.verbose,
|
|
311
|
-
onProgress: async (progress) => await scanner.progress("Compressing file", progress),
|
|
312
|
-
});
|
|
205
|
+
let packIndex = 0;
|
|
206
|
+
for (const pack of packs) {
|
|
207
|
+
const packBasename = [`pack`, (packIndex++).toString(), pack.name]
|
|
208
|
+
.filter((v) => typeof v === "string")
|
|
209
|
+
.map((v) => encodeURIComponent(v.toString().replace(/[\\/]/g, "-")))
|
|
210
|
+
.join("-");
|
|
211
|
+
const ext = pack.compress ? `.tar.gz` : `.tar`;
|
|
212
|
+
if (pack.includeResult.length)
|
|
213
|
+
await (0, tar_1.createTar)({
|
|
214
|
+
compress: pack.compress,
|
|
215
|
+
verbose: data.options.verbose,
|
|
216
|
+
include: pack.includeResult,
|
|
217
|
+
path: sourcePath,
|
|
218
|
+
output: (0, path_1.join)(outPath, packBasename) + ext,
|
|
219
|
+
onEntry: async (data) => await scanner.progress(pack.compress ? "Compressing" : "Packing", data.path),
|
|
220
|
+
});
|
|
313
221
|
}
|
|
222
|
+
await scanner.end();
|
|
314
223
|
// Meta
|
|
315
224
|
const metaPath = `${outPath}/meta.json`;
|
|
316
225
|
const nodePkg = (0, fs_1.parsePackageFile)();
|
|
@@ -337,23 +246,28 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
337
246
|
const targetPath = (0, path_1.resolve)((0, path_1.join)(data.mirrorRepositoryConfig.outPath, snapshotName));
|
|
338
247
|
if (data.options.verbose)
|
|
339
248
|
(0, cli_1.logExec)(`Copying backup files to ${targetPath}`);
|
|
340
|
-
await (0, promises_1.mkdir)(targetPath);
|
|
249
|
+
await (0, promises_1.mkdir)(targetPath, { recursive: true });
|
|
250
|
+
await (0, fs_1.ensureEmptyDir)(targetPath);
|
|
341
251
|
const scanner = await (0, fs_1.createFileScanner)({
|
|
252
|
+
onProgress: data.onProgress,
|
|
342
253
|
glob: {
|
|
343
254
|
include: ["**/*"],
|
|
344
255
|
cwd: sourcePath,
|
|
345
256
|
},
|
|
346
|
-
onProgress: data.onProgress,
|
|
347
257
|
});
|
|
348
|
-
|
|
349
|
-
await (
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
sourcePath,
|
|
353
|
-
},
|
|
354
|
-
targetPath,
|
|
355
|
-
onProgress: async (progress) => await scanner.progress(progress.type === "end" ? "Files copied" : "Copying file", progress),
|
|
258
|
+
const entryPaths = [];
|
|
259
|
+
await scanner.start(async (entry) => {
|
|
260
|
+
entryPaths.push(entry.path);
|
|
261
|
+
return true;
|
|
356
262
|
});
|
|
263
|
+
for (const entryPath of entryPaths) {
|
|
264
|
+
const sourceFile = (0, path_1.join)(sourcePath, entryPath);
|
|
265
|
+
const targetFile = (0, path_1.join)(targetPath, entryPath);
|
|
266
|
+
await scanner.progress("Copying", entryPath);
|
|
267
|
+
await (0, promises_1.mkdir)((0, path_1.dirname)(targetFile), { recursive: true });
|
|
268
|
+
await (0, promises_1.cp)(sourceFile, targetFile);
|
|
269
|
+
}
|
|
270
|
+
await scanner.end();
|
|
357
271
|
}
|
|
358
272
|
async onRestore(data) {
|
|
359
273
|
const relRestorePath = data.targetPath ?? data.package.restorePath;
|
|
@@ -373,71 +287,40 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
373
287
|
});
|
|
374
288
|
const sourcePath = (0, path_1.join)(this.config.outPath, snapshotName);
|
|
375
289
|
const scanner = await (0, fs_1.createFileScanner)({
|
|
290
|
+
onProgress: data.onProgress,
|
|
376
291
|
glob: {
|
|
377
|
-
include: ["unpacked/**/*"],
|
|
378
292
|
cwd: sourcePath,
|
|
293
|
+
include: ["**/*"],
|
|
379
294
|
},
|
|
380
|
-
onProgress: data.onProgress,
|
|
381
|
-
disableEndProgress: true,
|
|
382
295
|
});
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
const
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
await (0, zip_1.listZip)({
|
|
393
|
-
path,
|
|
296
|
+
const tarFiles = [];
|
|
297
|
+
await scanner.start(async (entry) => {
|
|
298
|
+
const path = (0, path_1.join)(sourcePath, entry.name);
|
|
299
|
+
const isTar = entry.name.endsWith(".tar");
|
|
300
|
+
const isTarGz = entry.name.endsWith(".tar.gz");
|
|
301
|
+
if (isTar || isTarGz) {
|
|
302
|
+
tarFiles.push(path);
|
|
303
|
+
await (0, tar_1.listTar)({
|
|
304
|
+
input: path,
|
|
394
305
|
verbose: data.options.verbose,
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
if (!isDir)
|
|
398
|
-
scanner.total++;
|
|
399
|
-
await scanner.updateProgress();
|
|
306
|
+
onEntry: () => {
|
|
307
|
+
scanner.total++;
|
|
400
308
|
},
|
|
401
309
|
});
|
|
402
310
|
}
|
|
403
|
-
|
|
404
|
-
await scanner.updateProgress(true);
|
|
405
|
-
if (data.options.verbose)
|
|
406
|
-
(0, cli_1.logExec)(`Copying files to ${restorePath}`);
|
|
407
|
-
await (0, fs_1.cpy)({
|
|
408
|
-
input: {
|
|
409
|
-
type: "glob",
|
|
410
|
-
sourcePath: (0, path_1.join)(sourcePath, "unpacked"),
|
|
411
|
-
},
|
|
412
|
-
targetPath: restorePath,
|
|
413
|
-
concurrency: this.config.fileCopyConcurrency,
|
|
414
|
-
onProgress: async (progress) => await scanner.progress(progress.type === "end" ? "Files copied" : "Copying file", progress),
|
|
311
|
+
return false;
|
|
415
312
|
});
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
await (0, fs_1.applyPermissions)(restorePath, path);
|
|
426
|
-
await scanner.progress("Permissions applied", {
|
|
427
|
-
current: 1,
|
|
428
|
-
type: "end",
|
|
429
|
-
});
|
|
430
|
-
}
|
|
431
|
-
else if (dirent.name.endsWith(".zip")) {
|
|
432
|
-
await (0, zip_1.unzip)({
|
|
433
|
-
input: path,
|
|
434
|
-
output: restorePath,
|
|
435
|
-
verbose: data.options.verbose,
|
|
436
|
-
onProgress: async (progress) => await scanner.progress("Extracting file", progress),
|
|
437
|
-
});
|
|
438
|
-
}
|
|
313
|
+
if (data.options.verbose)
|
|
314
|
+
(0, cli_1.logExec)(`Unpacking files to ${restorePath}`);
|
|
315
|
+
for (const tarFile of tarFiles) {
|
|
316
|
+
await (0, tar_1.extractTar)({
|
|
317
|
+
input: tarFile,
|
|
318
|
+
output: restorePath,
|
|
319
|
+
verbose: data.options.verbose,
|
|
320
|
+
onEntry: async (data) => await scanner.progress(tarFile.endsWith(".tar.gz") ? "Extracting" : "Unpacking", data.path),
|
|
321
|
+
});
|
|
439
322
|
}
|
|
323
|
+
await scanner.end();
|
|
440
324
|
}
|
|
441
325
|
}
|
|
442
326
|
exports.DatatruckRepository = DatatruckRepository;
|
|
443
|
-
DatatruckRepository.zipBasenameTpl = `.*.dd.zip`;
|
|
@@ -32,6 +32,7 @@ exports.gitPackageRepositoryDefinition = {
|
|
|
32
32
|
properties: {},
|
|
33
33
|
};
|
|
34
34
|
class GitRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
35
|
+
static refPrefix = "dt";
|
|
35
36
|
onGetSource() {
|
|
36
37
|
return this.config.repo;
|
|
37
38
|
}
|
|
@@ -244,4 +245,3 @@ class GitRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
244
245
|
}
|
|
245
246
|
}
|
|
246
247
|
exports.GitRepository = GitRepository;
|
|
247
|
-
GitRepository.refPrefix = "dt";
|
|
@@ -12,11 +12,13 @@ var SnapshotTagEnum;
|
|
|
12
12
|
SnapshotTagEnum["TAGS"] = "tags";
|
|
13
13
|
SnapshotTagEnum["VERSION"] = "version";
|
|
14
14
|
SnapshotTagEnum["SIZE"] = "size";
|
|
15
|
-
})(SnapshotTagEnum
|
|
15
|
+
})(SnapshotTagEnum || (exports.SnapshotTagEnum = SnapshotTagEnum = {}));
|
|
16
16
|
class RepositoryAbstract {
|
|
17
|
+
repository;
|
|
18
|
+
config;
|
|
19
|
+
tmpDirs = [];
|
|
17
20
|
constructor(repository) {
|
|
18
21
|
this.repository = repository;
|
|
19
|
-
this.tmpDirs = [];
|
|
20
22
|
this.config = repository.config;
|
|
21
23
|
}
|
|
22
24
|
async mkTmpDir(prefix, id) {
|
|
@@ -81,6 +81,8 @@ exports.resticPackageRepositoryDefinition = {
|
|
|
81
81
|
properties: {},
|
|
82
82
|
};
|
|
83
83
|
class ResticRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
84
|
+
static refPrefix = "dt-";
|
|
85
|
+
env;
|
|
84
86
|
async buildEnv() {
|
|
85
87
|
if (this.env)
|
|
86
88
|
return this.env;
|
|
@@ -386,4 +388,3 @@ class ResticRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
386
388
|
}
|
|
387
389
|
}
|
|
388
390
|
exports.ResticRepository = ResticRepository;
|
|
389
|
-
ResticRepository.refPrefix = "dt-";
|
|
@@ -14,11 +14,15 @@ const sep = (0, chalk_1.grey)(`|`);
|
|
|
14
14
|
const renderBadge = (badge) => `${badge.color(badge.name)}${(0, chalk_1.grey)(`:`)} ${(0, chalk_1.white)(badge.value)}`;
|
|
15
15
|
const renderBadges = (badges) => badges.map(renderBadge).join(` ${sep} `);
|
|
16
16
|
class ConsoleSessionDriver extends SessionDriverAbstract_1.SessionDriverAbstract {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
lastMessage;
|
|
18
|
+
lastMessageText;
|
|
19
|
+
prints = 0;
|
|
20
|
+
renderInterval;
|
|
21
|
+
rendering;
|
|
22
|
+
lastColumns;
|
|
23
|
+
startTime;
|
|
24
|
+
chron = (0, date_1.createChron)();
|
|
25
|
+
tty;
|
|
22
26
|
async onInit() {
|
|
23
27
|
this.tty = this.options.verbose
|
|
24
28
|
? false
|
|
@@ -7,7 +7,7 @@ var ActionEnum;
|
|
|
7
7
|
ActionEnum[ActionEnum["Start"] = 1] = "Start";
|
|
8
8
|
ActionEnum[ActionEnum["Progress"] = 2] = "Progress";
|
|
9
9
|
ActionEnum[ActionEnum["End"] = 3] = "End";
|
|
10
|
-
})(ActionEnum
|
|
10
|
+
})(ActionEnum || (exports.ActionEnum = ActionEnum = {}));
|
|
11
11
|
var EntityEnum;
|
|
12
12
|
(function (EntityEnum) {
|
|
13
13
|
EntityEnum[EntityEnum["BackupSession"] = 0] = "BackupSession";
|
|
@@ -16,8 +16,9 @@ var EntityEnum;
|
|
|
16
16
|
EntityEnum[EntityEnum["RestoreSession"] = 3] = "RestoreSession";
|
|
17
17
|
EntityEnum[EntityEnum["RestoreSessionTask"] = 4] = "RestoreSessionTask";
|
|
18
18
|
EntityEnum[EntityEnum["RestoreSessionRepository"] = 5] = "RestoreSessionRepository";
|
|
19
|
-
})(EntityEnum
|
|
19
|
+
})(EntityEnum || (exports.EntityEnum = EntityEnum = {}));
|
|
20
20
|
class SessionDriverAbstract {
|
|
21
|
+
options;
|
|
21
22
|
constructor(options) {
|
|
22
23
|
this.options = options;
|
|
23
24
|
}
|
|
@@ -20,10 +20,8 @@ const path_2 = require("path");
|
|
|
20
20
|
const sqlite_1 = require("sqlite");
|
|
21
21
|
const sqlite3_1 = __importDefault(require("sqlite3"));
|
|
22
22
|
class SqliteSessionDriver extends SessionDriverAbstract_1.SessionDriverAbstract {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
this.idMap = {};
|
|
26
|
-
}
|
|
23
|
+
idMap = {};
|
|
24
|
+
db;
|
|
27
25
|
async onInit() {
|
|
28
26
|
this.db = await (0, sqlite_1.open)({
|
|
29
27
|
filename: process.env["DATATRUCK_SQLITE_DB"] ??
|
|
@@ -8,12 +8,9 @@ const SessionDriverAbstract_1 = require("../SessionDriver/SessionDriverAbstract"
|
|
|
8
8
|
const ObjectVault_1 = require("../utils/ObjectVault");
|
|
9
9
|
const SessionManagerAbstract_1 = __importDefault(require("./SessionManagerAbstract"));
|
|
10
10
|
class BackupSessionManager extends SessionManagerAbstract_1.default {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
this.taskVault = new ObjectVault_1.ObjectVault();
|
|
15
|
-
this.repositoryVault = new ObjectVault_1.ObjectVault();
|
|
16
|
-
}
|
|
11
|
+
sessionVault = new ObjectVault_1.ObjectVault();
|
|
12
|
+
taskVault = new ObjectVault_1.ObjectVault();
|
|
13
|
+
repositoryVault = new ObjectVault_1.ObjectVault();
|
|
17
14
|
findId(data) {
|
|
18
15
|
return this.sessionVault.getId([data.packageName]);
|
|
19
16
|
}
|
|
@@ -8,12 +8,9 @@ const SessionDriverAbstract_1 = require("../SessionDriver/SessionDriverAbstract"
|
|
|
8
8
|
const ObjectVault_1 = require("../utils/ObjectVault");
|
|
9
9
|
const SessionManagerAbstract_1 = __importDefault(require("./SessionManagerAbstract"));
|
|
10
10
|
class RestoreSessionManager extends SessionManagerAbstract_1.default {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
this.repositoryVault = new ObjectVault_1.ObjectVault();
|
|
15
|
-
this.taskVault = new ObjectVault_1.ObjectVault();
|
|
16
|
-
}
|
|
11
|
+
sessionVault = new ObjectVault_1.ObjectVault();
|
|
12
|
+
repositoryVault = new ObjectVault_1.ObjectVault();
|
|
13
|
+
taskVault = new ObjectVault_1.ObjectVault();
|
|
17
14
|
findId(data) {
|
|
18
15
|
return this.sessionVault.getId([data.packageName]);
|
|
19
16
|
}
|
package/Task/GitTask.js
CHANGED
package/Task/MariadbTask.js
CHANGED
|
@@ -6,7 +6,7 @@ const cli_1 = require("../utils/cli");
|
|
|
6
6
|
const fs_1 = require("../utils/fs");
|
|
7
7
|
const math_1 = require("../utils/math");
|
|
8
8
|
const process_1 = require("../utils/process");
|
|
9
|
-
const
|
|
9
|
+
const tar_1 = require("../utils/tar");
|
|
10
10
|
const TaskAbstract_1 = require("./TaskAbstract");
|
|
11
11
|
const assert_1 = require("assert");
|
|
12
12
|
const fs_2 = require("fs");
|
|
@@ -101,6 +101,7 @@ function parseLine(line) {
|
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
class MariadbTask extends TaskAbstract_1.TaskAbstract {
|
|
104
|
+
verbose;
|
|
104
105
|
get command() {
|
|
105
106
|
return this.config.command ?? "mariabackup";
|
|
106
107
|
}
|
|
@@ -255,17 +256,17 @@ class MariadbTask extends TaskAbstract_1.TaskAbstract {
|
|
|
255
256
|
await data.onProgress({
|
|
256
257
|
absolute,
|
|
257
258
|
});
|
|
258
|
-
await (0,
|
|
259
|
+
await (0, tar_1.extractTar)({
|
|
259
260
|
input: (0, path_1.join)(restorePath, zipFile),
|
|
260
261
|
output: restorePath,
|
|
261
262
|
verbose: this.verbose,
|
|
262
|
-
async
|
|
263
|
+
async onEntry(item) {
|
|
263
264
|
await data.onProgress({
|
|
264
265
|
absolute,
|
|
265
266
|
relative: {
|
|
266
267
|
payload: item.path,
|
|
267
268
|
format: "amount",
|
|
268
|
-
percent: item.percent,
|
|
269
|
+
percent: item.progress.percent,
|
|
269
270
|
},
|
|
270
271
|
});
|
|
271
272
|
},
|
package/Task/MssqlTask.js
CHANGED
|
@@ -25,6 +25,8 @@ exports.mssqlTaskDefinition = {
|
|
|
25
25
|
},
|
|
26
26
|
};
|
|
27
27
|
class MssqlTask extends TaskAbstract_1.TaskAbstract {
|
|
28
|
+
static SUFFIX = ".BAK";
|
|
29
|
+
verbose;
|
|
28
30
|
get command() {
|
|
29
31
|
return this.config.command ?? "sqlcmd";
|
|
30
32
|
}
|
|
@@ -106,4 +108,3 @@ class MssqlTask extends TaskAbstract_1.TaskAbstract {
|
|
|
106
108
|
}
|
|
107
109
|
}
|
|
108
110
|
exports.MssqlTask = MssqlTask;
|
|
109
|
-
MssqlTask.SUFFIX = ".BAK";
|
package/Task/ScriptTask.js
CHANGED