mirror of
https://github.com/borgbackup/borg.git
synced 2026-06-11 01:41:57 -04:00
Merge pull request #8798 from ThomasWaldmann/remove-append-only
remove remainders of append-only support
This commit is contained in:
commit
d11ba6e7f8
62 changed files with 93 additions and 399 deletions
|
|
@ -55,16 +55,6 @@ multiple times to permit access to more than one repository.
|
|||
The repository may not exist yet; it can be initialized by the user,
|
||||
which allows for encryption.
|
||||
|
||||
**Specificities: Append-only repositories**
|
||||
|
||||
Running ``borg init`` via a ``borg serve --append-only`` server will **not**
|
||||
create a repository that is configured to be append-only by its repository
|
||||
config.
|
||||
|
||||
But, ``--append-only`` arguments in ``authorized_keys`` will override the
|
||||
repository config, therefore append-only mode can be enabled on a key by key
|
||||
basis.
|
||||
|
||||
Refer to the `sshd(8) <https://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man8/sshd.8>`_
|
||||
man page for more details on SSH options.
|
||||
See also :ref:`borg_serve`
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ to *borg-client* has to have read and write permissions on ``/run/borg``::
|
|||
On *borg-server*, we have to start the command ``borg serve`` and make its
|
||||
standard input and output available to a unix socket::
|
||||
|
||||
borg-server:~$ socat UNIX-LISTEN:/run/borg/reponame.sock,fork EXEC:"borg serve --append-only --restrict-to-path /path/to/repo"
|
||||
borg-server:~$ socat UNIX-LISTEN:/run/borg/reponame.sock,fork EXEC:"borg serve --restrict-to-path /path/to/repo"
|
||||
|
||||
Socat will wait until a connection is opened. Then socat will execute the
|
||||
command given, redirecting Standard Input and Output to the unix socket. The
|
||||
|
|
@ -350,7 +350,7 @@ dedicated ssh key:
|
|||
|
||||
borgs@borg-server$ install -m 700 -d ~/.ssh/
|
||||
borgs@borg-server$ ssh-keygen -N '' -t rsa -f ~/.ssh/borg-client_key
|
||||
borgs@borg-server$ { echo -n 'command="borg serve --append-only --restrict-to-repo ~/repo",restrict '; cat ~/.ssh/borg-client_key.pub; } >> ~/.ssh/authorized_keys
|
||||
borgs@borg-server$ { echo -n 'command="borg serve --restrict-to-repo ~/repo",restrict '; cat ~/.ssh/borg-client_key.pub; } >> ~/.ssh/authorized_keys
|
||||
borgs@borg-server$ chmod 600 ~/.ssh/authorized_keys
|
||||
|
||||
``install -m 700 -d ~/.ssh/``
|
||||
|
|
@ -365,12 +365,10 @@ dedicated ssh key:
|
|||
Another more complex approach is using a unique ssh key for each pull operation.
|
||||
This is more secure as it guarantees that the key will not be used for other purposes.
|
||||
|
||||
``{ echo -n 'command="borg serve --append-only --restrict-to-repo ~/repo",restrict '; cat ~/.ssh/borg-client_key.pub; } >> ~/.ssh/authorized_keys``
|
||||
``{ echo -n 'command="borg serve --restrict-to-repo ~/repo",restrict '; cat ~/.ssh/borg-client_key.pub; } >> ~/.ssh/authorized_keys``
|
||||
|
||||
Add borg-client's ssh public key to ~/.ssh/authorized_keys with forced command and restricted mode.
|
||||
The borg client is restricted to use one repo at the specified path and to append-only operation.
|
||||
Commands like *delete*, *prune* and *compact* have to be executed another way, for example directly on *borg-server*
|
||||
side or from a privileged, less restricted client (using another authorized_keys entry).
|
||||
The borg client is restricted to use one repo at the specified path.
|
||||
|
||||
``chmod 600 ~/.ssh/authorized_keys``
|
||||
|
||||
|
|
|
|||
12
docs/faq.rst
12
docs/faq.rst
|
|
@ -146,13 +146,6 @@ How can I restore huge file(s) over an unstable connection?
|
|||
Try using ``borg mount`` and ``rsync`` (or a similar tool that supports
|
||||
resuming a partial file copy from what's already copied).
|
||||
|
||||
How can I switch append-only mode on and off?
|
||||
---------------------------------------------
|
||||
|
||||
You could do that (via borg config REPO append_only 0/1), but using different
|
||||
ssh keys and different entries in ``authorized_keys`` is much easier and also
|
||||
maybe has less potential of things going wrong somehow.
|
||||
|
||||
My machine goes to sleep causing `Broken pipe`
|
||||
----------------------------------------------
|
||||
|
||||
|
|
@ -371,8 +364,8 @@ Another option is to not consider inode numbers in the files cache by passing
|
|||
Why are backups slow on a Linux server that is a member of a Windows domain?
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
If a Linux server is a member of a Windows domain, username to userid resolution might be
|
||||
performed via ``winbind`` without caching, which can slow down backups significantly.
|
||||
If a Linux server is a member of a Windows domain, username to userid resolution might be
|
||||
performed via ``winbind`` without caching, which can slow down backups significantly.
|
||||
You can use e.g. ``nscd`` to add caching and improve the speed.
|
||||
|
||||
Security
|
||||
|
|
@ -553,7 +546,6 @@ C to delete all backups residing on S.
|
|||
|
||||
These are your options to protect against that:
|
||||
|
||||
- Do not allow to delete data permanently from the repo, see :ref:`append_only_mode`.
|
||||
- Use a pull-mode setup using ``ssh -R``, see :ref:`pull_backup` for more information.
|
||||
- Mount C's filesystem on another machine and then create a backup of it.
|
||||
- Do not give C filesystem-level access to S.
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-ANALYZE" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-ANALYZE" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-analyze \- Analyze archives
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-BENCHMARK-CPU" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-BENCHMARK-CPU" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-benchmark-cpu \- Benchmark CPU bound operations.
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-BENCHMARK-CRUD" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-BENCHMARK-CRUD" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-benchmark-crud \- Benchmark Create, Read, Update, Delete for archives.
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-BENCHMARK" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-BENCHMARK" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-benchmark \- benchmark command
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-BREAK-LOCK" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-BREAK-LOCK" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-break-lock \- Break the repository lock (e.g. in case it was left by a dead borg.
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-CHECK" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-CHECK" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-check \- Check repository consistency
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-COMMON" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-COMMON" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-common \- Common options of Borg commands
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-COMPACT" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-COMPACT" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-compact \- Collect garbage in repository
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-COMPRESSION" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-COMPRESSION" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-compression \- Details regarding compression
|
||||
.SH DESCRIPTION
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-CREATE" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-CREATE" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-create \- Create new archive
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-DELETE" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-DELETE" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-delete \- Delete archives
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-DIFF" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-DIFF" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-diff \- Diff contents of two archives
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-EXPORT-TAR" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-EXPORT-TAR" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-export-tar \- Export archive contents as a tarball
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-EXTRACT" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-EXTRACT" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-extract \- Extract archive contents
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-IMPORT-TAR" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-IMPORT-TAR" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-import-tar \- Create a backup archive from a tarball
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-INFO" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-INFO" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-info \- Show archive details such as disk space used
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-KEY-CHANGE-LOCATION" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-KEY-CHANGE-LOCATION" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-key-change-location \- Change repository key location
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-KEY-CHANGE-PASSPHRASE" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-KEY-CHANGE-PASSPHRASE" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-key-change-passphrase \- Change repository key file passphrase
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-KEY-EXPORT" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-KEY-EXPORT" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-key-export \- Export the repository key for backup
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-KEY-IMPORT" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-KEY-IMPORT" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-key-import \- Import the repository key from backup
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-KEY" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-KEY" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-key \- Manage a keyfile or repokey of a repository
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-LIST" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-LIST" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-list \- List archive contents
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-MATCH-ARCHIVES" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-MATCH-ARCHIVES" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-match-archives \- Details regarding match-archives
|
||||
.SH DESCRIPTION
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-MOUNT" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-MOUNT" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-mount \- Mount archive or an entire repository as a FUSE filesystem
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-PATTERNS" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-PATTERNS" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-patterns \- Details regarding patterns
|
||||
.SH DESCRIPTION
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-PLACEHOLDERS" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-PLACEHOLDERS" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-placeholders \- Details regarding placeholders
|
||||
.SH DESCRIPTION
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-PRUNE" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-PRUNE" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-prune \- Prune repository archives according to specified rules
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-RECREATE" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-RECREATE" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-recreate \- Re-create archives
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-RENAME" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-RENAME" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-rename \- Rename an existing archive
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-REPO-COMPRESS" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-REPO-COMPRESS" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-repo-compress \- Repository (re-)compression
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-REPO-CREATE" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-REPO-CREATE" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-repo-create \- Create a new, empty repository
|
||||
.SH SYNOPSIS
|
||||
|
|
@ -248,12 +248,6 @@ other repository is borg 1.x
|
|||
.BI \-e \ MODE\fR,\fB \ \-\-encryption \ MODE
|
||||
select encryption key mode \fB(required)\fP
|
||||
.TP
|
||||
.B \-\-append\-only
|
||||
create an append\-only mode repository. Note that this only affects the low level structure of the repository, and running \fIdelete\fP or \fIprune\fP will still be allowed. See \fIappend_only_mode\fP in Additional Notes for more details.
|
||||
.TP
|
||||
.BI \-\-storage\-quota \ QUOTA
|
||||
Set storage quota of the new repository (e.g. 5G, 1.5T). Default: no quota.
|
||||
.TP
|
||||
.B \-\-copy\-crypt\-key
|
||||
copy the crypt_key (used for authenticated encryption) from the key of the other repo (default: new random key).
|
||||
.UNINDENT
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-REPO-DELETE" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-REPO-DELETE" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-repo-delete \- Delete a repository
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-REPO-INFO" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-REPO-INFO" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-repo-info \- Show repository infos
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-REPO-LIST" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-REPO-LIST" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-repo-list \- List the archives contained in a repository
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-REPO-SPACE" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-REPO-SPACE" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-repo-space \- Manage reserved space in repository
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-SERVE" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-SERVE" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-serve \- Start in server mode. This command is usually not used manually.
|
||||
.SH SYNOPSIS
|
||||
|
|
@ -59,12 +59,6 @@ restrict repository access to PATH. Can be specified multiple times to allow the
|
|||
.TP
|
||||
.BI \-\-restrict\-to\-repository \ PATH
|
||||
restrict repository access. Only the repository located at PATH (no sub\-directories are considered) is accessible. Can be specified multiple times to allow the client access to several repositories. Unlike \fB\-\-restrict\-to\-path\fP sub\-directories are not accessible; PATH needs to point directly at a repository location. PATH may be an empty directory or the last element of PATH may not exist, in which case the client may initialize a repository there.
|
||||
.TP
|
||||
.B \-\-append\-only
|
||||
only allow appending to repository segment files. Note that this only affects the low level structure of the repository, and running \fIdelete\fP or \fIprune\fP will still be allowed. See \fIappend_only_mode\fP in Additional Notes for more details.
|
||||
.TP
|
||||
.BI \-\-storage\-quota \ QUOTA
|
||||
Override storage quota of the repository (e.g. 5G, 1.5T). When a new repository is initialized, sets the storage quota on the new repository as well. Default: no quota.
|
||||
.UNINDENT
|
||||
.SH EXAMPLES
|
||||
.sp
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-TAG" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-TAG" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-tag \- Manage tags
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-TRANSFER" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-TRANSFER" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-transfer \- archives transfer from other repository, optionally upgrade data format
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-UMOUNT" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-UMOUNT" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-umount \- un-mount the FUSE filesystem
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-UNDELETE" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-UNDELETE" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-undelete \- Undelete archives
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-VERSION" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-VERSION" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-version \- Display the borg client / borg server version
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG-WITH-LOCK" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG-WITH-LOCK" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg-with-lock \- run a user specified command with the repository lock held
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORG" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORG" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borg \- deduplicating and encrypting backup tool
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "BORGFS" "1" "2025-04-21" "" "borg backup tool"
|
||||
.TH "BORGFS" "1" "2025-04-28" "" "borg backup tool"
|
||||
.SH NAME
|
||||
borgfs \- Mount archive or an entire repository as a FUSE filesystem
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -177,10 +177,6 @@ Separate compaction
|
|||
Borg does not auto-compact the segment files in the repository at commit time
|
||||
(at the end of each repository-writing command) any more (since borg 1.2.0).
|
||||
|
||||
This causes a similar behaviour of the repository as if it was in append-only
|
||||
mode (see below) most of the time (until ``borg compact`` is invoked or an
|
||||
old client triggers auto-compaction).
|
||||
|
||||
This has some notable consequences:
|
||||
|
||||
- repository space is not freed immediately when deleting / pruning archives
|
||||
|
|
@ -197,133 +193,6 @@ This has some notable consequences:
|
|||
|
||||
You can manually run compaction by invoking the ``borg compact`` command.
|
||||
|
||||
.. _append_only_mode:
|
||||
|
||||
Append-only mode (forbid compaction)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A repository can be made "append-only", which means that Borg will never
|
||||
overwrite or delete committed data (append-only refers to the segment files,
|
||||
but borg will also reject to delete the repository completely).
|
||||
|
||||
If ``borg compact`` command is used on a repo in append-only mode, there
|
||||
will be no warning or error, but no compaction will happen.
|
||||
|
||||
append-only is useful for scenarios where a backup client machine backups
|
||||
remotely to a backup server using ``borg serve``, since a hacked client machine
|
||||
cannot delete backups on the server permanently.
|
||||
|
||||
To activate append-only mode, set ``append_only`` to 1 in the repository config:
|
||||
|
||||
::
|
||||
|
||||
borg config append_only 1
|
||||
|
||||
Note that you can go back-and-forth between normal and append-only operation with
|
||||
``borg config``; it's not a "one way trip."
|
||||
|
||||
In append-only mode Borg will create a transaction log in the ``transactions`` file,
|
||||
where each line is a transaction and a UTC timestamp.
|
||||
|
||||
In addition, ``borg serve`` can act as if a repository is in append-only mode with
|
||||
its option ``--append-only``. This can be very useful for fine-tuning access control
|
||||
in ``.ssh/authorized_keys``:
|
||||
|
||||
::
|
||||
|
||||
command="borg serve --append-only ..." ssh-rsa <key used for not-always-trustable backup clients>
|
||||
command="borg serve ..." ssh-rsa <key used for backup management>
|
||||
|
||||
Running ``borg repo-create`` via a ``borg serve --append-only`` server will *not* create
|
||||
an append-only repository. Running ``borg repo-create --append-only`` creates an append-only
|
||||
repository regardless of server settings.
|
||||
|
||||
Example
|
||||
+++++++
|
||||
|
||||
Suppose an attacker remotely deleted all backups, but your repository was in append-only
|
||||
mode. A transaction log in this situation might look like this:
|
||||
|
||||
::
|
||||
|
||||
transaction 1, UTC time 2016-03-31T15:53:27.383532
|
||||
transaction 5, UTC time 2016-03-31T15:53:52.588922
|
||||
transaction 11, UTC time 2016-03-31T15:54:23.887256
|
||||
transaction 12, UTC time 2016-03-31T15:55:54.022540
|
||||
transaction 13, UTC time 2016-03-31T15:55:55.472564
|
||||
|
||||
From your security logs you conclude the attacker gained access at 15:54:00 and all
|
||||
the backups where deleted or replaced by compromised backups. From the log you know
|
||||
that transactions 11 and later are compromised. Note that the transaction ID is the
|
||||
name of the *last* file in the transaction. For example, transaction 11 spans files 6
|
||||
to 11.
|
||||
|
||||
In a real attack you'll likely want to keep the compromised repository
|
||||
intact to analyze what the attacker tried to achieve. It's also a good idea to make this
|
||||
copy just in case something goes wrong during the recovery. Since recovery is done by
|
||||
deleting some files, a hard link copy (``cp -al``) is sufficient.
|
||||
|
||||
The first step to reset the repository to transaction 5, the last uncompromised transaction,
|
||||
is to remove the ``hints.N``, ``index.N`` and ``integrity.N`` files in the repository (these
|
||||
files are always expendable). In this example N is 13.
|
||||
|
||||
Then remove or move all segment files from the segment directories in ``data/`` starting
|
||||
with file 6::
|
||||
|
||||
rm data/**/{6..13}
|
||||
|
||||
That's all to do in the repository.
|
||||
|
||||
If you want to access this rolled back repository from a client that already has
|
||||
a cache for this repository, the cache will reflect a newer repository state
|
||||
than what you actually have in the repository now, after the rollback.
|
||||
|
||||
Thus, you need to clear the cache::
|
||||
|
||||
borg repo-delete --cache-only
|
||||
|
||||
The cache will get rebuilt automatically. Depending on repo size and archive
|
||||
count, it may take a while.
|
||||
|
||||
You also will need to remove ~/.config/borg/security/REPOID/manifest-timestamp.
|
||||
|
||||
Drawbacks
|
||||
+++++++++
|
||||
|
||||
As data is only appended, and nothing removed, commands like ``prune`` or ``delete``
|
||||
won't free disk space, they merely tag data as deleted in a new transaction.
|
||||
|
||||
Be aware that as soon as you write to the repo in non-append-only mode (e.g. prune,
|
||||
delete or create archives from an admin machine), it will remove the deleted objects
|
||||
permanently (including the ones that were already marked as deleted, but not removed,
|
||||
in append-only mode). Automated edits to the repository (such as a cron job running
|
||||
``borg prune``) will render append-only mode moot if data is deleted.
|
||||
|
||||
Even if an archive appears to be available, it is possible an attacker could delete
|
||||
just a few chunks from an archive and silently corrupt its data. While in append-only
|
||||
mode, this is reversible, but ``borg check`` should be run before a writing/pruning
|
||||
operation on an append-only repository to catch accidental or malicious corruption::
|
||||
|
||||
# run without append-only mode
|
||||
borg check --verify-data && borg compact
|
||||
|
||||
Aside from checking repository & archive integrity you may also want to check
|
||||
backups manually to ensure their content seems correct.
|
||||
|
||||
Further considerations
|
||||
++++++++++++++++++++++
|
||||
|
||||
Append-only mode is not respected by tools other than Borg. ``rm`` still works on the
|
||||
repository. Make sure that backup client machines only get to access the repository via
|
||||
``borg serve``.
|
||||
|
||||
Ensure that no remote access is possible if the repository is temporarily set to normal mode
|
||||
for e.g. regular pruning.
|
||||
|
||||
Further protections can be implemented, but are outside of Borg's scope. For example,
|
||||
file system snapshots or wrapping ``borg serve`` to set special permissions or ACLs on
|
||||
new data files.
|
||||
|
||||
SSH batch mode
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
|||
|
|
@ -12,25 +12,21 @@ borg repo-create
|
|||
|
||||
.. class:: borg-options-table
|
||||
|
||||
+-------------------------------------------------------+------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| **options** |
|
||||
+-------------------------------------------------------+------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| | ``--other-repo SRC_REPOSITORY`` | reuse the key material from the other repository |
|
||||
+-------------------------------------------------------+------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| | ``--from-borg1`` | other repository is borg 1.x |
|
||||
+-------------------------------------------------------+------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| | ``-e MODE``, ``--encryption MODE`` | select encryption key mode **(required)** |
|
||||
+-------------------------------------------------------+------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| | ``--append-only`` | create an append-only mode repository. Note that this only affects the low level structure of the repository, and running `delete` or `prune` will still be allowed. See :ref:`append_only_mode` in Additional Notes for more details. |
|
||||
+-------------------------------------------------------+------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| | ``--storage-quota QUOTA`` | Set storage quota of the new repository (e.g. 5G, 1.5T). Default: no quota. |
|
||||
+-------------------------------------------------------+------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| | ``--copy-crypt-key`` | copy the crypt_key (used for authenticated encryption) from the key of the other repo (default: new random key). |
|
||||
+-------------------------------------------------------+------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| .. class:: borg-common-opt-ref |
|
||||
| |
|
||||
| :ref:`common_options` |
|
||||
+-------------------------------------------------------+------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
+-------------------------------------------------------+------------------------------------+------------------------------------------------------------------------------------------------------------------+
|
||||
| **options** |
|
||||
+-------------------------------------------------------+------------------------------------+------------------------------------------------------------------------------------------------------------------+
|
||||
| | ``--other-repo SRC_REPOSITORY`` | reuse the key material from the other repository |
|
||||
+-------------------------------------------------------+------------------------------------+------------------------------------------------------------------------------------------------------------------+
|
||||
| | ``--from-borg1`` | other repository is borg 1.x |
|
||||
+-------------------------------------------------------+------------------------------------+------------------------------------------------------------------------------------------------------------------+
|
||||
| | ``-e MODE``, ``--encryption MODE`` | select encryption key mode **(required)** |
|
||||
+-------------------------------------------------------+------------------------------------+------------------------------------------------------------------------------------------------------------------+
|
||||
| | ``--copy-crypt-key`` | copy the crypt_key (used for authenticated encryption) from the key of the other repo (default: new random key). |
|
||||
+-------------------------------------------------------+------------------------------------+------------------------------------------------------------------------------------------------------------------+
|
||||
| .. class:: borg-common-opt-ref |
|
||||
| |
|
||||
| :ref:`common_options` |
|
||||
+-------------------------------------------------------+------------------------------------+------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
.. raw:: html
|
||||
|
||||
|
|
@ -48,8 +44,6 @@ borg repo-create
|
|||
--other-repo SRC_REPOSITORY reuse the key material from the other repository
|
||||
--from-borg1 other repository is borg 1.x
|
||||
-e MODE, --encryption MODE select encryption key mode **(required)**
|
||||
--append-only create an append-only mode repository. Note that this only affects the low level structure of the repository, and running `delete` or `prune` will still be allowed. See :ref:`append_only_mode` in Additional Notes for more details.
|
||||
--storage-quota QUOTA Set storage quota of the new repository (e.g. 5G, 1.5T). Default: no quota.
|
||||
--copy-crypt-key copy the crypt_key (used for authenticated encryption) from the key of the other repo (default: new random key).
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,6 @@ borg serve
|
|||
+-------------------------------------------------------+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| | ``--restrict-to-repository PATH`` | restrict repository access. Only the repository located at PATH (no sub-directories are considered) is accessible. Can be specified multiple times to allow the client access to several repositories. Unlike ``--restrict-to-path`` sub-directories are not accessible; PATH needs to point directly at a repository location. PATH may be an empty directory or the last element of PATH may not exist, in which case the client may initialize a repository there. |
|
||||
+-------------------------------------------------------+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| | ``--append-only`` | only allow appending to repository segment files. Note that this only affects the low level structure of the repository, and running `delete` or `prune` will still be allowed. See :ref:`append_only_mode` in Additional Notes for more details. |
|
||||
+-------------------------------------------------------+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| | ``--storage-quota QUOTA`` | Override storage quota of the repository (e.g. 5G, 1.5T). When a new repository is initialized, sets the storage quota on the new repository as well. Default: no quota. |
|
||||
+-------------------------------------------------------+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| .. class:: borg-common-opt-ref |
|
||||
| |
|
||||
| :ref:`common_options` |
|
||||
|
|
@ -41,10 +37,8 @@ borg serve
|
|||
|
||||
|
||||
options
|
||||
--restrict-to-path PATH restrict repository access to PATH. Can be specified multiple times to allow the client access to several directories. Access to all sub-directories is granted implicitly; PATH doesn't need to point directly to a repository.
|
||||
--restrict-to-repository PATH restrict repository access. Only the repository located at PATH (no sub-directories are considered) is accessible. Can be specified multiple times to allow the client access to several repositories. Unlike ``--restrict-to-path`` sub-directories are not accessible; PATH needs to point directly at a repository location. PATH may be an empty directory or the last element of PATH may not exist, in which case the client may initialize a repository there.
|
||||
--append-only only allow appending to repository segment files. Note that this only affects the low level structure of the repository, and running `delete` or `prune` will still be allowed. See :ref:`append_only_mode` in Additional Notes for more details.
|
||||
--storage-quota QUOTA Override storage quota of the repository (e.g. 5G, 1.5T). When a new repository is initialized, sets the storage quota on the new repository as well. Default: no quota.
|
||||
--restrict-to-path PATH restrict repository access to PATH. Can be specified multiple times to allow the client access to several directories. Access to all sub-directories is granted implicitly; PATH doesn't need to point directly to a repository.
|
||||
--restrict-to-repository PATH restrict repository access. Only the repository located at PATH (no sub-directories are considered) is accessible. Can be specified multiple times to allow the client access to several repositories. Unlike ``--restrict-to-path`` sub-directories are not accessible; PATH needs to point directly at a repository location. PATH may be an empty directory or the last element of PATH may not exist, in which case the client may initialize a repository there.
|
||||
|
||||
|
||||
:ref:`common_options`
|
||||
|
|
|
|||
|
|
@ -88,7 +88,6 @@ complete -c borg -l 'rsh' -d 'Use COMMAND instead of s
|
|||
# borg init options
|
||||
set -l encryption_modes "none keyfile keyfile-blake2 repokey repokey-blake2 authenticated authenticated-blake2"
|
||||
complete -c borg -f -s e -l 'encryption' -d 'Encryption key MODE' -a "$encryption_modes" -n "__fish_seen_subcommand_from init"
|
||||
complete -c borg -f -l 'append-only' -d 'Create an append-only mode repository' -n "__fish_seen_subcommand_from init"
|
||||
complete -c borg -f -l 'make-parent-dirs' -d 'Create parent directories' -n "__fish_seen_subcommand_from init"
|
||||
|
||||
# borg create options
|
||||
|
|
@ -314,7 +313,6 @@ complete -c borg -f -l 'strip-components' -d 'Remove NUMBER of leading
|
|||
# borg serve
|
||||
complete -c borg -l 'restrict-to-path' -d 'Restrict repository access to PATH' -n "__fish_seen_subcommand_from serve"
|
||||
complete -c borg -l 'restrict-to-repository' -d 'Restrict repository access at PATH' -n "__fish_seen_subcommand_from serve"
|
||||
complete -c borg -f -l 'append-only' -d 'Only allow appending to repository' -n "__fish_seen_subcommand_from serve"
|
||||
|
||||
# borg config
|
||||
complete -c borg -f -s c -l 'cache' -d 'Get/set/list values in the repo cache' -n "__fish_seen_subcommand_from config"
|
||||
|
|
|
|||
|
|
@ -401,7 +401,7 @@ class Archiver(
|
|||
# client is allowed to specify the allowlisted options,
|
||||
# everything else comes from the forced "borg serve" command (or the defaults).
|
||||
# stuff from denylist must never be used from the client.
|
||||
denylist = {"restrict_to_paths", "restrict_to_repositories", "append_only", "umask"}
|
||||
denylist = {"restrict_to_paths", "restrict_to_repositories", "umask"}
|
||||
allowlist = {"debug_topics", "lock_wait", "log_level"}
|
||||
not_present = object()
|
||||
for attr_name in allowlist:
|
||||
|
|
|
|||
|
|
@ -30,29 +30,19 @@ from ..logger import create_logger
|
|||
logger = create_logger(__name__)
|
||||
|
||||
|
||||
def get_repository(location, *, create, exclusive, lock_wait, lock, append_only, args, v1_or_v2):
|
||||
def get_repository(location, *, create, exclusive, lock_wait, lock, args, v1_or_v2):
|
||||
if location.proto in ("ssh", "socket"):
|
||||
RemoteRepoCls = LegacyRemoteRepository if v1_or_v2 else RemoteRepository
|
||||
repository = RemoteRepoCls(
|
||||
location,
|
||||
create=create,
|
||||
exclusive=exclusive,
|
||||
lock_wait=lock_wait,
|
||||
lock=lock,
|
||||
append_only=append_only,
|
||||
args=args,
|
||||
location, create=create, exclusive=exclusive, lock_wait=lock_wait, lock=lock, args=args
|
||||
)
|
||||
|
||||
elif location.proto in ("sftp", "file", "rclone") and not v1_or_v2: # stuff directly supported by borgstore
|
||||
repository = Repository(
|
||||
location, create=create, exclusive=exclusive, lock_wait=lock_wait, lock=lock, append_only=append_only
|
||||
)
|
||||
repository = Repository(location, create=create, exclusive=exclusive, lock_wait=lock_wait, lock=lock)
|
||||
|
||||
else:
|
||||
RepoCls = LegacyRepository if v1_or_v2 else Repository
|
||||
repository = RepoCls(
|
||||
location.path, create=create, exclusive=exclusive, lock_wait=lock_wait, lock=lock, append_only=append_only
|
||||
)
|
||||
repository = RepoCls(location.path, create=create, exclusive=exclusive, lock_wait=lock_wait, lock=lock)
|
||||
return repository
|
||||
|
||||
|
||||
|
|
@ -114,7 +104,6 @@ def with_repository(
|
|||
raise Error("missing repository, please use --repo or BORG_REPO env var!")
|
||||
assert isinstance(exclusive, bool)
|
||||
lock = getattr(args, "lock", _lock)
|
||||
append_only = getattr(args, "append_only", False)
|
||||
|
||||
repository = get_repository(
|
||||
location,
|
||||
|
|
@ -122,7 +111,6 @@ def with_repository(
|
|||
exclusive=exclusive,
|
||||
lock_wait=self.lock_wait,
|
||||
lock=lock,
|
||||
append_only=append_only,
|
||||
args=args,
|
||||
v1_or_v2=False,
|
||||
)
|
||||
|
|
@ -190,7 +178,6 @@ def with_other_repository(manifest=False, cache=False, compatibility=None):
|
|||
exclusive=True,
|
||||
lock_wait=self.lock_wait,
|
||||
lock=True,
|
||||
append_only=False,
|
||||
args=args,
|
||||
v1_or_v2=v1_or_v2,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from ._common import with_repository, with_other_repository, Highlander
|
|||
from ..cache import Cache
|
||||
from ..constants import * # NOQA
|
||||
from ..crypto.key import key_creator, key_argument_names
|
||||
from ..helpers import CancelledByUser, CommandError
|
||||
from ..helpers import CancelledByUser
|
||||
from ..helpers import location_validator, Location
|
||||
from ..manifest import Manifest
|
||||
|
||||
|
|
@ -18,8 +18,6 @@ class RepoCreateMixIn:
|
|||
@with_other_repository(manifest=True, compatibility=(Manifest.Operation.READ,))
|
||||
def do_repo_create(self, args, repository, *, other_repository=None, other_manifest=None):
|
||||
"""Create a new, empty repository"""
|
||||
if args.append_only:
|
||||
raise CommandError("append-only is not supported (yet?)")
|
||||
other_key = other_manifest.key if other_manifest is not None else None
|
||||
path = args.location.canonical_path()
|
||||
logger.info('Initializing repository at "%s"' % path)
|
||||
|
|
@ -224,15 +222,6 @@ class RepoCreateMixIn:
|
|||
action=Highlander,
|
||||
help="select encryption key mode **(required)**",
|
||||
)
|
||||
subparser.add_argument(
|
||||
"--append-only",
|
||||
dest="append_only",
|
||||
action="store_true",
|
||||
help="create an append-only mode repository. Note that this only affects "
|
||||
"the low level structure of the repository, and running `delete` "
|
||||
"or `prune` will still be allowed. See :ref:`append_only_mode` in "
|
||||
"Additional Notes for more details.",
|
||||
)
|
||||
subparser.add_argument(
|
||||
"--copy-crypt-key",
|
||||
dest="copy_crypt_key",
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ class RepoInfoMixIn:
|
|||
Repository ID: {id}
|
||||
Location: {location}
|
||||
Repository version: {version}
|
||||
Append only: {append_only}
|
||||
{encryption}
|
||||
"""
|
||||
)
|
||||
|
|
@ -45,7 +44,6 @@ class RepoInfoMixIn:
|
|||
id=bin_to_hex(repository.id),
|
||||
location=repository._location.canonical_path(),
|
||||
version=repository.version,
|
||||
append_only=repository.append_only,
|
||||
encryption=info["encryption"],
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import argparse
|
||||
|
||||
from ..constants import * # NOQA
|
||||
from ..helpers import CommandError
|
||||
from ..remote import RepositoryServer
|
||||
|
||||
from ..logger import create_logger
|
||||
|
|
@ -12,12 +11,9 @@ logger = create_logger()
|
|||
class ServeMixIn:
|
||||
def do_serve(self, args):
|
||||
"""Start in server mode. This command is usually not used manually."""
|
||||
if args.append_only:
|
||||
raise CommandError("append-only is not supported (yet?)")
|
||||
RepositoryServer(
|
||||
restrict_to_paths=args.restrict_to_paths,
|
||||
restrict_to_repositories=args.restrict_to_repositories,
|
||||
append_only=args.append_only,
|
||||
use_socket=args.use_socket,
|
||||
).serve()
|
||||
|
||||
|
|
@ -71,12 +67,3 @@ class ServeMixIn:
|
|||
"PATH may be an empty directory or the last element of PATH may not exist, in which case "
|
||||
"the client may initialize a repository there.",
|
||||
)
|
||||
subparser.add_argument(
|
||||
"--append-only",
|
||||
dest="append_only",
|
||||
action="store_true",
|
||||
help="only allow appending to repository segment files. Note that this only "
|
||||
"affects the low level structure of the repository, and running `delete` "
|
||||
"or `prune` will still be allowed. See :ref:`append_only_mode` in Additional "
|
||||
"Notes for more details.",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -245,9 +245,7 @@ class LegacyRemoteRepository:
|
|||
def required_version(self):
|
||||
return self.args[1]
|
||||
|
||||
def __init__(
|
||||
self, location, create=False, exclusive=False, lock_wait=None, lock=True, append_only=False, args=None
|
||||
):
|
||||
def __init__(self, location, create=False, exclusive=False, lock_wait=None, lock=True, args=None):
|
||||
self.location = self._location = location
|
||||
self.preload_ids = []
|
||||
self.msgid = 0
|
||||
|
|
@ -329,12 +327,10 @@ class LegacyRemoteRepository:
|
|||
lock_wait=lock_wait,
|
||||
lock=lock,
|
||||
exclusive=exclusive,
|
||||
append_only=append_only,
|
||||
v1_or_v2=True, # make remote use LegacyRepository
|
||||
)
|
||||
info = self.info()
|
||||
self.version = info["version"]
|
||||
self.append_only = info["append_only"]
|
||||
|
||||
except Exception:
|
||||
self.close()
|
||||
|
|
@ -625,10 +621,9 @@ class LegacyRemoteRepository:
|
|||
|
||||
@api(
|
||||
since=parse_version("1.0.0"),
|
||||
append_only={"since": parse_version("1.0.7"), "previously": False},
|
||||
v1_or_v2={"since": parse_version("2.0.0b8"), "previously": True}, # TODO fix version
|
||||
)
|
||||
def open(self, path, create=False, lock_wait=None, lock=True, exclusive=False, append_only=False, v1_or_v2=False):
|
||||
def open(self, path, create=False, lock_wait=None, lock=True, exclusive=False, v1_or_v2=False):
|
||||
"""actual remoting is done via self.call in the @api decorator"""
|
||||
|
||||
@api(since=parse_version("2.0.0a3"))
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import struct
|
|||
import time
|
||||
from collections import defaultdict
|
||||
from configparser import ConfigParser
|
||||
from datetime import datetime, timezone
|
||||
from functools import partial
|
||||
from itertools import islice
|
||||
from typing import Callable, DefaultDict
|
||||
|
|
@ -190,9 +189,7 @@ class LegacyRepository:
|
|||
|
||||
exit_mcode = 21
|
||||
|
||||
def __init__(
|
||||
self, path, create=False, exclusive=False, lock_wait=None, lock=True, append_only=False, send_log_cb=None
|
||||
):
|
||||
def __init__(self, path, create=False, exclusive=False, lock_wait=None, lock=True, send_log_cb=None):
|
||||
self.path = os.path.abspath(path)
|
||||
self._location = Location("file://%s" % self.path)
|
||||
self.version = None
|
||||
|
|
@ -218,7 +215,6 @@ class LegacyRepository:
|
|||
self.do_create = create
|
||||
self.created = False
|
||||
self.exclusive = exclusive
|
||||
self.append_only = append_only
|
||||
self.transaction_doomed = None
|
||||
# v2 is the default repo version for borg 2.0
|
||||
# v1 repos must only be used in a read-only way, e.g. for
|
||||
|
|
@ -327,7 +323,6 @@ class LegacyRepository:
|
|||
config.set("repository", "version", str(self.version))
|
||||
config.set("repository", "segments_per_dir", str(DEFAULT_SEGMENTS_PER_DIR))
|
||||
config.set("repository", "max_segment_size", str(DEFAULT_MAX_SEGMENT_SIZE))
|
||||
config.set("repository", "append_only", str(int(self.append_only)))
|
||||
config.set("repository", "additional_free_space", "0")
|
||||
config.set("repository", "id", bin_to_hex(os.urandom(32)))
|
||||
self.save_config(path, config)
|
||||
|
|
@ -385,8 +380,6 @@ class LegacyRepository:
|
|||
|
||||
def destroy(self):
|
||||
"""Destroy the repository at `self.path`"""
|
||||
if self.append_only:
|
||||
raise ValueError(self.path + " is in append-only mode")
|
||||
self.close()
|
||||
os.remove(os.path.join(self.path, "config")) # kill config first
|
||||
shutil.rmtree(self.path)
|
||||
|
|
@ -468,9 +461,6 @@ class LegacyRepository:
|
|||
raise self.InvalidRepositoryConfig(path, "max_segment_size >= %d" % MAX_SEGMENT_SIZE_LIMIT) # issue 3592
|
||||
self.segments_per_dir = self.config.getint("repository", "segments_per_dir")
|
||||
self.additional_free_space = parse_file_size(self.config.get("repository", "additional_free_space", fallback=0))
|
||||
# append_only can be set in the constructor
|
||||
# it shouldn't be overridden (True -> False) here
|
||||
self.append_only = self.append_only or self.config.getboolean("repository", "append_only", fallback=False)
|
||||
self.id = hex_to_bin(self.config.get("repository", "id").strip(), length=32)
|
||||
self.io = LoggedIO(self.path, self.max_segment_size, self.segments_per_dir)
|
||||
|
||||
|
|
@ -484,7 +474,7 @@ class LegacyRepository:
|
|||
|
||||
def info(self):
|
||||
"""return some infos about the repo (must be opened first)"""
|
||||
info = dict(id=self.id, version=self.version, append_only=self.append_only)
|
||||
info = dict(id=self.id, version=self.version)
|
||||
self._load_hints()
|
||||
return info
|
||||
|
||||
|
|
@ -506,7 +496,7 @@ class LegacyRepository:
|
|||
segment = self.io.write_commit()
|
||||
self.segments.setdefault(segment, 0)
|
||||
self.compact[segment] += LoggedIO.header_fmt.size
|
||||
if compact and not self.append_only:
|
||||
if compact:
|
||||
self.compact_segments(threshold)
|
||||
self.write_index()
|
||||
self.rollback()
|
||||
|
|
@ -632,15 +622,6 @@ class LegacyRepository:
|
|||
transaction_id = self.io.get_segments_transaction_id()
|
||||
assert transaction_id is not None
|
||||
|
||||
# Log transaction in append-only mode
|
||||
if self.append_only:
|
||||
with open(os.path.join(self.path, "transactions"), "a") as log:
|
||||
print(
|
||||
"transaction %d, UTC time %s"
|
||||
% (transaction_id, datetime.now(tz=timezone.utc).isoformat(timespec="microseconds")),
|
||||
file=log,
|
||||
)
|
||||
|
||||
# Write hints file
|
||||
hints_name = "hints.%d" % transaction_id
|
||||
hints_file = os.path.join(self.path, hints_name)
|
||||
|
|
@ -704,7 +685,7 @@ class LegacyRepository:
|
|||
required_free_space += hints_size
|
||||
|
||||
required_free_space += self.additional_free_space
|
||||
if not self.append_only:
|
||||
if True:
|
||||
full_segment_size = self.max_segment_size + MAX_OBJECT_SIZE
|
||||
if len(self.compact) < 10:
|
||||
# This is mostly for the test suite to avoid overestimated free space needs. This can be annoying
|
||||
|
|
@ -723,7 +704,7 @@ class LegacyRepository:
|
|||
)
|
||||
required_free_space += compact_working_space
|
||||
else:
|
||||
# Keep one full worst-case segment free in non-append-only mode
|
||||
# Keep one full worst-case segment free.
|
||||
required_free_space += full_segment_size
|
||||
|
||||
try:
|
||||
|
|
@ -1002,8 +983,6 @@ class LegacyRepository:
|
|||
This method verifies all segment checksums and makes sure
|
||||
the index is consistent with the data stored in the segments.
|
||||
"""
|
||||
if self.append_only and repair:
|
||||
raise ValueError(self.path + " is in append-only mode")
|
||||
error_found = False
|
||||
|
||||
def report_error(msg, *args):
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ class RepositoryServer: # pragma: no cover
|
|||
"store_move",
|
||||
)
|
||||
|
||||
def __init__(self, restrict_to_paths, restrict_to_repositories, append_only, use_socket):
|
||||
def __init__(self, restrict_to_paths, restrict_to_repositories, use_socket):
|
||||
self.repository = None
|
||||
self.RepoCls = None
|
||||
self.rpc_methods = ("open", "close", "negotiate")
|
||||
|
|
@ -193,7 +193,6 @@ class RepositoryServer: # pragma: no cover
|
|||
# i.e. it reflects local system policy and generally ranks higher than
|
||||
# whatever the client wants, except when initializing a new repository
|
||||
# (see RepositoryServer.open below).
|
||||
self.append_only = append_only
|
||||
self.client_version = None # we update this after client sends version information
|
||||
if use_socket is False:
|
||||
self.socket_path = None
|
||||
|
|
@ -371,7 +370,7 @@ class RepositoryServer: # pragma: no cover
|
|||
path = os.path.realpath(path)
|
||||
return path
|
||||
|
||||
def open(self, path, create=False, lock_wait=None, lock=True, exclusive=None, append_only=False, v1_or_v2=False):
|
||||
def open(self, path, create=False, lock_wait=None, lock=True, exclusive=None, v1_or_v2=False):
|
||||
self.RepoCls = LegacyRepository if v1_or_v2 else Repository
|
||||
self.rpc_methods = self._legacy_rpc_methods if v1_or_v2 else self._rpc_methods
|
||||
logging.debug("Resolving repository path %r", path)
|
||||
|
|
@ -395,18 +394,8 @@ class RepositoryServer: # pragma: no cover
|
|||
break
|
||||
else:
|
||||
raise PathNotAllowed(path)
|
||||
# "borg init" on "borg serve --append-only" (=self.append_only) does not create an append only repo,
|
||||
# while "borg init --append-only" (=append_only) does, regardless of the --append-only (self.append_only)
|
||||
# flag for serve.
|
||||
append_only = (not create and self.append_only) or append_only
|
||||
self.repository = self.RepoCls(
|
||||
path,
|
||||
create,
|
||||
lock_wait=lock_wait,
|
||||
lock=lock,
|
||||
append_only=append_only,
|
||||
exclusive=exclusive,
|
||||
send_log_cb=self.send_queued_log,
|
||||
path, create, lock_wait=lock_wait, lock=lock, exclusive=exclusive, send_log_cb=self.send_queued_log
|
||||
)
|
||||
self.repository.__enter__() # clean exit handled by serve() method
|
||||
return self.repository.id
|
||||
|
|
@ -574,7 +563,7 @@ class RemoteRepository:
|
|||
def required_version(self):
|
||||
return self.args[1]
|
||||
|
||||
def __init__(self, location, create=False, exclusive=False, lock_wait=1.0, lock=True, append_only=False, args=None):
|
||||
def __init__(self, location, create=False, exclusive=False, lock_wait=1.0, lock=True, args=None):
|
||||
self.location = self._location = location
|
||||
self.preload_ids = []
|
||||
self.msgid = 0
|
||||
|
|
@ -651,16 +640,10 @@ class RemoteRepository:
|
|||
raise Exception("Server insisted on using unsupported protocol version %s" % version)
|
||||
|
||||
self.id = self.open(
|
||||
path=self.location.path,
|
||||
create=create,
|
||||
lock_wait=lock_wait,
|
||||
lock=lock,
|
||||
exclusive=exclusive,
|
||||
append_only=append_only,
|
||||
path=self.location.path, create=create, lock_wait=lock_wait, lock=lock, exclusive=exclusive
|
||||
)
|
||||
info = self.info()
|
||||
self.version = info["version"]
|
||||
self.append_only = info["append_only"]
|
||||
|
||||
except Exception:
|
||||
self.close()
|
||||
|
|
@ -965,10 +948,9 @@ class RemoteRepository:
|
|||
|
||||
@api(
|
||||
since=parse_version("1.0.0"),
|
||||
append_only={"since": parse_version("1.0.7"), "previously": False},
|
||||
v1_or_v2={"since": parse_version("2.0.0b8"), "previously": True}, # TODO fix version
|
||||
)
|
||||
def open(self, path, create=False, lock_wait=None, lock=True, exclusive=False, append_only=False, v1_or_v2=False):
|
||||
def open(self, path, create=False, lock_wait=None, lock=True, exclusive=False, v1_or_v2=False):
|
||||
"""actual remoting is done via self.call in the @api decorator"""
|
||||
|
||||
@api(since=parse_version("2.0.0a3"))
|
||||
|
|
|
|||
|
|
@ -93,16 +93,7 @@ class Repository:
|
|||
|
||||
exit_mcode = 21
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
path_or_location,
|
||||
create=False,
|
||||
exclusive=False,
|
||||
lock_wait=1.0,
|
||||
lock=True,
|
||||
append_only=False,
|
||||
send_log_cb=None,
|
||||
):
|
||||
def __init__(self, path_or_location, create=False, exclusive=False, lock_wait=1.0, lock=True, send_log_cb=None):
|
||||
if isinstance(path_or_location, Location):
|
||||
location = path_or_location
|
||||
if location.proto == "file":
|
||||
|
|
@ -139,7 +130,6 @@ class Repository:
|
|||
self.created = False
|
||||
self.acceptable_repo_versions = (3,)
|
||||
self.opened = False
|
||||
self.append_only = append_only # XXX not implemented / not implementable
|
||||
self.lock = None
|
||||
self.do_lock = lock
|
||||
self.lock_wait = lock_wait
|
||||
|
|
@ -254,7 +244,7 @@ class Repository:
|
|||
"""return some infos about the repo (must be opened first)"""
|
||||
# note: don't do anything expensive here or separate the lock refresh into a separate method.
|
||||
self._lock_refresh() # do not remove, see do_with_lock()
|
||||
info = dict(id=self.id, version=self.version, append_only=self.append_only)
|
||||
info = dict(id=self.id, version=self.version)
|
||||
return info
|
||||
|
||||
def check(self, repair=False, max_duration=0):
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ class TestCommonOptions:
|
|||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
)
|
||||
subparser.set_defaults(func=1234)
|
||||
subparser.add_argument("--append-only", dest="append_only", action="store_true")
|
||||
subparser.add_argument("--foo-bar", dest="foo_bar", action="store_true")
|
||||
|
||||
def parse_vars_from_line(*line):
|
||||
print(line)
|
||||
|
|
@ -149,19 +149,19 @@ class TestCommonOptions:
|
|||
"lock_wait": 1,
|
||||
"log_level": "critical",
|
||||
"progress": False,
|
||||
"append_only": False,
|
||||
"foo_bar": False,
|
||||
"func": 1234,
|
||||
}
|
||||
|
||||
with pytest.raises(SystemExit):
|
||||
parse_vars_from_line("--append-only", "subcommand")
|
||||
parse_vars_from_line("--foo-bar", "subcommand")
|
||||
|
||||
assert parse_vars_from_line("--append=foo", "--append", "bar", "subcommand", "--append", "baz") == {
|
||||
"append": ["foo", "bar", "baz"],
|
||||
"lock_wait": 1,
|
||||
"log_level": "warning",
|
||||
"progress": False,
|
||||
"append_only": False,
|
||||
"foo_bar": False,
|
||||
"func": 1234,
|
||||
}
|
||||
|
||||
|
|
@ -180,7 +180,7 @@ class TestCommonOptions:
|
|||
"lock_wait": 1,
|
||||
"log_level": "warning",
|
||||
"progress": False,
|
||||
"append_only": False,
|
||||
"foo_bar": False,
|
||||
"func": 1234,
|
||||
args_key: args_value,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -511,39 +511,6 @@ def test_shadow_index_rollback(repository):
|
|||
assert repository.shadow_index[H(1)] == [] # because the deletion is considered unstable
|
||||
|
||||
|
||||
def test_destroy_append_only(repository):
|
||||
with repository:
|
||||
# can't destroy append only repo (via the API)
|
||||
repository.append_only = True
|
||||
with pytest.raises(ValueError):
|
||||
repository.destroy()
|
||||
assert repository.append_only
|
||||
|
||||
|
||||
def test_append_only(repository):
|
||||
def segments_in_repository(repo):
|
||||
return len(list(repo.io.segment_iterator()))
|
||||
|
||||
with repository:
|
||||
repository.append_only = True
|
||||
repository.put(H(0), fchunk(b"foo"))
|
||||
repository.commit(compact=False)
|
||||
|
||||
repository.append_only = False
|
||||
assert segments_in_repository(repository) == 2
|
||||
repository.put(H(0), fchunk(b"foo"))
|
||||
repository.commit(compact=True)
|
||||
# normal: compact squashes the data together, only one segment
|
||||
assert segments_in_repository(repository) == 2
|
||||
|
||||
repository.append_only = True
|
||||
assert segments_in_repository(repository) == 2
|
||||
repository.put(H(0), fchunk(b"foo"))
|
||||
repository.commit(compact=False)
|
||||
# append only: does not compact, only new segments written
|
||||
assert segments_in_repository(repository) == 4
|
||||
|
||||
|
||||
def test_additional_free_space(repository):
|
||||
with repository:
|
||||
add_keys(repository)
|
||||
|
|
@ -680,7 +647,6 @@ def test_unknown_integrity_version(repository):
|
|||
|
||||
def _subtly_corrupted_hints_setup(repository):
|
||||
with repository:
|
||||
repository.append_only = True
|
||||
assert len(repository) == 1
|
||||
assert pdchunk(repository.get(H(0))) == b"foo"
|
||||
repository.put(H(1), fchunk(b"bar"))
|
||||
|
|
@ -703,7 +669,6 @@ def test_subtly_corrupted_hints(repository):
|
|||
make_auxiliary(repository)
|
||||
_subtly_corrupted_hints_setup(repository)
|
||||
with repository:
|
||||
repository.append_only = False
|
||||
repository.put(H(3), fchunk(b"1234"))
|
||||
# do a compaction run, which succeeds since the failed checksum prompted a rebuild of the index+hints.
|
||||
repository.commit(compact=True)
|
||||
|
|
@ -719,7 +684,6 @@ def test_subtly_corrupted_hints_without_integrity(repository):
|
|||
integrity_path = os.path.join(repository.path, "integrity.5")
|
||||
os.unlink(integrity_path)
|
||||
with repository:
|
||||
repository.append_only = False
|
||||
repository.put(H(3), fchunk(b"1234"))
|
||||
# do a compaction run, which fails since the corrupted refcount wasn't detected and causes an assertion failure.
|
||||
with pytest.raises(AssertionError) as exc_info:
|
||||
|
|
|
|||
Loading…
Reference in a new issue