From bbefb8124ef06f1d203a12fa416185e047beacfd Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Thu, 18 Dec 2025 22:46:15 +0100 Subject: [PATCH] refactor: separate healthcheck and auto remount in two separate jobs --- app/server/core/constants.ts | 6 +----- app/server/jobs/auto-remount.ts | 24 ++++++++++++++++++++++ app/server/jobs/repository-healthchecks.ts | 6 ------ app/server/modules/lifecycle/startup.ts | 2 ++ 4 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 app/server/jobs/auto-remount.ts diff --git a/app/server/core/constants.ts b/app/server/core/constants.ts index 2f876968..a59f558d 100644 --- a/app/server/core/constants.ts +++ b/app/server/core/constants.ts @@ -4,10 +4,6 @@ export const REPOSITORY_BASE = "/var/lib/zerobyte/repositories"; export const DATABASE_URL = "/var/lib/zerobyte/data/ironmount.db"; export const RESTIC_PASS_FILE = "/var/lib/zerobyte/data/restic.pass"; -export const DEFAULT_EXCLUDES = [ - DATABASE_URL, - RESTIC_PASS_FILE, - "/var/lib/zerobyte/repositories/**", // To avoid circular backups -]; +export const DEFAULT_EXCLUDES = [DATABASE_URL, RESTIC_PASS_FILE, REPOSITORY_BASE]; export const REQUIRED_MIGRATIONS = ["v0.14.0"]; diff --git a/app/server/jobs/auto-remount.ts b/app/server/jobs/auto-remount.ts new file mode 100644 index 00000000..1e735dbd --- /dev/null +++ b/app/server/jobs/auto-remount.ts @@ -0,0 +1,24 @@ +import { Job } from "../core/scheduler"; +import { volumeService } from "../modules/volumes/volume.service"; +import { logger } from "../utils/logger"; +import { db } from "../db/db"; +import { eq } from "drizzle-orm"; +import { volumesTable } from "../db/schema"; + +export class VolumeAutoRemountJob extends Job { + async run() { + logger.debug("Running auto-remount for all errored volumes..."); + + const volumes = await db.query.volumesTable.findMany({ + where: eq(volumesTable.status, "error"), + }); + + for (const volume of volumes) { + if (volume.autoRemount) { + await volumeService.mountVolume(volume.name); + } + } + + return { done: true, timestamp: new Date() }; + } +} diff --git a/app/server/jobs/repository-healthchecks.ts b/app/server/jobs/repository-healthchecks.ts index bc233903..1e600c9f 100644 --- a/app/server/jobs/repository-healthchecks.ts +++ b/app/server/jobs/repository-healthchecks.ts @@ -4,7 +4,6 @@ import { logger } from "../utils/logger"; import { db } from "../db/db"; import { eq, or } from "drizzle-orm"; import { repositoriesTable } from "../db/schema"; -import { repoMutex } from "../core/repository-mutex"; export class RepositoryHealthCheckJob extends Job { async run() { @@ -15,11 +14,6 @@ export class RepositoryHealthCheckJob extends Job { }); for (const repository of repositories) { - if (repoMutex.isLocked(repository.id)) { - logger.debug(`Skipping health check for repository ${repository.name}: currently locked`); - continue; - } - try { await repositoriesService.checkHealth(repository.id); } catch (error) { diff --git a/app/server/modules/lifecycle/startup.ts b/app/server/modules/lifecycle/startup.ts index 23ec81fb..2761bf88 100644 --- a/app/server/modules/lifecycle/startup.ts +++ b/app/server/modules/lifecycle/startup.ts @@ -12,6 +12,7 @@ import { BackupExecutionJob } from "../../jobs/backup-execution"; import { CleanupSessionsJob } from "../../jobs/cleanup-sessions"; import { repositoriesService } from "../repositories/repositories.service"; import { notificationsService } from "../notifications/notifications.service"; +import { VolumeAutoRemountJob } from "~/server/jobs/auto-remount"; const ensureLatestConfigurationSchema = async () => { const volumes = await db.query.volumesTable.findMany({}); @@ -67,4 +68,5 @@ export const startup = async () => { Scheduler.build(RepositoryHealthCheckJob).schedule("50 12 * * *"); Scheduler.build(BackupExecutionJob).schedule("* * * * *"); Scheduler.build(CleanupSessionsJob).schedule("0 0 * * *"); + Scheduler.build(VolumeAutoRemountJob).schedule("*/5 * * * *"); };