Restore extractTarball

This commit is contained in:
Iván Ovejero 2024-10-11 13:02:45 +02:00
parent b2e0c9e4c9
commit 64606591c6
No known key found for this signature in database
2 changed files with 37 additions and 9 deletions

View file

@ -3,9 +3,7 @@ import { ensureError, jsonParse } from 'n8n-workflow';
import fs from 'node:fs';
import path from 'node:path';
import readline from 'node:readline';
import { pipeline } from 'node:stream/promises';
import { Service } from 'typedi';
import { Extract } from 'unzip-stream';
import { NotObjectLiteralError } from '@/errors/not-object-literal.error';
import { RowCountMismatchError } from '@/errors/row-count-mismatch.error';
@ -28,7 +26,7 @@ import { DatabaseSchemaService } from '../database-schema.service';
@Service()
export class DatabaseImportService {
private config: DatabaseImportConfig = {
importFilePath: '',
importFilePath: '/tmp/backup/n8n-db-export-2024-10-11.tar.gz',
extractDirPath: '/tmp/backup',
truncateDestination: true, // @TODO: Only for dev, default it to `false` later
};
@ -85,12 +83,7 @@ export class DatabaseImportService {
if (dbType !== 'postgresdb') throw new UnsupportedDestinationError(dbType);
// @TODO: Stream instead of extracting to filesystem
await pipeline(
fs.createReadStream(this.config.importFilePath),
Extract({ path: this.config.extractDirPath }),
);
await this.fsService.extractTarball(this.config.importFilePath, this.config.extractDirPath);
this.manifest = await this.getManifest();

View file

@ -1,10 +1,18 @@
import { FileNotFoundError } from 'n8n-core';
import { ensureError } from 'n8n-workflow';
import fs from 'node:fs';
import path from 'node:path';
import { pipeline } from 'node:stream/promises';
import { createGunzip } from 'node:zlib';
import tar from 'tar-stream';
import { Service } from 'typedi';
import { Logger } from '@/logging/logger.service';
@Service()
export class FilesystemService {
constructor(private readonly logger: Logger) {}
/**
* Ensure a directory exists by checking or creating it.
* @param dirPath Path to the directory to check or create.
@ -46,4 +54,31 @@ export class FilesystemService {
}
}
}
/**
* Extract a tarball to a given directory.
* @param tarballPath Path to the tarball file to extract.
* @param dstDir Path to the directory to extract the tarball into.
* @returns Paths to the extracted files.
*/
async extractTarball(tarballPath: string, dstDir: string) {
await this.checkAccessible(tarballPath); // @TODO: Clearer error if tarball missing
const extractedFilePaths: string[] = [];
const extract = tar.extract();
extract.on('entry', async (header, stream, next) => {
const filePath = path.join(dstDir, header.name);
await pipeline(stream, fs.createWriteStream(filePath));
extractedFilePaths.push(filePath);
next();
});
await pipeline(fs.createReadStream(tarballPath), createGunzip(), extract);
this.logger.info('[FilesystemService] Extracted tarball', { tarballPath });
return extractedFilePaths;
}
}