Remove ssh:// and socket:// remote repository for current repos (use rest://)#9732
Merged
ThomasWaldmann merged 4 commits intoJun 8, 2026
Merged
Conversation
The modern client/server transport (RemoteRepository served by `borg serve` over an msgpack RPC protocol) is now redundant for current (borg 2) repos: its functionality is replaced by rest:// (which can tunnel over ssh to a remote borgstore REST server). Remove the modern RemoteRepository (both ssh:// and socket://) entirely. Legacy v1 (borg 1.x) repos remain reachable over ssh:// via the separate LegacyRemoteRepository client, and `borg serve` / RepositoryServer is kept, trimmed to the legacy-only path, so a remote borg2 can still serve a v1 repo for `borg transfer --from-borg1`. Details: - remote.py: delete RemoteRepository, SleepingBandwidthLimiter and the `api` decorator; trim RepositoryServer to legacy-only (drop modern _rpc_methods, socket serving, non-legacy open() branch); keep cache_if_remote / RepositoryCache / RepositoryNoCache (used by all repos). - get_repository(): non-legacy ssh:// now raises a clear "use rest://" error; socket:// route and the global --socket option removed. - parseformat: drop the socket:// scheme (now an invalid location). - borg serve: keep the command (serves legacy v1 ssh only); update epilog. - borg version: drop modern remote query; keep legacy ssh path. - update isinstance/import sites (cache, archive, fuse/hlfuse, analyze/compact, archiver __init__ -> LegacyRemoteRepository.RPCError). - tests/docs updated; obsolete socket serve test removed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #9732 +/- ##
==========================================
+ Coverage 83.59% 84.69% +1.09%
==========================================
Files 93 92 -1
Lines 15717 14959 -758
Branches 2360 2231 -129
==========================================
- Hits 13139 12669 -470
+ Misses 1834 1593 -241
+ Partials 744 697 -47 ☔ View full report in Codecov by Harness. |
After removing the modern RemoteRepository, cache_if_remote always returned RepositoryNoCache in production (the only RepositoryCache path was the removed isinstance(RemoteRepository) check; force_cache=True was used only by a test). Delete the vestigial RepositoryCache class and simplify cache_if_remote: drop the pack/unpack/force_cache parameters and the LZ4/xxh64 cache-file machinery, keep building the decrypted_cache -> transform closure, and always return RepositoryNoCache. Remove the imports that only RepositoryCache used. Replace the RepositoryCache tests with a focused test of the surviving cache_if_remote path (plain passthrough and decrypted (csize, plaintext) tuples). The legacy copy in borg/legacy/remote.py is intentionally left untouched (its RepositoryCache is still used for LegacyRemoteRepository). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
borg.legacy.remote.cache_if_remote (and the RepositoryCache / RepositoryNoCache classes it returns) are dead code: nothing imports or calls them. Every cache_if_remote consumer (archive check, mount, tests) uses the non-legacy borg.remote version, and legacy repos never reach it (Archive.check rejects legacy repos). The trio was copied wholesale during the borg.legacy split (borgbackup#9556). Delete RepositoryNoCache, RepositoryCache and cache_if_remote, plus the imports that only they used (shutil, struct, tempfile, xxhash.xxh64, compress.Compressor, helpers.safe_unlink). LegacyRemoteRepository and the rest of the module are unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…itory borg.remote no longer fit its name: it held the legacy-only borg serve server plus generic repository cache wrappers used by current repos. Split by purpose and remove the module: - Move RepositoryServer into borg.legacy.remote (it only serves legacy v1 ssh repositories). It reuses the exception classes (PathNotAllowed, InvalidRPCMethod, UnexpectedRPCDataFormatFromClient) and BORG_VERSION / MSGID constants already defined there; open() uses the module-level LegacyRepository. serve_cmd.py now imports RepositoryServer from ..legacy.remote. - Move RepositoryNoCache and cache_if_remote into borg.repository (they wrap a Repository and are used by Archive.check and mount of current repos). archive.py and mount_cmds.py import them from ..repository now. - Move the cache_if_remote tests into repository_test.py; delete remote_test.py. - Delete src/borg/remote.py; fix the stale BUFSIZE comment in constants.py. Pure relocation, no behavior change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This was referenced Jun 8, 2026
This was referenced Jun 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Removes the modern
RemoteRepository(thessh://andsocket://client/server transport served byborg serveover an msgpack RPC protocol). For current (borg 2) repositories its functionality is replaced byrest://, which can itself tunnel over ssh to a remote borgstore REST server.Legacy v1 (borg 1.x) access over ssh is preserved. It uses the separate
LegacyRemoteRepositoryclient, andborg serve/RepositoryServeris kept (trimmed to the legacy-only path) so a remote borg2 can still serve a v1 repo forborg transfer --from-borg1.Changes
remote.py: deleteRemoteRepository,SleepingBandwidthLimiterand theapidecorator; trimRepositoryServerto legacy-only (drop modern_rpc_methods, socket serving, non-legacyopen()branch). Keep the general-purposecache_if_remote/RepositoryCache/RepositoryNoCache(used by all repos).get_repository(): non-legacyssh://now raises a clear "use rest://" error; thesocket://route and the global--socketoption are removed.parseformat: drop thesocket://scheme (now an invalid location).ssh://(legacy) andrest://unchanged.borg serve: kept as a command (serves legacy v1 ssh only); epilog updated.borg version: drop the modern remote query; keep the legacy ssh path.cache.py,archive.py,fuse.py/hlfuse.py,analyze_cmd.py,compact_cmd.py, andarchiver/__init__.py(RPCError handling retargeted toLegacyRemoteRepository).serve_cmd_test.pyremoved; changelog entry added.Net: 23 files changed, +101 / −1194.
Behavior
borg -r rest://…works (replacement path).borg -r ssh://host/repo create …(no--from-borg1) fails with a clear "use rest://" error;socket://…is rejected as an invalid location.borg transfer --from-borg1 --other-repo ssh://…still works: the localLegacyRemoteRepositoryspawns a remoteborg serve, which serves the v1 repo via the trimmedRepositoryServerlegacy path.Testing
Run with a venv that has
borgstore[rest](soborgstore-server-restis on PATH). All changed/related suites pass — 322 passed, 21 skipped — including the rest://remote_archivertests and the legacy ssh serve tests (legacyrepository_test.py).🤖 Generated with Claude Code