You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add optional per-job support for Borg exclusion pattern files through --exclude-from PATH.
A central exclusion file lets experienced Borg users maintain many file and directory rules in one place. It complements the current explicit path exclusions and the proposed marker-based --exclude-if-present option without requiring arbitrary additional Borg arguments.
Motivation
Users migrating existing Borg scripts often already maintain an exclusion file. Without --exclude-from, every rule must be recreated as an individual path in the wizard. This is inefficient for large or dynamic configurations and prevents reuse of Borg-native pattern styles.
Current behavior
Borg Backup UI currently stores concrete exclusion paths in each job and generates a separate Borg --exclude argument for each path. It does not accept a Borg pattern file and intentionally does not expose a free-form command-line field.
Borg semantics
--exclude-from PATH reads exclusion patterns from a file. The file can contain Borg pattern styles and therefore has more expressive behavior than the current absolute path picker.
The implementation should preserve Borg's native file semantics instead of translating the file into UI paths. Explicit path exclusions, marker-based exclusions and exclusion files should be additive.
Store a path to an existing exclusion file and pass it to Borg at runtime.
Advantages:
smallest implementation;
users can continue editing their existing file;
no duplicate copy is created.
Disadvantages and risks:
the file can be moved, deleted or become unreadable;
its contents can change outside the job wizard without an auditable job edit;
it may not be included in plugin settings backup or job export;
a path on temporary storage may disappear after reboot;
importing the job on another system can leave a broken reference;
unrestricted paths create avoidable validation and support complexity.
If this option is selected, the implementation must validate the path as a readable regular file at save time and again immediately before borg create. A missing or unreadable file must fail the job before archive creation. The allowed persistent path roots must be defined explicitly; arbitrary raw paths must not be forwarded unchecked.
Option B: Import a managed copy into the plugin configuration
Let the user select or upload an exclusion file and copy its exact contents into the existing persistent plugin data layout. The job references the managed copy rather than the original file.
Advantages:
stable behavior across reboots;
the exact rules used by the job are owned by the job configuration;
settings backup/restore and job transfer can include the file deliberately;
external edits cannot silently change a backup job;
missing-file diagnostics and lifecycle handling are easier to define.
Disadvantages and risks:
replacing or removing the file needs an explicit lifecycle;
job duplication, deletion and immutable job IDs must be considered;
the UI must show which copy is active and when it was imported;
imported content can disclose filesystem names in exports or support packages and must be handled consistently with existing job paths;
size and encoding limits are required.
This is the recommended first implementation because it makes backup behavior reproducible and keeps the job self-contained.
Option C: Add an integrated Borg pattern editor
Store the pattern text with the job and provide an editor with validation and documentation.
Advantages:
best discoverability;
no external files;
easy review while editing the job.
Disadvantages and risks:
largest UI and validation scope;
Borg pattern syntax is expert functionality and easy to misunderstand;
syntax highlighting, line-level errors and safe editing increase complexity;
changing Borg syntax across supported versions would need consideration.
This can be a later enhancement. It should not block a managed file import.
Recommended phased design
Phase 1: Managed import
Add an advanced subsection under Job Wizard -> Sources and target -> Exclusions:
Optional exclusion pattern file.
Import or replace a file explicitly.
Show the original filename, import timestamp, size and a content hash.
Allow the managed file to be downloaded for inspection and removed with confirmation.
Explain that patterns use Borg syntax and can exclude more data than intended.
Do not provide or accept arbitrary additional Borg flags.
Store the exact imported bytes in the established persistent plugin data layout. The precise path must follow current job storage conventions and must not introduce a new top-level data architecture.
The final schema should align with the immutable job ID work in #447. If this feature is implemented before #447, its storage design must avoid adding another filename keyed only by mutable job names or archive prefixes.
Phase 2: Optional editing
After the managed import is stable, consider a dedicated editor for the managed content. Editing must be explicit, validated and visible as a job configuration change.
Runtime behavior
Resolve only the managed reference belonging to the current job.
Verify that it is a readable regular file and still matches the stored metadata or update policy.
Fail before borg create if the file is missing, unreadable, oversized or invalid according to the selected validation level.
Add arguments without shell interpolation:
--exclude-from /resolved/managed/path
Combine the file with existing explicit --exclude arguments and optional --exclude-if-present markers.
Log the managed filename and hash, but do not dump the full rule contents into normal logs.
Show the active file in the flow preview and final job summary.
Validation and safety requirements
Define a conservative maximum file size and maximum line length.
Reject NUL bytes and unsupported file types.
Decide whether UTF-8 is required or whether the exact byte content is retained.
Never evaluate the file through a shell.
Do not silently ignore missing or unreadable files.
Do not silently rewrite Borg patterns.
Provide a prominent warning that an incorrect rule can exclude required backup data.
Encourage a manual backup run and archive inspection after adding or replacing the file.
Preserve file permissions appropriate for plugin-owned configuration.
Ensure path traversal and symlink attacks cannot escape the managed storage location.
Define cleanup behavior when a job is deleted, while respecting repository and migration safety rules.
Import, export and diagnostics
The implementation must define:
whether the managed file is included in job export and full settings backup;
how filename collisions are avoided;
how job duplication creates an independent or shared copy;
how restore handles a missing, corrupt or conflicting managed file;
how support packages report metadata without unnecessarily exposing the full pattern list;
how system health reports an orphaned or missing managed file;
how a future immutable job ID migration maps the file safely.
Open decisions
Before implementation, decide:
Managed import only, external reference only, or both?
One exclusion file per job initially, or a repeatable list?
Should the browser select a file already on the Unraid server, upload one from the administrator's computer, or support both?
Should Borg be the only syntax validator, or should the UI perform limited structural validation first?
Should the managed file be included in job transfer by default?
This issue is intentionally blocked by #447 and should be implemented only after immutable job IDs are available.
The recommended managed-import design creates a persistent, job-owned exclusion file. Its storage path, lifecycle, duplication, cleanup, transfer and recovery behavior must be keyed by the immutable job ID introduced in #447. Implementing the managed file before #447 would require a temporary association based on a mutable job name, job key or archive prefix and would then require another migration. It would also increase the risk of orphaned files or incorrect ownership after a job is renamed or otherwise changed.
Define the managed exclusion file location and lifecycle using that immutable job ID.
Implement the managed --exclude-from workflow described in this issue.
The external-path-only alternative described under Option A could technically be implemented without #447 because it stores only a path in the job metadata. However, that is not the recommended target design and must not be used merely to bypass this dependency unless the issue scope is explicitly changed.
Until #447 is complete, this issue remains blocked and implementation should not begin.
Summary
Add optional per-job support for Borg exclusion pattern files through
--exclude-from PATH.A central exclusion file lets experienced Borg users maintain many file and directory rules in one place. It complements the current explicit path exclusions and the proposed marker-based
--exclude-if-presentoption without requiring arbitrary additional Borg arguments.Motivation
Users migrating existing Borg scripts often already maintain an exclusion file. Without
--exclude-from, every rule must be recreated as an individual path in the wizard. This is inefficient for large or dynamic configurations and prevents reuse of Borg-native pattern styles.Current behavior
Borg Backup UI currently stores concrete exclusion paths in each job and generates a separate Borg
--excludeargument for each path. It does not accept a Borg pattern file and intentionally does not expose a free-form command-line field.Borg semantics
--exclude-from PATHreads exclusion patterns from a file. The file can contain Borg pattern styles and therefore has more expressive behavior than the current absolute path picker.The implementation should preserve Borg's native file semantics instead of translating the file into UI paths. Explicit path exclusions, marker-based exclusions and exclusion files should be additive.
Reference: https://borgbackup.readthedocs.io/en/1.4-maint/usage/create.html
Implementation alternatives
Option A: Reference an existing server-side file
Store a path to an existing exclusion file and pass it to Borg at runtime.
Advantages:
Disadvantages and risks:
If this option is selected, the implementation must validate the path as a readable regular file at save time and again immediately before
borg create. A missing or unreadable file must fail the job before archive creation. The allowed persistent path roots must be defined explicitly; arbitrary raw paths must not be forwarded unchecked.Option B: Import a managed copy into the plugin configuration
Let the user select or upload an exclusion file and copy its exact contents into the existing persistent plugin data layout. The job references the managed copy rather than the original file.
Advantages:
Disadvantages and risks:
This is the recommended first implementation because it makes backup behavior reproducible and keeps the job self-contained.
Option C: Add an integrated Borg pattern editor
Store the pattern text with the job and provide an editor with validation and documentation.
Advantages:
Disadvantages and risks:
This can be a later enhancement. It should not block a managed file import.
Recommended phased design
Phase 1: Managed import
Add an advanced subsection under Job Wizard -> Sources and target -> Exclusions:
Store the exact imported bytes in the established persistent plugin data layout. The precise path must follow current job storage conventions and must not introduce a new top-level data architecture.
Suggested metadata shape:
{ "exclude_from": { "managed_file": "relative-managed-reference", "original_name": "exclude.txt", "sha256": "...", "imported_at": "..." } }The final schema should align with the immutable job ID work in #447. If this feature is implemented before #447, its storage design must avoid adding another filename keyed only by mutable job names or archive prefixes.
Phase 2: Optional editing
After the managed import is stable, consider a dedicated editor for the managed content. Editing must be explicit, validated and visible as a job configuration change.
Runtime behavior
borg createif the file is missing, unreadable, oversized or invalid according to the selected validation level.--excludearguments and optional--exclude-if-presentmarkers.Validation and safety requirements
Import, export and diagnostics
The implementation must define:
Open decisions
Before implementation, decide:
Tests
Add coverage for:
Acceptance criteria
--exclude-fromwithout shell evaluation or silent rewriting.Dependency on #447
This issue is intentionally blocked by #447 and should be implemented only after immutable job IDs are available.
The recommended managed-import design creates a persistent, job-owned exclusion file. Its storage path, lifecycle, duplication, cleanup, transfer and recovery behavior must be keyed by the immutable job ID introduced in #447. Implementing the managed file before #447 would require a temporary association based on a mutable job name, job key or archive prefix and would then require another migration. It would also increase the risk of orphaned files or incorrect ownership after a job is renamed or otherwise changed.
Required implementation order:
--exclude-fromworkflow described in this issue.The external-path-only alternative described under Option A could technically be implemented without #447 because it stores only a path in the job metadata. However, that is not the recommended target design and must not be used merely to bypass this dependency unless the issue scope is explicitly changed.
Until #447 is complete, this issue remains blocked and implementation should not begin.