Skip to content

remove --remote-path, --rsh, --upload-ratelimit, --upload-buffer, --iec and --debug-profile options#9952

Merged
ThomasWaldmann merged 9 commits into
borgbackup:masterfrom
ThomasWaldmann:remove-remote-path-option
Jul 26, 2026
Merged

remove --remote-path, --rsh, --upload-ratelimit, --upload-buffer, --iec and --debug-profile options#9952
ThomasWaldmann merged 9 commits into
borgbackup:masterfrom
ThomasWaldmann:remove-remote-path-option

Conversation

@ThomasWaldmann

@ThomasWaldmann ThomasWaldmann commented Jul 24, 2026

Copy link
Copy Markdown
Member

Removes six common ("global") options. Four of them were dead weight for borg2 repositories, two are settings that belong into the environment rather than onto every command line.

Dead for borg2: --remote-path, --rsh, --upload-ratelimit, --upload-buffer

All four were only ever honoured on the legacy (borg 1.x, ssh://) code path in legacy/remote.py:

remote_path = args.remote_path or os.environ.get("BORG_REMOTE_PATH", "borg")
rsh = self._args.rsh or os.environ.get("BORG_RSH", "ssh")

For borg2 repositories they did nothing:

  • the remote borg comes from rest_serve_command() in repository.py, which only ever looked at BORG_REMOTE_PATH
  • the remote shell command comes from borgstore, which reads its own BORGSTORE_RSH
  • borgstore does no rate limiting or upload buffering at all

They were accepted for every command and silently ignored. For --remote-path the failure only showed up as a confusing error from the far end:

BackendError: stdio server exited with code 127:
zsh:1: command not found: borg

Rather than plumbing args down into the borgstore code paths, the options are gone and the environment variables are the one way to set these, for legacy and borg2 repositories alike. Being consistent beats failing silently for borg2 repos.

  • BORG_RSH is given to borgstore as BORGSTORE_RSH, except if that was set explicitly - then the user wants a different command for borgstore (new propagate_rsh() in repository.py, called from Repository.__init__)
  • replace_placeholders() is applied to BORG_REMOTE_PATH on the rest:// path, which the legacy path already did
  • --upload-ratelimit / --upload-buffer have no replacement: we only support transferring from borg1 repos, so there is not much traffic in the upload direction of a borg1 repo anyway. The SleepingBandwidthLimiter class goes with them; what remains of it is write_to_fd(), which turns a BrokenPipeError into the nicer ConnectionBrokenWithHint. Without an upload buffer size limit, the "queue more calls" condition simplifies to "the send buffer is empty".

Better placed in the environment: --iec and --debug-profile

These two did work for borg2, but both are settings one wants for all invocations rather than per command:

  • BORG_IEC=yes selects IEC units (1KiB = 1024B). true and 1 are accepted too, because jsonargparse's automatic BORG_<OPTION> environment variables accepted those for --iec.
  • BORG_DEBUG_PROFILE=FILE writes an execution profile; a .pyprof suffix still selects the Python-compatible format.

Note that removing an option also removes its automatic jsonargparse environment variable, so both are now read explicitly (use_iec_units() in helpers/parseformat.py, os.environ in archiver/__init__.py). BORG_DEBUG_PROFILE applies to every borg invocation while it is set, unlike the option - documented, and the profile test switches it off around the borg debug convert-profile call, which would otherwise profile itself over the profile it is reading.

Everything else

  • borg benchmark crud no longer inherits these options into its sub-invocations - environment variables are inherited by the subprocess anyway, so the parse_args wrapper is gone
  • borg help placeholders: placeholders are supported in BORG_REMOTE_PATH (was: --remote-path)
  • docs: env vars now say they are the replacement for the removed option, BORG_IEC and BORG_DEBUG_PROFILE are documented for the first time, changelog entries under the removed options, deployment/pull-backup.rst examples use BORG_RSH=... instead of --rsh ..., the FAQ no longer recommends the long-removed --remote-ratelimit, usage/man regenerated, fish completions dropped
  • two drive-by commits: the stale --socket fish completion (not a borg option for a while), and the docs naming the profile converter borg debug profile-convert when it is convert-profile

Verification

Manually verified against a rest://user@localhost/... repo (repo-create + 2 archives + repo-list), with BORG_REMOTE_PATH pointing at a borg outside of PATH and BORG_RSH (with BORGSTORE_RSH unset) selecting a specific ssh identity - both are picked up. BORG_IEC=yes switches borg info from 336.68 kB to 328.79 KiB; BORG_DEBUG_PROFILE writes a profile that borg debug convert-profile converts and pstats reads. Each removed option now fails fast with error: Unrecognized arguments: ....

Full test suite passes locally after each step, including the remote tests that exercise the legacy transport: 2048 passed, 110 skipped.

The --remote-path option was only honoured on the legacy (borg 1.x, ssh://)
code path in legacy/remote.py. For borg2 rest:// repositories, the remote
borg is determined by rest_serve_command(), which only ever looked at the
BORG_REMOTE_PATH environment variable - so giving --remote-path silently had
no effect and the far end failed with "command not found: borg".

Rather than plumbing args into rest_serve_command(), drop the option
completely and use BORG_REMOTE_PATH consistently for both repo types. Also
apply replace_placeholders() to it for rest:// repos, as the legacy code
path already did.
@codecov

codecov Bot commented Jul 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.28571% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.61%. Comparing base (e5ed8f6) to head (a7a35d0).
⚠️ Report is 7 commits behind head on master.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/borg/legacy/remote.py 75.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #9952      +/-   ##
==========================================
+ Coverage   85.49%   85.61%   +0.11%     
==========================================
  Files          93       93              
  Lines       16122    16096      -26     
  Branches     2466     2458       -8     
==========================================
- Hits        13783    13780       -3     
+ Misses       1632     1614      -18     
+ Partials      707      702       -5     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

Like --remote-path, --rsh was only honoured on the legacy (borg 1.x, ssh://)
code path. For borg2 repositories the remote shell command comes from
borgstore, which reads its own BORGSTORE_RSH environment variable, so --rsh
silently had no effect there.

Remove the option; BORG_RSH is now the only way to set the remote shell
command. For borgstore-based repositories, borg gives the BORG_RSH value to
borgstore as BORGSTORE_RSH, except if that was set explicitly (then the user
wants a different command for borgstore).

borg benchmark crud does not need to inherit --rsh / --remote-path into its
sub-invocations any more (environment variables are inherited anyway), so the
parse_args wrapper is gone.
@ThomasWaldmann ThomasWaldmann changed the title remove --remote-path option, use BORG_REMOTE_PATH remove --remote-path and --rsh options, use BORG_REMOTE_PATH / BORG_RSH Jul 24, 2026
Both were only ever read by the legacy (borg 1.x, ssh://) remote repository
code, so they had no effect on borg2 repositories - borgstore does not do
rate limiting or upload buffering at all.

For the legacy code path they are not worth keeping either: we only support
transferring FROM borg1 repos, so there is not much traffic in the upload
direction of a borg1 repo anyway.

Removes the SleepingBandwidthLimiter class with them; the only thing left
from it is write_to_fd(), which turns a BrokenPipeError into the nicer
ConnectionBrokenWithHint. Without an upload buffer size limit, the "queue
more calls" condition simplifies to "the send buffer is empty".
borg has no --socket option (any more), so do not complete it.
@ThomasWaldmann ThomasWaldmann changed the title remove --remote-path and --rsh options, use BORG_REMOTE_PATH / BORG_RSH remove --remote-path, --rsh, --upload-ratelimit and --upload-buffer options Jul 25, 2026
--remote-ratelimit was not replaced by --upload-ratelimit for long: that one
is gone now, too. Fix the upgrade note and the FAQ, which still told users to
use the (long removed) --remote-ratelimit option.
Unlike the other options removed recently, --iec did work for borg2 repos -
but the same setting is better placed in the environment: it is a display
preference one usually wants for all borg invocations, not per command.

BORG_IEC=yes now selects IEC units (1KiB = 1024B); "true" and "1" are
accepted, too, because jsonargparse's automatic BORG_<OPTION> environment
variables accepted these for --iec. Note that removing the option also
removes that automatic environment variable, so the new use_iec_units()
helper reads BORG_IEC explicitly.

The iec=... plumbing through Archive, Statistics, ArchiveFormatter and Cache
is unchanged, only the places reading args.iec now call use_iec_units().
Set BORG_DEBUG_PROFILE to a filename to get an execution profile written
there; a ".pyprof" suffix still selects the Python-compatible format.

Note that this now applies to EVERY borg invocation while the variable is
set, not just to a single command like the option did - the docs say so and
the test switches it off around the "borg debug convert-profile" call, which
would otherwise profile itself over the profile it is reading.
The command is "borg debug convert-profile", not "profile-convert".
Also, scripts/msgpack2marshal.py does not exist any more - that command
does the same job.
@ThomasWaldmann ThomasWaldmann changed the title remove --remote-path, --rsh, --upload-ratelimit and --upload-buffer options remove --remote-path, --rsh, --upload-ratelimit, --upload-buffer, --iec and --debug-profile options Jul 25, 2026
@ThomasWaldmann
ThomasWaldmann merged commit 14089ba into borgbackup:master Jul 26, 2026
19 checks passed
@ThomasWaldmann
ThomasWaldmann deleted the remove-remote-path-option branch July 26, 2026 12:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant