@datatruck/cli 0.0.1
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/lib/Action/BackupAction.d.ts +32 -0
- package/lib/Action/BackupAction.js +201 -0
- package/lib/Action/BackupSessionsAction.d.ts +13 -0
- package/lib/Action/BackupSessionsAction.js +16 -0
- package/lib/Action/CleanCacheAction.d.ts +9 -0
- package/lib/Action/CleanCacheAction.js +18 -0
- package/lib/Action/ConfigAction.d.ts +14 -0
- package/lib/Action/ConfigAction.js +64 -0
- package/lib/Action/InitAction.d.ts +18 -0
- package/lib/Action/InitAction.js +39 -0
- package/lib/Action/PruneAction.d.ts +37 -0
- package/lib/Action/PruneAction.js +80 -0
- package/lib/Action/RestoreAction.d.ts +36 -0
- package/lib/Action/RestoreAction.js +246 -0
- package/lib/Action/RestoreSessionsAction.d.ts +13 -0
- package/lib/Action/RestoreSessionsAction.js +16 -0
- package/lib/Action/SnapshotsAction.d.ts +30 -0
- package/lib/Action/SnapshotsAction.js +35 -0
- package/lib/Command/BackupCommand.d.ts +15 -0
- package/lib/Command/BackupCommand.js +83 -0
- package/lib/Command/BackupSessionsCommand.d.ts +12 -0
- package/lib/Command/BackupSessionsCommand.js +88 -0
- package/lib/Command/CleanCacheCommand.d.ts +6 -0
- package/lib/Command/CleanCacheCommand.js +20 -0
- package/lib/Command/CommandAbstract.d.ts +19 -0
- package/lib/Command/CommandAbstract.js +14 -0
- package/lib/Command/ConfigCommand.d.ts +17 -0
- package/lib/Command/ConfigCommand.js +61 -0
- package/lib/Command/InitCommand.d.ts +13 -0
- package/lib/Command/InitCommand.js +67 -0
- package/lib/Command/PruneCommand.d.ts +27 -0
- package/lib/Command/PruneCommand.js +160 -0
- package/lib/Command/RestoreCommand.d.ts +14 -0
- package/lib/Command/RestoreCommand.js +71 -0
- package/lib/Command/RestoreSessionsCommand.d.ts +12 -0
- package/lib/Command/RestoreSessionsCommand.js +87 -0
- package/lib/Command/SnapshotsCommand.d.ts +25 -0
- package/lib/Command/SnapshotsCommand.js +128 -0
- package/lib/Config/Config.d.ts +8 -0
- package/lib/Config/Config.js +19 -0
- package/lib/Config/PackageConfig.d.ts +27 -0
- package/lib/Config/PackageConfig.js +69 -0
- package/lib/Config/PackageRepositoryConfig.d.ts +17 -0
- package/lib/Config/PackageRepositoryConfig.js +37 -0
- package/lib/Config/PrunePolicyConfig.d.ts +4 -0
- package/lib/Config/PrunePolicyConfig.js +28 -0
- package/lib/Config/RepositoryConfig.d.ts +18 -0
- package/lib/Config/RepositoryConfig.js +37 -0
- package/lib/Config/TaskConfig.d.ts +23 -0
- package/lib/Config/TaskConfig.js +39 -0
- package/lib/Decorator/EntityDecorator.d.ts +11 -0
- package/lib/Decorator/EntityDecorator.js +17 -0
- package/lib/Entity/BackupSessionEntity.d.ts +6 -0
- package/lib/Entity/BackupSessionEntity.js +22 -0
- package/lib/Entity/BackupSessionRepositoryEntity.d.ts +6 -0
- package/lib/Entity/BackupSessionRepositoryEntity.js +22 -0
- package/lib/Entity/BackupSessionTaskEntity.d.ts +5 -0
- package/lib/Entity/BackupSessionTaskEntity.js +22 -0
- package/lib/Entity/CrudEntityAbstract.d.ts +5 -0
- package/lib/Entity/CrudEntityAbstract.js +6 -0
- package/lib/Entity/RestoreSessionEntity.d.ts +5 -0
- package/lib/Entity/RestoreSessionEntity.js +22 -0
- package/lib/Entity/RestoreSessionRepositoryEntity.d.ts +6 -0
- package/lib/Entity/RestoreSessionRepositoryEntity.js +22 -0
- package/lib/Entity/RestoreSessionTaskEntity.d.ts +5 -0
- package/lib/Entity/RestoreSessionTaskEntity.js +22 -0
- package/lib/Entity/StateEntityAbstract.d.ts +12 -0
- package/lib/Entity/StateEntityAbstract.js +7 -0
- package/lib/Error/AppError.d.ts +2 -0
- package/lib/Error/AppError.js +6 -0
- package/lib/Factory/CommandFactory.d.ts +42 -0
- package/lib/Factory/CommandFactory.js +79 -0
- package/lib/Factory/EntityFactory.d.ts +6 -0
- package/lib/Factory/EntityFactory.js +40 -0
- package/lib/Factory/RepositoryFactory.d.ts +3 -0
- package/lib/Factory/RepositoryFactory.js +23 -0
- package/lib/Factory/TaskFactory.d.ts +3 -0
- package/lib/Factory/TaskFactory.js +30 -0
- package/lib/JsonSchema/DefinitionEnum.d.ts +25 -0
- package/lib/JsonSchema/DefinitionEnum.js +32 -0
- package/lib/JsonSchema/JsonSchema.d.ts +4 -0
- package/lib/JsonSchema/JsonSchema.js +50 -0
- package/lib/Repository/GitRepository.d.ts +29 -0
- package/lib/Repository/GitRepository.js +237 -0
- package/lib/Repository/LocalRepository.d.ts +51 -0
- package/lib/Repository/LocalRepository.js +358 -0
- package/lib/Repository/RepositoryAbstract.d.ts +77 -0
- package/lib/Repository/RepositoryAbstract.js +19 -0
- package/lib/Repository/ResticRepository.d.ts +36 -0
- package/lib/Repository/ResticRepository.js +230 -0
- package/lib/SessionDriver/ConsoleSessionDriver.d.ts +37 -0
- package/lib/SessionDriver/ConsoleSessionDriver.js +178 -0
- package/lib/SessionDriver/SessionDriverAbstract.d.ts +78 -0
- package/lib/SessionDriver/SessionDriverAbstract.js +27 -0
- package/lib/SessionDriver/SqliteSessionDriver.d.ts +20 -0
- package/lib/SessionDriver/SqliteSessionDriver.js +169 -0
- package/lib/SessionManager/BackupSessionManager.d.ts +44 -0
- package/lib/SessionManager/BackupSessionManager.js +206 -0
- package/lib/SessionManager/RestoreSessionManager.d.ts +44 -0
- package/lib/SessionManager/RestoreSessionManager.js +206 -0
- package/lib/Task/GitTask.d.ts +35 -0
- package/lib/Task/GitTask.js +248 -0
- package/lib/Task/MariadbTask.d.ts +25 -0
- package/lib/Task/MariadbTask.js +139 -0
- package/lib/Task/MssqlTask.d.ts +22 -0
- package/lib/Task/MssqlTask.js +109 -0
- package/lib/Task/MysqlDumpTask.d.ts +14 -0
- package/lib/Task/MysqlDumpTask.js +129 -0
- package/lib/Task/PostgresqlDumpTask.d.ts +14 -0
- package/lib/Task/PostgresqlDumpTask.js +101 -0
- package/lib/Task/SqlDumpTaskAbstract.d.ts +36 -0
- package/lib/Task/SqlDumpTaskAbstract.js +146 -0
- package/lib/Task/TaskAbstract.d.ts +37 -0
- package/lib/Task/TaskAbstract.js +17 -0
- package/lib/bin.d.ts +2 -0
- package/lib/bin.js +5 -0
- package/lib/cli.d.ts +4 -0
- package/lib/cli.js +110 -0
- package/lib/index.d.ts +0 -0
- package/lib/index.js +1 -0
- package/lib/util/DataFormat.d.ts +24 -0
- package/lib/util/DataFormat.js +50 -0
- package/lib/util/GitUtil.d.ts +38 -0
- package/lib/util/GitUtil.js +105 -0
- package/lib/util/ObjectVault.d.ts +13 -0
- package/lib/util/ObjectVault.js +31 -0
- package/lib/util/ResticUtil.d.ts +92 -0
- package/lib/util/ResticUtil.js +144 -0
- package/lib/util/cli-util.d.ts +27 -0
- package/lib/util/cli-util.js +118 -0
- package/lib/util/datatruck/config-util.d.ts +55 -0
- package/lib/util/datatruck/config-util.js +93 -0
- package/lib/util/datatruck/paths-util.d.ts +5 -0
- package/lib/util/datatruck/paths-util.js +22 -0
- package/lib/util/datatruck/snapshot-util.d.ts +4 -0
- package/lib/util/datatruck/snapshot-util.js +31 -0
- package/lib/util/date-util.d.ts +12 -0
- package/lib/util/date-util.js +74 -0
- package/lib/util/entity-util.d.ts +4 -0
- package/lib/util/entity-util.js +10 -0
- package/lib/util/fs-util.d.ts +43 -0
- package/lib/util/fs-util.js +278 -0
- package/lib/util/math-util.d.ts +1 -0
- package/lib/util/math-util.js +7 -0
- package/lib/util/object-util.d.ts +7 -0
- package/lib/util/object-util.js +58 -0
- package/lib/util/process-util.d.ts +50 -0
- package/lib/util/process-util.js +181 -0
- package/lib/util/string-util.d.ts +17 -0
- package/lib/util/string-util.js +77 -0
- package/lib/util/zip-util.d.ts +52 -0
- package/lib/util/zip-util.js +135 -0
- package/migrations/001-initial.sql +122 -0
- package/package.json +62 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RestoreAction = void 0;
|
|
4
|
+
const AppError_1 = require("../Error/AppError");
|
|
5
|
+
const RepositoryFactory_1 = require("../Factory/RepositoryFactory");
|
|
6
|
+
const TaskFactory_1 = require("../Factory/TaskFactory");
|
|
7
|
+
const cli_util_1 = require("../util/cli-util");
|
|
8
|
+
const config_util_1 = require("../util/datatruck/config-util");
|
|
9
|
+
const fs_util_1 = require("../util/fs-util");
|
|
10
|
+
const object_util_1 = require("../util/object-util");
|
|
11
|
+
const process_util_1 = require("../util/process-util");
|
|
12
|
+
const assert_1 = require("assert");
|
|
13
|
+
const os_1 = require("os");
|
|
14
|
+
class RestoreAction {
|
|
15
|
+
constructor(config, options) {
|
|
16
|
+
this.config = config;
|
|
17
|
+
this.options = options;
|
|
18
|
+
this.taskErrors = {};
|
|
19
|
+
this.repoErrors = {};
|
|
20
|
+
}
|
|
21
|
+
assocConfigs(packages, snapshots) {
|
|
22
|
+
return snapshots.map((snapshot) => {
|
|
23
|
+
const pkg = packages.find((pkg) => pkg.name === snapshot.packageName) ?? null;
|
|
24
|
+
return [snapshot, pkg];
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
async init(session, snapshotId, snapshots) {
|
|
28
|
+
await session.initDrivers();
|
|
29
|
+
for (const [, pkg] of snapshots) {
|
|
30
|
+
(0, assert_1.ok)(pkg);
|
|
31
|
+
const sessionId = await session.init({
|
|
32
|
+
snapshotId: snapshotId,
|
|
33
|
+
packageName: pkg.name,
|
|
34
|
+
});
|
|
35
|
+
if (pkg.task)
|
|
36
|
+
await session.initTask({
|
|
37
|
+
sessionId: sessionId,
|
|
38
|
+
taskName: pkg.task.name,
|
|
39
|
+
});
|
|
40
|
+
for (const repositoryName of pkg.repositoryNames ?? []) {
|
|
41
|
+
const repo = (0, config_util_1.findRepositoryOrFail)(this.config, repositoryName);
|
|
42
|
+
await session.initRepository({
|
|
43
|
+
sessionId: sessionId,
|
|
44
|
+
repositoryName: repositoryName,
|
|
45
|
+
repositoryType: repo.type,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async findSnapshots() {
|
|
51
|
+
const result = [];
|
|
52
|
+
for (const repository of this.config.repositories) {
|
|
53
|
+
if (this.options.repositoryNames &&
|
|
54
|
+
!this.options.repositoryNames.includes(repository.name))
|
|
55
|
+
continue;
|
|
56
|
+
if (this.options.repositoryTypes &&
|
|
57
|
+
!this.options.repositoryTypes.includes(repository.type))
|
|
58
|
+
continue;
|
|
59
|
+
const repoInstance = (0, RepositoryFactory_1.RepositoryFactory)(repository);
|
|
60
|
+
const snapshots = await repoInstance.onSnapshots({
|
|
61
|
+
options: {
|
|
62
|
+
packageNames: this.options.packageNames,
|
|
63
|
+
ids: [this.options.snapshotId],
|
|
64
|
+
tags: this.options.tags,
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
result.push(...snapshots.map((snapshot) => ({
|
|
68
|
+
...snapshot,
|
|
69
|
+
repositoryName: repository.name,
|
|
70
|
+
})));
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
groupSnapshots(snapshots) {
|
|
75
|
+
const names = [];
|
|
76
|
+
return snapshots.filter((snapshot) => {
|
|
77
|
+
if (names.includes(snapshot.packageName))
|
|
78
|
+
return false;
|
|
79
|
+
names.push(snapshot.packageName);
|
|
80
|
+
return true;
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
async execTask(session, pkg, task, snapshot, targetPath) {
|
|
84
|
+
const taskId = session.findTaskId({
|
|
85
|
+
packageName: pkg.name,
|
|
86
|
+
taskName: task.name,
|
|
87
|
+
});
|
|
88
|
+
await session.startTask({
|
|
89
|
+
id: taskId,
|
|
90
|
+
});
|
|
91
|
+
let error;
|
|
92
|
+
if (this.repoErrors[pkg.name]?.length) {
|
|
93
|
+
error = new AppError_1.AppError("Repository failed");
|
|
94
|
+
}
|
|
95
|
+
else if (this.taskErrors[pkg.name]?.length) {
|
|
96
|
+
error = new AppError_1.AppError("Previous task failed");
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
try {
|
|
100
|
+
const taskInstance = (0, TaskFactory_1.TaskFactory)(task);
|
|
101
|
+
await taskInstance.onRestore({
|
|
102
|
+
package: pkg,
|
|
103
|
+
options: this.options,
|
|
104
|
+
snapshot,
|
|
105
|
+
targetPath,
|
|
106
|
+
onProgress: async (data) => {
|
|
107
|
+
await session.progressTask({
|
|
108
|
+
id: taskId,
|
|
109
|
+
progressCurrent: data.current,
|
|
110
|
+
progressPercent: data.percent,
|
|
111
|
+
progressStep: data.step,
|
|
112
|
+
progressStepPercent: data.stepPercent,
|
|
113
|
+
progressTotal: data.total,
|
|
114
|
+
});
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
catch (_) {
|
|
119
|
+
if (!this.taskErrors[pkg.name])
|
|
120
|
+
this.taskErrors[pkg.name] = [];
|
|
121
|
+
this.taskErrors[pkg.name].push((error = _));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
await session.endTask({
|
|
125
|
+
id: taskId,
|
|
126
|
+
error: error?.stack,
|
|
127
|
+
});
|
|
128
|
+
return error ? false : true;
|
|
129
|
+
}
|
|
130
|
+
async execRepository(session, pkg, repo, snapshot, targetPath) {
|
|
131
|
+
const repositoryId = session.findRepositoryId({
|
|
132
|
+
packageName: pkg.name,
|
|
133
|
+
repositoryName: repo.name,
|
|
134
|
+
});
|
|
135
|
+
await session.startRepository({
|
|
136
|
+
id: repositoryId,
|
|
137
|
+
});
|
|
138
|
+
let repoError;
|
|
139
|
+
try {
|
|
140
|
+
if (typeof pkg.restorePath !== "string")
|
|
141
|
+
throw new AppError_1.AppError("Restore path is not defined");
|
|
142
|
+
await (0, fs_util_1.mkdirIfNotExists)(pkg.restorePath);
|
|
143
|
+
if (!(await (0, fs_util_1.isDirEmpty)(pkg.restorePath)))
|
|
144
|
+
throw new AppError_1.AppError(`Restore path is not empty: ${pkg.restorePath}`);
|
|
145
|
+
if (this.options.verbose)
|
|
146
|
+
(0, cli_util_1.logExec)(`restorePath=${pkg.restorePath}`);
|
|
147
|
+
const repoInstance = (0, RepositoryFactory_1.RepositoryFactory)(repo);
|
|
148
|
+
await repoInstance.onRestore({
|
|
149
|
+
package: pkg,
|
|
150
|
+
targetPath,
|
|
151
|
+
packageConfig: pkg.repositoryConfigs?.find((config) => config.type === repo.type &&
|
|
152
|
+
(!config.names || config.names.includes(repo.name)))?.config,
|
|
153
|
+
options: this.options,
|
|
154
|
+
snapshot: snapshot,
|
|
155
|
+
onProgress: async (data) => {
|
|
156
|
+
await session.progressRepository({
|
|
157
|
+
id: repositoryId,
|
|
158
|
+
progressCurrent: data.current,
|
|
159
|
+
progressPercent: data.percent,
|
|
160
|
+
progressStep: data.step,
|
|
161
|
+
progressStepPercent: data.stepPercent,
|
|
162
|
+
progressTotal: data.total,
|
|
163
|
+
});
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
if (pkg.restorePermissions && (0, os_1.platform)() !== "win32")
|
|
167
|
+
await (0, process_util_1.exec)("chown", [
|
|
168
|
+
"-R",
|
|
169
|
+
`${pkg.restorePermissions.uid}:${pkg.restorePermissions.gid}`,
|
|
170
|
+
pkg.restorePath,
|
|
171
|
+
], {}, {
|
|
172
|
+
log: this.options.verbose,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
(0, object_util_1.push)(this.repoErrors, pkg.name, (repoError = error));
|
|
177
|
+
}
|
|
178
|
+
await session.endRepository({
|
|
179
|
+
id: repositoryId,
|
|
180
|
+
error: repoError?.stack,
|
|
181
|
+
});
|
|
182
|
+
return repoError ? false : true;
|
|
183
|
+
}
|
|
184
|
+
getError(pkg) {
|
|
185
|
+
const taskErrors = this.taskErrors[pkg.name]?.length;
|
|
186
|
+
const repoErrors = this.repoErrors[pkg.name]?.length;
|
|
187
|
+
if (taskErrors && repoErrors) {
|
|
188
|
+
return new AppError_1.AppError("Task and repository failed");
|
|
189
|
+
}
|
|
190
|
+
else if (taskErrors && !repoErrors) {
|
|
191
|
+
return new AppError_1.AppError("Task failed");
|
|
192
|
+
}
|
|
193
|
+
else if (!taskErrors && repoErrors) {
|
|
194
|
+
return new AppError_1.AppError("Repository failed");
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
async exec(session) {
|
|
201
|
+
if (!this.options.snapshotId)
|
|
202
|
+
throw new AppError_1.AppError("Snapshot id is required");
|
|
203
|
+
const snapshots = this.groupSnapshots(await this.findSnapshots());
|
|
204
|
+
if (!snapshots.length)
|
|
205
|
+
throw new AppError_1.AppError("None snapshot found");
|
|
206
|
+
let packages = (0, config_util_1.filterPackages)(this.config, this.options);
|
|
207
|
+
packages = (0, config_util_1.resolvePackages)(packages, {
|
|
208
|
+
snapshotId: this.options.snapshotId,
|
|
209
|
+
action: "restore",
|
|
210
|
+
});
|
|
211
|
+
const snapshotAndConfigs = this.assocConfigs(packages, snapshots);
|
|
212
|
+
await this.init(session, this.options.snapshotId, snapshotAndConfigs);
|
|
213
|
+
let sessionErrors = 0;
|
|
214
|
+
for (const [snapshot, pkg] of snapshotAndConfigs) {
|
|
215
|
+
(0, assert_1.ok)(pkg);
|
|
216
|
+
const repo = (0, config_util_1.findRepositoryOrFail)(this.config, snapshot.repositoryName);
|
|
217
|
+
const id = session.findId({
|
|
218
|
+
packageName: pkg.name,
|
|
219
|
+
});
|
|
220
|
+
await session.start({ id });
|
|
221
|
+
let targetPath;
|
|
222
|
+
if (pkg.task) {
|
|
223
|
+
const taskInstance = (0, TaskFactory_1.TaskFactory)(pkg.task);
|
|
224
|
+
const result = await taskInstance.onBeforeRestore({
|
|
225
|
+
options: this.options,
|
|
226
|
+
package: pkg,
|
|
227
|
+
snapshot,
|
|
228
|
+
});
|
|
229
|
+
targetPath = result?.targetPath;
|
|
230
|
+
}
|
|
231
|
+
await this.execRepository(session, pkg, repo, snapshot, targetPath);
|
|
232
|
+
if (pkg.task)
|
|
233
|
+
await this.execTask(session, pkg, pkg.task, snapshot, targetPath);
|
|
234
|
+
const error = this.getError(pkg);
|
|
235
|
+
await session.end({
|
|
236
|
+
id,
|
|
237
|
+
error: error?.message,
|
|
238
|
+
});
|
|
239
|
+
if (error)
|
|
240
|
+
sessionErrors++;
|
|
241
|
+
}
|
|
242
|
+
await session.endDrivers();
|
|
243
|
+
return !sessionErrors;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
exports.RestoreAction = RestoreAction;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ConfigType } from "../Config/Config";
|
|
2
|
+
import { ReadDataType } from "../SessionDriver/SessionDriverAbstract";
|
|
3
|
+
import { RestoreSessionManager } from "../SessionManager/RestoreSessionManager";
|
|
4
|
+
import { IfRequireKeys } from "../util/ts-util";
|
|
5
|
+
export declare type RestoreSessionsActionOptionsType = ReadDataType & {
|
|
6
|
+
verbose?: boolean;
|
|
7
|
+
};
|
|
8
|
+
export declare class RestoreSessionsAction<TRequired extends boolean = true> {
|
|
9
|
+
readonly config: ConfigType;
|
|
10
|
+
readonly options: IfRequireKeys<TRequired, RestoreSessionsActionOptionsType>;
|
|
11
|
+
constructor(config: ConfigType, options: IfRequireKeys<TRequired, RestoreSessionsActionOptionsType>);
|
|
12
|
+
exec(manager: RestoreSessionManager): Promise<import("../SessionDriver/SessionDriverAbstract").ReadResultType[]>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RestoreSessionsAction = void 0;
|
|
4
|
+
class RestoreSessionsAction {
|
|
5
|
+
constructor(config, options) {
|
|
6
|
+
this.config = config;
|
|
7
|
+
this.options = options;
|
|
8
|
+
}
|
|
9
|
+
async exec(manager) {
|
|
10
|
+
await manager.initDrivers();
|
|
11
|
+
const result = await manager.readAll(this.options);
|
|
12
|
+
await manager.endDrivers();
|
|
13
|
+
return result;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.RestoreSessionsAction = RestoreSessionsAction;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ConfigType } from "../Config/Config";
|
|
2
|
+
import { SnapshotResultType } from "../Repository/RepositoryAbstract";
|
|
3
|
+
import { IfRequireKeys } from "../util/ts-util";
|
|
4
|
+
export declare type SnapshotGroupByType = keyof Pick<SnapshotExtendedType, "packageName" | "repositoryName" | "repositoryType">;
|
|
5
|
+
export declare type SnapshotsActionOptionsType = {
|
|
6
|
+
ids?: string[];
|
|
7
|
+
repositoryNames?: string[];
|
|
8
|
+
packageNames?: string[];
|
|
9
|
+
repositoryTypes?: string[];
|
|
10
|
+
verbose?: boolean;
|
|
11
|
+
tags?: string[];
|
|
12
|
+
last?: number;
|
|
13
|
+
lastMinutely?: number;
|
|
14
|
+
lastHourly?: number;
|
|
15
|
+
lastDaily?: number;
|
|
16
|
+
lastWeekly?: number;
|
|
17
|
+
lastMonthly?: number;
|
|
18
|
+
lastYearly?: number;
|
|
19
|
+
groupBy?: SnapshotGroupByType[];
|
|
20
|
+
};
|
|
21
|
+
export declare type SnapshotExtendedType = {
|
|
22
|
+
repositoryName: string;
|
|
23
|
+
repositoryType: string;
|
|
24
|
+
} & SnapshotResultType;
|
|
25
|
+
export declare class SnapshotsAction<TRequired extends boolean = true> {
|
|
26
|
+
readonly config: ConfigType;
|
|
27
|
+
readonly options: IfRequireKeys<TRequired, SnapshotsActionOptionsType>;
|
|
28
|
+
constructor(config: ConfigType, options: IfRequireKeys<TRequired, SnapshotsActionOptionsType>);
|
|
29
|
+
exec(): Promise<SnapshotExtendedType[]>;
|
|
30
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SnapshotsAction = void 0;
|
|
4
|
+
const RepositoryFactory_1 = require("../Factory/RepositoryFactory");
|
|
5
|
+
const snapshot_util_1 = require("../util/datatruck/snapshot-util");
|
|
6
|
+
class SnapshotsAction {
|
|
7
|
+
constructor(config, options) {
|
|
8
|
+
this.config = config;
|
|
9
|
+
this.options = options;
|
|
10
|
+
}
|
|
11
|
+
async exec() {
|
|
12
|
+
let result = [];
|
|
13
|
+
for (const repo of this.config.repositories) {
|
|
14
|
+
if (this.options.repositoryNames &&
|
|
15
|
+
!this.options.repositoryNames.includes(repo.name))
|
|
16
|
+
continue;
|
|
17
|
+
if (this.options.repositoryTypes &&
|
|
18
|
+
!this.options.repositoryTypes.includes(repo.type))
|
|
19
|
+
continue;
|
|
20
|
+
const repoInstance = (0, RepositoryFactory_1.RepositoryFactory)(repo);
|
|
21
|
+
const snapshots = await repoInstance.onSnapshots({
|
|
22
|
+
options: this.options,
|
|
23
|
+
});
|
|
24
|
+
const extentedItems = snapshots.map((item) => ({
|
|
25
|
+
...item,
|
|
26
|
+
repositoryName: repo.name,
|
|
27
|
+
repositoryType: repo.type,
|
|
28
|
+
}));
|
|
29
|
+
result.push(...extentedItems);
|
|
30
|
+
}
|
|
31
|
+
result = result.sort((a, b) => b.date.localeCompare(a.date));
|
|
32
|
+
return (0, snapshot_util_1.groupAndFilter)(result, this.options.groupBy, this.options);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.SnapshotsAction = SnapshotsAction;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { RepositoryConfigType } from "../Config/RepositoryConfig";
|
|
2
|
+
import { If } from "../util/ts-util";
|
|
3
|
+
import { CommandAbstract } from "./CommandAbstract";
|
|
4
|
+
export declare type BackupCommandOptionsType<TResolved = false> = {
|
|
5
|
+
package?: If<TResolved, string[]>;
|
|
6
|
+
repository?: If<TResolved, string[]>;
|
|
7
|
+
repositoryType?: If<TResolved, RepositoryConfigType["type"][]>;
|
|
8
|
+
tag?: If<TResolved, string[]>;
|
|
9
|
+
dryRun?: boolean;
|
|
10
|
+
date?: string;
|
|
11
|
+
};
|
|
12
|
+
export declare class BackupCommand extends CommandAbstract<BackupCommandOptionsType<false>, BackupCommandOptionsType<true>> {
|
|
13
|
+
onOptions(): import("../util/cli-util").OptionsType<BackupCommandOptionsType<false>, BackupCommandOptionsType<true>>;
|
|
14
|
+
onExec(): Promise<0 | 1>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BackupCommand = void 0;
|
|
4
|
+
const BackupAction_1 = require("../Action/BackupAction");
|
|
5
|
+
const ConfigAction_1 = require("../Action/ConfigAction");
|
|
6
|
+
const AppError_1 = require("../Error/AppError");
|
|
7
|
+
const ConsoleSessionDriver_1 = require("../SessionDriver/ConsoleSessionDriver");
|
|
8
|
+
const SqliteSessionDriver_1 = require("../SessionDriver/SqliteSessionDriver");
|
|
9
|
+
const BackupSessionManager_1 = require("../SessionManager/BackupSessionManager");
|
|
10
|
+
const string_util_1 = require("../util/string-util");
|
|
11
|
+
const CommandAbstract_1 = require("./CommandAbstract");
|
|
12
|
+
class BackupCommand extends CommandAbstract_1.CommandAbstract {
|
|
13
|
+
onOptions() {
|
|
14
|
+
return this.returnsOptions({
|
|
15
|
+
dryRun: {
|
|
16
|
+
description: "Skip execution",
|
|
17
|
+
option: "--dryRun",
|
|
18
|
+
},
|
|
19
|
+
package: {
|
|
20
|
+
description: "Package names",
|
|
21
|
+
option: "-p,--package <values>",
|
|
22
|
+
parser: string_util_1.parseStringList,
|
|
23
|
+
},
|
|
24
|
+
repository: {
|
|
25
|
+
description: "Repository names",
|
|
26
|
+
option: "-r,--repository <values>",
|
|
27
|
+
parser: string_util_1.parseStringList,
|
|
28
|
+
},
|
|
29
|
+
repositoryType: {
|
|
30
|
+
description: "Repository types",
|
|
31
|
+
option: "-t,--repository-type <values>",
|
|
32
|
+
parser: (v) => (0, string_util_1.parseStringList)(v),
|
|
33
|
+
},
|
|
34
|
+
tag: {
|
|
35
|
+
description: "Tags",
|
|
36
|
+
option: "--tag <values>",
|
|
37
|
+
parser: string_util_1.parseStringList,
|
|
38
|
+
},
|
|
39
|
+
date: {
|
|
40
|
+
description: "Date time (ISO)",
|
|
41
|
+
option: "--date <value>",
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
async onExec() {
|
|
46
|
+
const verbose = this.globalOptions.verbose ?? 0;
|
|
47
|
+
const configAction = new ConfigAction_1.ConfigAction({
|
|
48
|
+
path: this.globalOptions.config,
|
|
49
|
+
verbose: verbose > 0,
|
|
50
|
+
});
|
|
51
|
+
const config = await configAction.exec();
|
|
52
|
+
const backup = new BackupAction_1.BackupAction(config, {
|
|
53
|
+
packageNames: this.options.package,
|
|
54
|
+
repositoryNames: this.options.repository,
|
|
55
|
+
repositoryTypes: this.options.repositoryType,
|
|
56
|
+
tags: this.options.tag,
|
|
57
|
+
dryRun: this.options.dryRun,
|
|
58
|
+
verbose: verbose > 0,
|
|
59
|
+
date: this.options.date,
|
|
60
|
+
});
|
|
61
|
+
const sessionManager = new BackupSessionManager_1.BackupSessionManager({
|
|
62
|
+
driver: new SqliteSessionDriver_1.SqliteSessionDriver({
|
|
63
|
+
verbose: verbose > 1,
|
|
64
|
+
}),
|
|
65
|
+
altDrivers: [
|
|
66
|
+
new ConsoleSessionDriver_1.ConsoleSessionDriver({
|
|
67
|
+
verbose: verbose > 0,
|
|
68
|
+
}),
|
|
69
|
+
],
|
|
70
|
+
});
|
|
71
|
+
const result = await backup.exec(sessionManager);
|
|
72
|
+
if (result.errors) {
|
|
73
|
+
return 1;
|
|
74
|
+
}
|
|
75
|
+
else if (!result.total) {
|
|
76
|
+
throw new AppError_1.AppError("None package config found");
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
return 0;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
exports.BackupCommand = BackupCommand;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { If } from "../util/ts-util";
|
|
2
|
+
import { CommandAbstract } from "./CommandAbstract";
|
|
3
|
+
export declare type BackupSessionsCommandOptionsType<TResolved = false> = {
|
|
4
|
+
package?: If<TResolved, string[]>;
|
|
5
|
+
repository?: If<TResolved, string[]>;
|
|
6
|
+
tag?: If<TResolved, string[]>;
|
|
7
|
+
limit?: number;
|
|
8
|
+
};
|
|
9
|
+
export declare class BackupSessionsCommand extends CommandAbstract<BackupSessionsCommandOptionsType<false>, BackupSessionsCommandOptionsType<true>> {
|
|
10
|
+
onOptions(): import("../util/cli-util").OptionsType<BackupSessionsCommandOptionsType<false>, BackupSessionsCommandOptionsType<true>>;
|
|
11
|
+
onExec(): Promise<number>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BackupSessionsCommand = void 0;
|
|
4
|
+
const BackupSessionsAction_1 = require("../Action/BackupSessionsAction");
|
|
5
|
+
const ConfigAction_1 = require("../Action/ConfigAction");
|
|
6
|
+
const SqliteSessionDriver_1 = require("../SessionDriver/SqliteSessionDriver");
|
|
7
|
+
const BackupSessionManager_1 = require("../SessionManager/BackupSessionManager");
|
|
8
|
+
const DataFormat_1 = require("../util/DataFormat");
|
|
9
|
+
const cli_util_1 = require("../util/cli-util");
|
|
10
|
+
const string_util_1 = require("../util/string-util");
|
|
11
|
+
const CommandAbstract_1 = require("./CommandAbstract");
|
|
12
|
+
class BackupSessionsCommand extends CommandAbstract_1.CommandAbstract {
|
|
13
|
+
onOptions() {
|
|
14
|
+
return this.returnsOptions({
|
|
15
|
+
package: {
|
|
16
|
+
description: "Package names",
|
|
17
|
+
option: "-p,--package <values>",
|
|
18
|
+
parser: string_util_1.parseStringList,
|
|
19
|
+
},
|
|
20
|
+
repository: {
|
|
21
|
+
description: "Repository names",
|
|
22
|
+
option: "-r,--repository <values>",
|
|
23
|
+
parser: string_util_1.parseStringList,
|
|
24
|
+
},
|
|
25
|
+
tag: {
|
|
26
|
+
description: "Tags",
|
|
27
|
+
option: "--tag <values>",
|
|
28
|
+
parser: string_util_1.parseStringList,
|
|
29
|
+
},
|
|
30
|
+
limit: {
|
|
31
|
+
description: "Limit",
|
|
32
|
+
option: "-l,--limit <value>",
|
|
33
|
+
defaults: 10,
|
|
34
|
+
parser: Number,
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
async onExec() {
|
|
39
|
+
const verbose = this.globalOptions.verbose ?? 0;
|
|
40
|
+
const configAction = new ConfigAction_1.ConfigAction({
|
|
41
|
+
path: this.globalOptions.config,
|
|
42
|
+
verbose: verbose > 0,
|
|
43
|
+
});
|
|
44
|
+
const config = await configAction.exec();
|
|
45
|
+
const action = new BackupSessionsAction_1.BackupSessionsAction(config, {
|
|
46
|
+
packageNames: this.options.package,
|
|
47
|
+
repositoryNames: this.options.repository,
|
|
48
|
+
tags: this.options.tag,
|
|
49
|
+
limit: this.options.limit,
|
|
50
|
+
verbose: verbose > 0,
|
|
51
|
+
});
|
|
52
|
+
const manager = new BackupSessionManager_1.BackupSessionManager({
|
|
53
|
+
driver: new SqliteSessionDriver_1.SqliteSessionDriver({
|
|
54
|
+
verbose: verbose > 1,
|
|
55
|
+
}),
|
|
56
|
+
verbose: verbose > 1,
|
|
57
|
+
});
|
|
58
|
+
const dataFormat = new DataFormat_1.DataFormat({
|
|
59
|
+
items: await action.exec(manager),
|
|
60
|
+
table: {
|
|
61
|
+
labels: [
|
|
62
|
+
" ",
|
|
63
|
+
"Id.",
|
|
64
|
+
"Snapshot id.",
|
|
65
|
+
"Date",
|
|
66
|
+
"Repository",
|
|
67
|
+
"Repository type",
|
|
68
|
+
"Package",
|
|
69
|
+
"",
|
|
70
|
+
],
|
|
71
|
+
handler: (item) => [
|
|
72
|
+
(0, cli_util_1.resultColumn)(item.error, item.state),
|
|
73
|
+
item.id,
|
|
74
|
+
item.snapshotId.slice(0, 8),
|
|
75
|
+
(0, string_util_1.formatDateTime)(item.creationDate),
|
|
76
|
+
item.repositoryName,
|
|
77
|
+
item.repositoryType,
|
|
78
|
+
item.packageName,
|
|
79
|
+
(0, cli_util_1.errorColumn)(item.error, verbose),
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
if (this.globalOptions.outputFormat)
|
|
84
|
+
console.log(dataFormat.format(this.globalOptions.outputFormat));
|
|
85
|
+
return 0;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
exports.BackupSessionsCommand = BackupSessionsCommand;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { CommandAbstract } from "./CommandAbstract";
|
|
2
|
+
export declare type CleanCacheCommandOptionsType<TResolved = false> = {};
|
|
3
|
+
export declare class CleanCacheCommand extends CommandAbstract<CleanCacheCommandOptionsType<false>, CleanCacheCommandOptionsType<true>> {
|
|
4
|
+
onOptions(): import("../util/cli-util").OptionsType<CleanCacheCommandOptionsType<false>, CleanCacheCommandOptionsType<true>>;
|
|
5
|
+
onExec(): Promise<number>;
|
|
6
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CleanCacheCommand = void 0;
|
|
4
|
+
const CleanCacheAction_1 = require("../Action/CleanCacheAction");
|
|
5
|
+
const fs_util_1 = require("../util/fs-util");
|
|
6
|
+
const CommandAbstract_1 = require("./CommandAbstract");
|
|
7
|
+
class CleanCacheCommand extends CommandAbstract_1.CommandAbstract {
|
|
8
|
+
onOptions() {
|
|
9
|
+
return this.returnsOptions({});
|
|
10
|
+
}
|
|
11
|
+
async onExec() {
|
|
12
|
+
const action = new CleanCacheAction_1.CleanCacheAction({
|
|
13
|
+
verbose: !!this.globalOptions.verbose,
|
|
14
|
+
});
|
|
15
|
+
console.info(`Cleaning ${(0, fs_util_1.parentTmpDir)()}...`);
|
|
16
|
+
await action.exec();
|
|
17
|
+
return 0;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.CleanCacheCommand = CleanCacheCommand;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { FormatType } from "../util/DataFormat";
|
|
2
|
+
import { OptionsType } from "../util/cli-util";
|
|
3
|
+
import { SimilarObject } from "../util/ts-util";
|
|
4
|
+
export declare type GlobalOptionsType<TResolved = false> = {
|
|
5
|
+
config: string;
|
|
6
|
+
outputFormat?: FormatType;
|
|
7
|
+
verbose?: number;
|
|
8
|
+
};
|
|
9
|
+
export declare type CommandConstructorType<TUnresolvedOptions, TOptions extends SimilarObject<TUnresolvedOptions>> = {
|
|
10
|
+
new (globalOptions: GlobalOptionsType<true>, options: TOptions): CommandAbstract<TUnresolvedOptions, TOptions>;
|
|
11
|
+
};
|
|
12
|
+
export declare abstract class CommandAbstract<TUnresolvedOptions, TOptions extends SimilarObject<TUnresolvedOptions>> {
|
|
13
|
+
readonly globalOptions: GlobalOptionsType<true>;
|
|
14
|
+
readonly options: TOptions;
|
|
15
|
+
constructor(globalOptions: GlobalOptionsType<true>, options: TUnresolvedOptions);
|
|
16
|
+
abstract onOptions(): OptionsType<TUnresolvedOptions, TOptions>;
|
|
17
|
+
protected returnsOptions(options: OptionsType<TUnresolvedOptions, TOptions>): OptionsType<TUnresolvedOptions, TOptions>;
|
|
18
|
+
abstract onExec(): Promise<number>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CommandAbstract = void 0;
|
|
4
|
+
const cli_util_1 = require("../util/cli-util");
|
|
5
|
+
class CommandAbstract {
|
|
6
|
+
constructor(globalOptions, options) {
|
|
7
|
+
this.globalOptions = globalOptions;
|
|
8
|
+
this.options = (0, cli_util_1.parseOptions)(options, this.onOptions());
|
|
9
|
+
}
|
|
10
|
+
returnsOptions(options) {
|
|
11
|
+
return options;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.CommandAbstract = CommandAbstract;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { RepositoryConfigType } from "../Config/RepositoryConfig";
|
|
2
|
+
import { If } from "../util/ts-util";
|
|
3
|
+
import { CommandAbstract } from "./CommandAbstract";
|
|
4
|
+
export declare type ConfigCommandOptionsType<TResolved = false> = {
|
|
5
|
+
package?: If<TResolved, string[]>;
|
|
6
|
+
repository?: If<TResolved, string[]>;
|
|
7
|
+
repositoryType?: If<TResolved, RepositoryConfigType["type"][]>;
|
|
8
|
+
};
|
|
9
|
+
export declare type ConfigCommandLogType = {
|
|
10
|
+
package: string;
|
|
11
|
+
repositoryNames: string[];
|
|
12
|
+
taskName: string | undefined;
|
|
13
|
+
}[];
|
|
14
|
+
export declare class ConfigCommand extends CommandAbstract<ConfigCommandOptionsType<false>, ConfigCommandOptionsType<true>> {
|
|
15
|
+
onOptions(): import("../util/cli-util").OptionsType<ConfigCommandOptionsType<false>, ConfigCommandOptionsType<true>>;
|
|
16
|
+
onExec(): Promise<number>;
|
|
17
|
+
}
|