feat: built-in automatic database backups (#13773)

This commit is contained in:
Zack Pollard
2024-10-31 11:29:42 +00:00
committed by GitHub
parent 30d42e571c
commit 7d933ec97a
41 changed files with 994 additions and 17 deletions

View File

@@ -22,6 +22,7 @@ import { INotificationRepository } from 'src/interfaces/notification.interface';
import { IOAuthRepository } from 'src/interfaces/oauth.interface';
import { IPartnerRepository } from 'src/interfaces/partner.interface';
import { IPersonRepository } from 'src/interfaces/person.interface';
import { IProcessRepository } from 'src/interfaces/process.interface';
import { ISearchRepository } from 'src/interfaces/search.interface';
import { IServerInfoRepository } from 'src/interfaces/server-info.interface';
import { ISessionRepository } from 'src/interfaces/session.interface';
@@ -59,6 +60,7 @@ import { NotificationRepository } from 'src/repositories/notification.repository
import { OAuthRepository } from 'src/repositories/oauth.repository';
import { PartnerRepository } from 'src/repositories/partner.repository';
import { PersonRepository } from 'src/repositories/person.repository';
import { ProcessRepository } from 'src/repositories/process.repository';
import { SearchRepository } from 'src/repositories/search.repository';
import { ServerInfoRepository } from 'src/repositories/server-info.repository';
import { SessionRepository } from 'src/repositories/session.repository';
@@ -98,6 +100,7 @@ export const repositories = [
{ provide: IOAuthRepository, useClass: OAuthRepository },
{ provide: IPartnerRepository, useClass: PartnerRepository },
{ provide: IPersonRepository, useClass: PersonRepository },
{ provide: IProcessRepository, useClass: ProcessRepository },
{ provide: ISearchRepository, useClass: SearchRepository },
{ provide: IServerInfoRepository, useClass: ServerInfoRepository },
{ provide: ISessionRepository, useClass: SessionRepository },

View File

@@ -30,6 +30,9 @@ export const JOBS_TO_QUEUE: Record<JobName, QueueName> = {
[JobName.PERSON_CLEANUP]: QueueName.BACKGROUND_TASK,
[JobName.USER_SYNC_USAGE]: QueueName.BACKGROUND_TASK,
// backups
[JobName.BACKUP_DATABASE]: QueueName.BACKUP_DATABASE,
// conversion
[JobName.QUEUE_VIDEO_CONVERSION]: QueueName.VIDEO_CONVERSION,
[JobName.VIDEO_CONVERSION]: QueueName.VIDEO_CONVERSION,

View File

@@ -0,0 +1,16 @@
import { Inject, Injectable } from '@nestjs/common';
import { ChildProcessWithoutNullStreams, spawn, SpawnOptionsWithoutStdio } from 'node:child_process';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { IProcessRepository } from 'src/interfaces/process.interface';
import { StorageRepository } from 'src/repositories/storage.repository';
@Injectable()
export class ProcessRepository implements IProcessRepository {
constructor(@Inject(ILoggerRepository) private logger: ILoggerRepository) {
this.logger.setContext(StorageRepository.name);
}
spawn(command: string, args: readonly string[], options?: SpawnOptionsWithoutStdio): ChildProcessWithoutNullStreams {
return spawn(command, args, options);
}
}

View File

@@ -2,9 +2,10 @@ import { Inject, Injectable } from '@nestjs/common';
import archiver from 'archiver';
import chokidar, { WatchOptions } from 'chokidar';
import { escapePath, glob, globStream } from 'fast-glob';
import { constants, createReadStream, existsSync, mkdirSync } from 'node:fs';
import { constants, createReadStream, createWriteStream, existsSync, mkdirSync } from 'node:fs';
import fs from 'node:fs/promises';
import path from 'node:path';
import { Writable } from 'node:stream';
import { CrawlOptionsDto, WalkOptionsDto } from 'src/dtos/library.dto';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import {
@@ -42,6 +43,10 @@ export class StorageRepository implements IStorageRepository {
return fs.writeFile(filepath, buffer, { flag: 'wx' });
}
createWriteStream(filepath: string): Writable {
return createWriteStream(filepath, { flags: 'w' });
}
createOrOverwriteFile(filepath: string, buffer: Buffer) {
return fs.writeFile(filepath, buffer, { flag: 'w' });
}