added progress bar and scheduler

This commit is contained in:
Philipp
2026-05-21 08:53:21 +02:00
parent 3d46f8543b
commit f9350587fe
18 changed files with 624 additions and 165 deletions
+22 -3
View File
@@ -1,5 +1,5 @@
import { spawn } from 'node:child_process';
import { PassThrough } from 'node:stream';
import { PassThrough, Transform } from 'node:stream';
import { resticProcessEnv } from './config.js';
export class CommandError extends Error {
@@ -74,7 +74,22 @@ export function runRestic(args, options = {}) {
});
}
export function streamResticDumpToDd(snapshotId, filename, outputPath, log) {
export function createProgressStream(totalBytes, onProgress) {
let currentBytes = 0;
return new Transform({
transform(chunk, _encoding, callback) {
currentBytes += chunk.length;
onProgress?.({
currentBytes,
totalBytes,
percent: totalBytes ? (currentBytes / totalBytes) * 100 : 0,
});
callback(null, chunk);
},
});
}
export function streamResticDumpToDd(snapshotId, filename, outputPath, log, progress = null) {
return new Promise((resolve, reject) => {
const restic = spawn('restic', ['dump', snapshotId, filename], {
env: resticProcessEnv(),
@@ -91,7 +106,11 @@ export function streamResticDumpToDd(snapshotId, filename, outputPath, log) {
let resticClosed = false;
let ddClosed = false;
const pipe = new PassThrough();
restic.stdout.pipe(pipe).pipe(dd.stdin);
let restoreStream = restic.stdout.pipe(pipe);
if (progress) {
restoreStream = restoreStream.pipe(createProgressStream(progress.totalBytes, progress.onProgress));
}
restoreStream.pipe(dd.stdin);
restic.stderr.on('data', (chunk) => log?.(chunk.toString().trimEnd()));
dd.stderr.on('data', (chunk) => log?.(chunk.toString().trimEnd()));