dodo-mcp 1.2.1 → 1.3.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/README.md +29 -6
- package/dist/cli/dataRecovery.js +38 -0
- package/dist/cli/dataRecovery.js.map +1 -0
- package/dist/cli/deployment.js +61 -0
- package/dist/cli/deployment.js.map +1 -0
- package/dist/cli/main.js +35 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/config/globalConfig.js +3 -5
- package/dist/config/globalConfig.js.map +1 -1
- package/dist/errors.js +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/ipc/server.js +2 -0
- package/dist/ipc/server.js.map +1 -1
- package/dist/ipc/timeouts.js +5 -0
- package/dist/ipc/timeouts.js.map +1 -0
- package/dist/platform/privateFs.js +32 -3
- package/dist/platform/privateFs.js.map +1 -1
- package/dist/platform/windowsPrivateAcl.js +90 -0
- package/dist/platform/windowsPrivateAcl.js.map +1 -0
- package/dist/security/outboundAddress.js +20 -0
- package/dist/security/outboundAddress.js.map +1 -0
- package/dist/server/aiAdmin.js +5 -4
- package/dist/server/aiAdmin.js.map +1 -1
- package/dist/server/appServer.js +2 -5
- package/dist/server/appServer.js.map +1 -1
- package/dist/server/bootstrap.js +14 -0
- package/dist/server/bootstrap.js.map +1 -1
- package/dist/server/configUi/index.html +3 -0
- package/dist/server/configUi/ui/dataRecovery.js +90 -0
- package/dist/server/configUi/ui/deployment.js +111 -0
- package/dist/server/configUi/ui/recovery.js +167 -0
- package/dist/server/configUi/workbench.js +23 -7
- package/dist/server/installationRuntime.js +3 -1
- package/dist/server/installationRuntime.js.map +1 -1
- package/dist/server/instructions.js.map +1 -1
- package/dist/server/ipcDispatch.js +219 -0
- package/dist/server/ipcDispatch.js.map +1 -1
- package/dist/server/localConfig.js +1 -1
- package/dist/server/localConfig.js.map +1 -1
- package/dist/server/stdioServer.js +2 -5
- package/dist/server/stdioServer.js.map +1 -1
- package/dist/services/ai/network.js +1 -18
- package/dist/services/ai/network.js.map +1 -1
- package/dist/services/ai/subagents.js +5 -2
- package/dist/services/ai/subagents.js.map +1 -1
- package/dist/services/assistance/verification.js +43 -10
- package/dist/services/assistance/verification.js.map +1 -1
- package/dist/services/changes/applier.js +472 -297
- package/dist/services/changes/applier.js.map +1 -1
- package/dist/services/git/gitService.js +150 -34
- package/dist/services/git/gitService.js.map +1 -1
- package/dist/services/jobs/jobManager.js +59 -2
- package/dist/services/jobs/jobManager.js.map +1 -1
- package/dist/services/jobs/spool.js +9 -3
- package/dist/services/jobs/spool.js.map +1 -1
- package/dist/services/multimodal/mediaService.js +6 -6
- package/dist/services/multimodal/mediaService.js.map +1 -1
- package/dist/services/recovery/configKeys.js +115 -0
- package/dist/services/recovery/configKeys.js.map +1 -0
- package/dist/services/recovery/configVault.js +361 -0
- package/dist/services/recovery/configVault.js.map +1 -0
- package/dist/services/recovery/contracts.js +24 -0
- package/dist/services/recovery/contracts.js.map +1 -0
- package/dist/services/recovery/databaseAwareness.js +179 -0
- package/dist/services/recovery/databaseAwareness.js.map +1 -0
- package/dist/services/recovery/deploymentArchive.js +129 -0
- package/dist/services/recovery/deploymentArchive.js.map +1 -0
- package/dist/services/recovery/deploymentContracts.js +70 -0
- package/dist/services/recovery/deploymentContracts.js.map +1 -0
- package/dist/services/recovery/deploymentHealth.js +143 -0
- package/dist/services/recovery/deploymentHealth.js.map +1 -0
- package/dist/services/recovery/deploymentMaintenance.js +197 -0
- package/dist/services/recovery/deploymentMaintenance.js.map +1 -0
- package/dist/services/recovery/deploymentService.js +429 -0
- package/dist/services/recovery/deploymentService.js.map +1 -0
- package/dist/services/recovery/deploymentSource.js +36 -0
- package/dist/services/recovery/deploymentSource.js.map +1 -0
- package/dist/services/recovery/dockerDeployment.js +172 -0
- package/dist/services/recovery/dockerDeployment.js.map +1 -0
- package/dist/services/recovery/drift.js +178 -0
- package/dist/services/recovery/drift.js.map +1 -0
- package/dist/services/recovery/evidence.js +127 -0
- package/dist/services/recovery/evidence.js.map +1 -0
- package/dist/services/recovery/gitCopies.js +219 -0
- package/dist/services/recovery/gitCopies.js.map +1 -0
- package/dist/services/recovery/history.js +423 -0
- package/dist/services/recovery/history.js.map +1 -0
- package/dist/services/recovery/recoveryService.js +521 -0
- package/dist/services/recovery/recoveryService.js.map +1 -0
- package/dist/services/recovery/storage.js +344 -0
- package/dist/services/recovery/storage.js.map +1 -0
- package/dist/services/schedules/scheduleService.js +9 -10
- package/dist/services/schedules/scheduleService.js.map +1 -1
- package/dist/store/db.js +71 -0
- package/dist/store/db.js.map +1 -1
- package/dist/tools/catalog.js +4 -0
- package/dist/tools/catalog.js.map +1 -1
- package/dist/tools/changeTools.js +1 -1
- package/dist/tools/changeTools.js.map +1 -1
- package/dist/tools/context.js +23 -3
- package/dist/tools/context.js.map +1 -1
- package/dist/tools/deploymentTools.js +58 -0
- package/dist/tools/deploymentTools.js.map +1 -0
- package/dist/tools/directTools.js +9 -5
- package/dist/tools/directTools.js.map +1 -1
- package/dist/tools/gitTools.js +7 -2
- package/dist/tools/gitTools.js.map +1 -1
- package/dist/tools/jobTools.js +4 -4
- package/dist/tools/jobTools.js.map +1 -1
- package/dist/tools/projectTools.js +1 -0
- package/dist/tools/projectTools.js.map +1 -1
- package/dist/tools/recoveryTools.js +79 -0
- package/dist/tools/recoveryTools.js.map +1 -0
- package/dist/tools/runtimeTools.js +1 -1
- package/dist/tools/runtimeTools.js.map +1 -1
- package/dist/tools/surface.js +6 -1
- package/dist/tools/surface.js.map +1 -1
- package/dist/tunnel/credentials.js +1 -1
- package/dist/tunnel/credentials.js.map +1 -1
- package/docs/ARCHITECTURE.md +82 -2
- package/docs/CI.md +118 -0
- package/docs/COMPATIBILITY.md +7 -6
- package/docs/EVALUATION.md +17 -12
- package/docs/MANUAL_ACCEPTANCE.md +59 -2
- package/docs/RECOVERY.md +448 -0
- package/docs/RELEASE_1.3.0.md +64 -0
- package/docs/RELEASE_NOTES.md +23 -0
- package/docs/SECURITY.md +112 -0
- package/docs/TEST_REPORT.md +300 -5
- package/docs/adr/051-source-recovery-foundation.md +45 -0
- package/docs/adr/052-reviewed-source-restore.md +50 -0
- package/docs/adr/053-content-drift-and-private-git-recovery.md +29 -0
- package/docs/adr/054-verified-source-checkpoints.md +58 -0
- package/docs/adr/055-reviewed-docker-deployments.md +42 -0
- package/docs/adr/056-owner-data-recovery.md +47 -0
- package/docs/adr/README.md +7 -0
- package/native/private-state-windows.cs +105 -0
- package/package.json +6 -1
- package/schemas/global-config.schema.json +34 -0
- package/schemas/tools.compact.json +175 -15
- package/schemas/tools.hybrid.json +350 -16
- package/schemas/tools.json +4883 -816
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { spawn } from 'node:child_process';
|
|
4
|
+
import { createHash } from 'node:crypto';
|
|
5
|
+
import { DodoError } from '../../errors.js';
|
|
6
|
+
import { buildChildEnv } from '../../security/env.js';
|
|
7
|
+
import { resolveTrustedExecutable } from '../../platform/execResolve.js';
|
|
8
|
+
import { assertPrivatePath, ensurePrivateDirectory } from '../../platform/privateFs.js';
|
|
9
|
+
import { isWithinPath } from '../../platform/pathPolicy.js';
|
|
10
|
+
import { rootIdentity, syncDir } from './storage.js';
|
|
11
|
+
/** Each immutable copy is an independent bare repository. Never reads objects from
|
|
12
|
+
* the working Git database, its index, alternates, hooks, filters or remotes. */
|
|
13
|
+
export class RecoveryGitCopies {
|
|
14
|
+
s;
|
|
15
|
+
storage;
|
|
16
|
+
configDir;
|
|
17
|
+
last = { state: 'not_checked' };
|
|
18
|
+
constructor(s, storage, configDir) {
|
|
19
|
+
this.s = s;
|
|
20
|
+
this.storage = storage;
|
|
21
|
+
this.configDir = configDir;
|
|
22
|
+
}
|
|
23
|
+
status() { return { ...this.last, location: 'private_owner_storage', coverage: 'approved source bytes only; empty directories and exact modes remain in the source manifest; no Git history, LFS downloads or submodule history' }; }
|
|
24
|
+
reviewDestination(policy) {
|
|
25
|
+
if (!policy.gitDirectory)
|
|
26
|
+
return undefined;
|
|
27
|
+
const p = policy.gitDirectory;
|
|
28
|
+
if (!path.isAbsolute(p) || fs.realpathSync.native(p) !== p)
|
|
29
|
+
throw new DodoError('PATH_DENIED', 'Git recovery destination must be an existing canonical private directory');
|
|
30
|
+
assertPrivatePath(p, true);
|
|
31
|
+
if (p.split(/[\\/]/).some(part => ['.ssh', '.gnupg', '.aws', '.azure', '.kube', '.docker'].includes(part.toLowerCase())))
|
|
32
|
+
throw new DodoError('PATH_DENIED', 'Git recovery cannot use a credential namespace');
|
|
33
|
+
for (const name of fs.readdirSync(p)) {
|
|
34
|
+
const item = path.join(p, name);
|
|
35
|
+
const row = this.s.store.db.prepare('SELECT identity FROM recovery_git_copies WHERE directory=?').get(item);
|
|
36
|
+
if (!/^snap_[a-f0-9-]{36}\.git$/.test(name) || !row || row.identity !== rootIdentity(item))
|
|
37
|
+
throw new DodoError('PATH_DENIED', 'choose an empty dedicated private backup directory, not an existing data directory');
|
|
38
|
+
}
|
|
39
|
+
const roots = this.s.store.db.prepare('SELECT canonical_root AS root FROM project_registry WHERE removed_at IS NULL').all();
|
|
40
|
+
for (const root of [this.configDir, ...roots.map(r => r.root)])
|
|
41
|
+
if (isWithinPath(root, p) || isWithinPath(p, root))
|
|
42
|
+
throw new DodoError('PATH_DENIED', 'Git recovery destination overlaps source or private credentials');
|
|
43
|
+
return { path: p, identity: rootIdentity(p) };
|
|
44
|
+
}
|
|
45
|
+
configure(policy) {
|
|
46
|
+
const d = this.reviewDestination(policy);
|
|
47
|
+
if (d)
|
|
48
|
+
this.s.store.db.prepare('INSERT INTO recovery_git_destinations VALUES (?,?,?) ON CONFLICT(workspace_id) DO UPDATE SET path=excluded.path,identity=excluded.identity').run(this.s.workspaceId, d.path, d.identity);
|
|
49
|
+
else
|
|
50
|
+
this.s.store.db.prepare('DELETE FROM recovery_git_destinations WHERE workspace_id=?').run(this.s.workspaceId);
|
|
51
|
+
}
|
|
52
|
+
destination(policy) {
|
|
53
|
+
if (policy.gitDirectory) {
|
|
54
|
+
const d = this.s.store.db.prepare('SELECT path,identity FROM recovery_git_destinations WHERE workspace_id=?').get(this.s.workspaceId);
|
|
55
|
+
if (!d || d.path !== policy.gitDirectory || rootIdentity(d.path) !== d.identity)
|
|
56
|
+
throw new DodoError('PATH_DENIED', 'owner-selected Git recovery volume is unavailable or replaced');
|
|
57
|
+
this.reviewDestination(policy);
|
|
58
|
+
return d.path;
|
|
59
|
+
}
|
|
60
|
+
assertPrivatePath(this.storage.directory, true);
|
|
61
|
+
const p = path.join(this.storage.directory, 'git');
|
|
62
|
+
ensurePrivateDirectory(p);
|
|
63
|
+
return p;
|
|
64
|
+
}
|
|
65
|
+
async command(dir, args, input, deadline = Date.now() + 60000, maxOutput = 2 * 1024 * 1024) {
|
|
66
|
+
if (Date.now() >= deadline)
|
|
67
|
+
throw new DodoError('RESOURCE_LIMIT', 'Git checkpoint exceeded time budget');
|
|
68
|
+
const executable = resolveTrustedExecutable('git', this.s.wfs.root, { allowBatch: false });
|
|
69
|
+
const env = buildChildEnv({ parentEnv: process.env, workspaceRoot: this.s.wfs.root, extraAllowlist: [] });
|
|
70
|
+
Object.assign(env, { GIT_CONFIG_NOSYSTEM: '1', GIT_CONFIG_GLOBAL: process.platform === 'win32' ? 'NUL' : '/dev/null', GIT_TERMINAL_PROMPT: '0', GIT_NO_REPLACE_OBJECTS: '1', GIT_OPTIONAL_LOCKS: '0', GIT_CONFIG_COUNT: '0', GIT_ATTR_NOSYSTEM: '1', GIT_INDEX_FILE: path.join(dir, 'private-index'), GIT_AUTHOR_NAME: 'DODO Recovery', GIT_AUTHOR_EMAIL: 'recovery@localhost.invalid', GIT_COMMITTER_NAME: 'DODO Recovery', GIT_COMMITTER_EMAIL: 'recovery@localhost.invalid' });
|
|
71
|
+
const flags = ['--git-dir=' + dir, '-c', 'core.hooksPath=' + path.join(dir, 'disabled-hooks'), '-c', 'core.fsmonitor=false', '-c', 'core.attributesFile=' + (process.platform === 'win32' ? 'NUL' : '/dev/null'), '-c', 'gc.auto=0', '-c', 'maintenance.auto=false', '-c', 'protocol.allow=never', '-c', 'credential.helper='];
|
|
72
|
+
return new Promise((resolve, reject) => {
|
|
73
|
+
const child = spawn(executable, [...flags, ...args], { cwd: dir, env, shell: false, windowsHide: true, stdio: ['pipe', 'pipe', 'pipe'] });
|
|
74
|
+
let bytes = 0, finished = false;
|
|
75
|
+
const output = [];
|
|
76
|
+
const finish = (error) => { if (finished)
|
|
77
|
+
return; finished = true; clearTimeout(timer); if (error) {
|
|
78
|
+
child.kill();
|
|
79
|
+
reject(error);
|
|
80
|
+
}
|
|
81
|
+
else
|
|
82
|
+
resolve(Buffer.concat(output)); };
|
|
83
|
+
const timer = setTimeout(() => finish(new DodoError('RESOURCE_LIMIT', 'Git checkpoint command timed out')), Math.min(15000, Math.max(1, deadline - Date.now())));
|
|
84
|
+
child.on('error', () => finish(new DodoError('NOT_SUPPORTED', 'Git checkpoint process could not start')));
|
|
85
|
+
child.stdout.on('data', (b) => { bytes += b.length; if (bytes > maxOutput)
|
|
86
|
+
finish(new DodoError('RESOURCE_LIMIT', 'Git checkpoint output exceeded budget'));
|
|
87
|
+
else
|
|
88
|
+
output.push(b); });
|
|
89
|
+
child.stderr.resume();
|
|
90
|
+
child.stdin.on('error', () => { });
|
|
91
|
+
child.stdin.end(input);
|
|
92
|
+
child.on('close', code => finish(code === 0 ? undefined : new DodoError('RECOVERY_REQUIRED', 'Git checkpoint command failed; repository output hidden')));
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
seal(dir) {
|
|
96
|
+
ensurePrivateDirectory(dir);
|
|
97
|
+
let bytes = 0;
|
|
98
|
+
for (const name of fs.readdirSync(dir)) {
|
|
99
|
+
const p = path.join(dir, name), st = fs.lstatSync(p);
|
|
100
|
+
if (st.isSymbolicLink() || (!st.isFile() && !st.isDirectory()) || (st.isFile() && st.nlink !== 1))
|
|
101
|
+
throw new DodoError('PATH_DENIED', 'Git copy has unsafe objects');
|
|
102
|
+
if (st.isDirectory()) {
|
|
103
|
+
bytes += this.seal(p);
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
// These are newly created private copies, never working repository files.
|
|
107
|
+
// Git can mark object files read-only; Windows FlushFileBuffers requires
|
|
108
|
+
// a write-capable handle. Clear that bit only after verifying the ACL.
|
|
109
|
+
if (process.platform === 'win32')
|
|
110
|
+
assertPrivatePath(p);
|
|
111
|
+
fs.chmodSync(p, 0o600);
|
|
112
|
+
assertPrivatePath(p);
|
|
113
|
+
const fd = fs.openSync(p, fs.constants.O_RDWR | (fs.constants.O_NOFOLLOW ?? 0));
|
|
114
|
+
try {
|
|
115
|
+
const opened = fs.fstatSync(fd);
|
|
116
|
+
if (!opened.isFile() || opened.nlink !== 1 || opened.dev !== st.dev || opened.ino !== st.ino || opened.size !== st.size)
|
|
117
|
+
throw new DodoError('PATH_DENIED', 'Git copy file changed during sealing');
|
|
118
|
+
fs.fsyncSync(fd);
|
|
119
|
+
}
|
|
120
|
+
finally {
|
|
121
|
+
fs.closeSync(fd);
|
|
122
|
+
}
|
|
123
|
+
bytes += st.size;
|
|
124
|
+
}
|
|
125
|
+
syncDir(dir);
|
|
126
|
+
return bytes;
|
|
127
|
+
}
|
|
128
|
+
async capture(m, policy) {
|
|
129
|
+
if (m.scope !== 'source' || m.trigger === 'emergency-observed')
|
|
130
|
+
return;
|
|
131
|
+
let directory, identity, recorded = false;
|
|
132
|
+
try {
|
|
133
|
+
const metadata = await this.s.git.recoveryMetadata();
|
|
134
|
+
if (!metadata.isRepo) {
|
|
135
|
+
this.last = { state: 'not_a_git_repository' };
|
|
136
|
+
if (policy.gitRequired)
|
|
137
|
+
throw new DodoError('NOT_SUPPORTED', 'Git-required project has no Git repository');
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const base = this.destination(policy);
|
|
141
|
+
const estimate = m.entries.reduce((n, e) => n + e.bytes * 2 + 512, 1024 * 1024);
|
|
142
|
+
// Shared DB reservation covers copies from different active projects too.
|
|
143
|
+
this.s.store.db.transaction(() => {
|
|
144
|
+
const usage = this.storage.usageFor(this.s.workspaceId), install = this.storage.installationPolicy(), stat = fs.statfsSync(base, { bigint: true });
|
|
145
|
+
const pending = this.s.store.db.prepare("SELECT (SELECT COALESCE(SUM(bytes),0) FROM recovery_git_copies WHERE state='PREPARING') + (SELECT COALESCE(SUM(bytes+staging_bytes),0) FROM recovery_reservations) AS n").get().n;
|
|
146
|
+
if (usage.installationBytes + usage.reservedBytes + estimate > install.storageBytes || usage.projectBytes + estimate > policy.projectBytes || stat.bavail * stat.bsize < BigInt(install.freeFloorBytes + pending + estimate))
|
|
147
|
+
throw new DodoError('RESOURCE_LIMIT', 'Git recovery quota or free-space floor reached');
|
|
148
|
+
directory = path.join(base, m.id + '.git');
|
|
149
|
+
this.s.store.db.prepare('INSERT INTO recovery_git_copies VALUES (?,?,?,NULL,?,\'PREPARING\',?)').run(m.id, this.s.workspaceId, directory, estimate, JSON.stringify(metadata));
|
|
150
|
+
recorded = true;
|
|
151
|
+
}).immediate();
|
|
152
|
+
fs.mkdirSync(directory, { mode: 0o700 });
|
|
153
|
+
ensurePrivateDirectory(directory);
|
|
154
|
+
identity = rootIdentity(directory);
|
|
155
|
+
this.s.store.db.prepare('UPDATE recovery_git_copies SET identity=? WHERE snapshot_id=?').run(identity, m.id);
|
|
156
|
+
const deadline = Date.now() + 60000;
|
|
157
|
+
await this.command(directory, ['init', '--bare', '--template=', '.'], undefined, deadline);
|
|
158
|
+
await this.command(directory, ['read-tree', '--empty'], undefined, deadline);
|
|
159
|
+
const index = [];
|
|
160
|
+
const objects = [];
|
|
161
|
+
for (const e of m.entries)
|
|
162
|
+
if (e.kind === 'file') {
|
|
163
|
+
const bytes = await this.storage.readObject(e.hash, e.bytes, policy.fileBytes);
|
|
164
|
+
const oid = (await this.command(directory, ['hash-object', '-w', '--no-filters', '--stdin'], bytes, deadline)).toString().trim();
|
|
165
|
+
if (!/^[a-f0-9]{40,64}$/.test(oid))
|
|
166
|
+
throw new DodoError('RECOVERY_REQUIRED', 'invalid Git object ID');
|
|
167
|
+
index.push(Buffer.from(`${(e.mode ?? 0) & 0o111 ? '100755' : '100644'} ${oid}\t${e.path}\0`));
|
|
168
|
+
objects.push({ oid, hash: e.hash, bytes: e.bytes });
|
|
169
|
+
}
|
|
170
|
+
await this.command(directory, ['update-index', '-z', '--index-info'], Buffer.concat(index), deadline);
|
|
171
|
+
const tree = (await this.command(directory, ['write-tree'], undefined, deadline)).toString().trim();
|
|
172
|
+
const commit = (await this.command(directory, ['commit-tree', tree], Buffer.from('DODO approved source checkpoint\n'), deadline)).toString().trim();
|
|
173
|
+
const ref = 'refs/dodo/snapshots/' + m.id;
|
|
174
|
+
await this.command(directory, ['update-ref', ref, commit, '0'.repeat(commit.length)], undefined, deadline);
|
|
175
|
+
await this.command(directory, ['fsck', '--strict', '--no-reflogs'], undefined, deadline);
|
|
176
|
+
// Verify independent Git bytes, not just a successful plumbing exit code.
|
|
177
|
+
for (const object of objects) {
|
|
178
|
+
const bytes = await this.command(directory, ['cat-file', 'blob', object.oid], undefined, deadline, policy.fileBytes);
|
|
179
|
+
if (bytes.length !== object.bytes || createHash('sha256').update(bytes).digest('hex') !== object.hash)
|
|
180
|
+
throw new DodoError('RECOVERY_REQUIRED', 'Git recovery content verification failed');
|
|
181
|
+
}
|
|
182
|
+
fs.rmSync(path.join(directory, 'private-index'), { force: true });
|
|
183
|
+
fs.writeFileSync(path.join(directory, 'dodo-source-manifest.json'), JSON.stringify(m), { flag: 'wx', mode: 0o600 });
|
|
184
|
+
const bytes = this.seal(directory);
|
|
185
|
+
if (bytes > estimate)
|
|
186
|
+
throw new DodoError('RESOURCE_LIMIT', 'Git recovery copy exceeded reserved size');
|
|
187
|
+
syncDir(directory);
|
|
188
|
+
syncDir(base);
|
|
189
|
+
this.s.store.db.prepare("UPDATE recovery_git_copies SET state='READY',bytes=?,payload=? WHERE snapshot_id=?").run(bytes, JSON.stringify({ ref, commit, tree, metadata }), m.id);
|
|
190
|
+
this.last = { state: 'ready', checkpointId: m.id, commit };
|
|
191
|
+
}
|
|
192
|
+
catch (e) {
|
|
193
|
+
if (directory && identity && fs.existsSync(directory) && rootIdentity(directory) === identity) {
|
|
194
|
+
fs.rmSync(directory, { recursive: true });
|
|
195
|
+
if (recorded)
|
|
196
|
+
this.s.store.db.prepare('DELETE FROM recovery_git_copies WHERE snapshot_id=?').run(m.id);
|
|
197
|
+
}
|
|
198
|
+
else if (recorded)
|
|
199
|
+
this.s.store.db.prepare("UPDATE recovery_git_copies SET state='INCOMPLETE' WHERE snapshot_id=?").run(m.id);
|
|
200
|
+
this.last = { state: 'unavailable', errorCode: e instanceof DodoError ? e.code : 'BACKUP_IO_ERROR' };
|
|
201
|
+
if (policy.gitRequired || policy.gitDirectory)
|
|
202
|
+
throw new DodoError('RECOVERY_REQUIRED', 'configured Git recovery copy is unavailable; no fallback destination was used');
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
prune() {
|
|
206
|
+
const rows = this.s.store.db.prepare('SELECT snapshot_id,directory,identity FROM recovery_git_copies WHERE workspace_id=? AND NOT EXISTS(SELECT 1 FROM recovery_snapshots WHERE id=snapshot_id)').all(this.s.workspaceId);
|
|
207
|
+
for (const r of rows) {
|
|
208
|
+
try {
|
|
209
|
+
if (!r.identity || rootIdentity(r.directory) !== r.identity)
|
|
210
|
+
continue;
|
|
211
|
+
assertPrivatePath(r.directory, true);
|
|
212
|
+
fs.rmSync(r.directory, { recursive: true });
|
|
213
|
+
this.s.store.db.prepare('DELETE FROM recovery_git_copies WHERE snapshot_id=?').run(r.snapshot_id);
|
|
214
|
+
}
|
|
215
|
+
catch { /* missing selected volume: keep quota accounting, never fallback */ }
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
//# sourceMappingURL=gitCopies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitCopies.js","sourceRoot":"","sources":["../../../src/services/recovery/gitCopies.ts"],"names":[],"mappings":"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"}
|