mirror of
https://github.com/nicotsx/ironmount.git
synced 2025-12-10 12:10:51 +01:00
feat: backup schedule frontend
This commit is contained in:
@@ -155,6 +155,11 @@ const executeBackup = async (scheduleId: number) => {
|
||||
throw new NotFoundError("Backup schedule not found");
|
||||
}
|
||||
|
||||
if (!schedule.enabled) {
|
||||
logger.info(`Backup schedule ${scheduleId} is disabled. Skipping execution.`);
|
||||
return;
|
||||
}
|
||||
|
||||
const volume = await db.query.volumesTable.findFirst({
|
||||
where: eq(volumesTable.id, schedule.volumeId),
|
||||
});
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
getRepositoryDto,
|
||||
listRepositoriesDto,
|
||||
listSnapshotsDto,
|
||||
listSnapshotsFilters,
|
||||
type DeleteRepositoryDto,
|
||||
type GetRepositoryDto,
|
||||
type ListRepositoriesDto,
|
||||
@@ -38,9 +39,11 @@ export const repositoriesController = new Hono()
|
||||
|
||||
return c.json<DeleteRepositoryDto>({ message: "Repository deleted" }, 200);
|
||||
})
|
||||
.get("/:name/snapshots", listSnapshotsDto, async (c) => {
|
||||
.get("/:name/snapshots", listSnapshotsDto, validator("query", listSnapshotsFilters), async (c) => {
|
||||
const { name } = c.req.param();
|
||||
const res = await repositoriesService.listSnapshots(name);
|
||||
const { volumeId } = c.req.valid("query");
|
||||
|
||||
const res = await repositoriesService.listSnapshots(name, Number(volumeId));
|
||||
|
||||
const snapshots = res.map((snapshot) => {
|
||||
const { summary } = snapshot;
|
||||
|
||||
@@ -145,6 +145,10 @@ const listSnapshotsResponse = type({
|
||||
|
||||
export type ListSnapshotsDto = typeof listSnapshotsResponse.infer;
|
||||
|
||||
export const listSnapshotsFilters = type({
|
||||
volumeId: "string?",
|
||||
});
|
||||
|
||||
export const listSnapshotsDto = describeRoute({
|
||||
description: "List all snapshots in a repository",
|
||||
tags: ["Repositories"],
|
||||
|
||||
@@ -4,10 +4,11 @@ import { eq } from "drizzle-orm";
|
||||
import { ConflictError, InternalServerError, NotFoundError } from "http-errors-enhanced";
|
||||
import slugify from "slugify";
|
||||
import { db } from "../../db/db";
|
||||
import { repositoriesTable } from "../../db/schema";
|
||||
import { repositoriesTable, volumesTable } from "../../db/schema";
|
||||
import { toMessage } from "../../utils/errors";
|
||||
import { restic } from "../../utils/restic";
|
||||
import { cryptoUtils } from "../../utils/crypto";
|
||||
import { getVolumePath } from "../volumes/helpers";
|
||||
|
||||
const listRepositories = async () => {
|
||||
const repositories = await db.query.repositoriesTable.findMany({});
|
||||
@@ -105,7 +106,7 @@ const deleteRepository = async (name: string) => {
|
||||
await db.delete(repositoriesTable).where(eq(repositoriesTable.name, name));
|
||||
};
|
||||
|
||||
const listSnapshots = async (name: string) => {
|
||||
const listSnapshots = async (name: string, volumeId?: number) => {
|
||||
const repository = await db.query.repositoriesTable.findFirst({
|
||||
where: eq(repositoriesTable.name, name),
|
||||
});
|
||||
@@ -114,7 +115,22 @@ const listSnapshots = async (name: string) => {
|
||||
throw new NotFoundError("Repository not found");
|
||||
}
|
||||
|
||||
const snapshots = await restic.snapshots(repository.config);
|
||||
let snapshots = await restic.snapshots(repository.config);
|
||||
|
||||
if (volumeId) {
|
||||
const volume = await db.query.volumesTable.findFirst({
|
||||
where: eq(volumesTable.id, volumeId),
|
||||
});
|
||||
|
||||
if (!volume) {
|
||||
throw new NotFoundError("Volume not found");
|
||||
}
|
||||
|
||||
snapshots = snapshots.filter((snapshot) => {
|
||||
return snapshot.paths.some((path) => path.includes(getVolumePath(volume.name)));
|
||||
});
|
||||
}
|
||||
|
||||
return snapshots;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user