mirror of
https://github.com/unraid/api.git
synced 2026-01-02 14:40:01 -06:00
chore: types
This commit is contained in:
@@ -94,7 +94,7 @@
|
||||
"command-exists": "1.2.9",
|
||||
"convert": "5.12.0",
|
||||
"cookie": "1.0.2",
|
||||
"cron": "4.3.1",
|
||||
"cron": "4.3.0",
|
||||
"cross-fetch": "4.1.0",
|
||||
"diff": "8.0.2",
|
||||
"dockerode": "4.0.7",
|
||||
@@ -192,6 +192,7 @@
|
||||
"@types/wtfnode": "0.7.3",
|
||||
"@vitest/coverage-v8": "3.2.4",
|
||||
"@vitest/ui": "3.2.4",
|
||||
"commit-and-tag-version": "9.6.0",
|
||||
"cz-conventional-changelog": "3.3.0",
|
||||
"eslint": "9.30.1",
|
||||
"eslint-plugin-import": "2.32.0",
|
||||
@@ -203,7 +204,6 @@
|
||||
"nodemon": "3.1.10",
|
||||
"prettier": "3.6.2",
|
||||
"rollup-plugin-node-externals": "8.0.1",
|
||||
"commit-and-tag-version": "9.6.0",
|
||||
"tsx": "4.20.3",
|
||||
"type-fest": "4.41.0",
|
||||
"typescript": "5.8.3",
|
||||
@@ -225,7 +225,8 @@
|
||||
"nest-authz": {
|
||||
"@nestjs/common": "$@nestjs/common",
|
||||
"@nestjs/core": "$@nestjs/core"
|
||||
}
|
||||
},
|
||||
"cron": "4.3.1"
|
||||
},
|
||||
"private": true,
|
||||
"packageManager": "pnpm@10.13.1"
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
CreateBackupJobConfigInput,
|
||||
UpdateBackupJobConfigInput,
|
||||
} from '@app/unraid-api/graph/resolvers/backup/backup.model.js';
|
||||
import { getBackupJobGroupId } from '@app/unraid-api/graph/resolvers/backup/backup.utils.js';
|
||||
import {
|
||||
DestinationConfigInput,
|
||||
DestinationType,
|
||||
@@ -520,7 +521,7 @@ export class BackupConfigService implements OnModuleInit {
|
||||
'UTC'
|
||||
);
|
||||
|
||||
this.schedulerRegistry.addCronJob(`${JOB_GROUP_PREFIX}${config.id}`, job);
|
||||
this.schedulerRegistry.addCronJob(getBackupJobGroupId(config.id), job);
|
||||
job.start();
|
||||
this.logger.log(`Scheduled backup job: ${config.name} with schedule: ${config.schedule}`);
|
||||
} catch (error) {
|
||||
@@ -530,7 +531,7 @@ export class BackupConfigService implements OnModuleInit {
|
||||
|
||||
private unscheduleJob(id: string): void {
|
||||
try {
|
||||
const jobName = `${JOB_GROUP_PREFIX}${id}`;
|
||||
const jobName = getBackupJobGroupId(id);
|
||||
if (this.schedulerRegistry.doesExist('cron', jobName)) {
|
||||
this.schedulerRegistry.deleteCronJob(jobName);
|
||||
this.logger.log(`Unscheduled backup job: ${id}`);
|
||||
|
||||
@@ -81,8 +81,7 @@ export class BackupOrchestrationService {
|
||||
sourceProcessor,
|
||||
destinationProcessor,
|
||||
jobConfig,
|
||||
internalJobId,
|
||||
configId // Pass configId for handleJobCompletion
|
||||
internalJobId
|
||||
);
|
||||
} else {
|
||||
await this.executeRegularBackup(
|
||||
@@ -201,7 +200,7 @@ export class BackupOrchestrationService {
|
||||
this.emitJobStatus(internalJobId, { status: BackupJobStatus.FAILED, error: errorMsg });
|
||||
// Call handleJobCompletion before throwing
|
||||
await this.backupConfigService.handleJobCompletion(
|
||||
configId,
|
||||
jobConfig.id,
|
||||
BackupJobStatus.FAILED,
|
||||
internalJobId
|
||||
);
|
||||
@@ -218,7 +217,7 @@ export class BackupOrchestrationService {
|
||||
});
|
||||
// Call handleJobCompletion on success
|
||||
await this.backupConfigService.handleJobCompletion(
|
||||
configId,
|
||||
jobConfig.id,
|
||||
BackupJobStatus.COMPLETED,
|
||||
internalJobId
|
||||
);
|
||||
@@ -251,7 +250,7 @@ export class BackupOrchestrationService {
|
||||
});
|
||||
// Call handleJobCompletion on failure
|
||||
await this.backupConfigService.handleJobCompletion(
|
||||
configId,
|
||||
jobConfig.id,
|
||||
BackupJobStatus.FAILED,
|
||||
internalJobId
|
||||
);
|
||||
|
||||
@@ -11,6 +11,11 @@ import got, { HTTPError } from 'got';
|
||||
import pRetry from 'p-retry';
|
||||
|
||||
import { sanitizeParams } from '@app/core/log.js';
|
||||
import {
|
||||
getConfigIdFromGroupId,
|
||||
isBackupJobGroup,
|
||||
} from '@app/unraid-api/graph/resolvers/backup/backup.utils.js';
|
||||
import { BackupJobStatus } from '@app/unraid-api/graph/resolvers/backup/orchestration/backup-job-status.model.js';
|
||||
import { RCloneStatusService } from '@app/unraid-api/graph/resolvers/rclone/rclone-status.service.js';
|
||||
import {
|
||||
CreateRCloneRemoteDto,
|
||||
@@ -72,7 +77,7 @@ interface JobOperationResult {
|
||||
|
||||
@Injectable()
|
||||
export class RCloneApiService implements OnModuleInit, OnModuleDestroy {
|
||||
private isInitialized: boolean = false;
|
||||
private initialized: boolean = false;
|
||||
private readonly logger = new Logger(RCloneApiService.name);
|
||||
private rcloneSocketPath: string = '';
|
||||
private rcloneBaseUrl: string = '';
|
||||
@@ -86,12 +91,51 @@ export class RCloneApiService implements OnModuleInit, OnModuleDestroy {
|
||||
|
||||
constructor(private readonly statusService: RCloneStatusService) {}
|
||||
|
||||
get isInitialized(): boolean {
|
||||
return this.initialized;
|
||||
}
|
||||
|
||||
async onModuleInit(): Promise<void> {
|
||||
try {
|
||||
await this.initializeRCloneService();
|
||||
} catch (error: unknown) {
|
||||
this.logger.error(`Error initializing RCloneApiService: ${error}`);
|
||||
this.isInitialized = false;
|
||||
// Check if rclone binary is available first
|
||||
const isBinaryAvailable = await this.checkRcloneBinaryExists();
|
||||
if (!isBinaryAvailable) {
|
||||
this.logger.warn('RClone binary not found on system, skipping initialization');
|
||||
this.initialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const { getters } = await import('@app/store/index.js');
|
||||
// Check if Rclone Socket is running, if not, start it.
|
||||
this.rcloneSocketPath = getters.paths()['rclone-socket'];
|
||||
const logFilePath = join(getters.paths()['log-base'], 'rclone-unraid-api.log');
|
||||
this.logger.log(`RClone socket path: ${this.rcloneSocketPath}`);
|
||||
this.logger.log(`RClone log file path: ${logFilePath}`);
|
||||
|
||||
// Format the base URL for Unix socket
|
||||
this.rcloneBaseUrl = `http://unix:${this.rcloneSocketPath}:`;
|
||||
|
||||
// Check if the RClone socket exists, if not, create it.
|
||||
const socketExists = await this.checkRcloneSocketExists(this.rcloneSocketPath);
|
||||
|
||||
if (socketExists) {
|
||||
const isRunning = await this.checkRcloneSocketRunning();
|
||||
if (isRunning) {
|
||||
this.initialized = true;
|
||||
return;
|
||||
} else {
|
||||
this.logger.warn(
|
||||
'RClone socket is not running but socket exists, removing socket before starting...'
|
||||
);
|
||||
await rm(this.rcloneSocketPath, { force: true });
|
||||
}
|
||||
|
||||
this.logger.warn('RClone socket is not running, starting it...');
|
||||
this.initialized = await this.startRcloneSocket(this.rcloneSocketPath, logFilePath);
|
||||
return;
|
||||
} else {
|
||||
this.logger.warn('RClone socket does not exist, creating it...');
|
||||
this.initialized = await this.startRcloneSocket(this.rcloneSocketPath, logFilePath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +158,7 @@ export class RCloneApiService implements OnModuleInit, OnModuleDestroy {
|
||||
await this.stopRcloneSocket();
|
||||
|
||||
this.logger.warn('Proceeding to start new RClone socket...');
|
||||
this.isInitialized = await this.startRcloneSocket(this.rcloneSocketPath, logFilePath);
|
||||
this.initialized = await this.startRcloneSocket(this.rcloneSocketPath, logFilePath);
|
||||
}
|
||||
|
||||
private async startRcloneSocket(socketPath: string, logFilePath: string): Promise<boolean> {
|
||||
@@ -200,7 +244,7 @@ export class RCloneApiService implements OnModuleInit, OnModuleDestroy {
|
||||
|
||||
private cleanupFailedProcess(): void {
|
||||
this.rcloneProcess = null;
|
||||
this.isInitialized = false;
|
||||
this.initialized = false;
|
||||
}
|
||||
|
||||
private async waitForSocketReady(): Promise<void> {
|
||||
@@ -349,9 +393,7 @@ export class RCloneApiService implements OnModuleInit, OnModuleDestroy {
|
||||
|
||||
this.logger.log(`Starting backup: ${input.srcPath} → ${input.dstPath}`);
|
||||
|
||||
const group = input.configId
|
||||
? getBackupJobGroupId(input.configId)
|
||||
: BACKUP_JOB_GROUP_PREFIX + 'manual';
|
||||
const group = input.configId ? getConfigIdFromGroupId(input.configId) : 'manual';
|
||||
|
||||
const params = {
|
||||
srcFs: input.srcPath,
|
||||
|
||||
@@ -48,7 +48,7 @@ export class RCloneService {
|
||||
*/
|
||||
async onModuleInit(): Promise<void> {
|
||||
try {
|
||||
if (!this.rcloneApiService.initialized) {
|
||||
if (!this.rcloneApiService.isInitialized) {
|
||||
this.logger.warn(
|
||||
'RClone API service is not initialized, skipping provider info loading'
|
||||
);
|
||||
|
||||
13
pnpm-lock.yaml
generated
13
pnpm-lock.yaml
generated
@@ -157,8 +157,8 @@ importers:
|
||||
specifier: 1.0.2
|
||||
version: 1.0.2
|
||||
cron:
|
||||
specifier: 4.3.1
|
||||
version: 4.3.1
|
||||
specifier: 4.3.0
|
||||
version: 4.3.0
|
||||
cross-fetch:
|
||||
specifier: 4.1.0
|
||||
version: 4.1.0
|
||||
@@ -6509,10 +6509,6 @@ packages:
|
||||
resolution: {integrity: sha512-ciiYNLfSlF9MrDqnbMdRWFiA6oizSF7kA1osPP9lRzNu0Uu+AWog1UKy7SkckiDY2irrNjeO6qLyKnXC8oxmrw==}
|
||||
engines: {node: '>=18.x'}
|
||||
|
||||
cron@4.3.1:
|
||||
resolution: {integrity: sha512-7x7DoEOxV11t3OPWWMjj1xrL1PGkTV5RV+/54IJTZD7gStiaMploY43EkeBSkDZTLRbUwk+OISbQ0TR133oXyA==}
|
||||
engines: {node: '>=18.x'}
|
||||
|
||||
croner@4.1.97:
|
||||
resolution: {integrity: sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ==}
|
||||
|
||||
@@ -19428,11 +19424,6 @@ snapshots:
|
||||
'@types/luxon': 3.6.2
|
||||
luxon: 3.6.1
|
||||
|
||||
cron@4.3.1:
|
||||
dependencies:
|
||||
'@types/luxon': 3.6.2
|
||||
luxon: 3.6.1
|
||||
|
||||
croner@4.1.97: {}
|
||||
|
||||
croner@9.1.0: {}
|
||||
|
||||
Reference in New Issue
Block a user