diff --git a/app/client/modules/backups/components/create-schedule-form.tsx b/app/client/modules/backups/components/create-schedule-form.tsx
index 8f6de25c..2cf62e15 100644
--- a/app/client/modules/backups/components/create-schedule-form.tsx
+++ b/app/client/modules/backups/components/create-schedule-form.tsx
@@ -318,7 +318,7 @@ export const CreateScheduleForm = ({ initialValues, formId, onSubmit, volume }:
onSelectionChange={handleSelectionChange}
withCheckboxes={true}
foldersOnly={false}
- className="flex-1 border rounded-md bg-card p-2 min-h-[300px] max-h-[400px] overflow-auto"
+ className="flex-1 border rounded-md bg-card p-2 min-h-75 max-h-100 overflow-auto"
/>
{selectedPaths.size > 0 && (
@@ -342,7 +342,7 @@ export const CreateScheduleForm = ({ initialValues, formId, onSubmit, volume }:
@@ -375,7 +375,7 @@ export const CreateScheduleForm = ({ initialValues, formId, onSubmit, volume }:
diff --git a/app/server/modules/backends/utils/backend-utils.ts b/app/server/modules/backends/utils/backend-utils.ts
index 637001fb..e610217d 100644
--- a/app/server/modules/backends/utils/backend-utils.ts
+++ b/app/server/modules/backends/utils/backend-utils.ts
@@ -7,6 +7,7 @@ import { $ } from "bun";
export const executeMount = async (args: string[]): Promise => {
let stderr: string | undefined;
+ logger.debug(`Executing mount ${args.join(" ")}`);
const result = await $`mount ${args}`.nothrow();
stderr = result.stderr.toString();
@@ -22,7 +23,8 @@ export const executeMount = async (args: string[]): Promise => {
export const executeUnmount = async (path: string): Promise => {
let stderr: string | undefined;
- const result = await $`umount -l -f ${path}`.nothrow();
+ logger.debug(`Executing umount -l ${path}`);
+ const result = await $`umount -l ${path}`.nothrow();
stderr = result.stderr.toString();
if (stderr?.trim()) {
diff --git a/app/server/modules/backups/backups.service.ts b/app/server/modules/backups/backups.service.ts
index bb28f29a..b32c317a 100644
--- a/app/server/modules/backups/backups.service.ts
+++ b/app/server/modules/backups/backups.service.ts
@@ -13,6 +13,7 @@ import { serverEvents } from "../../core/events";
import { notificationsService } from "../notifications/notifications.service";
import { repoMutex } from "../../core/repository-mutex";
import { checkMirrorCompatibility, getIncompatibleMirrorError } from "~/server/utils/backend-compatibility";
+import path from "node:path";
const runningBackups = new Map();
@@ -258,7 +259,16 @@ const executeBackup = async (scheduleId: number, manual = false) => {
};
if (schedule.excludePatterns && schedule.excludePatterns.length > 0) {
- backupOptions.exclude = schedule.excludePatterns;
+ const excludePatterns = [];
+ for (const pattern of schedule.excludePatterns) {
+ if (!pattern.startsWith(volumePath)) {
+ excludePatterns.push(path.join(volumePath, pattern));
+ } else {
+ excludePatterns.push(pattern);
+ }
+ }
+
+ backupOptions.exclude = excludePatterns;
}
if (schedule.excludeIfPresent && schedule.excludeIfPresent.length > 0) {
@@ -266,7 +276,16 @@ const executeBackup = async (scheduleId: number, manual = false) => {
}
if (schedule.includePatterns && schedule.includePatterns.length > 0) {
- backupOptions.include = schedule.includePatterns;
+ const includePatterns = [];
+ for (const pattern of schedule.includePatterns) {
+ if (!pattern.startsWith(volumePath)) {
+ includePatterns.push(path.join(volumePath, pattern));
+ } else {
+ includePatterns.push(pattern);
+ }
+ }
+
+ backupOptions.include = includePatterns;
}
const releaseBackupLock = await repoMutex.acquireShared(repository.id, `backup:${volume.name}`);
diff --git a/app/server/utils/restic.ts b/app/server/utils/restic.ts
index 0e1a7330..a4e076f5 100644
--- a/app/server/utils/restic.ts
+++ b/app/server/utils/restic.ts
@@ -267,9 +267,7 @@ const backup = async (
const tmp = await fs.mkdtemp(path.join(os.tmpdir(), "zerobyte-restic-include-"));
includeFile = path.join(tmp, `include.txt`);
- const includePaths = options.include.map((p) => path.join(source, p));
-
- await fs.writeFile(includeFile, includePaths.join("\n"), "utf-8");
+ await fs.writeFile(includeFile, options.include.join("\n"), "utf-8");
args.push("--files-from", includeFile);
} else {
@@ -280,10 +278,14 @@ const backup = async (
args.push("--exclude", exclude);
}
+ let excludeFile: string | null = null;
if (options?.exclude && options.exclude.length > 0) {
- for (const pattern of options.exclude) {
- args.push("--exclude", pattern);
- }
+ const tmp = await fs.mkdtemp(path.join(os.tmpdir(), "zerobyte-restic-exclude-"));
+ excludeFile = path.join(tmp, `exclude.txt`);
+
+ await fs.writeFile(excludeFile, options.exclude.join("\n"), "utf-8");
+
+ args.push("--exclude-file", excludeFile);
}
if (options?.excludeIfPresent && options.excludeIfPresent.length > 0) {
@@ -330,6 +332,7 @@ const backup = async (
},
finally: async () => {
includeFile && (await fs.unlink(includeFile).catch(() => {}));
+ excludeFile && (await fs.unlink(excludeFile).catch(() => {}));
await cleanupTemporaryKeys(config, env);
},
});